Thursday, March 22, 2012

EJB testing with JUnit + OpenEJB + JPA 2.x

One disadvantage of using EJB technology in our application is that they need a container where they can be deployed. Typically you would lose too much time testing them because of the application server; It has to be running so that the EJBs are deployed, and if you have trouble and have to fix some code then you have to redeploy those EJBs just to do some tests... Well, you can use an embedded container in your tests where your EJBs can be automatically deployed and do some tests, everything without the need of an expensive server running and thus, saving a lot of time!

OpenEJB is a lightweight EJB container which can be used to perform EJB testing. In this example we deploy an EJB that saves some data in a table.
In default mode, OpenEJB automatically uses OpenJPA as the JPA implementation. We are going to change it and use Hibernate instead.

By the time I write this post, OpenEJB 3.2.0-SNAPSHOT is the current version that supports JPA2, which is the one that's going to be used in the example. Previous versions of OpenEJB like 3.1.4 only support JPA1, so, be careful when if you come into strange and undescriptive errors and you don't know what may be going on...


So, first of all we need the following jar files:

pom.xml
<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>ar.com.openejb</groupId>
 <artifactId>openejb3-example</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>openejb3-example</name>
 <url>http://maven.apache.org</url>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>
 
 <repositories>
  <repository>
   <id>JBoss Developer</id>
   <url>https://repository.jboss.org/nexus/content/groups/developer/</url>
  </repository>
 </repositories>

 <dependencies>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
   <version>3.6.9.Final</version>
   <scope>test</scope>
  </dependency>

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.8.2</version>
   <scope>test</scope>
  </dependency>

  <!-- Here we use PostgreSQL, you may use another database -->
  <dependency>
   <groupId>postgresql</groupId>
   <artifactId>postgresql</artifactId>
   <version>9.1-901.jdbc4</version>
   <scope>test</scope>
  </dependency>

  <dependency>
   <groupId>org.apache.openejb</groupId>
   <artifactId>openejb-core</artifactId>
   <version>3.2.0-SNAPSHOT</version>
   <scope>test</scope>
  </dependency>

  <dependency>
   <groupId>org.jboss.ejb3</groupId>
   <artifactId>jboss-ejb3-api</artifactId>
   <version>3.1.0</version>
   <scope>test</scope>
  </dependency>

  <!-- This one is to let OpenEJB log stuff -->
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-jcl</artifactId>
   <version>1.6.4</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
</project>

The java.naming.factory.initial is the minimum variable requirement to start the container. Here, it is set via jndi.properties file, just make sure it is available in the classpath.

jndi.properties
#This is the minimun requirement to lauch OpenEJB
java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory

#We want OpenEJB to log everything in debug mode
log4j.category.OpenEJB.options = debug
log4j.category.OpenEJB.startup = debug
log4j.category.OpenEJB.startup.config = debug

#We tell OpenEJB to scan the whole classpath
openejb.deployments.classpath.include=".*"
openejb.deployments.classpath.exclude=""

#Definition of the default datasource
myDS=new://Resource?type=DataSource
myDS.JdbcDriver=org.postgresql.Driver
myDS.JdbcUrl=jdbc:postgresql://localhost:5432/openejb3-example
myDS.JtaManaged=true
myDS.DefaultAutoCommit=true
myDS.UserName=postgres
myDS.Password=123456

The service we have created where we inject an entity manager:

PersonServiceBean.java
@Stateless
public class PersonServiceBean implements PersonService {
 
 @PersistenceContext(unitName="openejb3-example")
 private EntityManager entityManager;

 @Override
 public Integer save(Person person) throws Exception {
  entityManager.persist(person);
  
  return person.getId();
 }
}

Now we can start the context with InitialContext() which will read our jndi.properties file and start automatically the OpenEJB container and allow us to lookup services.

PersonServiceTest.java
private PersonService service;

 @Before
 public void init() throws NamingException {
  InitialContext ctx = new InitialContext();
  service = (PersonService) ctx.lookup("PersonServiceBeanLocal");
 }
 
 @Test
 public void saveTest() throws Exception {
  Person person = new Person();
  person.setName("Rudolph");
  
  Integer id = service.save(person);
  
  System.out.println("The person id is " + id);
 }

This is the test persistence file:

persistence.xml
<persistence version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/persistence" xsi:schemalocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
 <persistence-unit name="openejb3-example" transaction-type="JTA">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <class>ar.com.model.Person</class>
  <properties>
   <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
   <property name="hibernate.hbm2ddl.auto" value="update" />
   <property name="hibernate.show_sql" value="true" />
  </properties>
 </persistence-unit>
</persistence>

Monday, February 27, 2012

Really useful Eclipse shortcuts

I tended to remain skeptical about the advantages of using shortcuts in order to "gain more time". After all, how much time would you really save learning to use them? Well, I gave them a try. Even tough I think I didn't gain more time, I found myself using shortcuts instead of making abuse of "copy & paste" and learning from Eclipse suggestions while developing. So, I am putting here the shortcuts that I mostly use:

CTRL + 1
With this one, the scenarios where it is really useful are:
  • You have a variable in a class, with this shortcut you can refactor rename it.
  • You can switch between a local variable declaration and attribute of the class.
  • Or if you are creating the local variable and assigning a value to it in the same line, you can split it in two lines.
  • You have a call to a function that returns a value, with this you can automatically create a local variable or class attribute and assign the return value to it.
There are other suggestions possible that Eclipse will offer you, like rewriting code in other ways. You can learn a lot from those suggestions too! I really recommend the use of this shortcut.

CTRL + .
With this you can navigate through warnings or errors inside your class.

CTRL + F and CTRL + K
You open the find box with the first one, and look for other occurrences in the same file.

CTRL + SHIFT + O
To organize imports in your class, these are automatically deleted, added or a suggestion box may appear in case there are two classes with same name under different package in the project. This one is a must.

CTRL + SHIFT + R
To open a resource without losing time searching for it in the Package Explorer. This one is a must.

CTRL + O
It will ease the navigation though attributes and methods inside a class.

CTRL + 3
You can choose different commands Eclipse allows you to use, but instead of doing that through a graphical menu choosing your option, you can write the word and the command will show. E. G.: you want to create a new project then: press the shortcut, write "new project" and choose it, in the same way write "servers" to open the "servers" view.

CTRL + SHIFT + LEFT or RIGHT
This is like SHIFT + LEFT or RIGHT to highlight words, but the difference is that with this one you highlight complete words, not one at a time. This one in particular is not from Eclipse, but very helpful in everyday development :)

Hide the "target" folder in Eclipse IDE

If you are using a development IDE like Eclipse and using Maven to manage your project, then you sure have faced the situation where you edit a class which is inside the target folder instead of the real one.

To avoid having this kind of issues again you have to:

Right-click in target folder ---> Properties ---> Resource ---> Check the Derived option


This option will prevent you from opening a resource (Ctrl + Shift + R) that is inside that folder, but you will still see that folder in the Package Explorer. To hide it you should:



Accept and now every target folder in your Package Explorer won't be shown, but they will still exist in your filesystem.

Wednesday, February 8, 2012

Running JBoss as a daemon

The advantage of running a JBoss instance as a service (or daemon) is that it will run in the background, taking advantage of the fact that the JBoss server is a non-interactive process. This way of running processes is particularly useful whenever you need to access a server through a command-line interface, deploy an application and run the server.

This procedure was done under Fedora 16 x64 and JBoss 5.1 community version.

1) Copy the file jboss_init_redhat.sh which is under $JBOSS_HOME/bin into /etc/init.d
2) You should rename it so that it represents the service you are referring to, for example jboss-dev
3) Now you should at least modify the following variables in the jboss-dev file:
#define where jboss is - this is the directory containing directories log, bin, conf etc  
JBOSS_HOME=${JBOSS_HOME:-"/opt/jboss"}

#define the user under which jboss will run, or use 'RUNASIS' to run as the current user
JBOSS_USER=${JBOSS_USER:-"RUNASIS"}

#make sure java is in your path
JAVAPTH=${JAVAPTH:-"/usr/local/jdk/bin"}

#configuration to use, usually one of 'minimal', 'default', 'all'
JBOSS_CONF=${JBOSS_CONF:-"test-standard"}

4) Now you can run these commands to start, restart or stop the servers:
service jboss-dev start
service jboss-dev restart
service jboss-dev stop

Even when stopping JBoss through a service it may fail due to external events and we may not notice it. So, it is always recommended to check the logs...
tail -f /opt/jboss/server/test-standard/log/server.log
...as well as running services:
ps aux | grep java
If you see the process is still there then you should take the pid of that process (say 999), and kill the process with either one of these two commands: (keep in mind that -15 is a clean shutdown and -9 should be used in case the process still does not respond)
kill -15 999
kill -9 999