【问题标题】:Eclipse plugin rt.jar semms not to be in classpathEclipse 插件 rt.jar semms 不在类路径中
【发布时间】:2011-01-18 14:50:16
【问题描述】:

我们为 eclipse (helios) 开发了一个插件,它在工作台上运行良好,但是当我尝试导出和部署它时,出现以下异常:

java.lang.ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver
    at org.eclipse.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)

我已在插件配置的概览选项卡中设置为使用 JavaSE-1.6,并尝试了几种不同的配置。 据我所知,JdbcOjdbcDriver 是包含在 rt.jar 中的一个类,我觉得它丢失了让我很困惑。 我错过了什么?

问候, 费尔南多

【问题讨论】:

    标签: java eclipse eclipse-plugin classpath


    【解决方案1】:

    JdbcOdbcDriver 真正打包到 rt.jar 中,必须自动包含到类路径中。如果它不存在我相信你在 Eclipse 和部署环境中的 rt.jar 是不同的:

    • 版本不同
    • 供应商不同。

    你没有提到你是如何部署你的应用程序的。我相信您可以编译您的应用程序。如果您直接在代码中使用驱动程序,则它在编译时位于您的类路径中。在这种情况下,请检查编译环境和运行时环境之间的区别。

    如果您通过动态类加载引用此驱动程序:Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"),则无法在编译时确定问题。

    在这种情况下,首先尝试按下 Ctrl-Shift-T,键入 JDbcOdbcDriver 并查看 Eclipse 是否找到了一些东西。如果是,请查看它来自 rt.jar,并且这是 Eclipse 中配置的 JDK 使用的 rt.jar。可能您有多个 JDK:其中一个包含驱动程序,另一个不包含?

    【讨论】:

      【解决方案2】:

      看完OSGi and Equinox,我对OSGi类加载器有了更深入的了解。

      类查找算法

      在这里,我们假设一个包试图在包 P 中加载一些 C 类。

      1. 如果 P 以“java”开头。 || P 是引导委托
        返回 parent.loadClass(C)
      2. 如果导入了 P
        return exporter.loadClass(C)
      3. 如果 P 由某些必需的捆绑包导出
        每个出口商
        如果找到则返回 exporter.loadClass(C)
      4. 如果在本地找到 C
        返回 C
      5. 如果在片段中找到 C
        返回 C
      6. 如果 P 是动态导入的
        return exporter.loadClass(C)
      7. 如果为此捆绑包启用了好友加载 返回 BuddyLoader.loadClass(C)
      8. 抛出 ClassNotFoundException

      第 7 步不是标准的 OSGi 行为。 Equinox 增加了这一步。

      步骤 1 确保所有 java.* 包对所有包都隐式可用——它们不需要显式导入。但是,必须显式导入来自 JRE 的所有其他包。这意味着有一个匹配的出口商。 OSGi 规范规定系统捆绑包必须从 JRE 导出附加包。

      系统包在 Equinox 中称为 org.eclipse.osgi。它维护一组配置文件,其中列出了常见 JRE 类库(如 J2SE1.4、J2SE1.5 和 JCL Foundation)中可用的标准 API 包。这些配置文件不包括特定于实现的包,例如 com.sun.* 和 sun.*,因为它们不是标准的,并且并非在所有 JRE 中都可用。

      类加载算法的第 1 步提到了引导委托的概念。这是一种覆盖机制,用于标识其类加载应来自父类加载器的特定包。这对于访问不是 java.* 且不以其他方式由包导出的包很有用。要访问此类包,您可以更新 JRE 配置文件或使用 config.ini 中的 org.osgi.framework.bootdelegation 属性列出可访问的包前缀集,如下所示:

      org.osgi.framework.bootdelegation=com.sun.*,sun.*
      

      【讨论】:

      • 嗨,凯恩,感谢您的回答。我以前尝试过,但不允许我这样做。显示错误“'sun.jdbc.odbc' 没有可用的捆绑包”。我应该如何导入它?
      • 打开插件的 manifest.mf。转到“依赖项”选项卡以选择“导入包”的“添加”按钮。我只是安装 J2SE,所以我看不到这样的包。也许它是 SUN 的 J2EE 的一部分。
      • 尝试后修改我的答案
      猜你喜欢
      • 2023-03-20
      • 2011-12-22
      • 2017-11-07
      • 2010-12-08
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多