【问题标题】:JBoss 7 classloading miraclesJBoss 7 类加载奇迹
【发布时间】:2014-01-29 07:50:36
【问题描述】:

我在使用 JBoss 7 下捆绑为 WAR 的 webservice/OSGi 应用程序时遇到问题。

我的问题是:

  1. 默认情况下应用程序可以使用哪些模块?我知道如何添加依赖项以及如何排除依赖项。但是我怎么知道默认值呢?我认为它们被称为“全局模块”。
  2. 默认为应用程序提供了哪些JDK包?全部?一些?我该如何调查?
  3. 具体错误如下。一些引导代码调用javax.xml.parsers.DocumentBuilderFactory.newInstance()。这导致异常javax.xml.parsers.FactoryConfigurationError: Provider __redirected.__DocumentBuilderFactory not found。在 JBoss 中,系统属性 javax.xml.parsers.DocumentBuilderFactory 似乎指向上述奇怪的实现 __redirected.__DocumentBuilderFactory

感谢您的帮助!

【问题讨论】:

标签: java osgi jboss7.x classloader


【解决方案1】:

回答我自己的问题:

  1. 隐式添加的模块在此处的 JBoss 文档中有详细描述:https://docs.jboss.org/author/display/AS7/Implicit+module+dependencies+for+deployments。正如另一个答案已经指出的那样,可以通过在 jboss-deployment-structure.xml 中声明排除来抑制依赖关系。

  2. 见上面的答案

  3. 部署到 JBoss 的应用程序是一个 WAR 文件,它本身引导一个 OSGi 容器。在容器内部,Gemini Blueprint 用于管理 OSGi 服务依赖项。 Gemini Blueprint 搜索 Spring Application Context 文件,如果找到,则启动 bundle 的 Spring 上下文。解析 XML 文件失败,出现上述异常。原因是软件包 __redirected 不适用于捆绑包。我通过引导委托来管理它。

    # In JBoss some JDK classes like "javax.xml.parsers.DocumentBuilderFactory" are redirected to a JBoss package "__redirected" via a system property
    # The corresponding implementation "__redirected/__DocumentBuilderFactory" is made accessible from all bundles via "boot delegation" 
    org.osgi.framework.bootdelegation = __redirected
    # Sets the parent classloader to the one that loads the framework. It must have access to the bootdelegation pakages, e. g. "__redirected"
    org.osgi.framework.bundle.parent = framework
    

【讨论】:

  • 你怎么知道双子蓝图正在被使用?我在 OP 中没有看到任何相关内容
【解决方案2】:
  1. 您可以检查管理控制台/OSGi 选项卡以查看运行时可用的内容。 “默认情况下”取决于您的启动配置,您可以使用 4 个替代启动配置文件 IIRC。

  2. 检查 $JBOSS/modules/sun/jdk/main/module.xml 以查看哪些包已导入,哪些未导入。只有其中一些是。其他需要手动添加 using jboss-deployment-structure 或修改 sun.jdk module.xml 文件,如果需要的话。除了JDK之外还有其他的自动依赖,列在this page

  3. 您需要提供更多详细信息来回答此问题,包括您的依赖关系。 Xerces 解析器是模块化类加载器的一大难题。

【讨论】:

    【解决方案3】:

    问题在于setContextClassLoader方法的使用。这会覆盖可以加载 DocumentBuilderFactory 的类加载器。一种解决方法是使用 OrderClassLoaders。

    Thread currentThread = Thread.currentThread();
    ClassLoader originalCl = currentThread.getContextClassLoader();
    currentThread.setContextClassLoader( new OrderClassLoaders( myCl, originalCl ) );
    

    【讨论】:

      猜你喜欢
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-01
      相关资源
      最近更新 更多