Starting Components On Java EE 5 Appserver In a Portable Way

The last time I was frequently asked how to start components / initialize the infrastructure during server's startup. I saw several solutions already, some really esotheric, most of them not portable across servers. However the solution is really simple. All you need is a servlet with an init method:

public class BootstrapServlet extends HttpServlet {   

     //optional, only needed in case you would like to startup a session bean as well
    @EJB
    private BootstrapBean bootstrap;
   
    @Override
    public void init(){
        System.out.println("##################################### Hello World init");
    }

   public void doGet...

}

 To cause the application to init the servlet at startup, you have to include the <load-on-startup> tag in the web.xml.

 <web-app version="2.5" 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/web-app_2_5.xsd">
    <servlet>
        <servlet-name>BootstrapServlet</servlet-name>
        <servlet-class>com.abien.bootstrap.BootstrapServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>BootstrapServlet</servlet-name>
        <url-pattern>/BootstrapServlet</url-pattern>
    </servlet-mapping>
 </web-app>

 

The spec says: "...The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these
        element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet
        whenever it chooses. If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that
        servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value...
"

If you would like to initialize a Session Bean during the startup just inject the Session Bean into the servlet -> and it has to be initialized to. The EJB 3.1 spec will come with a Singleton Bean which will solve this problem - even without a servlet... I checked in this sample code as a Netbeans 6.1/Glassfish v2 into http://p4j5.dev.java.net, the project name is ServletBootStrapping.

EJB 3 and Memory Consumption Myths or Is it worth to use POJOs instead of EJB 3 in terms of memory?

The last time I'm often asked about the usage Stateless Session Beans  (EJB 3) regarding memory consumption and comparing them to POJOs. The nice Markus Kohler's comment for my recent post:
"Is it worth to use POJOs instead of EJB 3 in terms of performance? (with results, source and load scripts)" made me curious - and I started some evaluation. Some facts:

  1. Yes, it is true that an EJB 3 consumes some more memory comparing it to a standalone POJO. The decoration process (often with dynamic proxies), consumes times more memory, than a one instance of a class. However you will need the same aspects in POJO scenario as well. At least transactions, concurrency and remoting are often required. Then it wouldn't be much difference between the both.
  2. Under load the application server tries to create as less Stateless Session Beans (SLSB) as possible. You will only get several instances of one SLSB, in case the requests will arrive exact in the same time. Achieving the same effect with POJOs in WebContainer isn't an easy task. Most of the application server (especially commercial ones, or glassfish) allow you fine graine runtime configuration (Min/Max Pool Size) and especially minimize the scalability (which is really important to avoid Denial Of Service attacks)....
  3. In a pragmatic architecture you wouldn't have many SLSB. In general case you will get some facades - which wouldn't cascade in general. Even for huge application you will only in rare case get more then 30 SLSBs. In this context the additional consumption just doesn't matter.
  4. Yes, there is an initial overhead between plain WebContainer and and full-stack applicationserver. But in the practice it just doesn't matter. I run this weblog (not a huge traffic: 3500 visits a day and 20k hits), http://greenfire.dev.java.net (here happens a lot), http://underworld.dev.java.net (this one is heavy) and some Java EE 5 applications like http://www.adam-bien.com/tdb ....with -Xmx786m setting. I attached to Glassfish the JConsole and found out, that it actually only needs around 400MB RAM. My "commodity" box has 4GB built-in so I just don't care...
  5. It is worth to use an application-server, not just because of development, but especially production. An application server offers you sophisticated monitoring and management capabilities (they have to exists since J2EE 1.4, because of JSR-77). Glassfish goes beyond that and offers you CallFlow.
  6. Remember, Plain Old WebContainers are dead :-).
  7. The popular Wotif page runs on Glassfish with 8GB RAM server. I'm not really sure, whether it would be possible to minimize the memory consumption with a plain WebContainer - and what costs could be saved with such an action in this case.
  8. 1 GB RAM costs on amazon.com around 20 $ :-).
  9. The tooling for EJB 3 and JPA and integration with an application server are just great (just check out Netbeans 6.0/6.1). The mix of Dependency Injection and Convention Over Configuration saves lot of  code. This is good for maintainability and a topic for one of the next posts :-)
I heard the criticism about the memory consumption several times, we discussed the whole story during the Entwicklertage Java EE 5 workshop in great detail as well. It is actually a really good sign - it seems like a one and only remaining criticsm to EJB 3 :-). EJB 3 are really lightweight - sometimes lighter than POJOs....

The X-Files (actually -Xmx files), reloaded.

I got interesting feedback for my last post about the -Xmx and windows issues, with many links to external resources. First of all,  32bit applications on windows are limited to 2GB RAM. This limit can be raised to 3GB, however some settings at OS-level are required. This is just a fact, and has nothing to do with Java. This article covers the issues and settings in great detail.

Some JVMs, like JRockit, allow more heap, than 1.6GB - 1.85GB, or 2.85GB in particular, however the memory is partitioned (fragmented) in this case. So the performance of the allocation, as well as garbage collection, could degrade. The "trick" with /3GB switch is also mentioned for the IBM JVM.

The -Xmx switch is somehow dangerous as well. Too high setting causes the JVM to "crash" (actually not to start), with the following message:

"Invalid maximum heap size: -Xmx4g
The specified size exceeds the maximum representable size.
Could not create the Java virtual machine
."

So the proper -Xmx configuration is a crucial for all Rich Internet Applications, which are installed or deployed vie WebStart etc. In this case the lowest common denominator is crucial... On most machines there should be no problem with configuration below -Xmx1.4g. Fine tuning could be dangerous, especially if you are responsible for user support :-). On the server the issue is less a problem - the "try and error" strategy works well. However only in view companies I know the servers run on windows...:-)

Why you (developer) will like Glassfish v2 - 10 1/2 reasons

  1. The installation is easy and fast ( jar -Xmx256m glassfish…  + ant -f setup.xml) or just download it with e.g. Netbeans 6.0b2 - then no additional steps are required.
  2. Glassfish can be easily administered from commandline (launch asadmin.bat), XML-configuration, partially Netbeans (the services tab), and slick webapp ( http://localhost:4848)
  3. Glassfish allows autodeployment: just copy the ears, wars, ejb-jars into one folder (e.g. domains/domain1/autodeploy), as well as JMX deployment (used by the IDE).
  4. The mailing lists are responsive. You get in general feedback in hours (if not in minutes). Especially important is the persistence@glassfish.dev.java.net (persistence is the most complicated part of the Java EE 5). So you get a good base support for free (commercial support is available as well).
  5. Debugging and even profiling (threads, memory, performance) is really easy and e.g. built-in in netbeans 6.0b2 (right mouse click, profile)
  6. Glassfish is surprisingly well documented. Most of the docs are available in PDF as well. The answers for more detailed questions (clustering, caching, mod_jk integration etc) are available in blogs.
  7. The buit-in monitoring capabilities are useful. E.g. the callflow visualizes the call hierarchy of Servlets, Session Beans (also nested) etc.
  8. (The performance, scalability are good as well) - this feature isn't so important for developers :-)
  9. You can set all JVM-parameters (-Xmx), logging etc. using the admin console. The administration is easy: e.g. you can create a JMS Destination or JDBC-Datasource with only few clicks.
  10. Project WSIT makes Glassfish interesting for all interoperability projects with .NET.
  11. Glassfish is lean: no strange and proprietary ant tasks, annotations, XML-deployment descriptors etc. for the development and deployment of Java EE 5 applications are needed.
  12. I use Glassfish since early V1. It improves continually. The V2 seems to be solid. Dependency injection, especially overwriting the annotations with XML etc., Interceptors etc. work really well (just no issues). Until now I hadn't had any problems with EJB 3 layer (WebServices, Session Beans, Stateful Beans, Interceptors) - in fact I use Glassfish to reproduce issues with other commercial servers as well :-).  The persistence is also solid- in more complicated applications it is hard to say whether it is a JPA' or application's problem. However there were no show-stopper so far. I even use GlassfishV2 for controlling the heating - and we have hard winters in Germany :-). I will opensource the application soon (Project GreenFire) and present it at the oop conference 2008 in munich.

From zero to Java EE 5 app - in few minutes (on a fast machine :-))

I'm often asked, how to start with Java EE 5 with minimal setup/environment. In the world of Java there in general several options available - which is a good thing. However, you have to start somehow and refine your environment later. The easiest way (minimal amount of mouse-clicks), is the following:

  • Buy a mouse with a good, right button :-) 

This downloads netbeans with full Java EE support, as well as the production read reference implementation (Glassfish v2). It works with Netbeans 5.5.1 as well, but the editor of Netbeans 6.0 was improved significantly

  • In netbeans: Select Tab "Projects", right mouse click, Enterprise Projects -> Enterprise Application
  • Go to the "Bean Project" (EJB Module). right mouse click, select a "Session Bean". Implement a "Hello World" method with a return value (e.g. String sayHello()).
  • Go to the "Globe Project" (War). right mouse click, select a "Servlet". right mouse click -> Enterprise Resources ->  Call  Enterprise Bean.  Invoke the bean inside the method "processRequest"
  • Right click on the "Triangle Project" (EAR) right mouse click -> run. This can take several seconds/minutes. Netbeans starts the application server, deploys the application and opens the browser.
  • Close the IDE, Shutdown the machine -> and enjoy the weekend :-)
As you can clearly see -> the most important thing for Java EE 5 developers is the right mouse button :-).

Preventing Injection in JPA Query language - sample app and project

SQL and QL injection can be effectively prevented with the use of JPA Named Queries. In the contrary to the CMP 2.X spec, JPA QL are in general more flexible and can be parameterized. You can cover almost 90% of all cases with named queries. However, named queries only works in case the structure of the query is stable, and the parameters vary. Sometimes more flexibility is needed. Building the queries with Strings has several drawbacks:

  1. Lack or IDE support
  2. Syntax is evaluated at runtime. (affects performance and stability)
  3. QL/SQL injection is possible.

With a little "hack" and builder pattern, it is possible to use almost the old syntax more conveniently.

Instead of writing a something like this: 

        String expected = "SELECT e FROM Customer e WHERE e.name = :name";


You could chain methods, which looks like this:


EntityQuery query = new EntityQuery.SELECT().ENTITY().FROM(Customer.class).WHERE().attribute("name").build();

A static inner class with the name SELECT implements the builder pattern and takes the responsibility for building the queries:

public class EntityQuery {
       
        private String query;
        //attribute declaration    
        public static class SELECT<T>{
      
                
     public SELECT(){
            this.sqlQuery = new StringBuilder();
            this.sqlQuery.append("SELECT");
     }
       
        public SELECT column(String name){
            if(!multipleColumns){
                multipleColumns = true;
            }else{
                this.sqlQuery.append(SEPARATOR);
            }
            this.sqlQuery.append(name);
            return this;
        }
       
        public SELECT FROM(Class entity){
            this.sqlQuery.append(BLANK).append(FROM).append(BLANK);
    }

//...

The Entity Query Builder, as well as the unit tests are available from http://qlb.dev.java.net. I'm working now on the EntityManager integration. First samples should be available in few days.

First Workshop with Netbeans 6beta 1 ...and where is the Problems View?

This week I gave a Java EE 5 Patterns class in Munich. We used Netbeans 5.5.1, some students 6.0b1 for the exercises.
It was a risky decision, but Netbeans 6.0 beta1 was surprisingly stable. There were only few minor problems with the editor (some packages were marked with the "error" icon, although there were no issues). We built a sample application called "chicken order". It was motivated by the "Oktoberfest" :-). Deployment to Glassfish v2 FCS, EJB 3 wizzards, Java Server Faces editors worked without any problems. However Glassfish had to be restarted from time to time on Windows, because it locked the ears - and then they cannot be deleted. This is really annoying, but otherwise it would be unbelievable efficient :-).

Some students already had experience with Netbeans which surprised me as well - in Germany Netbeans-IDE wasn't really popular few years ago. Some FAQs they asked me:

  • Where ist the Eclipse's "Problem's View"? 
    • Answer: Strg+6, or Window->Task List
  • Do we have to install plugins? :-)
    • Answer: Some interesting Plugins are: UML Support, Collaboration Tool, JavaFX plugin. However for mainstream Java EE development, no additional plugins or extensions are needed. Just single ZIP dowload (about 90-100MB) is enough.
  • Is really everything already included?
    • Answer: yes. Netbeans 6.0 comes with Profiler, JSF Designer, SQL Explorer, Subversion, CVS, Swing GUI Designer, Tomcat and good Java EE support.
  • What keybinding are supported?
    • Answer: Tools -> Options -> Keymap. Eclipse, Emacs and Netbeans 5.5 are supported. In the folder [netbeans_home]/nb6.0 you will find a PDF with all shortcuts documented
I switched completely to Netbeans 6.0 (from 5.5.1 :-)) it works really well for me so far. However I didn't tried the Mobile Developement capabilities yet.

Generic CRUD Components with Java EE 5

The mix of EJB 3, JPA and generics makes it possible to build lean and powerful management components with only few lines of code. Especially reusable CRUD components (e.g. masterdata management) do not have to be coded over and over again. The CRUD methods can be defined in a remote or local interface of a stateless session bean:

public interface CrudService<K,T> {
    public  T create(T t);
    public  T find(K id);
    public void delete(T t);
    public  T update(T t);
   //finders...
}
It is a plain interface without the @Remote annotation (a simple POJI).
The CRUD-logic is realized in a stateless session bean which provides the type of the primary key, as well as of the persistent entity:

@Stateless
@Remote(CrudService.class)
public class CrudServiceBean implements CrudService<Integer,Customer> {
   
    @PersistenceContext
    private EntityManager em;

    public Customer create(Customer t) {
        this.em.persist(t);
        return t;
   //remaining methods
    }

In this particular case, the interface is defined only once and realized by specific EJBs (which have to be implemented and deployed for each JPA-entity)
However a type-unsafe variation can be even more flexible.The usage of the java.io.Serializable (or Object), instead of a generic type allows the deployment of only one EJB, which is able then to manage all JPA-entities.

public interface GenericCrudService {
    public  Serializable create(Serializable t);
    public  Serializable find(Serializable id,Class type);
    public void delete(Serializable t);
    public  Serializable update(Serializable t);
    public Collection<Serializable> findByNamedQuery(String queryName);
    public Collection<Serializable> findByNamedQuery(String queryName,int resultLimit);
}

The implementation of the interface is straightforward:

@Stateless
@Remote(GenericCrudService.class)
public class GenericCrudServiceBean implements GenericCrudService {
  
    @PersistenceContext
    private EntityManager em;

    public Serializable create(Serializable t) {
        this.em.persist(t);
        return t;
    }

    @SuppressWarnings("unchecked")
    public Serializable find(Serializable id, Class type) {
       return (Serializable) this.em.find(type, id);
    }

    public void delete(Serializable t) {
       t = this.em.merge(t);
       this.em.remove(t);
    }

    public Serializable update(Serializable t) {
        return this.em.merge(t);
    }

    public Collection<Serializable> findByNamedQuery(String queryName) {
        return this.em.createNamedQuery(queryName).getResultList();
    }

    public Collection<Serializable> findByNamedQuery(String queryName, int resultLimit) {
        return this.em.createNamedQuery(queryName).setMaxResults(resultLimit).getResultList();
    }
EJB 3 are even efficient enough for the implementation of really simple use cases. This change a lot, comparing it to the J2EE/EJB 2.0 spec.
The whole example is available in p4j5.

JPA Injection Shortcomings and Possible Workaround

I got a really interesting question/suggestion as a feedback for p4j5 and the PDO pattern. If you are going to realize rich domain objects, sometimes it's necessary to access the resources like EntityManager from inside a JPA-Entity. Eg. sometimes it is useful to search for entites, access other Session Beans/Services etc. The problem here - dependency injection in JPA is not supported by the EJB-Container (now).
However simple Strategy algorithms, can be injected in e.g. the Service Facade, or Persitent Domain Object Facade (checkout p4j5)
Sample:

/** SessionBean Discount Strategy */
@Stateless
public class DiscountStrategyImpl implements DiscountStrategy { ... }

/** ShoppingCart uses a DiscountStrategy to calculate discount */
@Entity
public class ShoppingCart
{
  @Transient
  private DiscountStrategy strategy;
  ..
  void setDiscountStrategy(DiscountStrategy discountStrategy) { this.strategy = discountStrategy; }
}

/** Facade for ShoopingCart */
@Stateless
public class ShoppingCartService
{
  @EJB
   private DiscountStrategy strategy;

  public ShoppingCart findById(Object id)
  {
    final ShoppingCart cart = em.find(ShoppingCart.class, id);
    cart.setDiscountStrategy(strategy);
    return cart;
  }
}
The solution only works for the "master", and not dependent entities, however the master-entity could propagate the strategy to the children as well. This could change in Java EE 6 with the "Singleton Beans".
Thanks to Thomas Bauer for the suggestion of this pattern. He suggested the name "Service Injection". However "Strategy Injection" could be a better name for this specific case above.
Btw. there are now 24 approved observers in p4j5.

Generic Data Transfer Object checked into p4j5

A sample implementation of the Generic Data Transfer Object pattern is checked in to p4j5. The idea of the GDTO is to provide a flexible, but type-unsafe, way to transport data between tiers.
Beyond pure data transport the GDTO can be also used for validation. The flexibility of the GDTO costs also performance - there are more instances involved.

It is also not very easy to work with GDTO directly:

  private GenericDTO generic;
 
    public void setUp(){
         this.generic = new GenericDTO("Cart");
    }
 
   public void testAdd() {
        assertEquals(0,this.generic.getNumberOfAttributes());
        StringType description = new StringType(null,"a simple cart for test purposes");
        this.generic.add("description", description);
        assertEquals(1,this.generic.getNumberOfAttributes());
        assertFalse(this.generic.isEmpty());
        String toString = generic.toString();
        assertNotNull(toString);
        System.out.println(toString);
    }

However it's intended to be used in reflective way (e.g. binding the UI automatically to the GDTO). Changes to the underlying data also do not affect the compatibility of the interfaces/layers - however the stability of the interface requires more testing. The lack or renaming of attributes can cause runtime exceptions.

...the last 150 posts
...the last 10 comments
License