奇怪的“NoClassDefFoundError

时间:2012-06-20 17:58:44

标签: eclipse eclipse-plugin

这个真让我难过。

情景:

  • Windows 7 64位
  • Lotus Notes(8.5.2)
  • Eclipse Helios
  • 使用JDK 7的Java 6 Update 33(64位)
  • 插件项目的已安装JRE设置为使用Notes下安装的JVM(即C:\NotesDev\Notes\jvm)。
  • 目标平台使用上面安装的JRE,并在“位置”选项卡上导入framework\rcp\eclipseframework\shared\eclipse子文件夹。我可以看到这两个文件夹之间总共有713个插件。
  • “运行配置”显示总共选择了714个插件(其中包括目标平台中的713和我的插件)。我可以看到此列表包含org.eclipse.swt.win32.win32.x86_3.5.2.v34557f-RCP20100710-0200.jarcom.ibm.rcp.swtex.win32_6.2.2.20100729-1241.jar

问题:

  1. 如果我没有在构建路径中明确包含上述两个JAR文件,则应用程序无法编译(尝试导入org.eclipse.swt.widgets.Displaycom.ibm.rcp.swt.swidgets.SToolItem)。
  2. 如果我在构建路径中包含上述JAR文件,则应用程序会编译,但由于NoClassDefFound异常而无法运行。
  3. 问题:

    1. 为什么我需要首先包含这些文件?它们是工作区的一部分,我所引用的其他JAR文件似乎都不需要显式引用。
    2. 为什么这会在运行时失败?我的理解是NoClassDefFound发生是因为该类在编译时可用,但不是在运行时。但这是在同一台机器上发生的。 (我正在尝试在本地调试它,我甚至标记了要导出的JAR文件!)
    3. 在我看来,如果文件列在运行时配置的加载插件选项卡中,我就不必显式引用它们。我对此不正确吗? (请善待!我当然不是这方面的专家。)

      提前致谢。

      P.S。值得注意的是,如果我将文件包含在构建路径中,我可以看到它们在MANIFEST.MF.CLASSPATH文件中都被正确引用。

      MANIFEST.MF目录

      Manifest-Version: 1.0
      Bundle-ManifestVersion: 2
      Bundle-Name: Plugin
      Bundle-SymbolicName: com.satuit.crm.plugin;singleton:=true
      Bundle-Version: 1.0.0.qualifier
      Bundle-Activator: com.satuit.crm.plugin.Activator
      Bundle-Vendor: Satuit Technologies, Inc.
      Require-Bundle: org.eclipse.ui,
       org.eclipse.core.runtime,
       org.apache.axis,
       org.eclipse.ui;bundle-version="3.4.2",
       org.eclipse.core.runtime;bundle-version="3.4.0",
       org.eclipse.ui.views;bundle-version="3.3.1",
       com.ibm.rcp.jfaceex;bundle-version="6.2.2"
      Bundle-RequiredExecutionEnvironment: JavaSE-1.6
      Bundle-ActivationPolicy: lazy
      Export-Package: com.satuit.crm.plugin,
       com.satuit.crm.plugin.document,
       com.satuit.crm.plugin.ui,
       com.satuit.crm.webservice.agent
      Bundle-ClassPath: .,
       /NotesDev/Notes/framework/rcp/eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.5.2.v3557f-RCP20100710-0200.jar,
       /NotesDev/Notes/framework/rcp/eclipse/plugins/com.ibm.rcp.swtex.win32_6.2.2.20100729-1241.jar,
       /NotesDev/lib/activation-1.1.1.jar,
       /NotesDev/lib/mail.jar,
       /NotesDev/lib/commons-lang3-3.1.jar,
       /NotesDev/lib/SatuitCRM_XML_API2.jar
      

      ** .CLASSPATH目录**

      <?xml version="1.0" encoding="UTF-8"?>
      <classpath>
          <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
          <classpathentry exported="true" kind="con" path="org.eclipse.pde.core.requiredPlugins"/>  
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Notes/framework/rcp/eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.5.2.v3557f-RCP20100710-0200.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Notes/framework/rcp/eclipse/plugins/com.ibm.rcp.swtex.win32_6.2.2.20100729-1241.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Workspace/lib/commons-lang3-3.1.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Workspace/lib/activation-1.1.1.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Workspace/lib/mail.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Workspace/lib/SatuitCRM_XML_API2.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Notes/framework/rcp/eclipse/plugins/org.apache.axis_1.4.0.20100729-1241/axispatch.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Notes/framework/rcp/eclipse/plugins/org.apache.axis_1.4.0.20100729-1241/axis.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Notes/framework/rcp/eclipse/plugins/org.apache.axis_1.4.0.20100729-1241/jaxrpc.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Notes/framework/rcp/eclipse/plugins/org.apache.axis_1.4.0.20100729-1241/saaj.jar"/>
          <classpathentry exported="true" kind="lib" path="C:/NotesDev/Notes/framework/rcp/eclipse/plugins/org.apache.axis_1.4.0.20100729-1241/wsdl4j-1.5.1.jar"/>
          <classpathentry kind="src" path="src"/>
          <classpathentry kind="output" path="bin"/>
      </classpath>
      

3 个答案:

答案 0 :(得分:1)

当找不到Display或SToolItem引用的类时,也可能会出现NoClassDefFound错误。我知道找出哪个类无法找到的唯一方法是使用-verbose选项运行java应用程序。您获得的日志记录远远超过您想要查看的日志,但是在所有这些输出行中的某处是命名无法找到的特定类的错误消息。

答案 1 :(得分:1)

OSGi MANIFEST不接受系统中jar的绝对路径(它用于在包中包含jar),如果更新Java Build Path,它可能在部署时不起作用。

从根本上说,你正在编写一个OSGi包,你必须小心使用类路径。看起来你需要改变两个不同的问题。

  1. org.eclipse.swt.win32.win32.x86_3.5.2.v3557f-RCP20100710-0200.jar和com.ibm.rcp.swtex.win32_6.2.2.20100729-1241.jar已经是OSGi包。他们需要在您的目标平台上。然后,您需要将它们添加到Required-Bundles,就像com.ibm.rcp.jfaceex一样。说实话,它们看起来像碎片。在这种情况下,应该自动选择org.eclipse.swt.win32.win32.x86,因为你使用org.eclipse.ui,它会重新导出org.eclipse.swt。可能需要在com.ibm.rcp.swtex(win32 swtex片段的可能主机包)上添加Require-Bundle

  2. 您添加到Bundle-ClassPath的所有jar文件。您目标平台中已经存在的包中是否需要这些类?理想情况下,您希望从现有的OSGi包中使用它们。至少org.apache.axis已经是一个OSGi包。对于其他人来说,如果您确实需要来自这些jar的类并且它们尚未作为目标平台中的导出包存在,则需要将它们转换为OSGi包并将它们包含在目标平台中或< / strong>实际上将它们包含在你的eclipse项目中,并从那里将它们添加到你的Bundle-ClassPath(它将是一个项目根相对路径)。

答案 2 :(得分:0)

嗯,事实证明,OSGI清单接受类路径上的绝对路径。惊喜,惊喜。

是否应是另一个故事。一旦部署应用程序将对应用程序做什么是任何人的猜测。但是运行时和编译时错误已经消失,到目前为止似乎没有重新铺设。

再一次,我们认为事实和实际事实被证明是两件截然不同的事情。