Thursday 15 November 2012

GlassFish 3.1: Deactivation of MDB does not call endpointDeactivation() of custom resource adapter

I recently developed a custom JCA resource adapter for a sockets-based protocol used in one of our projects where I work. The resource adapter is deployed standalone to GlassFish 3.1 as a .rar file, and is then used by two other projects deployed to the same application server: an EAR-based project consisting of several EJB- and WAR-modules, and another standalone web (WAR-only) project containing some embedded EJBs (as is allowed with Java EE 6). Both these "client" projects contain message-driven beans (MDBs) that use the different message listener interfaces defined by the resource adapter.

However, during testing it became apparent that the endpointDeaction() method of the resource adapter was not being called when a client MDB is deactivated or undeployed - obviously resulting in resource constraint problems. Since endpointActivation() was being called just fine, I started thinking that this might be a bug in GlassFish, and sure enough, someone had reported it already:

http://java.net/jira/browse/GLASSFISH-16056

Anyhow, the solution (or workaround, rather) was provided in the first comment of that bug report by leonline. I am repeating it here in the hope that someone searching for a solution to this in the future will find the answer a bit quicker.

Add a glassfish-ejb-jar.xml file (GlassFish deployment descriptor; formerly known as sun-ejb-jar.xml) to the project module containing your MDB. If your MDB is in a Java EE 6-style WAR module, add it to the module's WEB-INF folder.

The contents of the glassfish-ejb-jar.xml file should be:

<glassfish-ejb-jar>
    <enterprise-beans>
        <ejb>
           <ejb-name>YOUR MDB-NAME HERE</ejb-name>
        <mdb-resource-adapter>
                <resource-adapter-mid>YOUR ADAPTER NAME HERE (WITHOUT .RAR)</resource-adapter-mid>
            </mdb-resource-adapter>
        </ejb>
    </enterprise-beans>
</glassfish-ejb-jar>

Here is the actual contents of one of our glassfish-ejb-jar.xml files:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd">
<glassfish-ejb-jar>
    <enterprise-beans>
        <ejb>
           <ejb-name>SsmiServerRequestHandler</ejb-name>
        <mdb-resource-adapter>
                <resource-adapter-mid>SSMIConnector</resource-adapter-mid>
            </mdb-resource-adapter>
        </ejb>
    </enterprise-beans>
</glassfish-ejb-jar>
Note that in the above example, the relevant MDB's @MessageDriven annotation has its "name" parameter set to "SsmiServerRequestHandler". The name of the standalone resource adapter/connector resource is SSMIConnector.

With the glassfish-ejb-jar.xml deployment descriptor in place, endpointDeactivation() should now be called as expected.


1 comment:

  1. Hi Francois,

    thanks a lot for this post, it saved me quite a bit of time just now!
    I remember that I had this problem with another RA a while ago, but another workaround solved it back then. Unfortunately I could not use that workaround this time, so I am really grateful for this hint!

    Cheers,
    Julius

    ReplyDelete