应用程序中两个模块中的重复类 - 将由实例化类引用?

时间:2014-11-10 16:19:55

标签: java classloader ear oc4j

Web应用程序的EAR(myApp.ear)中有两个模块 - 一个Web模块(myWeb.war)和一个EJB模块(myModel.jar)。现在有一个类myDuplicate.class,它出现在同一个包myPackage的两个模块中。两个模块中类的实现都不同。

如果Web模块中的某个类创建了类myDuplicate的对象,那么该对象将来自myWeb中的对象或myModel中的对象?

这是否依赖于服务器的类加载机制?如果是,是否在OC4J服务器配置中有一个参数来控制此类加载?如果不是,那么控制它的是什么?


以上可能看起来过于通用,但这是我面临的一个实际问题。在不同的环境中,正在加载不同的类,但我无法找出控制它的内容。我试着搜索并找到了可能是答案的类加载器。但即使在那之后,我也无法找到如何控制它在两种环境中以一致的方式运行。

如果有任何不清楚的地方请分享不是的内容,我会尽力澄清。

2 个答案:

答案 0 :(得分:2)

在符合Java EE的应用程序服务器中,类可见性有非常明确的规则。

总之(并且在没有任何清单的Class-Path条目,外部库或RAR文件的情况下),EAR文件中的模块定义如下:

  • 每个Web模块都包含WEB-INF / classes的内容以及WEB-INF / lib目录中的所有jar文件
  • 每个ejb模块都是独立的
  • EAR / lib目录的内容被视为用于类可见性的单个模块。

鉴于上述情况:

  • Web模块是孤立的,无法看到彼此的类,但是他们可以看到EAR / lib类。他们经常可以看到ejb模块,但这不是必需的。兼容的应用程序将使用清单Class-Path条目来解决此问题。
  • ejb模块可以看到自己指定的客户端jar类和EAR / lib类。他们经常可以看到其他ejb模块,但这不是必需的。兼容的应用程序将使用清单Class-Path条目来解决此问题。
  • EAR / lib目录中的jar只能看到彼此的类

所以,希望这能让您清楚地了解不同组件之间的类可见性。但是,您仍然需要清楚地了解类加载顺序:

  • 在查看其他类加载器之前,自己的类将始终使用。
  • "父母第一"类加载适用于其他任何地方。

在您的特定情况下,将myDuplicate创建myWeb。如果您没有尝试将myDuplicate的实例传递到myModel,那么您应该没问题。这可能会导致类加载问题。

当开发人员在他们的EAR文件和他们的Web模块中捆绑log4j(或其他一些日志库)时,我经常会看到这种问题,导致很多类加载问题。

有关更多详细信息,请参阅§EE.8.2 Library Support的{​​{1}}。

答案 1 :(得分:0)

要解决oracle OC4J上的重复定义,您可以在orion-application.xml或orion-web.xml上添加这些配置。

1)WEB-INF / orion-web.xml配置:在web-inf / lib或pom.xml上添加预期的jar(未提供):

<orion-web-app ...>
  <web-app-class-loader search-local-classes-first="true" />
</orion-web-app>

2)META-INF / orion-application.xml:使用重复的lib名称(显示在日志消息中),删除你的链接配置:

<orion-application ...>
  <imported-shared-libraries>
    <remove-inherited name="name.of.your.lib"/>
  </imported-shared-libraries>
</orion-application>

3)在.war文件中打包这些文件/修改并将其部署在oc4j上。