Aseem Bansal
Aseem Bansal

Reputation: 6962

Duplicate class in two modules in an application - which will be referred to by an instantiating class?

There is an EAR(myApp.ear) of a web application in which there are two modules - a web module (myWeb.war) and an EJB module (myModel.jar). Now there is a class myDuplicate.class which is present in both the modules in the same package myPackage. The implementation of the class is different in both modules.

If a class in the web module creates an object of the class myDuplicate then the object will be of from the one in myWeb or the one in myModel?

Does this depend on classloading mechanisam of the server? If yes, is there a parameter in OC4J server configuration to control this classloading? If no, then what controls it?


The above may have seemed too generic but that it is a practical problem that I am facing. In different environments different classes are being loaded but I am unable to find out what is controlling it. I tried searching and came to classloaders which might be the answer. But even after that I was unable to find how to control it to behave in a consistent manner in both environments.

If anything is not clear please share what is not and I will try to clarify.

Upvotes: 1

Views: 3245

Answers (2)

Isaias Alves
Isaias Alves

Reputation: 43

To solve duplicate definitions on oracle OC4J you can add these configs on orion-application.xml or orion-web.xml.

1) WEB-INF/orion-web.xml config: Adding expected jars on web-inf/lib or pom.xml (not provided):

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

2) META-INF/orion-application.xml: With duplicated lib name (showed on log message), remove your link config:

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

3) Pack these files/modifications on your .war file and deploy it on oc4j.

Upvotes: 0

Steve C
Steve C

Reputation: 19445

There are very clear rules on class visibility in Java EE compliant application servers.

In summary (and in the absence of any manifest Class-Path entries, external libraries or RAR files), modules in an EAR file are defined as follows:

  • Each web module consists of the content of WEB-INF/classes plus all jars within the WEB-INF/lib directory
  • Each ejb module is standalone
  • The contents of the EAR/lib directory are considered to be a single module for class visibility.

Given the above:

  • web modules are isolated and cannot see each other's classes, but they can see EAR/lib classes. They can often see ejb modules too, but this not a requirement. A compliant application would use a manifest Class-Path entry to resolve this.
  • ejb modules can see their own specified client jar classes and EAR/lib classes. They can often see other ejb modules too, but this not a requirement. A compliant application would use a manifest Class-Path entry to resolve this.
  • jars in the EAR/lib directory can only see each other's classes

So, hopefully that gives you a clear idea of class visibility between the different components. However, you still need a clear picture of class loading order:

  • a web module's own classes will always be used before looking in the other class loaders.
  • "parent first" class loading applies everywhere else.

In your particular case, myDuplicate from myWeb would be created. You should be fine provided you don't attempt to pass an instance of myDuplicate up into myModel. This will likely result in class loading issues.

I see this kind of problem often in the wild when developers bundle log4j (or some other logging library) in both their EAR files and their web modules, resulting in lots of class loading problems.

See §EE.8.2 Library Support of Java™ Platform, Enterprise Edition (Java EE) Specification, v6 for more of the gory details.

Upvotes: 4

Related Questions