• Post Reply Bookmark Topic Watch Topic
  • New Topic

Class being found by classloader but NoClassDefFoundError on newInstance() method  RSS feed

 
Salil Surendran
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Friends,
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:


Output of the code:

UCL:java.net.URLClassLoader@72093dcd

Loaded class : org.junit.runner.JUnitCore

jar:file:/C:/maven.repo/sasurendran/ebox/junit/junit/4.11/junit-4.11.jar!/org/junit/runner/JUnitCore.class

Exception in thread "Thread-0" java.lang.NoClassDefFoundError: org/junit/runner/JUnitCore
at test.com.ebay.app.rtm.biz.JUnitThread.run(JUnitThread.java:25)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: org.junit.runner.JUnitCore
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 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?




 
James Boswell
Bartender
Posts: 1051
5
Chrome Eclipse IDE Hibernate
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Could you show the POM you are using for the code?
 
Salil Surendran
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
James Boswell wrote:Could you show the POM you are using for the code?

Not using a pom. This is a simple java application. Yes, the maven.repo might have thrown you off.
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!