Reputation: 51
I have a program in which I am generating classes at runtime (included only variable and associated getters and setters methods). Later I want to fill the classes.
To get the class - I know its Name, but its not in the classpath - I tried .forName() but I always get a ClassNotFoundException.
Here is my example:
Exception in thread "main" java.lang.ClassNotFoundException: com.test.wam.business.wsobjects.Testclass
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at gui.Application.main(Application.java:94)
And the code:
URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
DynamicURLClassLoader dynamicURLClassLoader = new DynamicURLClassLoader(urlClassLoader);
dynamicURLClassLoader.addURL(new URL("file://C:\\dev\\Eclipse_was\\guitest\\generated"));
Class c = Class.forName("com.test.wam.business.wsobjects.Testclass");
Object classInstance = c.newInstance();
The ClassLoader:
public class DynamicURLClassLoader extends URLClassLoader {
public DynamicURLClassLoader(URLClassLoader classLoader) {
super(classLoader.getURLs());
}
@Override
public void addURL(URL url) {
super.addURL(url);
}
}
The full qualified Name to the file (created with eclipse -> copy full qualified Name)
/guitest/generated/com/test/wam/business/wsobjects/Testclass.java
What is wrong here?
Upvotes: 3
Views: 12929
Reputation: 44965
The method Class.forName(String)
uses the ClassLoader
of the caller class, if you want to use a specific ClassLoader
to load your class you need to use Class.forName(String name, boolean initialize, ClassLoader loader)
instead as next:
Class c = Class.forName(
"com.test.wam.business.wsobjects.Testclass", true, dynamicURLClassLoader
);
NB: This will work if and only if the URL
that you provide to your DynamicURLClassLoader
is valid and is the path to the parent folder in which you have your class
Upvotes: 2
Reputation: 718768
I can see two problems:
1) You are creating a DynamicURLClassLoader
and adding the URL to it, but you are not actually using it. This statement:
Class c = Class.forName("com.test.wam.business.wsobjects.Testclass");
will use the classloader that loaded the current class. That is probably the application's default classloader, but it is certainly NOT the classloader you just created. The javadoc says:
[
Class.forName(className)
] returns theClass
object associated with the class or interface with the given string name. Invoking this method is equivalent to:Class.forName(className, true, currentLoader)
where
currentLoader
denotes the defining class loader of the current class.
So .... the solution is:
Class c = Class.forName("com.test.wam.business.wsobjects.Testclass",
true, dynamicURLClassLoader);
2) This string:
"file://C:\\dev\\Eclipse_was\\guitest\\generated"
is not a valid "file:" URL. The correct URL for the path you are trying to reference would be:
"file:///C:/dev/Eclipse_was/guitest/generated"
The way that you wrote the URL might work, but it is not the correct way to do it.
Reference:
Upvotes: 3