4

我问这个问题只是为了让我自己回答,因为它让我发疯了两天,没有其他人应该像我一样受苦。

部署我的耳朵时,我得到这样的例外:


Exception while invoking class org.glassfish.appclient.server.core.AppClientServerApplication start method
org.jvnet.hk2.component.ComponentException: injection failed on org.glassfish.appclient.server.core.jws.JavaWebStartInfo.dch with class org.glassfish.appclient.server.core.jws.DeveloperContentHandler
    at org.jvnet.hk2.component.InjectionManager.error_injectionException(InjectionManager.java:284)
    at org.jvnet.hk2.component.InjectionManager.inject(InjectionManager.java:161)
    at org.jvnet.hk2.component.InjectionManager.inject(InjectionManager.java:93)
.
.
Caused by: org.jvnet.hk2.component.ComponentException: Failed to create class org.glassfish.appclient.server.core.jws.DeveloperContentHandler
.
.
Caused by: java.lang.AbstractMethodError: javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
.
.

或者有时像这样:


Exception while loading the app : injection failed on org.glassfish.appclient.server.core.jws.JavaWebStartInfo.dch with class org.glassfish.appclient.server.core.jws.DeveloperContentHandler
org.jvnet.hk2.component.ComponentException: Failed to create class org.glassfish.appclient.server.core.jws.DeveloperContentHandler
    at com.sun.hk2.component.ConstructorCreator.create(ConstructorCreator.java:71)
    at com.sun.hk2.component.AbstractCreatorImpl.get(AbstractCreatorImpl.java:80)
.
.
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.glassfish.appclient.server.core.jws.DeveloperContentHandler

这个错误完全令人费解,因为在一台机器上运行良好的 ear 文件可能无法在另一台机器上部署,并且服务器可能看起来被该问题“感染”并拒绝部署以前运行良好的 ear。清除缓存和生成的文件不会让它消失。

4

2 回答 2

3

经过数小时的摆弄后,我想我有了答案-问题是由于ear lib文件夹中包含一个xerxes-impl jar文件引起的。我怀疑通过一些类加载怪异它正在替换服务器自己的 xml 解析器。这解释了奇怪的感染问题,因为类路径问题在服务器重新启动之前不会消失。任何 xml 解析器都可能会出现问题,但我没有检查过。

要解决此问题,请关闭 glassfish,确保您正在部署的 ear 中没有 xerces,然后重新启动 glassfish 并部署新的 clean ear 文件。它应该工作。它对我有用。如果做不到这一点,我认为你唯一的办法就是献血。

于 2012-05-12T18:08:24.977 回答
1

JDK 定义了javax.xml.parsers.DocumentBuilderFactory接口并提供了默认实现。服务提供者可以通过设置系统属性“javax.xml.parsers.DocumentBuilderFactory”来替换实现类。当您部署 xerces 时,它使用此属性来提供它自己的实现。

来自javax.xml.parsers.DocumentBuilderFactory的片段:

   public static DocumentBuilderFactory newInstance() {
    try {
        return (DocumentBuilderFactory) FactoryFinder.find(
            /* The default property name according to the JAXP spec */
            "javax.xml.parsers.DocumentBuilderFactory",
            /* The fallback implementation class name */
            "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
    } catch (FactoryFinder.ConfigurationError e) {
        throw new FactoryConfigurationError(e.getException(),
                                            e.getMessage());
    }

}

所有这些也适用于javax.xml.parsers.SAXParserFactory

选择解析器实现

如果未指定其他工厂类,则使用默认 SAXParserFactory 类。要使用来自不同制造商的解析器,您可以更改指向它的环境 > 变量的值。您可以从命令行执行此操作:

java -Djavax.xml.parsers.SAXParserFactory=yourFactoryHere [...]

您指定的工厂名称必须是完全限定的类名(所有包前缀>包含)。有关更多信息,请参阅 >SAXParserFactory 类的 newInstance() 方法中的文档。

http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html

于 2012-12-08T20:22:38.740 回答