• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

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

 
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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?




 
Bartender
Posts: 1051
5
Hibernate Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Could you show the POM you are using for the code?
 
Salil Surendran
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
reply
    Bookmark Topic Watch Topic
  • New Topic