We've developed a plugin for eclipse (helios) and it works perfectly at the workbench, but when I try to export and deploy it, the follow expcetion is being raised:
java.lang.ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver
at org.e开发者_开发知识库clipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:506)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:186)
at learsoft.system.plugin.handlers.endOracleSession.conect(endOracleSession.java:31)
at learsoft.system.plugin.handlers.SampleHandler.execute(SampleHandler.java:45)
at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:293)
at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
at org.eclipse.ui.internal.handlers.SlaveHandlerService.executeCommand(SlaveHandlerService.java:241)
at org.eclipse.ui.menus.CommandContributionItem.handleWidgetSelection(CommandContributionItem.java:820)
at org.eclipse.ui.menus.CommandContributionItem.access$19(CommandContributionItem.java:806)
at org.eclipse.ui.menus.CommandContributionItem$5.handleEvent(CommandContributionItem.java:796)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1258)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3552)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3171)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2629)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2593)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2427)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:670)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:663)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
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:369)
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:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
I've setted at the overview tab in plugin configuration to use JavaSE-1.6 and tryed several different configurations. As far as I know JdbcOjdbcDriver is a class included in rt.jar and seems confusing to me that it is missing. What am I missing?
Regards, Fernando
JdbcOdbcDriver is really packaged into rt.jar that must be automatically included into classpath. If it does not exist I believe that your rt.jar in eclipse and in deployment environments are different:
- versions are different
- vendors are different.
You did not mention how are you deploying your application. I believe that your can compile your application. If you are using the driver directly in your code it is in your classpath when compiling. In this case check what is the difference between compilation and runtime env.
If your are referencing to this driver via dynamic class loading: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") the problem just cannot determined in compile time.
In this case first try to strike Ctrl-Shift-T, type JDbcOdbcDriver and see whether Eclipse finds something. If yes, see that it is coming from rt.jar and that this is the rt.jar that is used by your JDK configured in Eclipse. Probably you have several JDKs: one of them contains the driver, other does not?
After reading OSGi and Equinox, I have better understanding of OSGi class loader.
Class Lookup Algorithm
Here, we assume that a bundle is trying to load some class C in package P.
- if P starts with "java." || P is boot delegated
return parent.loadClass(C)- if P is imported
return exporter.loadClass(C)- if P is exported by some required bundles
for each exporter
return exporter.loadClass(C) if found- if C is found locally
return C- if C is found in a fragment
return C- if P is dynamically imported
return exporter.loadClass(C)- if buddy loading is enabled for this bundle return BuddyLoader.loadClass(C)
- throw a ClassNotFoundException
Step 7 is not standard OSGi behavior. Equinox adds this step.
Step 1 ensures that all java.* packages implicitly available to all bundles--they need not be explicitly imported. All other packages from JRE must, however, be explicitly imported. This implies that there is a matching exporter. The OSGi specification states that the System Bundle must export the additional packages from the JRE.
The System Bundle is known as org.eclipse.osgi in Equinox. It maintains a set of profiles that lists the standard API packages available in common JRE class libraries such as J2SE1.4, J2SE1.5, and JCL Foundation. These profiles do not include implementation-specific packages such as com.sun.* and sun.*, as they are not standard and are not available in all JREs.
Step 1 of the class loading algorithm mentions the notion of boot delegation. This is an override mechanism that identifies particular packages whose class loads should come from the parent class loader. This is useful for accesssing packages that are not java.* and are not otherwise exported by a bundle. To get access to such packages, you can either update the JRE profile or use the org.osgi.framework.bootdelegation property in config.ini to list the set of accessible package prefixes as follows:
org.osgi.framework.bootdelegation=com.sun.*,sun.*
精彩评论