Reputation: 1210
I have a class Foo as follows:
public class Foo extends Bar
{
public Foo(com.example.X displayState, com.example.Y parent)
{
super(displayState, parent);
}
}
The Bar class is shown below:
public abstract class Bar {
public Bar(com.example.X displayState, com.example.Y parent)
{
// do something with received params
}
}
Additionally, there is a factory class with the following method:
public static Object getInstance(Class theSourceClass, Class theTargetClass, Class[] parameterClasses, Object[] parameterValues)
{
Class theClass = (theTargetClass == null) ? theSourceClass : theTargetClass;
try
{
Constructor classConstructor = theClass.getConstructor(parameterClasses);
return classConstructor.newInstance(parameterValues);
}
catch (NoSuchMethodException exp)
{
// log
}
The problem is that the NoSuchMethodException
exception always arises:
java.lang.NoSuchMethodException: com.example.Foo.<init>(com.example.X, com.example.Y)
at java.lang.Class.getConstructor0(Class.java:2715)
at java.lang.Class.getConstructor(Class.java:1659)
at com.example.MyFactory.getInstance(MyFactory.java:30)
I have debugged the code and the class information has correct details about the defined constructor; however, the exception is here.
Does anybody have any idea what is missed? Thanks!
Upvotes: 1
Views: 1449
Reputation: 1210
The root of the problem was the different version of the compiled Bar, X, Y, and factory classes which were used for the compilation and in runtime. Let me explain.
All 4 guys (Bar, X, Y, and factory class) are compiled and come from the library file for the Foo class compilation. However, the production system always re-compile these classes.
I created the library, connected it to the build path, and forgot about it. Technically, the project has no errors during the compilation yet the reflection fails.
The solution was simple - remove the library and use re-generated Bar, X, Y, and factory classes for the Foo compilation.
Upvotes: 0
Reputation: 94479
The following example will produce an instance of Foo
. The example ensures that a constructor in Bar
exists that accepts X
and Y
.
Foo.java
public class Foo extends Bar {
public Foo(com.example.X displayState, com.example.Y parent) {
super(displayState, parent);
}
}
Bar.java
import com.example.X;
import com.example.Y;
public class Bar {
public Bar(X displayState, Y parent) {
// TODO Auto-generated constructor stub
}
}
X.java
package com.example;
public class X {
}
Y.java
package com.example;
public class Y {
}
Test.java
import java.lang.reflect.Constructor;
import com.example.X;
import com.example.Y;
public class Test {
public static void main(String[] args) {
Class[] classes = {X.class, Y.class};
Object[] values = {new X(), new Y()};
Object obj = getInstance(Foo.class, null, classes, values);
System.out.println(obj);
}
public static Object getInstance(Class theSourceClass,
Class theTargetClass, Class[] parameterClasses,
Object[] parameterValues) {
Class theClass = (theTargetClass == null) ? theSourceClass
: theTargetClass;
try {
Constructor classConstructor = theClass
.getConstructor(parameterClasses);
return classConstructor.newInstance(parameterValues);
} catch (Exception e) {
}
return null;
}
}
Upvotes: 2