3

I am building a JEE project using NetBeans and Maven. The project contains an EJB module, a Web module and a SE class library. As usual, the Web module has the EJB module as a dependency. They both have the class library as a dependency. The project is a modified copy of a project that has been working for years using either GlassFish or JBoss, and more recently WildFly. The original project was built and deployed using Ant. Now I am using Maven. The new (maven) project runs just fine using GlassFish but not using WildFly 10. It throws a ClassCastException in a cast statement that definitively shouldn’t fail. To try to determine the source of the problem I performed a simple test. Its result is totally bizarre. Here it is:

First I created 3 interfaces, one in the class library and one in each module. These are:

// interface at the class library
package jee2ap102.lib;
public interface I01 {
}

// interface at the EJB module
package jee2ap102.ejb;
public interface I0101 extends jee2ap102.lib.I01 {
}

// interface at the Web module
package jee2ap102.web;
public interface I010101 extends jee2ap102.ejb.I0101 {
}

Then in the Web module I created a bean and added the following method:

public String check() {
    boolean b;
    b = jee2ap102.lib.I01.class.isAssignableFrom(jee2ap102.ejb.I0101.class);
    b = jee2ap102.lib.I01.class.isAssignableFrom(jee2ap102.web.I010101.class);
    b = jee2ap102.ejb.I0101.class.isAssignableFrom(jee2ap102.web.I010101.class);
}

The three statements should return true, but only the last one does. According to this, the interface I01, located in the class library, which is the root of the hierarchy, is not assignable from any of the interfaces located outside the library (either EJB or Web module) regardless of the fact that those interfaces extend it. Consistently, an attempt to cast I0101 or I010101 to I01 will throw a ClassCastException.

I would really appreciate any help to understand and solve this problem.

Jorge Campos
  • 22,647
  • 7
  • 56
  • 87
Jorge Campins
  • 413
  • 1
  • 4
  • 11
  • If your classes loaded using different class loaders then you may have this strange behavior. I've seen similar problem before when using ear modules. – Mikhail Chibel Jun 19 '16 at 06:20

1 Answers1

2

As per my comment, the issue most likely caused by the fact that war arhive uses different class loader from the lib jar. This is described in this question

Community
  • 1
  • 1
Mikhail Chibel
  • 1,865
  • 1
  • 22
  • 34
  • Hi there! Thanks for your answer. I was clueless until you mentioned the class loader. I could finally find the problem, and the solution. I guess it is something very likely to happen to Maven greenhorns, like me. The problem was that I added the class library dependency to the Web module by copying it from the EJB module and I didn’t realize that it needed to be a little bit different. The solution was to add a **scope provided** element to the Web module dependency. – Jorge Campins Jun 20 '16 at 15:57
  • As you might recall, the dependency in the EJB module causes Maven to add the class library to the ear’s lib directory. The dependency in the Web module was causing Maven to add the class library also to the war’s lib directory. So, I end up having the same jar twice and the class loader must have load them both. Using **scope provided** in the Web module prevents Maven from adding the jar to the war and therefore both modules share the only jar in the ear. Problem solved. Thanks again. – Jorge Campins Jun 20 '16 at 15:58
  • BTW, I couldn’t add an answer to this question, perhaps because it was marked as a duplicate of another question, and it didn’t seem appropriate to add the answer to that question, because that one is about someone **”playing with class loaders“**, which I wasn’t doing, at all. – Jorge Campins Jun 20 '16 at 15:58
  • A final note on this subject. As I mentioned in my question, the project runs just fine using GlassFish. So it seems GlassFish class loader is not loading the jar within the war (it is there, I just checked). Interesting, isn't it? – Jorge Campins Jun 20 '16 at 15:59
  • @user2734938 Glassfish and Wildlfy uses slightly different approach for classloading so you have this difference. While they both j2ee compliant once migrated to wildfly from Glassfish we've found lots of things to fix. – Mikhail Chibel Jun 20 '16 at 20:59