public class Hello { public String greetings(String name) { return name != null ? "hello, " + name : "hi, what's your name?"; } }
Excluding particular JUnit test cases that marked as slow in the time of execution
TweetPosted on Sunday Nov 01, 2015 at 03:43PM in Technology
Sometimes we need to create some slow test cases that involve some external resources such as databases, or external API servers. They are necessary to ensure that your application can integrate with such external resources while vast majority of test cases should stick with fast-running plain unit testing.
In such case, We usually wants to exclude such slow test cases from the ones that are frequently executed in local development environment so that we can get timely response from the tests. In this posting, I introduce you a solution that avoids maintenance of any hand-made listing of test cases.
Creating a suite that scans and runs all of test cases exist in classpath
First, assume we have a simple production class named Hello
.
We also have a couple of test cases against the preceding class:
public class HelloTest1 { @Test public void test() { System.out.println("Running " + getClass().getSimpleName()); Assert.assertEquals("hello, kyle", new Hello().greetings("kyle")); } } public class HelloTest2 { @Test public void test() { System.out.println("Running " + getClass().getSimpleName()); Assert.assertEquals("hi, what's your name?", new Hello().greetings(null)); } }
Next, We’d like to introduce a test suite that automatically includes the preceding two test cases. Put a following dependency to your pom.xml
:
<dependency> <groupId>io.takari.junit</groupId> <artifactId>takari-cpsuite</artifactId> <version>1.2.7</version> <scope>test</scope> </dependency>
And create a test suite that named AllTests
as follows. You can run this suite from your IDE or executing mvn -Dtest=AllTests test
.
@RunWith(ClasspathSuite.class) public class AllTests { }
Involving a slow test case and exclude it
First, Create a marker interface which indicates that this test is slow:
public interface SlowTest { }
Next create a slow test case which annotated with @Category(SlowTest.class)
that we would like to avoid execute it frequently:
@Category(SlowTest.class) public class HelloSlowTest { @Test public void test() throws Exception { System.out.println("Running " + getClass().getSimpleName()); Thread.sleep(3000); } }
Finally create a test suite that automatically excludes the test cases annotated as slow but executes rest of the test cases:
@RunWith(Categories.class) @ExcludeCategory(SlowTest.class) @SuiteClasses(AllTests.class) public class AllExceptSlowTests { }
You can run it on a daily basis instead of selecting root of your entire project and execute tests from your IDE or Maven without any hand maintenance of the listings of tests. For example, mvn -Dtest=AllExceptSlowTests test
produces following output in very short-term execution time:
... ------------------------------------------------------- T E S T S ------------------------------------------------------- Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8 Running category.suite.AllExceptSlowTests Running HelloTest1 Running HelloTest2 Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.084 sec ...
The complete resources can be obtained from https://github.com/lbtc-xxx/junit-category
SwingIrc: A simple IRC client
TweetPosted on Sunday Nov 01, 2015 at 01:42PM in Technology
About 6 years ago I’ve made a simple IRC client that uses Swing. I’ve digged source code of the app from my old PC by chance so I’ve Mavenized it and put it to GitHub. To be hornest, it’s a toy app but may someone like a student can refer it as an example of Java based GUI application.
How To Launch
Refer README.md in the repository.
How To Use
-
Put
name
,hostname
andport
to the dialog and hitconnect
-
Click
File
then selectJoin
-
Enter name of a channel to the dialog and hit
OK
-
Chat with other users
Future plans
-
Rewrite entire the app with JavaFX
-
Implement more features
-
Involve automated GUI testing
How to bind / lookup DataSource via JNDI without container
TweetPosted on Sunday Oct 25, 2015 at 10:58AM in Technology
While I prefer deploying JPA based apps to a Java EE container and test it via Arquillian as integration testing, some occasions won’t allow it and need arises that using a Servlet container or Java SE environment.
To supply information that required to connect the database (e.g. JDBC URL or credentials), it’s preferable to use JNDI rather than using DriverManager
or javax.persistence.jdbc.*
properties in persistence.xml
because using JNDI eliminates the need of managing such information in the application codebase, also it enables to use the container managed connection pool which is more flexible and scalable over another.
In such case, hard-coded JNDI name of a DataSource may be a problem in the time of testing because JNDI lookup doesn’t work without container as is. So we may need some considering of involve pluggable mechanism of acquiring java.sql.Connection
instance or creating persistence.xml
for unit testing.
These solutions are not much difficult to implement, but it’s preferable if JNDI lookup does work without container as well because it will decrease amount of testing specific code. In this posting, I’ll give you a complete example of looking up a DataSource without container using bare InitialContext
and the non-jta-datasource
persistence descriptor definition.
Environment
-
tomcat-catalina
artifact of Apache Tomcat 8.0.28: Enables binding a resource to JNDI context in Java SE environment -
Apache Commons DBCP 1.4: Supplies
BasicDataSource
class so make the example in database independent manner -
Apache Derby 10.12.1.1
-
EclipseLink 2.6.1
-
Oracle JDK8u60
Dependencies
<dependencies> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.apache.derby</groupId> <artifactId>derby</artifactId> <version>10.12.1.1</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina</artifactId> <version>8.0.28</version> <scope>runtime</scope> </dependency> </dependencies>
persistence.xml
Note that the non-jta-data-source
is used with JNDI name of DataSource.
<?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="myPU" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <non-jta-data-source>java:comp/env/jdbc/database</non-jta-data-source> <class>entity.Employee</class> <shared-cache-mode>NONE</shared-cache-mode> <properties> <property name="javax.persistence.schema-generation.database.action" value="create"/> <property name="eclipselink.logging.level" value="FINE"/> <property name="eclipselink.logging.parameters" value="true"/> </properties> </persistence-unit> </persistence>
Employee.java
This is a simple JPA entity class that will be used in testing.
@Entity public class Employee implements Serializable { @Id private Long id; private String firstName; private String lastName; // accessors omitted
Main.java
This binds a DataSource of Embedded in-memory Apache Derby database to java:comp/env/jdbc/database
, then lookup it via InitialContext
and EntityManagerFactory
.
public class Main { private static final String JNDI = "java:comp/env/jdbc/database"; public static void main(String[] args) throws Exception { bind(); lookup(); final EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPU"); populate(emf); query(emf); } private static void bind() throws NamingException { System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory"); System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming"); final BasicDataSource ds = new BasicDataSource(); ds.setUrl("jdbc:derby:memory:myDB;create=true"); final Context context = new InitialContext(); try { context.createSubcontext("java:"); context.createSubcontext("java:comp"); context.createSubcontext("java:comp/env"); context.createSubcontext("java:comp/env/jdbc"); context.bind(JNDI, ds); } finally { context.close(); } } private static void lookup() throws NamingException, SQLException { final Context context = new InitialContext(); try { final DataSource ds = (DataSource) context.lookup(JNDI); try (final Connection cn = ds.getConnection(); final Statement st = cn.createStatement(); final ResultSet rs = st.executeQuery("SELECT CURRENT_TIMESTAMP FROM SYSIBM.SYSDUMMY1")) { while (rs.next()) { System.out.println(rs.getTimestamp(1)); } } } finally { context.close(); } } private static void populate(final EntityManagerFactory emf) { final EntityManager em = emf.createEntityManager(); try { final EntityTransaction tx = em.getTransaction(); tx.begin(); final Employee emp = new Employee(); emp.setId(1l); emp.setFirstName("Jane"); emp.setLastName("Doe"); em.persist(emp); tx.commit(); } finally { em.close(); } } private static void query(final EntityManagerFactory emf) { final EntityManager em = emf.createEntityManager(); try { System.out.println(em.find(Employee.class, 1l)); } finally { em.close(); } } }
Log
You can see the lookup()
method dumped CURRENT_TIMESTAMP
and EclipseLink successfully acquired a DataSource as follows.
2015-10-25 10:33:24.235 [EL Fine]: server: 2015-10-25 10:33:24.478--Thread(Thread[main,5,main])--Configured server platform: org.eclipse.persistence.platform.server.NoServerPlatform [EL Config]: metadata: 2015-10-25 10:33:24.633--ServerSession(1323434987)--Thread(Thread[main,5,main])--The access type for the persistent class [class entity.Employee] is set to [FIELD]. [EL Config]: metadata: 2015-10-25 10:33:24.654--ServerSession(1323434987)--Thread(Thread[main,5,main])--The alias name for the entity class [class entity.Employee] is being defaulted to: Employee. [EL Config]: metadata: 2015-10-25 10:33:24.656--ServerSession(1323434987)--Thread(Thread[main,5,main])--The table name for entity [class entity.Employee] is being defaulted to: EMPLOYEE. [EL Config]: metadata: 2015-10-25 10:33:24.666--ServerSession(1323434987)--Thread(Thread[main,5,main])--The column name for element [firstName] is being defaulted to: FIRSTNAME. [EL Config]: metadata: 2015-10-25 10:33:24.668--ServerSession(1323434987)--Thread(Thread[main,5,main])--The column name for element [lastName] is being defaulted to: LASTNAME. [EL Config]: metadata: 2015-10-25 10:33:24.668--ServerSession(1323434987)--Thread(Thread[main,5,main])--The column name for element [id] is being defaulted to: ID. [EL Info]: 2015-10-25 10:33:24.7--ServerSession(1323434987)--Thread(Thread[main,5,main])--EclipseLink, version: Eclipse Persistence Services - 2.6.1.v20150916-55dc7c3 [EL Fine]: connection: 2015-10-25 10:33:24.706--Thread(Thread[main,5,main])--Detected database platform: org.eclipse.persistence.platform.database.JavaDBPlatform [EL Config]: connection: 2015-10-25 10:33:24.714--ServerSession(1323434987)--Connection(1872973138)--Thread(Thread[main,5,main])--connecting(DatabaseLogin( platform=>JavaDBPlatform user name=> "" connector=>JNDIConnector datasource name=>java:comp/env/jdbc/database )) [EL Config]: connection: 2015-10-25 10:33:24.715--ServerSession(1323434987)--Connection(1465346452)--Thread(Thread[main,5,main])--Connected: jdbc:derby:memory:myDB User: APP Database: Apache Derby Version: 10.12.1.1 - (1704137) Driver: Apache Derby Embedded JDBC Driver Version: 10.12.1.1 - (1704137) [EL Config]: connection: 2015-10-25 10:33:24.715--ServerSession(1323434987)--Connection(1634387050)--Thread(Thread[main,5,main])--connecting(DatabaseLogin( platform=>JavaDBPlatform user name=> "" connector=>JNDIConnector datasource name=>java:comp/env/jdbc/database )) [EL Config]: connection: 2015-10-25 10:33:24.716--ServerSession(1323434987)--Connection(1740223770)--Thread(Thread[main,5,main])--Connected: jdbc:derby:memory:myDB User: APP Database: Apache Derby Version: 10.12.1.1 - (1704137) Driver: Apache Derby Embedded JDBC Driver Version: 10.12.1.1 - (1704137) [EL Info]: connection: 2015-10-25 10:33:24.747--ServerSession(1323434987)--Thread(Thread[main,5,main])--/file:/Users/kyle/src/jndi-se/target/classes/_myPU login successful [EL Fine]: sql: 2015-10-25 10:33:24.784--ServerSession(1323434987)--Connection(762809053)--Thread(Thread[main,5,main])--CREATE TABLE EMPLOYEE (ID BIGINT NOT NULL, FIRSTNAME VARCHAR(255), LASTNAME VARCHAR(255), PRIMARY KEY (ID)) [EL Fine]: sql: 2015-10-25 10:33:24.85--ClientSession(1027495011)--Connection(1688470144)--Thread(Thread[main,5,main])--INSERT INTO EMPLOYEE (ID, FIRSTNAME, LASTNAME) VALUES (?, ?, ?) bind => [1, Jane, Doe] [EL Fine]: sql: 2015-10-25 10:33:24.877--ServerSession(1323434987)--Connection(640808588)--Thread(Thread[main,5,main])--SELECT ID, FIRSTNAME, LASTNAME FROM EMPLOYEE WHERE (ID = ?) bind => [1] Employee{id=1, firstName='Jane', lastName='Doe'}
The complete source code can be obtained from my GitHub repository.
Using DBUnit from Ant
TweetPosted 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
-
dbunit-2.5.1.jar (Not available on the download page on SourceForge. Obtain it from Maven Repository instead)
-
With dependencies: slf4j-api-1.7.12.jar, slf4j-jdk14-1.7.12.jar
-
-
postgresql-9.4-1203.jdbc42.jar
-
Apache Ant™ version 1.9.6
-
PostgreSQL 9.3.5
-
Oracle JDK8u40
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
References
Using RabbitMQ with Java
TweetPosted 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.
References
Tags: rabbitmq