March 28, 2016

Scheduling/Time Service in Java EE 6

In Java EE 6 is scheduling feature already built in.

Example from The Java EE 6 Tutorial (http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html).

Also good reading from Arun Gupta - https://blogs.oracle.com/arungupta/entry/totd_146_understanding_the_ejb

After reading the above I came across the following pitfalls.

Do not use persistent scheduling, because this means if you stop your server and then restart it. All scheduling event that should have taken place during shutdown will now run. Like a catchup effect.

  • Annotation way: javax.ejb.Schedule.persistent()
  • Programmatic way: javax.ejb.TimerConfig.TimerConfig(Serializable, boolean)

Another side effect is the default transaction type of javax.ejb.TransactionAttributeType.REQUIRED for all EJB. This is not always not wanted, because the meaning of a failed scheduling is it will be rerun.

I suggest changing default transaction type not supported and then move all logic to another EJB which will start transaction.

// Singleton Session Bean
@javax.ejb.Singleton
// "If the transaction is rolled back, the container will call the @Timeout
// method at least one more time." [Oracle Java EE 6 Tutorial]
@javax.ejb.TransactionAttribute(javax.ejb.TransactionAttributeType.NOT_SUPPORTED)
public class MyTimerBean {
...
}

And if you want your scheduling to start at boot use @javax.ejb.Startup

// Start at boot
@javax.ejb.Startup
// Singleton Session Bean
@javax.ejb.Singleton
// "If the transaction is rolled back, the container will call the @Timeout
// method at least one more time." [Oracle Java EE 6 Tutorial]
@javax.ejb.TransactionAttribute(javax.ejb.TransactionAttributeType.NOT_SUPPORTED)
public class MyTimerBean {
...
}

How to connect to JBoss EAP 6 using VisualVM

For this to work you need to have an account on access.redhat.com to be able to download the required jvisualvm.sh or .jvisualvm.bat script. See https://access.redhat.com/solutions/151343.

After download and copied to $JBOSS_HOME/bin, run it. Of course you need first to install VisualVM (jvisualvm). For Ubuntu see my previous blog. http://magnus-k-karlsson.blogspot.se/2016/03/how-to-install-visualvm-jvisualvm-on.html.

Then you need to bind the management interface to an external interface (only for remote usage) and create a management account. For details see my blog about jconsole http://magnus-k-karlsson.blogspot.se/2013/01/how-to-remote-connect-jconsole-to-jboss.html.

Then run the script and open File --> Add JMX Connection ...

How To Install VisualVM (jvisualvm) on Ubuntu

Default JDK on Ubuntu is OpenJDK. Because of legal restriction OpenJDK does not come with VisualVM, so you need to install it separately.

$ sudo apt-get install visualvm 

Choosing the Default Java on Ubuntu

sudo update-alternatives --config java

Remote Debugging in JBoss EAP 6

To enable remote debugging in JBoss EAP 6, set DEBUG_MODE to true in standalone.sh

jboss-eap-6.4.0/bin/standalone.sh

...
DEBUG_MODE=true
...

Then follow mine Eclipse settings in my previous blog for JBoss EAP 5.

http://magnus-k-karlsson.blogspot.se/2016/03/remote-debugging-in-jboss-eap-5.html

Remote Debugging in JBoss EAP 5

To enable remote debugging in JBoss EAP 5, uncomment the below in run.conf

jboss-eap-5.2.0/jboss-as/bin/run.conf

...
# Sample JPDA settings for remote socket debugging
JAVA_OPTS="$JAVA_OPTS -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
...

Now deploy your application and open Eclipse:

  1. Add breakpoint in your code.
  2. Add Debug Configuration and add Remote Java Application and set host and port.
  3. Click Debug and access your deployed application.

Minimalistic POM for Java EE 7

One of the greatest news about Java EE 7 is, there is a usable dependency in maven central.

And here is a minimalistic POM for your Java EE 7 projects. I also added log4j, junit and mockito which are not necessary, but I use them a lot, so I added them for convenience.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>se.magnuskkarlsson.examples</groupId>
    <artifactId>example-javaee7</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.build.outputEncoding>UTF-8</project.build.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- Test Support -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>1.10.19</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

If you need in memory database checkout "H2 Database Engine Cheat Sheet" [http://www.h2database.com/html/cheatSheet.html]