Kohei Nozaki's blog 

Using DBUnit from Ant


Posted on Wednesday Sep 23, 2015 at 12:02PM in Technology


It’s a common usecase that using DBUnit from JUnit testcases but sometimes I need to use DBUnit in a standalone application manner to achive tasks such as exporting the data from a database to a XML file for creating test data from an existing table. In such case, I feel using DBUnit Ant task is better rather than launching it from Maven plugin or write a standalone Java application uses DBUnit API. in this entry, I introduce you a complete working example of an Ant script that uses DBUnit Ant task.

Environment

Complete JAR file list in my ~/.ant/lib:

$ ls -l ~/.ant/lib
total 1236
-rw-rw-r--. 1 kyle kyle 560755 Sep 23 10:56 dbunit-2.5.1.jar
-rw-rw-r--. 1 kyle kyle 660126 Sep 23 10:54 postgresql-9.4-1203.jdbc42.jar
-rw-rw-r--. 1 kyle kyle  32127 Sep 23 11:15 slf4j-api-1.7.12.jar
-rw-rw-r--. 1 kyle kyle   7892 Sep 23 11:16 slf4j-jdk14-1.7.12.jar
$

Exporting example

build.xml

This script exports the result of a SQL to a flat XML file. The format can be specified in dbunit.format property that has set to flat as default. You can add additional query or table elements inside the dbunit element to include multiple dataset in single XML file. JDBC connection information such as credentials or URL is expected to be stored as a separate file named dbunit.properties that is placed under the same directory to this file.

<project name="dbunit-export" basedir=".">
    <taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask"/>

    <loadproperties srcFile="dbunit.properties"/>

    <fail unless="dbunit.driver"/>
    <fail unless="dbunit.url"/>
    <fail unless="dbunit.userid"/>
    <fail unless="dbunit.password"/>
    <fail unless="dbunit.datatypeFactory"/>

    <property name="dbunit.format" value="flat"/> <!-- Possible values are "flat", "xml", "csv", "dtd", "xls". Defaults to "flat" -->

    <target name="export">
        <fail unless="dbunit.sql"/>
        <fail unless="dbunit.dest"/>
        <fail unless="dbunit.format"/>
        <fail unless="dbunit.query"/>

        <dbunit driver="${dbunit.driver}" url="${dbunit.url}" userid="${dbunit.userid}" password="${dbunit.password}">
            <dbconfig>
                <property name="datatypeFactory" value="${dbunit.datatypeFactory}" />
            </dbconfig>
            <export dest="${dbunit.dest}">
                <query name="${dbunit.query}" sql="${dbunit.sql}"/>
            </export>
        </dbunit>
    </target>
</project>

dbunit.properties

Set each properties to suit your environment. See this page to check what datatypeFactory are available.

dbunit.driver=org.postgresql.Driver
dbunit.url=jdbc:postgresql://localhost:5432/mydb
dbunit.userid=someone
dbunit.password=somepass
dbunit.datatypeFactory=org.dbunit.ext.postgresql.PostgresqlDataTypeFactory

How to run

The following command exports a XML file from a SQL.

$ ant export "-Ddbunit.sql=select * from job_instance where jobinstanceid >= 399341 order by jobinstanceid" -Ddbunit.query=job_instance -Ddbunit.dest=job_instance.xml
Buildfile: /home/kyle/dbunit-ant-example/build.xml

export:
   [dbunit] Executing export:
   [dbunit]       in format: flat to datafile: /home/kyle/dbunit-ant-example/job_instance.xml
Successfully wrote file '/home/kyle/dbunit-ant-example/job_instance.xml'

BUILD SUCCESSFUL
Total time: 0 seconds

This produces a flat XML dataset named job_instance.xml something like:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <job_instance jobinstanceid="399341" jobname="somejob1" applicationname="someapp"/>
  <job_instance jobinstanceid="399342" jobname="somejob2" applicationname="someapp"/>
  <job_instance jobinstanceid="399343" jobname="somejob3" applicationname="someapp"/>
...
  <job_instance jobinstanceid="400004" jobname="somejob4" applicationname="someapp"/>
</dataset>

Exporting / importing an entire database

<project name="mydbunit" basedir=".">
    <taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask"/>

    <loadproperties srcFile="dbunit.properties"/>

    <fail unless="dbunit.driver"/>
    <fail unless="dbunit.url"/>
    <fail unless="dbunit.userid"/>
    <fail unless="dbunit.password"/>
    <fail unless="dbunit.datatypeFactory"/>

    <property name="dbunit.format" value="flat"/> <!-- Possible values are "flat", "xml", "csv", "dtd", "xls". Defaults to "flat" -->

    <target name="export">
        <fail unless="dbunit.dest"/>
        <fail unless="dbunit.format"/>

        <dbunit driver="${dbunit.driver}" url="${dbunit.url}" userid="${dbunit.userid}" password="${dbunit.password}">
            <dbconfig>
                <property name="datatypeFactory" value="${dbunit.datatypeFactory}" />
                <!-- <property name="escapePattern" value="`?`" /> -->
            </dbconfig>
            <export dest="${dbunit.dest}" ordered="true"/>
        </dbunit>
    </target>

    <target name="import">
        <fail unless="dbunit.src"/>
        <fail unless="dbunit.format"/>

        <dbunit driver="${dbunit.driver}" url="${dbunit.url}" userid="${dbunit.userid}" password="${dbunit.password}">
            <dbconfig>
                <property name="datatypeFactory" value="${dbunit.datatypeFactory}" />
                <!-- <property name="escapePattern" value="`?`" /> -->
            </dbconfig>
            <operation type="CLEAN_INSERT" src="${dbunit.src}" ordered="true"/>
        </dbunit>
    </target>

</project>

To export:

$ ant export -Ddbunit.dest=mydb.xml

To import:

$ ant import -Ddbunit.src=mydb.xml

Note that you need commons-collections3 jar file in your classpath.

Other tasks

There are more operations that can be achieved through Ant tasks available such as:

  • Data comparison

  • INSERT or UPDATE based on the file


Using RabbitMQ with Java


Posted on Wednesday Aug 05, 2015 at 05:04PM in Technology


RabbitMQ is an open source message broker software made with Erlang. RabbitMQ is sponsored by Pivotal Software, Inc. in this entry, we’ll see how to launch it, publish or receive simple messages with Java client on OS X.

Installation

I’m using OS X 10.9.5. download rabbitmq-server-mac-standalone-3.5.4.tar.gz for Macs then extract it on somewhere.

Start the server

The server can be launched via execute sbin/rabbitmq-server as follows.

$ ./rabbitmq-server

              RabbitMQ 3.5.4. Copyright (C) 2007-2015 Pivotal Software, Inc.
  ##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/
  ##  ##
  ##########  Logs: ./../var/log/rabbitmq/rabbit@kyle-no-MacBook.log
  ######  ##        ./../var/log/rabbitmq/rabbit@kyle-no-MacBook-sasl.log
  ##########
              Starting broker... completed with 0 plugins.

To shutdown, hit Ctrl+C then press a.

Next, we’ll look how to interact with the server from Java client.

Dependencies

RabbitMQ supplies the client library for Java in Maven Central. just put following dependency to your pom.xml.

<dependency>
	<groupId>com.rabbitmq</groupId>
	<artifactId>amqp-client</artifactId>
	<version>3.5.4</version>
</dependency>

Java examples in official tutorial

There is a complete Hello World example of a publisher in https://www.rabbitmq.com/tutorials/tutorial-one-java.html . just copy and paste it to your workspace and execute it after launch the server.

Complete a consumer example is here: https://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/Recv.java . just execute it after execution of publisher is done.

The whole project can be obtained from my GitHub repository, nothing interesting here though.

Remarks

It’s very easy to use, I haven’t experienced any pitfall at all.

I wanted to interact with the server using JMS, but the JMS client needs a commercial license to download and unfortunately I don’t have one.


Lean example of Tomcat 8 + Guice 4 + Jersey 2.19


Posted on Wednesday Aug 05, 2015 at 02:36PM in Technology


Jersey is the RI of JAX-RS. in this entry, I introduce you how to use Jersey 2.19 with Guice 4 on Tomcat 8. it looks like there are some issues exist as follows but thanks to https://github.com/Squarespace/jersey2-guice , I’ve succeeded to use them anyway.

The entire project which based on Maven can be obtained from My GitHub repository.

Dependencies

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey</groupId>
            <artifactId>jersey-bom</artifactId>
            <version>2.19</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.inject.extensions</groupId>
        <artifactId>guice-servlet</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.squarespace.jersey2-guice</groupId>
        <artifactId>jersey2-guice</artifactId>
        <version>0.10</version>
    </dependency>
</dependencies>

web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>guice.tomcat.jersey</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webapi/*</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>guice.tomcat.MyJerseyGuiceServletContextListener</listener-class>
    </listener>

    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

MyJerseyGuiceServletContextListener.java

In this example, we use the servlet context listener named JerseyGuiceServletContextListener which comes from jersey2-guice artifact as parent class.

public class MyJerseyGuiceServletContextListener extends JerseyGuiceServletContextListener {
    @Override
    protected List<? extends Module> modules() {
        return Collections.singletonList(new ServletModule() {
            @Override
            protected void configureServlets() {
                bind(MyService.class).to(MyServiceImpl.class);
            }
        });
    }
}

Service class

We use very simple pair of an interface and implementation that creates a simple greeting message, which used in a past entry so omitted for simplicity.

MyResource.java

This is an simple implementation of JAX-RS resource class. placed under guice.tomcat.jersey package. the preceding service class named MyService will be injected by @javax.inject.Inject annotation.

@Path("myresource")
public class MyResource {

    @Inject
    private MyService myService;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return myService.hello("Jersey");
    }
}

Test run

$ curl http://localhost:8080/webapi/myresource
Hello, Jersey


Lean example of Tomcat 8 + Guice 4 + EclipseLink 2.6.0


Posted on Tuesday Aug 04, 2015 at 07:26PM in Technology


I wrote a Lean example of Tomcat 8 + Guice 4 in previous entry. this time, I’ll try JPA(EclipseLink) integration with automatic transaction management.

The entire project which based on Maven can be obtained from My GitHub repository.

Prerequisites

For database connection, we’ll use a DataSource which is defined on Tomcat server. to define a Embedded Derby DataSource, This entry would help.

Dependencies

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.6.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.inject.extensions</groupId>
        <artifactId>guice-servlet</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.inject.extensions</groupId>
        <artifactId>guice-persist</artifactId>
        <version>4.0</version>
    </dependency>
</dependencies>

web.xml

No changes against previous entry except addition of resource-ref element.

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- taken from https://github.com/google/guice/wiki/Servlets -->

    <listener>
        <listener-class>guice.tomcat.MyGuiceServletConfig</listener-class>
    </listener>

    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <resource-ref>
        <res-ref-name>jdbc/derby</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

</web-app>

META-INF/persistence.xml

If you don’t want to use a DataSource on Tomcat, specify the connection information in javax.persistence.jdbc.* properties instead of non-jta-data-source.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="myJpaUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <non-jta-data-source>java:comp/env/jdbc/derby</non-jta-data-source>
        <class>guice.tomcat.MyEntity</class>
        <properties>
            <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
            <property name="eclipselink.logging.level" value="FINE"/>
            <property name="eclipselink.logging.level.sql" value="FINE"/>
        </properties>
    </persistence-unit>
</persistence>

MyGuiceServletConfig.java

The last two statements will take care of JPA integration.

public class MyGuiceServletConfig extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new ServletModule() {
            @Override
            protected void configureServlets() {
                serve("/*").with(MyServlet.class);
                bind(MyService.class).to(MyServiceImpl.class);

                install(new JpaPersistModule("myJpaUnit"));
                filter("/*").through(PersistFilter.class);
            }
        });
    }
}

MyEntity.java

This is a very simple JPA entity which keeps only generated id and ts (a timestamp).

@Entity
@NamedQuery(name = "MyEntity.findAll", query = "SELECT e FROM MyEntity e ORDER BY e.id DESC")
public class MyEntity implements Serializable {

    @Id
    @GeneratedValue
    private Long id;
    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date ts;

... accessors are omitted

Service class

MyService.java

public interface MyService {
    void save(MyEntity e);
    List<MyEntity> findAll();
}

MyServiceImpl.java

Note that you need to annotate a method with @com.google.inject.persist.Transactional if you need a transaction on it.

public class MyServiceImpl implements MyService {

    // Transactions doesn't start if EntityManager is directly injected via @Inject.
    // I have no idea why...

    // According to https://github.com/google/guice/wiki/JPA,
    // "Note that if you make MyService a @Singleton, then you should inject Provider<EntityManager> instead."
    @Inject
    private Provider<EntityManager> emp;

    @Override
    // @javax.transaction.Transactional is not supported yet. https://github.com/google/guice/issues/797
    @com.google.inject.persist.Transactional
    public void save(MyEntity e) {
        EntityManager em = emp.get();
        em.persist(e);
    }

    @Override
    public List<MyEntity> findAll() {
        return emp.get().createNamedQuery("MyEntity.findAll", MyEntity.class).getResultList();
    }
}

MyServlet.java

This servlet saves a MyEntity with current timestamp, then fetches all of rows and returns them to the client on every request.

@javax.inject.Singleton
public class MyServlet extends HttpServlet {

    @javax.inject.Inject
    private MyService myService;

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        MyEntity myEntity = new MyEntity();
        myEntity.setTs(new Date());
        myService.save(myEntity);

        PrintWriter writer = resp.getWriter();
        writer.write("<html><body><ul>");
        for(MyEntity e : myService.findAll()){
            writer.write("<li>");
            writer.write(e.toString());
            writer.write("</li>");
        }
        writer.write("</ul></body></html>");

    }
}

Test run

A row will be saved on every request as follows:

4d678c4b c55c 41e0 ba5d 65d2832409fb


Lean example of Tomcat 8 + Guice 4


Posted on Monday Aug 03, 2015 at 06:56PM in Technology


I prefer Java EE stack usually, but I need to learn a Tomcat based stack for some reasons these days. in this entry, I introduce you a very simple example of Tomcat 8 + Guice 4 app which uses GuiceFilter and GuiceServletContextListener so that bring Guice to a Servlet based web application.

The entire project which based on Maven can be obtained from My GitHub repository.

Dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>4.0</version>
</dependency>
<dependency>
    <groupId>com.google.inject.extensions</groupId>
    <artifactId>guice-servlet</artifactId>
    <version>4.0</version>
</dependency>

web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <listener>
        <listener-class>guice.tomcat.MyGuiceServletConfig</listener-class>
    </listener>

    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

MyGuiceServletConfig.java

We need to declare servlet mappings and the mappings between interfaces and implementations here.

public class MyGuiceServletConfig extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new ServletModule() {
            @Override
            protected void configureServlets() {
                serve("/*").with(MyServlet.class);
                bind(MyService.class).to(MyServiceImpl.class);
            }
        });
    }
}

Service class

We use a pair of a very simple implementation of a service class. it simply creates a greetings which uses an argument.

MyService.java

public interface MyService {
    String hello(String name);
}

MyServiceImpl.java

public class MyServiceImpl implements MyService {
    @Override
    public String hello(String name) {
        return "Hello, " + name;
    }
}

MyServlet.java

Note that we use @javax.inject.Singleton and @javax.inject.Inject annotations, that are standardized JSR API.

@javax.inject.Singleton
public class MyServlet extends HttpServlet {

    @javax.inject.Inject
    private MyService myService;

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write(myService.hello("Guice"));
    }
}

Test run

After deployment, send a request to check the response:

$ curl http://localhost:8080
Hello, Guice

Other things/functions need to be studied

  • Transaction management

  • CDI Producer equivalent

  • AOP

  • Automatic implementation scanning/binding