JSF 2.0 – The action event model

If you are working with JSF 2.0 there are different ways to interact with backend methods and passing params to action methods. A useful link for this topic can also seen here.

So for example if you have a JSF page with the following command link you use different ways to bound your backing bean:

<h:commandLink action="#{workflowController.editAction(workitem)}"
               actionListener="#{workflowController.doEdit}">
         <h:outputText value="click me" />
         <f:setPropertyActionListener
               target="#{workflowController.workitem}" value="#{workitem}" />
</h:commandLink>

The important thing here is the order which the jsf framework will trigger the differnt methods of the backingBean ‘worklfowController’

  1. The actionListener method will be called
  2. The setPropertyActionListener will trigger the setter method of the property ‘workitem’
  3. The action method with a custom param will be called

So in this case you backingBean can look something like this – note that there are two different ways to pass a param:

 

   // first the actionListener method will be called   
   public void doEdit(ActionEvent event) throws Exception {
        // do something...
       .....
    }

   // next the setter for the property will be called
   public void setWorkitem(Data aworkitem) {
        // do something    
   }

   // last the action method will be called
   public String editAction(String action) {
        // do something
        return action;      
    }

 

GlassFish – Heapsize settings

After playing around with some VM settings in my GlassFish 3.1.1 environment (development and productive) I came to a setup which brings up my glassfish server much faster. Here are my settings

Development (3GB RAM)

-client
-XX:+AggressiveHeap
-Xmx1024m
-Xms1024m
-Xss128k
-XX:+DisableExplicitGC

 

Productiv (4GB Ram)

-server
-XX:+AggressiveHeap
-Xmx2048m
-Xms2048m
-Xss128k
-XX:+DisableExplicitGC

Here is also a useful link for further performance settings:

http://jfarcand.wordpress.com/2009/11/27/putting-glassfish-v3-in-production-essential-surviving-guide/

 

 

GlassFish – EJB timer service not available

Today I had a situation where after a hardware crash my GlassFish Server did not work correctly. Specially the timer service did no longer work. The server log shows a lot of errors about

...EJB Timer Service not available

In the easiest case the reason why the timer service did not start are old db.lck files.

You can check this by stopping the server and then look for any lock files in the domain folder

../lib/databases/ejbtimer/

After removing the files

dbex.lck  
db.lck

you can restart the server and every thing should work again.

See also the following thread if this did not work for you:

http://forums.java.net/node/666385

Rest Service and the HTTPServletReqeust Object

Today I got a strange problem with my REST service which needs a HttpServletRequest object to perform the RemoteUser name.

First I injected the HttpServletRequest as a field into my RestService-Class

....
@Path("/")
@Produces({ "text/html", "application/xml", "application/json" })
@Stateless
public class SystemRestService {
 ...   
	@javax.ws.rs.core.Context
	private static HttpServletRequest servletRequest;
.....

This works fine on my local glassfish server 3.1.1. But after I deployed this into my productive environment (glassfish 3.1) the field ‘servletRequest’ was always null.

The problem here is that injecting the HttpServletRequest into an instance field can become very soon stale. The solution is to annotating a method parameter to assure that the request object is obtained in connection to processing a request.

... 	
@GET
	@Path("/profile.json")
	@Produces("application/json")
	public String getUserByID(@QueryParam("uid") String user,
			@QueryParam("items") String items,@Context HttpServletRequest servletRequest) {
.....

See also this discussion on the coderanch:

http://www.coderanch.com/t/510941/Web-Services/java/Print-Client-IP#2649412

Java EE6 – How to package an EAR

I spent the last weeks a lot of time to find out what’s the best way of packaging an EAR deployable on a JEE6 Application Server like Glassfish V3. I stumble on some problems when I try to deploy my EAR on Glassfish V3 which was running before on JEE5 Glassfish V2.1 server. Now I find out the missing parts and I want to describe my experiences here.

I am not talking about the typical EAR packaging situation you can see in the most of examples and tutorials where you have an EJB Module containing you business logic and a WEB Module containing your web frontend. As in JEE5 also in JEE6 it is pretty easy to deploy such an application. And there is in most cases no need to think about deployment descriptors as it was necessary before in J2EE (Java 1.3, 1.4).

What I tried to find out was the right packaging of an EAR including different libraries containing JEE components like EJBs, JPA Entities and Servlets on top of my EJB and WEB Module. I call such libraries “Component-Libraries” to indicate that these libraries containing JEE Components which can be used out of the box.

So first lets take a look on a simple situation where you want to package a simple JAR file together with a EJB and Web module. For example you have a JAR providing some POJOs used by both modules (EJB and web module). In this situation you can drop such a library simply into the /lib folder of you EAR. So your EAR should have the following structure:

[my-ear]
 - [lib]
     |- (pojo.jar)
 - [META-INF] 
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)

As the pojo.jar is packaged into the /lib folder (which is the default location for shared libraries) both modules (the web and the ejb) can access the pojo.jar library. This is a typical situation and it is very easy to use.

But what if you have a component-library containing additional EJBs? If you package this library also into the /lib location like this:

[my-ear]
 - [lib]
     |- (pojo.jar)
     |- (ejb-components.jar)
 - [META-INF] 
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)

the deployment will fail in most cases. The problem now is, that the EJBs  defined in the ejb-components.jar are in the top-level “lib” directory of the ear. That means the classes are visible to all modules in the ear. Each module (the my-ejb.jar and also the my-web.war) is processed for annotations, so the beans defined in the ejb-components.jar are created more than once. This is the reason that it is not recommended to put classes with component-defining annotations in a library .jar!

Ok – so lets put the ejb-components.jar out of the /lib folder location:

[my-ear]
 - [lib]
     |- (pojo.jar)
 - [META-INF] 
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)
 - (ejb-components.jar)

But now the EJBs of the ejb-components.jar will not be deployed because this jar is not a declared as an ejb module. Ok – you can add the jar to the application.xml file and declare this jar to an additional ejb module like this:

<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" version="5">
  <module>
    <web>
      <web-uri>my-web.war</web-uri>
      <context-root>/my-web</context-root>
    </web>
  </module>
  <module><ejb>my-ejb.jar</ejb></module>
  <module><ejb>ejb-components.jar</ejb></module>
</application>

This will work until you have to overwrite the ejb-jar.xml file. But this situation often occurs if you need to reconfigure the EJBs of the ejb-components.jar. And as you have no sources of this jar you can not easily rebuild it with additional descriptors. So now you have a real problem!

But there is a trick which enables you to take over control of all the EJBs defined in the ejb-componets.jar directly in your my-ejb.jar where you have the sources to build this module.
Simply add a Class-Path definition to the META-INF/MANIFEST.MF file of your ejb module:

Manifest-Version: 1.0
Class-Path: ejb-components.jar

Now the ejb-components.jar become a part of your my-ejb.jar and you can overwrite each setting in you ejb-jar.xml file. If you are using maven as your build tool you can add this additional Manifest entry simply by using the maven-ejb-plugin.

            .......
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId>
                <configuration>
                    <ejbVersion>3.0</ejbVersion>
                    <archive>
                        <manifestEntries>
                            <Class-Path>ejb-components.jar</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>                
            </plugin> 
            .......

If you are not using maven simply add the MANFIFEST.MF file into your my-ejb module.

OK why did I talking about all this stuff? In the situation I describe here I assume that your are not in the role of the component-developer of the EJBs implemented in the ejb-components.jar. Your are in the Role of the component-deployer. In this role you do not change the implementation but you may want to overwrite some settings of the ejbs provided by the component-developer. For example you want to define a ‘run-as-principal’ role to a ejb or a method. Or you would like to rename a ejb or inject a local jndi-mail or jndi-directory resource by name. In this cases you can do this now by the ejb-jar.xml which is located in your ejb modle (my-ejb.jar) and which is under your control.

Remember – JEE is in first place a component architecture. This means you develop an ejb component once and you can reuse and run this component everywhere in your environment. I think this part of JEE is sometimes missed in lots of JEE projects. So this concept follows the goal to simplify your deployment and your project structure but also reuse complex components in an easy way.

SERVLETS AND JPA ENTITIES

Until now I explained how to deploy ejb component jars. Next I want to take a look on another kind of JEE components – Servlets and JPA Entities.

If you have a jee-component.jar containing Servlets you can follow the instructions above. A servlet provided by the ejb-components.jar will be visible to a web module as your my-ejb.jar is part of your EAR. But your servlet will not able to use injected EJB or JNDI Ressources. So an annotation with an EJB injection in your servlet code will not work:

public class WorkflowRestService extends javax.servlet.http.HttpServlet
		implements javax.servlet.Servlet {
.... 
    @EJB
    org.imixs.workflow.jee.ejb.EntityService entityService;
.....

The reason why the entityService EJB in this case will not be injected is that the servlet class located in the ejb-componets.jar is visible to the web module but the servlet will not be scanned for injections because it is now part of our EJB module. So it is not recommended to deploy a component-library containing a servlet in the way described before.

Component-libraries containing Servlets and also JPA Entities can be still placed into the /lib location of your EAR.

[my-ear]
 - [lib]
     |- (pojo.jar)
     |- (servlet-components.jar)
     |- (jpa-components.jar)
 - [META-INF] 
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)
 - (ejb-components.jar)

In this case your servlet from the servlet-components.jar is visible now to the web module (my-web.war) and Injection will work as expected. So do not! mix up EJB, JPA and WEB components into one component-library. This is also important as you increase the deployment flexibility of your project for future.

I the case of the jpa-components.jar there is another detail to be pointed out.

I assume that the jpa-comonents.jar includes Entitie EJBs like this:

package org.imixs.workflow.jee.jpa;
.....
 @javax.persistence.Entity
public class Entity implements java.io.Serializable {
......

The Entities are typical injected by EJB components using an JPA EntityManager

    @PersistenceContext(unitName = "org.imixs.workflow.jee.jpa")
    private EntityManager manager;

As the jpa-components.jar is now located in the /lib folder of the ear you need to declare the location of the jpa unit in the persistence.xml file. And now I am back to the my-ejb.jar module where you are the component-developer. As you control this module you can place the persistence.xml file into the META-INF folder and define the location of your jpa-component.jar there:

persistence.xml:

<persistence>
    <persistence-unit name="org.imixs.workflow.jee.jpa">
        <jta-data-source>jdbc/workflow-db</jta-data-source>
        <properties>
            <property name="toplink.ddl-generation"
                value="create-tables" />
        </properties>
        <jar-file>lib/jpa-components.jar</jar-file>
    </persistence-unit>
</persistence>

So again you have full control about the deployment of all your components provided by third party component-libraries.

CONCLUSION

After some problems starting deploying my EAR on Glassfish V3 (migrating from Glassfish V2.1) I think JEE6 is still a flexible and powerful application platform. Also the platform supports strong capabilities in the configuration of complex applications and the usage of third party components. And JEE6 is a component architecture which supports a modular concept of build applications from components to be reused in different situations.

But I still have some problems in deploying WebService components from a component-library. I will continue to figure out how to deploy such components. If you have any suggestions or comments please let me know and post them here.

Imixs Workflow project started!

I am proud to announce that we started the new Open Source Workflow Project Imixs-Workflow. This project arise from the ix-workflow project we developed about for more than 3 years. But the new project is much more easy to use. We developed a bunch of simplifications in the Workflow API so the hole project is now much easier to integreate. I would be happy if you can give me some feedback to that project on the project home page.

I will provide a short video next time to show how easy it is building workflow applications based on the API.