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?
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: