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:
package test.com.ebay.app.rtm.biz;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
public class RunJUnitTests {
private String classPath = "C:\\Unzips\\jmockit-1.1\\jmockit\\jmockit.jar;C:\\maven.repo\\sasurendran\\ebox\\junit\\junit\\4.11\\junit-4.11.jar;... Very long classpath";
/**
* @param args
*/
public static void main(String[] args) {
RunJUnitTests runJUnitTests = new RunJUnitTests();
runJUnitTests.doWork();
}
private void doWork() {
//printClassPath(((URLClassLoader)this.getClass().getClassLoader()).getURLs());
URLClassLoader ucl = new URLClassLoader(getClassPathAsURLs(classPath));
System.out.println("UCL:" + ucl.toString());
/*printClassPath(ucl.getURLs());
Thread.currentThread().setContextClassLoader(ucl);*/
JUnitThread runJUnitTests = new JUnitThread(ucl);
Thread t = new Thread(runJUnitTests);
t.setContextClassLoader(ucl);
t.start();
}
private void printClassPath(URL[] urls){
for(URL url:urls)
System.out.println(url.toString());
}
public URL[] getClassPathAsURLs(String classpath) {
List<URL> urlList = new ArrayList<URL>();
for(String path : classpath.split(";")){
try {
urlList.add(new File(path).toURI().toURL());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return urlList.toArray(new URL[]{});
}
}
This is the thread class which uses the custom class loader I created:
package test.com.ebay.app.rtm.biz;
import java.net.URLClassLoader;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class JUnitThread implements Runnable {
URLClassLoader ucl;
public JUnitThread(URLClassLoader cl){
ucl = cl;
}
@Override
public void run() {
try {
Class<JUnitCore> clz = (Class<JUnitCore>) ucl.loadClass("org.junit.runner.JUnitCore");
System.out.println("Loaded class : " + clz.getName());
//Object obj = clz.newInstance();
System.out.println(clz.getClassLoader().getResource("org/junit/runner/JUnitCore.class"));
//JUnitCore junit = (JUnitCore)obj;
JUnitCore junit = clz.newInstance();
System.out.println("Thread CL:" + Thread.currentThread().getContextClassLoader().toString());
Result result = junit.runClasses(RtmCampaignSelectorTest.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
}
}
}
Output of the code:
UCL:java.net.URLClassLoader@72093dcd<br>
Loaded class : org.junit.runner.JUnitCore<br>
jar:file:/C:/maven.repo/sasurendran/ebox/junit/junit/4.11/junit-4.11.jar!/org/junit/runner/JUnitCore.class<br>
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?
Thanks,
Salil
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:
package test.com.ebay.app.rtm.biz;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
public class RunJUnitTests {
private String classPath = "C:\\Unzips\\jmockit-1.1\\jmockit\\jmockit.jar;C:\\maven.repo\\sasurendran\\ebox\\junit\\junit\\4.11\\junit-4.11.jar;... Very long classpath";
/**
* @param args
*/
public static void main(String[] args) {
RunJUnitTests runJUnitTests = new RunJUnitTests();
runJUnitTests.doWork();
}
private void doWork() {
//printClassPath(((URLClassLoader)this.getClass().getClassLoader()).getURLs());
URLClassLoader ucl = new URLClassLoader(getClassPathAsURLs(classPath));
System.out.println("UCL:" + ucl.toString());
/*printClassPath(ucl.getURLs());
Thread.currentThread().setContextClassLoader(ucl);*/
JUnitThread runJUnitTests = new JUnitThread(ucl);
Thread t = new Thread(runJUnitTests);
t.setContextClassLoader(ucl);
t.start();
}
private void printClassPath(URL[] urls){
for(URL url:urls)
System.out.println(url.toString());
}
public URL[] getClassPathAsURLs(String classpath) {
List<URL> urlList = new ArrayList<URL>();
for(String path : classpath.split(";")){
try {
urlList.add(new File(path).toURI().toURL());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return urlList.toArray(new URL[]{});
}
}
This is the thread class which uses the custom class loader I created:
package test.com.ebay.app.rtm.biz;
import java.net.URLClassLoader;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class JUnitThread implements Runnable {
URLClassLoader ucl;
public JUnitThread(URLClassLoader cl){
ucl = cl;
}
@Override
public void run() {
try {
Class<JUnitCore> clz = (Class<JUnitCore>) ucl.loadClass("org.junit.runner.JUnitCore");
System.out.println("Loaded class : " + clz.getName());
//Object obj = clz.newInstance();
System.out.println(clz.getClassLoader().getResource("org/junit/runner/JUnitCore.class"));
//JUnitCore junit = (JUnitCore)obj;
JUnitCore junit = clz.newInstance();
System.out.println("Thread CL:" + Thread.currentThread().getContextClassLoader().toString());
Result result = junit.runClasses(RtmCampaignSelectorTest.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
}
}
}
Output of the code:
UCL:java.net.URLClassLoader@72093dcd<br>
Loaded class : org.junit.runner.JUnitCore<br>
jar:file:/C:/maven.repo/sasurendran/ebox/junit/junit/4.11/junit-4.11.jar!/org/junit/runner/JUnitCore.class<br>
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?
Thanks,
Salil