【问题标题】:Eclipse RCP classloading problem with MetroMetro 的 Eclipse RCP 类加载问题
【发布时间】:2010-01-20 17:11:03
【问题描述】:

我正在尝试从 Eclipse RCP 应用程序中使用 Metro library 调用 Web 服务。我将相关的 Metro jar(webservices-tools.jarwebservices-rt.jarwebservices-api.jar)捆绑到一个插件中,并使我的主应用程序插件依赖于这个新的 Metro 插件。

我还将webservices-api.jar 添加到我的$JAVA_HOME/jre/lib/endorsed 目录中。根据 Metro 网站,在 Java 1.6 中使用 Metro 时需要这样做。

现在,当我调用任何 Web 服务时,我收到以下错误:

javax.xml.ws.WebServiceException: Provider com.sun.xml.ws.spi.ProviderImpl not found
at javax.xml.ws.spi.FactoryFinder.newInstance(FactoryFinder.jav a:38)
at javax.xml.ws.spi.FactoryFinder.find(FactoryFinder.java:133)
at javax.xml.ws.spi.Provider.provider(Provider.java:83)
at javax.xml.ws.Service.<init>(Service.java:56)  
...  
Caused by: java.lang.ClassNotFoundException: com.sun.xml.ws.spi.ProviderImpl
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301 )
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at org.eclipse.core.runtime.internal.adaptor.ContextFinder.load Class(ContextFinder.java:129)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at javax.xml.ws.spi.FactoryFinder.newInstance(FactoryFinder.jav a:34)
... 43 more

com.sun.xml.ws.spi.ProviderImpl 类位于webservices-rt.jar,这是我的 Metro 插件的一部分。此外,我已经验证了我的应用程序插件代码可以成功加载这个类,所以我不确定为什么javax.xml.ws.spi.FactoryFinder 不能。

由于javax.xml.ws.spi.FactoryFinder 驻留在webservices-api.jar 中(我必须将 jar 放在 jre 的认可目录中),我怀疑这与认可代码无法从 Eclipse 插件加载类有关。

是不是JVM从背书目录加载的代码不能从插件加载类?有什么办法可以启用吗?

Java 版本:1.6.0_16

Eclipse 版本:面向 Web 开发人员的 Eclipse Java EE IDE 构建 ID:20090920-1017(它不显示超出该版本的版本)

Metro 版本:与 Glassfish 2.1 捆绑在一起

非常感谢任何帮助。谢谢。

【问题讨论】:

    标签: java eclipse-rcp java-metro-framework


    【解决方案1】:

    对于遇到此问题的其他人,我能够找到解决方案。我使用这些 JVM 选项将 Metro jar 以及包含我的 wsit 配置文件的配置目录添加到 JVM 的引导类路径中:

    -Xbootclasspath/a:./lib/webservices-api.jar
    -Xbootclasspath/a:./lib/webservices-rt.jar
    -Xbootclasspath/a:./lib/webservices-tools.jar
    -Xbootclasspath/a:./config
    

    webservices-api.jar 不再需要在 $JAVA_HOME/jre/lib/endorsed 中才能正常工作。它当然不是普通的 Eclipse 模型,但这是我发现在 Java 1.6 的 Eclipse RCP 应用程序中使用 Metro 的唯一方法。

    【讨论】:

      【解决方案2】:

      Java SE 6 已经包含 Metro。它包含 jax-ws 2.0,因此您可以完全删除这些 jar。

      仅当您有特定需要将 jax-ws 2.1 与 java SE 6 一起使用时,您可以按照此处的说明进行操作 -> https://jax-ws.dev.java.net/faq/index.html

      编辑:你对你最后的评论是正确的。放置在 endorsed 文件夹中的代码是使用 endorsed 类加载器加载的,因此它无法找到位于插件中的类。我建议你把所有的地铁罐子放在认可的目录中。这样,它们不仅可用于您的插件,还可用于整个 VM。

      【讨论】:

      • 问题是JAX-WS的Java SE 6版本没有实现安全性。我已尝试按照您的建议删除 Metro jar,在这种情况下,我克服了上述错误,但随后我从服务器收到错误消息,抱怨我的客户端不包含安全标头(确认 JAX-WS 的 JDK 版本不实现安全性)。所以我认为我确实需要使用 JAX-WS 的 Metro 版本来实现安全性。
      • 您确定缺乏安全性吗?该指南明确指出“Java SE 6 Update Release 4 及更高版本已经包含 JAX-WS 2.1 API,不再需要以下解决方法”
      • 关于您的编辑,Metro 网站明确指出只有 webservices-api.jar 应该进入认可的目录,而不是其他 jar。不过,我确实尝试将其他 Metro jar 放在背书目录中。当我这样做时,我开始收到奇怪的 LinkageErrors。关于缺乏安全性,我在另一个在线论坛上读到过。当然,这并不意味着它是真的,但是当我尝试在没有任何 Metro jar 的情况下运行时,客户端会运行但在请求中不包含安全标头(由服务器和 tcpmon 返回的错误确认)。
      最近更新 更多