Time traveller brings J2EE back to the future from 2006

I’m sorry, J2EE? You realise Java EE has not officially called ‘J2EE’ since the release of Java EE 5 back in 2006, right? It’s now 2012. That’s SIX YEARS AGO.

For a while after the name changes it was acceptable and common to hear all combinations of the names, for example, referring to Java EE 5 as J2EE 1.5. The last EE version with the J2EE name was J2EE 1.4, released in 2003.

When I hear J2EE today, it tells me one of the following:

  • you haven’t actually worked hands on with Java since roughly 2006. At some point in the past you did have some hands on experience, but not recently, at least not in the last few years
  • you’ve been working with J2EE 1.4 technology since 2006
  • you’ve been working in cave in 2006 and have just emerged to get some sunlight
  • you just picked up an old copy of a J2EE book and decided to learn Java Enterprise technology, not realizing how old the book was, or the fact that it’s not vastly out of date
  • you possess a time machine and have just traveled to the future from 2006

Please – if you haven’t worked with Java technology for the last six years, please try and get up to date. A lot has changed in the last six years.

Also, if you have been working in the technological cave (a long running development project) for the past six years… you owe it to yourself and your career to try and keep more up to date with the tools that you use.

Enabling Spring Security Expression-based Access Control for methods in a Spring Roo app

Expression-based Access Control allows you to annotate specific methods with access rules. To enable, add the following element to your webmvc-config.xml file for your Roo webapp (not the security context file, it must be in the context file for the web app):

<security:global-method-security pre-post-annotations="enabled"/>

The explanation for why this needs to be in your webapp context is covered here.

Adding a Mysql datasource to JBoss AS 7

I haven’t used JBoss since 4.x days. Seems adding a datasource is a few steps more complicated than it used to be. To summarize this post, the steps you need are:

  1. create a com/mysql/main dir under /jobss-as-7.1.final-install-dir/modules
  2. drop your mysql connector in this dir
  3. create a module.xml file in the same dir with the following content:
  4. <?xml version="1.0" encoding="UTF-8"?>
    <module xmlns="urn:jboss:module:1.0" name="com.mysql">
      <resources>
        <resource-root path="mysql-connector-java-5.1.18-bin.jar"/>
      </resources>
      <dependencies>
        <module name="javax.api"/>
      </dependencies>
    </module>
  5. modify your jboss-install-dir/standalone/configuration/standalone.xml file and define your datasource by adding a section like this to the subsystem datasources section:
    <datasource jndi-name="java:jboss/datasources/MysqlDS" pool-name="MysqlDS" enabled="true" use-java-context="true">
                        <connection-url>jdbc:mysql://localhost:3306/your_db_name</connection-url>
                        <driver>mysql</driver>
                        <security>
                            <user-name>your_userid</user-name>
                            <password>your_password</password>
                        </security>
                    </datasource>
                    <drivers>
                        <driver name="mysql" module="com.mysql">
                            <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
                        </driver>
                    </drivers>

Configuring a Spring web app using JPA2 to use a JBoss datasource on OpenShift

By default, when creating a web app with Spring Roo, your JPA configuration is set up to use a Commons DBCP BasicDataSource. This works great for testing locally on Tomcat, but doesn’t work when deployed to the OpenShift environment, you’ll get errors like this as Hibernate tries to get connections and set up your schema based on your Entity mappings :

2012/03/08 18:17:03,423 ERROR [org.hibernate.tool.hbm2ddl.SchemaExport]
(MSC service thread 1-3) HHH000231: Schema export unsuccessful:
java.lang.UnsupportedOperationException: The application must supply JDBC connections

At the current time there isn’t a great deal of documentation on the Open Shift site that explains how to config your app to use a datasource, but this post on the community forum has some good clues (this one is Flex specific, but it mentions the standalone.xml JBoss config file).

When you add a database cartridge to your app in OpenShift, your JBoss in your environment is also configured with a DataSource using connection properties set up to access your MySQL (or other) db, and it’s ready to go.

To get your Spring Roo app configured to use the datasource requires a bit more effort. There’s various posts online about how to configure JPA2 to use a DataSource provided by a container, but getting all the right parts changed or removed in your existing config is a bit tricky. This post here lists all the steps needed, and most of the text below is taken from this post (thanks to the poster of this entry on the Spring forum as before I got to this stage I had already spent a few hours trying to piece this together) – here we go:

Edit src/main/resources/META-INF/spring/applicationContext.xml:

  • remove the BasicDataSource bean (the DataSource is now specified in persistence.xml)
  • remove the JpaTransactionManager bean
  • add <tx:jta-transaction-manager /> to look up JBoss’ JtaTransactionManager from JNDI instead. The default name of the bean using this tag is ‘transactionManager’
  • If you had previously used the <tx:annotation-driven> tag, make sure it’s transaction-manger attribute now uses ‘transactionManager’ (from the previous step):
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>

 

  • remove the LocalContainerEntityManagerFactoryBean
  • add this bean:
<jee:jndi-lookup id="entityManagerFactory"
        jndi-name="your/app/MyEntityManagerFactory"
        expected-type="javax.persistence.EntityManagerFactory" />

Your EntityManagerFactory gets exposed by JBoss from the following changes to your persistence.xml files:

Edit src/main/resources/META-INF/persistence.xml:

  • change the persistence-unit’s “transaction-type” attribute from RESOURCE_LOCAL to JTA
  • add a child element to “persistence-unit” as follows:
<jta-data-source>java:/MyDSName</jta-data-source>

Add the following property to expose your EntityManagerFactory:

<property name="jboss.entity.manager.factory.jndi.name"
        value="your/app/MyEntityManagerFactory"/>