Results 1 to 17 of 17
  1. #1
    martinmarinov is offline Member
    Join Date
    Jun 2010
    Posts
    9
    Rep Power
    0

    Default Class.forName and casting

    Hi there. I'm doing a bit of Android development and I stumbled across a problem :)

    Java Code:
    			Class<?> receiver_Class = Class.forName(FM_RECEIVER_PATH);
    			Object obj = getSystemService(FM_SERVICE);
    obj is an instance of the class receiver_Class. I'm sure that I have the correct receiver_Class cuz I tried printing its methods and they appear correct. I'm sure I have the correct instance, obj because it's not null :) The problem is how to combine them in a useful way.

    I don't have the source of the class but I have the decomiled .slimi file and I was able to reconstruct an interface that has all the methods inside the class. The problem is that when I try

    Java Code:
    IFMRadio receiver = (IFmReceiver) receiver_Class.cast(obj);
    where the IFMRadio is the interface I reconstructed, I get a ClassCastException error.

    Can somebody help me :)

    P.S.

    Java Code:
    receiver_Class.isInstance(obj)
    returns true :)

    Update:
    I put IFMRadio into a FM_RECEIVER_PATH package and the casting stopped throwing that error. But now when I try to invoke a method, the app on the phone just freezes :( I tried making IFMRadio an asbtract class instead of an interface and now everything just returns the default value for its type (like 0 if the procedure is due to return an int).

    And another update:
    I tried invoking a method by using Method.invoke on an object that has been assigned to receiver_Class.cast(obj). No errors occurred and the results were still 0s which might mean that using of an abstract class does work and the function I'm testing is supposed to return a value 0. But anyway I will need to cast that thing to a class or an interface, so I could be able to override some methods of a remote listener class.

    Do you thing casting on an abstract class actually worked?
    Last edited by martinmarinov; 06-09-2010 at 12:12 AM.

  2. #2
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,424
    Rep Power
    25

    Default

    Object obj = getSystemService(FM_SERVICE);
    Did you print obj.getClass.getName() to verify the correct class?
    IFMRadio receiver = (IFmReceiver)...
    You show different classes here? What's their relationship?

  3. #3
    martinmarinov is offline Member
    Join Date
    Jun 2010
    Posts
    9
    Rep Power
    0

    Default

    Well, sorry for the confusion. I wrote the name IFMRadio just as an example cuz the real name doesn't matter but anyway. The real name of the class is FmReceiver and FM_SERVICE is just a string leading to that class. I renamed the interface I created the same way FmReceiver and put it into a package with the same name (FM_SERVICE), but in my own project.
    Nevertheless, let's say
    Java Code:
    Object instance = receiver_Class.cast(obj);
    When I make FmReceiver an abstract class (instead of an interface) this returns true
    instance.getClass().getName().equals(FmReceiver.getClass().getName())
    Actually if they weren't equal doing
    Java Code:
    FmReceiver receiver = (FmReceiver) instance
    would rise an error (ClassCastException) but after I changed the name of my abstract class and put it into FM_SERVICE path (a.k.a the names of the two classes and their paths are now the same) I stopped getting that error.

    But now I can't be sure if that plan worked. Not getting an error doesn't mean that everything is ok (casting upon FmReceiver when it was an interface was giving me an error) :D I'll come up with a test to see whether receiver actually does anything useful :)

    And btw I only implemented the public methods and fields in my FmReceiver abstract class. Do I have to implement the private as well? :?

    Thank you for your time! :)

    Update:
    So I made a body of one of the methods (namely getStatus()) within my abstract class and made it always return -1. And when I do the casting and I call receiver.getStatus() i get 0. So do you thing that means that the casting is working :?
    Last edited by martinmarinov; 06-09-2010 at 08:12 AM.

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,014
    Rep Power
    20

    Default

    I'm seriously confused here.

    What class is FM_RECEIVER_PATH, and how does that relate to the class in FM_SERVICE, and the FmReceiver?

    More importantly, on the line throwing the exception:
    Java Code:
    IFMRadio receiver = (IFmReceiver) receiver_Class.cast(obj);
    How do all 4 bits here relate to each other?
    IFMRadio, IFMReceiver, receiver_Class (We don't use underscores by the way), and the class that obj is supposed to be (use a debugger to find that one out).

  5. #5
    martinmarinov is offline Member
    Join Date
    Jun 2010
    Posts
    9
    Rep Power
    0

    Default

    Yeah, it's hard to explain :D

    So here they are

    Java Code:
    public static final String FM_SERVICE = "blah blah";
    public static final String FM_RECEIVER_PATH = "blah blah";
    Class<?> receiver_Class = Class.forName(FM_RECEIVER_PATH);
    Object obj = getSystemService(FM_SERVICE);
    Object instance = receiver_Class.cast(obj);
    FmReceiver receiver = (FmReceiver) instance;
    
    receiver_Class.isInstance(obj); //returns true
    instance.getClass().getName().equals(FmReceiver.getClass().getName()); //returns true
    Last edited by martinmarinov; 06-09-2010 at 02:51 PM.

  6. #6
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,014
    Rep Power
    20

    Default

    OK, so which bit throws the ClassCast?

    Presumably it's this bit:
    Java Code:
    FmReceiver receiver = (FmReceiver) instance;
    Which implies that instance is not of the same FmReceiver class.
    How have you written FmReceiver?
    Are there two versions floating around?
    You talked about writing an interface from some decompiled class? If you think you can then cast from the "real" class to your interface then that won't work.

    You're going to have to explain, as I asked, the relationship between all this stuff.

  7. #7
    martinmarinov is offline Member
    Join Date
    Jun 2010
    Posts
    9
    Rep Power
    0

    Default

    :) Sorry for the confusing description. The whole thing is one big mess :D

    Anyway, here's what I did. Firstly I wrote FmReceiver as an interface and that didn't work. When FmReceiver was an interface
    Java Code:
    FmReceiver receiver = (FmReceiver) instance;
    threw the error. Then I made FmReceiver abstract class (by rewriting it), the error disappeared. But does it mean that the casting was successful?

  8. #8
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,014
    Rep Power
    20

    Default

    But what is "instance"?
    How do the classes relate to each other?

    You wrote FmReceiver, but is "instance" an FmReceiver?

    You can only cast an object into something that the object is a class of....that's it.

    Do you understand classes, interfaces, inheritance?

  9. #9
    martinmarinov is offline Member
    Join Date
    Jun 2010
    Posts
    9
    Rep Power
    0

    Default

    Quote Originally Posted by Tolls View Post
    But what is "instance"?
    How do the classes relate to each other?

    You wrote FmReceiver, but is "instance" an FmReceiver?

    You can only cast an object into something that the object is a class of....that's it.

    Do you understand classes, interfaces, inheritance?
    Java Code:
    Object instance = receiver_Class.cast(obj);
    FmReceiver receiver = (FmReceiver) instance;
    instance is just an object which should hold an instance of the com.(...).FmReceiver class.

    Ok, basically I'll try to put it down as a simple question. Nevermind all the examples :D

    Let's say I don't have the source code of a class and I want to load it dynamically. The only thing I know about this class is its name, its location in the system and its methods but I don't have their explicit implementation (body). I also have an object which I know is an instance of that particular class. So what should I do then :)
    Last edited by martinmarinov; 06-09-2010 at 02:51 PM.

  10. #10
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,014
    Rep Power
    20

    Default

    Cast it to that class.
    Why are you writing your own?

    You don't need the source code to use a Java class.

  11. #11
    martinmarinov is offline Member
    Join Date
    Jun 2010
    Posts
    9
    Rep Power
    0

    Default

    Quote Originally Posted by Tolls View Post
    Cast it to that class.
    How and to which one :( I don't have its source code...

    P.S. I can use getMethods and then invoke the one I need but that is very inconvenient.
    Last edited by martinmarinov; 06-09-2010 at 02:22 PM.

  12. #12
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,014
    Rep Power
    20

    Default

    Right, let's start at the beginning.

    Presumably you have the following class in a jar file somewhere:
    "com.broadcom.bt.service.fm.FmReceiver"

    Otherwise this would fail:
    Java Code:
    Class<?> receiver_Class = Class.forName(FM_RECEIVER_PATH);
    Is that correct?

  13. #13
    martinmarinov is offline Member
    Join Date
    Jun 2010
    Posts
    9
    Rep Power
    0

    Default

    Well, kind of. The class is on the Android device but it's in an odex file, not a jar file. I guess I can't import it into Eclipse. I decompiled it using smali. Hope that helps :(

  14. #14
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,014
    Rep Power
    20

    Default

    If you're working with Android you need the Android development kit.
    I wouldn't attempt to use stuff designed for that on a J2SE project...

  15. #15
    martinmarinov is offline Member
    Join Date
    Jun 2010
    Posts
    9
    Rep Power
    0

    Default

    Yep, I have installed Android SDK but the fm radio is not in the SDK (because it is device specific stuff) and it's not documented anywhere :D So I thought I was able to reconstruct some of the stuff. Btw if I turn the odex file into a dex file, can I import it into eclipse somehow?

    EDIT: I guess I can't cuz from what I've read dex is a "Dalvik Executable" file for the Android Dalvik VM... :( So I there's no way I can import anything from that into Eclipse
    Last edited by martinmarinov; 06-09-2010 at 02:41 PM.

  16. #16
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,014
    Rep Power
    20

    Default

    You really need to take this to an Android forum I would say.
    The one here always seems a bit quiet, so I'd find a more fully fledged one.

  17. #17
    martinmarinov is offline Member
    Join Date
    Jun 2010
    Posts
    9
    Rep Power
    0

    Default

    Ok, thanks man :)
    I really appreciated you time and effort :)

Similar Threads

  1. Class.forName(ObjectName).newInstance()
    By nurkhasanah in forum AWT / Swing
    Replies: 2
    Last Post: 05-07-2010, 04:51 AM
  2. Casting a child class into a parent class.
    By Unsub in forum New To Java
    Replies: 7
    Last Post: 01-30-2010, 01:39 AM
  3. Class.forName Exception
    By Moncleared in forum Advanced Java
    Replies: 5
    Last Post: 02-21-2009, 06:08 AM
  4. about Class.forName
    By angus203 in forum New To Java
    Replies: 0
    Last Post: 11-25-2007, 04:47 AM
  5. question about Class.forName()
    By oregon in forum JDBC
    Replies: 4
    Last Post: 08-01-2007, 04:52 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •