5 Replies Latest reply on Dec 23, 2014 12:05 AM by mazz

    WAR MDB cannot obtain superclass on module classpath

    mazz Master

      I have a problem with module classloading with a WAR that has an EJB MDB in it. Not sure if its a bug, a known issue, or if there is a workaround that I should be doing.

       

      I've attached a very simple .zip file that requires only two simple steps to replicate the problem:

       

      1) unzip the attached .zip in any Wildfly 8.2 distribution root directory ("cd <wildfly-home>; unzip mdb-test.zip") and it will install the necessary module and WAR deployment files

      2) run "<wildfly-home>/bin/standalone.sh" to see the problem (via log error message)

       

      Here's the setup. After unzipping the attached zip, you will notice I have a JBoss Module (deployed inside the modules/ directory) that includes a jar which has a very basic MessageListener implementation called MySuperListener (see <wildfly-home>/modules/.../org/mdbtest/main/mdbtest.jar). The idea is that I now can write a WAR that ships with an MDB that extends that superclass from that org.mdbtest module. And that is what I have in the example I had you unzip - see <wildfly-home>/standalone/deployments/warmdbtest.war.

       

      The full source of my two classes are in the zip file, but here's what the code looks like:

       

      1) the superclass that is deployed in the org.mdbtest module:

       

      public abstract class MySuperListener implements MessageListener {

          public void onMessage(Message m) {

              System.out.println("MySuperListener: " + m);

              doSomething(m);

          }

          protected abstract void doSomething(Message m);

      }

       

      2) The WAR's MDB class is the following:

       

      @MessageDriven(activationConfig = {

         @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),

         @ActivationConfigProperty(propertyName = "destination", propertyValue = "QueueName")})

      public class MyWarMDB extends MySuperListener {

         public void doSomething(Message m) {

             System.out.println("DO SOMETHING: " + m);

         }

      }

       

      When you run standalone.sh, the server tells me my WAR's MDB does not implement MessageListener. But that is wrong - it does implement that JMS interface by virtue of extending the module's MySuperListener. Here's the error:

       

      ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) JBAS014613: Operation ("deploy") failed - address: ([("deployment" => "warmdbtest.war")]) - failure description: {"JBAS014671: Failed services" => {"jboss.deployment.unit.\"warmdbtest.war\".PARSE" => "org.jboss.msc.service.StartException in service jboss.deployment.unit.\"warmdbtest.war\".PARSE: JBAS018733: Failed to process phase PARSE of deployment \"warmdbtest.war\"

      Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: JBAS014194: EJB 3.1 FR 5.4.2 MessageDrivenBean org.warmdbtest.MyWarMDB does not

      implement 1 interface nor specifies message listener interface"}}      

       

      You will notice that I do include a "jboss-deployment-structure.xml" in my WAR's WEB-INF directory that has this:

       

      <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">

          <deployment>

              <dependencies>

                  <module name="org.mdbtest" />

              </dependencies>

          </deployment>

      </jboss-deployment-structure>

       

      So the dependency on my custom module is specified and it is getting in the WAR classpath, otherwise, the WAR MDB class would never have been loaded in the first place since "MySuperListener" would have been missing and caused something like a ClassNotFoundException.

       

      Note that if I put my module jar (mdbtest.jar) inside my WAR's lib directory, things will deploy (well, up to the point when it wants to hook up to that queue - but since I didn't have you hook up the messaging subsystem in the replication procedures, it will fail later trying to find the messaging resource adapter, but ignore that since that's besides the point; I just want to show the deployment failing due to the class MySuperListener not getting seen by the JMS subsystem when the WAR MDB is deployed). Note that in my "real" production code where this example came from, it works fully if the superclass is in a jar in my WAR's lib.

       

      OK? What am I doing wrong? I'll assume there some magical configuration file I have to add to my WAR to get this to work