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.


Tuesday 30 October 2012

IE problems with jQuery.Form AJAX POSTs

jQuery.Form is an excellent plugin for jQuery that makes it really easy to post HTML forms via AJAX and parse the resulting response in a JavaScript handler (similar to jQuery's standard AJAX methods).

However, when submitting a "multipart/form-data"-form with a JSON response (content type set to "application/json"), Internet Explorer tries to download the response instead of calling your JavaScript reponse handler...  very irritating indeed. Of course, Firefox and Chrome handle these responses without any issues (I haven't tried IE10 yet).

A workaround is to set the response type to "text/html" on the server, and parse the resulting text string via jQuery.parse(). Not ideal, but at least works on all browsers that I tested.

On a side note: if you set the response content type to "text/plain", IE (and some versions of Firefox) will add <pre> tags to the response string - thus using "text/html" instead is quicker.

Tuesday 28 August 2012

Adding a prefix to Bootstrap CSS classes

Update 2013-03-15: Thanks to everyone for the bug reports and support. I apologise for the long silence - I had been busy with a lot of other things and didn't get round to updating the script. Should be fine from now on again, though. :-)

I recently started integrating Twitter's excellent Bootstrap framework into a hobby project of mine, but hit a snag: Bootstrap uses a lot of fairly common CSS classnames (e.g. "row", "container", etc)... and many of these clashed with classes that I had already defined in my own code, resulting in a fine mess.

The obvious solution was to modify the Bootstrap CSS so that everything in there uses a common prefix... however, the creator of Bootstrap made it clear that no prefixing of Bootstrap CSS classes would be implemented. Fair enough, it's their library, their call - and I suppose writing "row" instead of something like "tb-row" makes more sense if you just start out. But it does make implementing Bootstrap into an existing project harder than it needs to be, and I really did not want to rename my own CSS classes.

An alternative: Namespacing


One way to avoid the CSS name conflicts would be to wrap the Bootstrap CSS classes into a new top-level namespace using the Bootstrap Less source code and then wrapping your Bootstrap-sensitve page elements into a suitable container (as suggested in this stackoverflow answer). Not really what I was aiming for - having an option to merely define a "$prefix" variable in Bootstrap source and recompiling would've been far nicer. But, alas, things are not that simple: the CSS classes are referenced heavily in the Bootstrap Javascript source files, negating the usefulness of such a "prefix" Less variable.

Solution: Prefixing via post-processing script


To address this issue I whipped up a quick Python script that edits the Bootstrap CSS and Javascript files and adds a prefix to any CSS classnames it finds. The prefix defaults to "tb-" (for "Twitter Bootstrap"), but can be easily changed (see the docs below).

Using it is simple: just supply it with the path to your Bootstrap installation (it expects the default Bootstrap directory structure to be in place). The script will then output modified versions of the CSS and Javascript files it finds, with a ".prefixed" tag added to the filename.

Finally, include these "prefixed" files in your project instead of the original Bootstrap CSS and Javascript files - now you can (and must) refer to all Bootstrap CSS classes by adding the "tb-" prefix to the name, e.g. "row" becomes "tb-row", etc.

The "bootstrap_namespace_prefixer.py" script is available from GitHub, or you can download it by clicking here.

Please note: this script works for me. YMMV, but let me know if something goes wrong and I'll take a look at it.

Documentation


The script expects a Bootstrap directory structure like the following:
/bootstrap - top-level bootstrap dir; this is the path that must be supplied to the script
/bootstrap/css - directory containing CSS files for Boostrap
/bootstrap/js - directory containing Bootstrap  Javascript files

Call the script as follows:
$ python bootstrap_namespace_prefixer.py /path/to/boostrap/dir
The script will output the following files:
/bootstrap/css/bootstrap.prefixed.css - CSS with the added prefix
/bootstrap/css/bootstrap.min.prefixed.css - Minified CSS with the added prefix
/bootstrap/js/bootstrap.prefixed.js - Javascript using the prefixed classes
/bootstrap/js/bootstrap.min.prefixed.js - Minified Javascript using the prefixed classes

To change the classname prefix to something other than "tb-", edit the bootstrap_namespace_prefixer.py file and set the CSS_CLASS_PREFIX constant to whatever you want to use as a prefix.