I have an junit testcase that tests a eclipse application with a very long classpath and this can't be executed in Eclipse because of Windows classpath limitations. So I decided to write a program that will execute the the JUnit Test. I create my own classloader that takes the long classpath as url and then from the classpath create "org.junit.runner.JUnitCore" and create a new instance from this class. I can load the class without any problem but as soon as I try to instantiate an object of this class I get a NoClassDefFoundError. Here is the code:
This is the thread class which uses the custom class loader I created:
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: org/junit/runner/JUnitCore
Caused by: java.lang.ClassNotFoundException: org.junit.runner.JUnitCore
at java.security.AccessController.doPrivileged(Native Method)
... 2 more
As you can see the ClassLoader is able to find the class but not able to instantiate it from jar file 'jar:file:/C:/maven.repo/sasurendran/ebox/junit/junit/4.11/junit-4.11.jar' but not able to create a newInstance of it. Could you please help me?
So the problem comes from this line if I read you correctly:
If that is the case, the problem isn't the clz.newInstance(), it is the JUnitCore junit You could prove it to yourself by splitting the line into two and see where the error occurs:
Here is what happens: When you refer to JUnitCore on the left-hand-side, the JVM has to load that class. It gets loaded using the same ClassLoader which loaded the class in which the code resides - the ClassLoader which loaded the JUnitThread class - which is the same one which loaded the RunJUnitTests class, which is probably the default system class loader.
So how do you fix this?
1) Don't load the JUnitThread class from the system class loader. Instead, use the RunJUnitTests class to create the ClassLoader, then use the created class loader to load, instantiate, and start the JUnitThread. Never refer to the JUnitThread class by name - only use reflection.
2) Create a custom ClassLoader class, and use it as the System class loader (I believe there is a command line flag to do so.)
3) Flatten your class path so it isn't so deep that you can't access the classes you need.
Personally, I would go with #3, and if that was impossible, I would go with #1, because at least the entry point for JUnitThread class is simple.