Adam Bien's Weblog

Friday Nov 13, 2009

Java EE 6 Kills The WAR-Bloat - The KiloByte Deployment

The beauty of Java EE is the lack of libraries and JARs which have to be deployed with your project. Everything you needs resides already on the server. This makes your WARs / EJB-JARS / EARs extremely lean. They only consists of your compiled classes - the actual business logic. There is no need to deploy anything, because the frameworks (JPA implementation, EJB container, JSF implementation, REST implementation, JMS / JDBC-drivers) are already installed on the server. The last time I pushed some examples to: http://kenai.com/projects/javaee-patterns/. The size of the deployment units were:

  • BeanLocatorTest.war - 16 kB
  • FireAndForget.war - 8 kB
  • DAOPattern.war - 29kB
  • ResourceBinder.war - 8kB

Java EE 6 deployments gets even leaner, than Java EE 5 because REST implementation, Bean Validation, DI extensions (JSR-299, JSR-330) etc. are already part of the spec.

Small deployment units makes the deployment cycle really fast. With Glassfish v3 and incremental deployment of a EJB, Interceptor, JPA-Entity, JSF backing bean takes in general < 10 ms. The full deployment takes at most few seconds.

It seems like some developers are concerned about the size of the server. I prefer small deployments and actually don't care very much about the size of the server. Although Java EE 5/6 servers became surprisingly small. The EJB container in the newest Glassfish v3b71 build is still < 1 MB.

Small deployment units are good for short deployment times - furthermore you don't have to deploy the same stuff over and over again in your WARs.


Special Event: Java 8 with Java EE 7: "More Power with Less Code", 13th October, 2014

A book about rethinking Java EE Patterns

Comments:

Hi Adam,

{quote:}
"The beauty of Java EE is the lack of libraries and JARs which have to be deployed with your project."
{/quote:}

I think this is a theoretical statement and only true, if you stick to the standard stack.

But: Who realy want's to rebuild the features of for example JSF libraries? (RichFaces 3.3.2.SR1: ca 7 MB!, ICEfaces 1.8.2: ca 4 MB!, both without dependencies ..)

There are some more examples like this out there ...
What I am still missing is the rock solid standardized module support (JSR-294?)which is able to handle 3rd party addons in a more convenient way.
Or even a more standardized way of building JEE deployments.

I believe, that there will always be enough KiloBytes left to deploy to make development unhandy in real world projects ...

rgds
Markus

Posted by Markus on November 13, 2009 at 09:46 AM CET #

this goes straight against portability - no chance that every vendor will ship the same version of the supplied jars. I'd rather prefer shipping the exact dependencies with my app/product..

Posted by Kristof on November 13, 2009 at 10:32 AM CET #

hi adam,

{quote:}
"The beauty of Java EE is the lack of libraries and JARs which have to be deployed with your project."
{/quote:}

my experience from larger enterprise projects is exactly the opposite: its always bad to depend on the libraries that are shipped with the container itself.

just think of dependencies on special library versions in your app because of library-interopability, specific bugs,etc etc.

Posted by Hans Prueller on November 13, 2009 at 12:20 PM CET #

@Hans: I don't think Adam is saying one should depend on anything but standard APIs that will be part of any compliant container.

Posted by Alexis MP on November 13, 2009 at 01:17 PM CET #

I use maven for managing dependencies and hence my war and ear bloats up big time. Even though my applicaiton code runs into KBs, my deliverable viz ear, war runs into several MBs.

I am curious to know how one can solve such problem using Java EE 6 or otherwise.

Posted by Anand on November 13, 2009 at 09:07 PM CET #

@Anand,

in Java EE 6 additional libraries like REST are part of the spec, so you don't have deploy them with your app. JSF 2.0, EJB 3, Bean Validation are also a part of the server. Java EE 6 can of course do nothing against your 3rd-party dependencies. But you should minimize them anyway. E.g. whenever possible I prefer to use java.util.logging over Log4j etc. If you leverage the existing JDK and Java EE 6 libraries your deployment will be remarkable lean...

"I am curious to know how one can solve such problem using Java EE 6 or otherwise."

Change the scope from "runtime" to "provided" in your pom.xml :-),

thanks,

adam

Posted by Adam Bien on November 13, 2009 at 09:13 PM CET #

@Kristof,

"this goes straight against portability - no chance that every vendor will ship the same version of the supplied jars. I'd rather prefer shipping the exact dependencies with my app/product.."

Java EE 5/6 apps are surprisingly portable. But your are right - regardless whether your are packaging everything redundantly with your application, or not, you will have to test your application on another server.

But: you would really ship e.g. EclipseLink to Glassfish v3, although it already exists on the server? I never did that...

thanks for your thoughts!,

adam

Posted by Adam Bien on November 13, 2009 at 10:47 PM CET #

@Markus,

what I meant: you only have to deploy the delta from the Java EE 6 standard. 3rd party libraries can come with any size...

cheers!,

adam

Posted by Adam Bien on November 14, 2009 at 02:41 PM CET #

Hi Adam,

Having many small WARs might be nice for example projects in a development environment, I've never seen it work very well in a enterprise production environment. There are a few reasons for this:
1. The individual EARs always bloat up because people will include their own libraries (because of Maven as Anand point out) or even their own versions of the libraries (as Kristof point out).
2. Deploying in a single GlassFish might be quick, deploying to a cluster of WebSphere servers is not. Now your answer might be to not use WebSphere, but some people don't have that choice and WebSphere also offers a very good transactional model for its deployment (see http://blog.xebia.com/2009/11/13/do-application-server-vendors-really-understand-deployment/).
3. The governance over all these small artifacts is just too hard for most operations departments. Most people think in terms of "version 2.3 of the private banking application" instead of "version 1.4 of the mainframe connectivity, version 2.1 of the checking account logic, version 1.6 of the savings account logic and version 2.2 of the user interface". I've seen several attempts to modularize enterprise applications fail because of this simple fact.

One way to leverage your approach and still not get into this problem is to use separate WAR deployments in development and bundle them up into an EAR for deployment to production. This just an idea that hit me though, I've never seen it used.

Regards, Vincent.

Posted by Vincent Partington on November 20, 2009 at 10:45 AM CET #

Adam Bien wrote: "But: you would really ship e.g. EclipseLink to Glassfish v3, although it already exists on the server? I never did that..."

First of all - even if you ship EclipseLink to GF3, the one bundled with the server will be used due to classpath precedence; you can happily use other provider like Hibernate, but EL will stay frozen.

Second - the bundled EL is always behind, and for our project we even have our own fixes and maintain our own version (having donated the fixeds to EL of course - they are being incorporated, but it takes time we don't have). So, because of what I wrote before, we have to delete EL from GlassFish to really have our bundled version used. Please take a look at the bug report here: https://glassfish.dev.java.net/issues/show_bug.cgi?id=11667.

Posted by Wujek on June 22, 2010 at 02:25 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
realworldpatterns.com
...the last 150 posts
...the last 10 comments
Links
License