aspose file tools*
The moose likes Java in General and the fly likes Reflection Problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Reflection Problem" Watch "Reflection Problem" New topic
Author

Reflection Problem

Nikhil Sun
Ranch Hand

Joined: Nov 13, 2005
Posts: 108
Have written the following code section in my program:

Object[] o = new Object[2];
o[0] = new Integer(0);
o[1] = instance3;
m.invoke(instance1,o);

Above is giving IllegalArgumentException : argument type mismatch..
instance1 is the instance on which the method is called
the method takes 2 arguments rimitive int and another class instance.
So I have passed an integer wrapped inside Integer instance and also the correct instance3 of the other class.

Could anyone please tell me where could the problem be??
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
What does the Method m say its formal parameter types are, according to getParameterTypes() or getGenericParameterTypes()? Try getting this with a debugger, or by adding println() or logging.

Note, you could make your code rather nicer (though functionally identical): -



That's in Java 5+ only, of course.


Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.
Nikhil Sun
Ranch Hand

Joined: Nov 13, 2005
Posts: 108
the method is defined as follows:
public void setRoles(int index,MyClass clazz){
...
...
}

I did use the getParameterTypes() to get the methods formal parameters
they are int and class com.mypackage.MyClass.
And I have passed arguments as 0(wrapped in Integer instance) and instance3(which is instance of MyClass) respectively.Still I get the error...

I am using jdk1.3
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
Hmm. Sounds like you are calling correctly.

Have you checked the stack trace in detail? Is it possible that the reflection call is happening OK, but then there is an IllegalArgumentException happening during the call?
Nikhil Sun
Ranch Hand

Joined: Nov 13, 2005
Posts: 108
Ya did check the stack trace..
It gives IllegalArgumentException:argument type mismatch
This exception is surely thrown when the reflection call is made as the method that is getting invoked throws only a sole exception called RecordConversionException.So If there was any exception during the call it would have been RecordConversionException.

Also in my code initially, instance3 is defined as below:

Object instance3 = null;

Then I get the instance of MyClass through reflecting on the constructor of MyClass and let instance3 point to it:

instance3 = c.getConstructors()[1].newInstance(parameters)//parameters is null as I am calling the no args constructor

Is it possible that when instance3 is stored in the Object array at o[1] it is getting stored as an MyClass instance but as an Object because instance3 is of type Object??

Please assist me with this...stuck up
[ June 28, 2007: Message edited by: Nikhil Sun ]
Nikhil Sun
Ranch Hand

Joined: Nov 13, 2005
Posts: 108
Still need some way out...

Thing is MyClass is generated dynamically by calling an utility from my application.After this class is generated in a system folder I create an url out of it,load it and create an instance of it called instance3 as follows:

Object instance3 = null;
instance3 = c.getConstructors()[1].newInstance(parameters)//parameters is null as I am calling the no args constructor and c is loaded class MyClass
Object[] o = new Object[2];
o[0] = new Integer(0);
o[1] = instance3;
m.invoke(instance1,o);//method invoked is setRoles(int index,MyClass clazz)

I feel problem is because 2nd formal parameter expects MyClass instance but the argument passed is instance3 which points to MyClass instance but which itself is an Object reference..
Can somebody guide me how to proceed..I can't cast instance3 as it will cause ClassCastException..
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14688
    
  16

If you're not using java1.5, wouldn't the problem be here instead :
o[0] = new Integer(0); though your argument should be an "int" ?
[ June 29, 2007: Message edited by: Satou kurinosuke ]

[My Blog]
All roads lead to JavaRanch
Nikhil Sun
Ranch Hand

Joined: Nov 13, 2005
Posts: 108
If you're not using java1.5, wouldn't the problem be here instead :
o[0] = new Integer(0); though your argument should be an "int" ?


don't think so as I have sent parmeter values wrapped as Long,Short etc while invoking other methods that required long and short arguments ie primitive ones.In these cases no error is thrown.So I feel even in 1.3 the JVM internally accepts the wrapped parameters and converts them.
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14688
    
  16

ok. Are you sure that instance3 is really a MyClass instance ? Try to debug it. And is "m" pointing to the correct method ? Debug that too.
[ June 29, 2007: Message edited by: Satou kurinosuke ]
Nikhil Sun
Ranch Hand

Joined: Nov 13, 2005
Posts: 108
Yes Satou..instance3 is a MyClass instance and m too is the correct method..
Satou don't you think that the 2nd parameter is passed as an Object reference and that is the problem here?
I would like to know of some way in which this problem can be overcome..
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
After this much time, and several fairly experienced people looking at the issue, it seems that what you say you're doing is the right thing. If we disregard the small (though non-zero) chance that there's a bug in Java, we only other real possibility is that you aren't doing what you say you're doing. Only with a real, isolated piece of code can we tell.

So, at this stage, I think what you should do is try to reproduce the problem in a small piece of code, unconnected with the rest of your application. This will have two benefits: -
  • If you can't reproduce the problem in a small piece of code, the difference between the small code and your real code may reveal to you what's wrong.
  • If you can reproduce the problem in a small piece of code, you should end up with a small piece of code you can post on JavaRanch and an answer should be forthcoming quickly.

  • Christophe Verré
    Sheriff

    Joined: Nov 24, 2005
    Posts: 14688
        
      16

    m.invoke(instance1,o);//method invoked is setRoles(int index,MyClass clazz)

    I guess this is a typo, but here we go : you're passing instance1 instead of instance3.
    Nikhil Sun
    Ranch Hand

    Joined: Nov 13, 2005
    Posts: 108
    I guess this is a typo, but here we go : you're passing instance1 instead of instance3.

    Not a typo Satou ...

    Actually setRoles(int index,MyClass clazz) is a method of myMainClass...
    instance1 is instance of myMainClass and I am invoking it.Thsi method takes as 2nd parameter instance of myClass...

    Peter..will try and simulate this thing and post teh result..
    Christophe Verré
    Sheriff

    Joined: Nov 24, 2005
    Posts: 14688
        
      16

    Sorry Nikhil, I've been of no help here I hope another rancher will get it.
    Christophe Verré
    Sheriff

    Joined: Nov 24, 2005
    Posts: 14688
        
      16

    Ok. I've tried something very simple, which worked. I don't know...

    Christophe Verré
    Sheriff

    Joined: Nov 24, 2005
    Posts: 14688
        
      16

    By the way, at which line does the exception occur ? Is it really at invoke ?
    I've got a feel that the problem lies here :
    c.getConstructors()[1].newInstance(parameters)

    Why are you using 1 as an index ? How can you be sure of which constructor you're invoking ?
    Nikhil Sun
    Ranch Hand

    Joined: Nov 13, 2005
    Posts: 108
    Why are you using 1 as an index ? How can you be sure of which constructor you're invoking ?
    Satou...I am getting the no args constructor of the classes and in my case these classes are generated at runtime by a utility I use in my application.The no args constructor is at index 1 on reflecting on these auto generated code...

    Ok friends...here I go...I simulated my problem and found the reason for the exception...as suspected...

    I wrote 3 small programs:

    1)Mainclass

    public class MainClass {
    public void setRole(int i,MinorClass m){
    System.out.println("setRole is invoked");
    }

    2)MinorClass

    public class MinorClass {
    public static void main(String[] args) {
    }
    }

    3)Invoker

    public class Invoker {
    public static void main(String[] args) {
    try{
    Class c1 = Class.forName("com.test.MainClass");
    Object o1 = c1.getConstructors()[0].newInstance(null);
    Class c2 = Class.forName("com.test.MinorClass");
    Object o2 = c2.getConstructors()[0].newInstance(null);
    Method m = c1.getMethod("setRole",new Class[]{int.class,MinorClass.class});
    m.invoke(o1,new Object[]{new Integer("55"),o2});
    }catch(Exception e){
    e.printStackTrace();
    }
    }
    }

    On running Invoker program the same exception gets generated:
    java.lang.IllegalArgumentException: argument type mismatch

    When I made following changes to Invoker the method was invoked properly:

    MinorClass mc = new MinorClass();
    m.invoke(o1,new Object[]{new Integer("55"),mc});

    This time the code executes properly...

    My requirement is that when my application runs both MainClass and MinorClass are generated at runtime in a system folder...hence I can't possibly hardcode the line MinorClass mc = new MinorClass();

    Any way out???
    [ June 29, 2007: Message edited by: Nikhil Sun ]
    Peter Chase
    Ranch Hand

    Joined: Oct 30, 2001
    Posts: 1970
    o1 is a MainClass object
    Nikhil Sun
    Ranch Hand

    Joined: Nov 13, 2005
    Posts: 108
    sorry its o2..made the change..
    Peter Chase
    Ranch Hand

    Joined: Oct 30, 2001
    Posts: 1970
    And does it work now?
    Nikhil Sun
    Ranch Hand

    Joined: Nov 13, 2005
    Posts: 108
    ya it did work...i am surprised why it doesnt work in my application...no clues..
    Nikhil Sun
    Ranch Hand

    Joined: Nov 13, 2005
    Posts: 108
    yes finally got to the real cause of the problem...the classes MainClass and MinorClass get generated in a system folder at runtime.
    Then in my application I first load the MainClass using URLClassLoader..later on I load MinorClass but this time using another URLClassLoader instance...so here's the problem...the classes get loaded by different classloaders giving rise to the problem.

    In the simulation code this problem didn't exist as the classes were getting loaded by the same classloader....
    I guess I may be able to fix the problem now
    [ June 29, 2007: Message edited by: Nikhil Sun ]
    Nikhil Sun
    Ranch Hand

    Joined: Nov 13, 2005
    Posts: 108
    Friends though the previous problem is solved I am up against another obstacle now.

    If the method signature of setRole of MainClass is changed how do I invoke it???

    public class MainClass {
    public void setRole(int i,MinorClass[] m){
    System.out.println("setRole is invoked");
    }

    How could the setRole method be invoked...Please note that I am not allowed to instantiate MinorClass directly anywhere in my code ie
    I can't use MinorClass[] or new MinorClass() anywhere in my code...
    Please do suggest...
    Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    It would probably be a good idea to start a new topic on the new problem...


    The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Reflection Problem