EE6 @Schedule Timer Service on JBoss AS 7.1

It seems that @Schedule methods won’t execute on JBoss AS7.1 unless you specify at least both the hours and minutes values on the scheduled method.

For example, to execute a method every 30 seconds:

@Schedule(seconds="*/30")
public void doSomething() { ...}

Doesn’t execute, but if you include hours and minutes wildcards too then it does:

@Schedule(hour="*", minute-="*", second="*/30")
public void doSomething() { ...}

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"/>