March 29, 2016

Asynchronous Support in Java EE 6

Introduction

Java EE 6 comes with two ready to use asynchronous technique:

  • EJB
  • Servlet

EJB

Example

@Stateless
public class OrderBean {

    @Asynchronous
    public Future<String> processPayment(Order order) throws PaymentException {
        ...
        String status = ...;
        return new AsyncResult<String>(status);
    }
}

Oracle Java EE 6 Tutorial: Asynchronous Method Invocation

Oracle Java EE 6 Tutorial: Using Alternatives in CDI Applications

Servlet

This asynchronous feature is less documented, but could be used for example a servlet that generates a PDF or some other heavy computing.

Example

package se.magnuskkarlsson.example.servlet;

import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = "/MyAsyncServlet", asyncSupported = true)
public class MyAsyncServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        AsyncContext ac = request.startAsync(request, response);
        ac.addListener(new AsyncListener() {
            @Override
            public void onComplete(AsyncEvent event) throws IOException {
                event.getSuppliedResponse().getWriter().println("onComplete");
            }

            @Override
            public void onTimeout(AsyncEvent event) throws IOException {
                event.getSuppliedResponse().getWriter().println("onTimeout");
                event.getAsyncContext().complete();
            }

            @Override
            public void onError(AsyncEvent event) throws IOException {
                event.getSuppliedResponse().getWriter().println("onError");
            }

            @Override
            public void onStartAsync(AsyncEvent event) throws IOException {
                event.getSuppliedResponse().getWriter().println("onStartAsync");
            }
        });

        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 10,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2));
        executor.execute(new MyAsyncService(ac));
    }

    class MyAsyncService implements Runnable {

        AsyncContext ac;

        public MyAsyncService(AsyncContext ac) {
            this.ac = ac;
        }

        @Override
        public void run() {
            try {
                ac.getResponse().getWriter()
                        .println("Running inside MyAsyncService");
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
            ac.complete();
        }
    }
}

Containers for Java Microservices

In the recent years there has been a lot of talks about microservices. There is not a clear definitions of what a microservice is and maybe more important how to build one.

But there are some clear characteristics for one:
  • Loosely coupled
  • Doing a small task/single-purpose
  • Clear API and preferably language-agnostic API
  • Etc.
But this microservice need to run in some container/server. You could of course always write everything from scratch, but that would be reinventing the wheel for some common problems like:
  • Pooling
  • Transaction (you want your business code to run in one transaction, e.g. 1. select (does object exists or fetch data), 2. insert, 3. maybe more insert for complex object insert)
  • Operation & Management
  • And maybe you need Security or Asynchronous behaviour
So what are the most popular containers? Two are
You could google comparison between them, but one good is http://www.schibsted.pl/2015/07/spring-boot-and-dropwizard-in-microservices-development/.

But how fast are these containers? To really answer this question you should of course performance test them. But a quick test would be to merely compare boot up time on my slow laptop.

Spring Boot. Followed Hello World example https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started-first-application.html.

Started Example in 3.959 seconds

Dropwizard. Followed Hello World example http://www.dropwizard.io/0.9.2/docs/getting-started.html.

Started @2504ms

JBoss EAP 6.4. Created a simple Hello World example with JAX-RS.

JBoss EAP 6.4.0.GA (AS 7.5.0.Final-redhat-21) started in 3987ms

So dropwizard started really fast, but not amazingly fast compared with JBoss, so the question arise how much better are these alternative container compared with classical Java EE container? And also be aware you are locking your code into a specific framework stack.



How to Install Jad (Java decompiler) in Eclipse

  1. Download jadclipse from https://sourceforge.net/projects/jadclipse/.
  2. Put the JadClipse JAR file into the plugins folder of your Eclipse installation.
  3. Restart Eclipse (eclipse -clean).
  4. Download Jad from http://varaneckas.com/jad/ and make it executable.
  5. Configure the path to the Jad executable in Eclipse: Window --> Preferences --> Java --> JadClipse --> Path to Decompiler.
  6. In Eclipse go to Window --> Preferences --> General --> Editors --> File Associations and make sure that the JadClipse Class File Viewer has the default file association for *.class files.
Enjoy!

HornetQ is Deprecated in JBoss EAP 7

In every major upgrade of JBoss there is a new messaging broker.
  • HornetQ in JBoss EAP 6
  • JBoss Messaging in JBoss EAP 5
  • JBossMQ in JBoss EAP 4  
And now in JBoss EAP 7 it is A-MQ which comes from Apache ActiveMQ.

But one should not blame JBoss for changing broker, the development of software is going fast. But one should maybe reflect on one thing. Should the Java EE container be deployed with a messaging broker? I think not, for the same reason you do not deploy the database server inside the container.

So one should consider the built in messaging broker as a test feature, like most Java EE container comes with a in memory database. It is there for a test gracefulness. 

March 28, 2016

PicketBox Deprecated in JBoss EAP 7

JBoss EAP 7 is only release as a beta, but already now can a few changes been seen. For example is PicketBox deprecated and replaced with Elytron.


More news:

PicketLink and Keycloak projects are merging!

WildFly Elytron - Project Summary

Now Standard Embedded EJB Container in Java EE 6

With Java EE 6 there is a standardized Java EE embedded container javax.ejb.embedded.EJBContainer for example unit testing.

See https://docs.oracle.com/javaee/6/tutorial/doc/gkcrr.html.

Finally Standardized JNDI Naming in Java EE 6

Previous Java EE 6 each EE container had its own JNDI naming standard. This means when deploying an EJB in a Java EE 5 container, they were all accessed with different JNDI names.

Now this is history with Java EE 6, which sets the following JNDI naming standards.

  • java:global, e.g. java:global[/application name]/module name/enterprise bean name[/interface name]
  • java:module, e.g. java:module/enterprise bean name/[interface name]
  • java:app, e.g. java:app[/module name]/enterprise bean name[/interface name]

Reference: https://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html

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]