Fix for ClassNotFoundException in PDE JUnit Test Runner

When trying to run a PDE JUnit test suite in Eclipse, the requested unit test is not executed, the hosted workbench terminates immediately with the following error to the console (where org.epic.perleditor.editors.TestEditorAssociation is the name of the unit test). The plug-in which contains the allegedly missing class is present in the workspace. (This error also falls into the "it used to work before" category.)

Class not found org.epic.perleditor.editors.TestEditorAssociation
java.lang.ClassNotFoundException: org.epic.perleditor.editors.TestEditorAssociation
 at org.eclipse.osgi.framework.internal.core.BundleLoader.findClassInternal(BundleLoader.java:481)
 at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:397)
 at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:385)
 at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:87)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
 at org.eclipse.osgi.framework.internal.core.BundleLoader.loadClass(BundleLoader.java:313)
 at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:227)
 at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1274)
 at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner$BundleClassLoader.findClass(RemotePluginTestRunner.java:38)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClass(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClasses(RemoteTestRunner.java:425)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:445)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
 at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:62)
 at org.eclipse.pde.internal.junit.runtime.UITestApplication$1.run(UITestApplication.java:114)
 at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
 at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:133)
 at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3378)
 at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3036)
 at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2382)
 at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2346)
 at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2198)
 at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:493)
 at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:288)
 at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:488)
 at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
 at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
 at org.eclipse.pde.internal.junit.runtime.UITestApplication.start(UITestApplication.java:46)
 at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:193)
 at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
 at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
 at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:386)
 at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:549)
 at org.eclipse.equinox.launcher.Main.basicRun(Main.java:504)
 at org.eclipse.equinox.launcher.Main.run(Main.java:1236)
 at org.eclipse.equinox.launcher.Main.main(Main.java:1212)

Solution: edit META-INF/MANIFEST.MF of the plug-in containing the not found class and add the class folder (i.e. bin) to the Bundle-ClassPath: directive, like so:

Bundle-ClassPath: cglib-full-2.0.2.jar,
 easymock.jar,
 bin/

If you need to debug this problem in more detail, the method responsible for finding the class (which works in a good configuration, and fails otherwise) is org.eclipse.osgi.framework.internal.core.BundleLoader.findLocalClass.

1 comment:

Anonymous said...

cool tip, can save few hours. by the way java.lang.ClassNotFoundException comes because ClassLoader fails to load the class requested at runtime.This is mostly an environmental issue which depends upon whether request class is present in Classpath or not.to solve this error best approach is to first find the jar file in which problamatic class exists and then examine your classpath.also don't confuse this with NoClassDefFoundError which is entirely different , for details see here NoClassDefFoundError vs ClassNotFoundException in Java

Post a Comment