07 June 2011

Java EE 6 Server Comparison: Resin

The first time I read about Caucho Resin 4.x was last summer, when I was looking for alternative CDI implementations, i.e. other than Weld. Resin has its own CDI implementation named CanDI, and I was bold enough to give it a try, knowing that Resin 4.x was not yet Java EE 6 certified and probably not stable enough.

I didn't get very far at that time, CanDI looked ok, but the JPA API was broken and @Singleton @Startup beans did not work, so I left it at that and made a mental note to check back after the first stable release.


Now that Resin 4.0.17 passed the Java EE 6 Web Profile certification in May 2011, it's a good time to give it another try.

Considering that Caucho focuses on the Web Profile and has no intention to support the Full Profile, you'd expect Resin to be more lightweight than Glassfish or JBoss. In fact, Resin is amazingly small and easy to use, the perfect example to destroy common belief that Java Enterprise servers are heavyweight and slow.

The Resin download package has 23 MB (compared to 44 MB for Glassfish Web Profile, 78 MB for Glassfish Full Profile, and 173 MB for JBoss).

Resin has a very small number of third party dependencies. The largest part of Resin is a single resin.jar of less than 11 MB, the rest is Eclipselink (JPA), Mojarra (JSF), Java Mail and a couple of Java EE API JARs.

This fact is worth mentioning, not just as an achievement of the Resin development team, but also as a benefit for the application developer: The risk of a version conflict for a library used both by the application and the server is almost zero, given that Resin has little or no external dependencies.

Preparing the server


To configure my data source, I added the MySQL JDBC driver to Resin's lib directory and then added the following section to conf/resin.xml:

<database>
    <jndi-name>jdbc/tcm</jndi-name>
    <driver type="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
      <url>jdbc:mysql://localhost/myapp</url> 
      <user>myuser</user>
      <password>****</password>
    </driver>
    <prepared-statement-cache-size>8</prepared-statement-cache-size>
    <max-connections>20</max-connections>
    <max-idle-time>30s</max-idle-time>
  </database>

Then I started the server from the command line:

bin/resin.sh console

and copied my WAR to the webapps directory for deployment.

Troubleshooting


Resin's approach to proxy creation for EJBs and CDI beans is Java code generation and compilation at deployment time. In the current release 4.0.18, the EJB code generator is broken for some use cases with generic methods.

After I posted my problem in the Resin forum, the development team advised me to use the current snapshot which solved the problem at least partially, and for the remaining cases, I temporarily removed some generic parameters in a few source files of my application.

For the rest of my experiments, I used the pre-4.0.19 snaphot version labelled resin-4.0.s110531.

Besides the generic methods arguments, the code generator complained about a checked exception in a @PostConstruct method, but it was right in doing so: the PostConstruct Javadoc clearly states that methods with this annotation must not throw checked exceptions, so I wrapped my checked exception in an unchecked exception, and the problem was gone. (Glassfish and JBoss did not complain about the checked exception.)

The only remaining problem was a version conflict for the SLF4J API. Resin includes slf4j-1.6.1.jar in webapp-jars whereas my application requires 1.5.11. I deleted the 1.6.1 version from webapp-jars and added the Hibernate, Javassist and JAXB JARs I had needed to exclude from my WAR for JBoss.

Other problems like EL in JSPs not working turned out to be a side effect of a broken Eclipse plugin version.

Eclipse Integration


In fact, the Eclipse plugin was my biggest source of troubles with Resin. The current release 4.0.16 from Caucho's Update Site did not work at all in the default (i.e. WAR) deployment mode. After enabling directory-based deployment in the Server Runtime dialog, the plugin would deploy my application, but its update behaviour was a complete mystery to me. Sometimes it seemed to deploy out-dated versions of classes, including some classes I had already deleted.

The WAR deployment has been fixed in the current 4.0.19 snapshot version of the Eclipse plugin which can be installed from the Snapshot Update Site.

After deleting the 4.0.16 version and installing the 4.0.19 snapshot, the Eclipse plugin finally started to work more or less reliably in the default mode. The directory mode continues to be broken, causing all sorts of mysterious side effects.

With the default mode, there are still a number of issues:

  • Editing a source file of the top-level module redeploys the application as expected, editing a source of a dependent module does not.
  • Redeploying the application causes the EJB Proxies and JSPs to be regenerated and recompiled. For some reason, this process is much slower when running under the Eclipse plugin, compared to (re)deploying an application from the command line. Increasing MaxPermSize in the server launcher did not help.
  • After two or three redeployments from Eclipse, Resin dies with a PermGen size OutOfMemoryError.
From the command line, I was able to redeploy my application a couple of times without any apparent memory leaks.

Performance Measurements


  • Empty server startup time: 3.3 s
  • Empty server memory usage: 22 MB heap, 27 MB PermGen
  • MyApp deployment time: 8 s
  • Server + MyApp restart time: 9 s
  • Server + MyApp memory usage: 44 MB heap, 58 MB PermGen
  • MyApp redeployment time: 8 s
  • Server + MyApp startup time from Eclipse: 30 s
  • Server + MyApp memory usage from Eclipse: 245 MB heap, 124 MB PermGen
  • MyApp redeployment on Eclipse save: 25 s, heap reduced to 85 MB

It is strange that Resin works rather smoothly from the commandline and has no memory issues at all, while slowing down on code generation, using excessive amounts of memory and throwing PermGen exceptions in combination with the Eclipse plugin.

Summary


Resin is easy to use and incredibly lightweight. The documentation is rather terse and not always up-to-date, but all in all usable. The Resin Forum was extremely helpful, my questions were answered quickly and some of the bugs I found during this investigation have already been fixed by the Caucho team in the meantime.

It would be foolish to recommend any server for production use before having worked with it in a real project for at least a couple of months, but it is safe to say that Resin looks extremely promising and is fun to work with.

The sore point at the moment is the Eclipse integration, which is currently not stable enough for day-to-day development, so this is a real blocker, unless you are happy using command line tools, some other IDE, or maybe some other server for development and Resin for testing and production only.

Resin 4.0.x releases have been published once a month since February 2010, and if the team can keep up this pulse rate both for the server and the Eclipse plugin, I'm quite confident that Resin will be a first class Java EE 6 Web Profile platform within a few months.

Read the whole story


3 comments:

Reza Rahman said...

Harald,

Just to follow-up on this, we really could use your help in improving the Eclipse integration. As promised, Alex is looking into the Eclipse issues you already pointed out. Can we kindly get back in touch with you when he is done? We'd really like to do whatever is needed to make sure we are the best lightweight Java EE 6 application server in the market, including Spring+Tomcat and will take any feedback very seriously.

Cheers,
Reza

Harald Wellmann said...

Reza, I suppose the server is always the main focus for the development team, but for end users, it's a seamless end-to-end toolchain that really counts.

Just let me know when there's a new release of the Resin Eclipse plugin and I'll be happy to give it another try.

And I'll be keeping an eye on the Resin forum anyway.

Cheers,
Harald

Reza Rahman said...

Harald,

It is our aim to provide a great end-to-end development experience :-). Thanks for the offer to help!

Cheers,
Reza