Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 293334

Summary: NoClassDefFoundError when running JUnit Plug-in test referencing a plug-in with a Bundle-ClassPath.
Product: [Eclipse Project] JDT Reporter: Paul Slauenwhite <paulslau>
Component: UIAssignee: JDT-UI-Inbox <jdt-ui-inbox>
Status: CLOSED INVALID QA Contact:
Severity: critical    
Priority: P3 CC: daniel_megert
Version: 3.5.1   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:
Bug Depends on:    
Bug Blocks: 293335    
Attachments:
Description Flags
Sample Plug-in Projects.
none
Working Demo none

Description Paul Slauenwhite CLA 2009-10-26 12:44:10 EDT
Created attachment 150530 [details]
Sample Plug-in Projects.

NoClassDefFoundError when running JUnit Plug-in test referencing a plug-in with
a Bundle-ClassPath.

When running a JUnit Plug-in test from a plug-in project that depends on
another plug-in project with one or more entries on the Bundle-ClassPath, the
plug-in project is not activated causing the following exception:

java.lang.NoClassDefFoundError: <dependent class>

Steps to reproduce:

1) Import the attached sample projects.
2) Run /Plugin_Project_B/src/a/b/c/TestFileReaderTest.java as a JUnit Plug-in
test.
3) Note the following exception:

java.lang.NoClassDefFoundError: a.b.c.TestFileReader
    at a.b.c.TestFileReaderTest.testRead(TestFileReaderTest.java:12)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    at java.lang.reflect.Method.invoke(Method.java:599)
    at junit.framework.TestCase.runTest(TestCase.java:164)
    at junit.framework.TestCase.runBare(TestCase.java:130)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:120)
    at junit.framework.TestSuite.runTest(TestSuite.java:230)
    at junit.framework.TestSuite.run(TestSuite.java:225)
    at
org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    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:134)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3855)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3476)
    at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221)
    at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
    at
org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at
org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
    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:194)
    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:368)
    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:37)
    at java.lang.reflect.Method.invoke(Method.java:599)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1287)
Caused by: java.lang.ClassNotFoundException: a.b.c.TestFileReader
    at java.lang.ClassNotFoundException.<init>(ClassNotFoundException.java:76)
    at
org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:418)
    at
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)
    at
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:398)
    at
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:101)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:609)
    ... 46 more
Comment 1 Dani Megert CLA 2009-10-27 08:03:11 EDT
I'm sorry but this code is full of issues and can never work.

1. the Bundle-Class path only contains the resource folder and hence OSGi will
   never ever find any class from that bundle
2. the build.properties is not correct which you can easily see since there is
   a warning on it. Without fixing that it can also never work
3. the example has the same package in both bundles. This is called split-package
   and needs to be declared in the manifest as such
4. the code that reads and appends should use append(char): simply add this:
	public static void main(String[] args) {
		String s= TestFileReader.read();
		System.out.println(s);
	}
   and run it ==> 84101115116 instead of "Test" ==> the test will always fail
6. I might be wrong here but as far as I know you cannot use getSystemResource in
   the OSGi world. You need to resolve the resource via bundle.getEntry(...) and
   convert the URL to a File URL using FileLocator.
Comment 2 Dani Megert CLA 2009-10-27 09:11:47 EDT
Created attachment 150619 [details]
Working Demo
Comment 3 Paul Slauenwhite CLA 2009-10-30 12:36:16 EDT
(In reply to comment #1)
> I'm sorry but this code is full of issues and can never work.
> 
> 1. the Bundle-Class path only contains the resource folder and hence OSGi will
>    never ever find any class from that bundle
> 2. the build.properties is not correct which you can easily see since there is
>    a warning on it. Without fixing that it can also never work
> 3. the example has the same package in both bundles. This is called
> split-package
>    and needs to be declared in the manifest as such
> 4. the code that reads and appends should use append(char): simply add this:
>     public static void main(String[] args) {
>         String s= TestFileReader.read();
>         System.out.println(s);
>     }
>    and run it ==> 84101115116 instead of "Test" ==> the test will always fail
> 6. I might be wrong here but as far as I know you cannot use getSystemResource
> in
>    the OSGi world. You need to resolve the resource via bundle.getEntry(...)
> and
>    convert the URL to a File URL using FileLocator.

Thanks Dani for your comments/tips.  I misunderstood the scope of the Bundle-Class.  Apologies for the inconvenience.