Java EE 6 was released over
2 years ago and now there are 14
compliant application servers. In all my talks around the
world, a question that is frequently asked is
Why should I use Java EE 6 instead
of Spring ?
There are already several blogs covering that topic:
EE wins over Spring by Bill Burke
will I use Java EE instead of Spring in new Enterprise Java
projects in 2012 ? by Kai Waehner (more
discussion on TSS)
Spring to Java EE migration (Part 1
3 and 4 coming as well) by David Heffelfinger
to Java EE - A Migration Experience by Lincoln Baxter
Spring to Java EE 6 by Bert Ertman and Paul Bakker at
from Spring to Java EE 6 - The Age of Frameworks is Over
EE vs Spring Shootout by Rohit Kelapure and Reza Rehman at
EE 6 and the Ewoks by Murat Yener
excuse to avoid Spring forever - Bert Ertman and Arun
I will try to share my perspective in this blog.
First of all, I'd like to start with a note:
Thank you Spring framework for
filling the interim gap and providing functionality that is now
included in the mainstream Java EE 6 application servers. The Java
EE platform has evolved over the years learning from frameworks
like Spring and provides all the functionality to build an
enterprise application. Thank you very much Spring framework!
While Spring was revolutionary in its time and is still very popular
and quite main stream in the same way Struts was circa 2003, it
really is last generation's framework - some people are even calling
However my theory is "code is king". So my approach is to build/take
a simple Hello World CRUD application in Java EE 6 and Spring and
compare the deployable artifacts.
I started looking at the official tutorial Developing
a Spring Framework MVC Application Step-by-Step but it is
using the older version 2.5. I wasn't able to find any updated
version in the current 3.1 release. Next, I downloaded Spring Tool
Suite and thought that would provide some template samples to get
started. A least a quick search did not show any handy tutorials -
either video or text-based. So I searched and found a link to their
SVN repository at src.springframework.org/svn/spring-samples/.
I tried the "mvc-basic" sample and the generated WAR file was 4.43
While it was named a "basic" sample it seemed to come with 19
different libraries bundled but it was what I could find:
And it is not even using any database!
The app deployed fine on GlassFish 3.1.2 but the "@Controller
Example" link did not work as it was missing the context root.
With a bit of tweaking I could deploy the application and assume
that the account got created because no error was displayed in the
browser or server log.
Next I generated the WAR for "mvc-ajax" and the 5.1 MB WAR had 20
JARs (1 removed, 2 added):
2 more JARs for just doing Ajax.
Anyway, deploying this application gave the following error:
Caused by: java.lang.NoSuchMethodError: org.codehaus.jackson.map.SerializationConfig.<init>(Lorg/codehaus/jackson/map/ClassIntrospector;Lorg/codehaus/jackson/map/AnnotationIntrospector;Lorg/codehaus/jackson/map/introspect/VisibilityChecker;Lorg/codehaus/jackson/map/jsontype/SubtypeResolver;)V at org.springframework.samples.mvc.ajax.json.ConversionServiceAwareObjectMapper.<init>(ConversionServiceAwareObjectMapper.java:20) at org.springframework.samples.mvc.ajax.json.JacksonConversionServiceConfigurer.postProcessAfterInitialization(JacksonConversionServiceConfigurer.java:40) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
Seems like some incorrect repos in the "pom.xml".
Next one is "mvc-showcase" and the 6.49 MB WAR now has 28 JARs as
The app at least deployed and showed results this time. But still no
Next I tried building "jpetstore" and got the error:
[ERROR] Failed to execute goal on project org.springframework.samples.jpetstore:Could not resolve dependencies for project org.springframework.samples:org.springframework.samples.jpetstore:war:1.0.0-SNAPSHOT: Failed to collect dependencies for [commons-fileupload:commons-fileupload:jar:1.2.1 (compile), org.apache.struts:com.springsource.org.apache.struts:jar:1.2.9 (compile), javax.xml.rpc:com.springsource.javax.xml.rpc:jar:1.1.0 (compile), org.apache.commons:com.springsource.org.apache.commons.dbcp:jar:1.2.2.osgi (compile), commons-io:commons-io:jar:1.3.2 (compile), hsqldb:hsqldb:jar:126.96.36.199 (compile), org.apache.tiles:tiles-core:jar:2.2.0 (compile), org.apache.tiles:tiles-jsp:jar:2.2.0 (compile), org.tuckey:urlrewritefilter:jar:3.1.0 (compile), org.springframework:spring-webmvc:jar:3.0.0.BUILD-SNAPSHOT (compile), org.springframework:spring-orm:jar:3.0.0.BUILD-SNAPSHOT (compile), org.springframework:spring-context-support:jar:3.0.0.BUILD-SNAPSHOT (compile), org.springframework.webflow:spring-js:jar:2.0.7.RELEASE (compile), org.apache.ibatis:com.springsource.com.ibatis:jar:188.8.131.526 (runtime), com.caucho:com.springsource.com.caucho:jar:3.2.1 (compile), org.apache.axis:com.springsource.org.apache.axis:jar:1.4.0 (compile), javax.wsdl:com.springsource.javax.wsdl:jar:1.6.1 (compile), javax.servlet:jstl:jar:1.2 (runtime), org.aspectj:aspectjweaver:jar:1.6.5 (compile), javax.servlet:servlet-api:jar:2.5 (provided), javax.servlet.jsp:jsp-api:jar:2.1 (provided), junit:junit:jar:4.6 (test)]: Failed to read artifact descriptor for org.springframework:spring-webmvc:jar:3.0.0.BUILD-SNAPSHOT: Could not transfer artifact org.springframework:spring-webmvc:pom:3.0.0.BUILD-SNAPSHOT from/to JBoss repository (http://repository.jboss.com/maven2): Access denied to: http://repository.jboss.com/maven2/org/springframework/spring-webmvc/3.0.0.BUILD-SNAPSHOT/spring-webmvc-3.0.0.BUILD-SNAPSHOT.pom
It appears the sample is broken - maybe I was pulling from the wrong
repository - would be great if someone were to point me at a good
target to use here.
With a 50% hit on samples in this repository, I started searching
through numerous blogs, most of which have either outdated
information (using XML-heavy Spring 2.5), some piece of
configuration (which is a typical "feature" of Spring) is missing,
or too much complexity in the sample. I finally found this
blog that worked like a charm. This blog creates a trivial
Spring MVC 3 application using Hibernate and MySQL. This application
performs CRUD operations on a single table in a database using
typical Spring technologies. I downloaded the sample code from
the blog, deployed it on GlassFish 3.1.2 and could CRUD the "person"
entity. The source code for this application can be downloaded
here. More details on the application statistics below.
And then I built a similar CRUD application in Java EE 6 using
NetBeans wizards in a couple of
minutes. The source code for the application can be downloaded
here and the WAR
The Spring Source Tool Suite may also offer similar wizard-driven
capabilities but this blog focus primarily on comparing the
runtimes. The lack of STS tutorials was slightly disappointing as
well. NetBeans however has tons of text-based and video tutorials
and tons of material even by the community. One more bit
on the download size of tools bundle ...
NetBeans 7.1.1 "All" is 211 MB (which includes GlassFish and Tomcat)
Spring Tool Suite 2.9.0 is 347 MB (~ 65% bigger)
This blog is not about the tooling comparison so back to the Java EE
6 version of the application ....
In order to run the Java EE version on GlassFish, copy the MySQL
Connector/J to glassfish3/glassfish/domains/domain1/lib/ext
directory and create a JDBC connection pool and JDBC resource as:
./bin/asadmin create-jdbc-connection-pool --datasourceclassname \\
com.mysql.jdbc.jdbc2.optional.MysqlDataSource --restype \\
javax.sql.DataSource --property \\
./bin/asadmin create-jdbc-resource --connectionpoolid myConnectionPool jdbc/myDataSource
I generated WARs for the two projects and the table below highlights
some differences between them:
Java EE 6
WAR File Size
10.87 MB (~516x)
Number of files
53 (> 2.5x)
Total size of
LoC in XML files
50 (11 + 15 + 24)
129 (27 + 46 + 16 +
11 + 19) (~ 2.5x)
Some points worth highlighting from the table ...
516x WAR file, 10x deployment
time - With 12.1 MB of libraries (for a very basic
application) bundled in your application, the WAR file size and
the deployment time will naturally go higher. The WAR file for
Spring-based application is 516x bigger and the deployment time
is double during the first deployment and ~ 10x during
subsequent deployments. The Java EE 6 application is fully
portable and will run on any Java EE 6 compliant application
36 libraries in the WAR
- There are 14
EE 6 compliant application servers today. Each of those
servers provide all the functionality like transactions,
dependency injection, security, persistence, etc typically
required of an enterprise or web application. There is no need
to bundle 36 libraries worth 12.1 MB for a trivial CRUD
application. These 14 compliant application servers provide all
the functionality baked in.
Now you can also deploy these libraries in the container but
then you don't get the "portability" offered by Spring in that
case. Does your typical Spring deployment actually do that ?
3x LoC in XML - The
number of XML files is about 1.6x and the LoC is ~ 2.5x. So much
XML seems circa 2003 when the Java language had no annotations.
The XML files can be further reduced, e.g. faces-config.xml can
be replaced without providing i18n, but I just want to compare
Memory usage - Both
the applications were deployed on default GlassFish 3.1.2
installation and any additional memory consumed as part of
deployment/access was attributed to the application. This is by
no means scientific but at least provides an initial ballpark.
This area definitely needs more investigation.
Another table that compares typical Java EE 6 compliant
application servers and the custom-stack created for a Spring
Java EE 6
(tcServer 2.6.3 Developer Edition)
(Spring Security 3.1.0)
(Hibernate 4.1.0, required)
(Spring WS 2.0.4)
(RabbitMQ Server 2.7.1)
936 KB (Java client 936)
(Spring OSGi 1.2.1)
and WebLogic (starting at 33 MB)
There are differentiating factors on both the stacks. But most of
the functionality like security, persistence, and dependency
injection is baked in a Java EE 6 compliant application server but
needs to be individually managed and patched for a Spring
application. This very quickly leads to a "stack explosion". The
Java EE 6 servers are tested extensively on a variety of platforms
in different combinations whereas a Spring application developer is
responsible for testing with different JDKs, Operating Systems,
Versions, Patches, etc. Oracle
has both the leading OSS lightweight server with GlassFish and the
leading enterprise Java server with WebLogic Server, both Java EE 6
and both with lightweight deployment options.
The Web Container offered as part of a Java EE 6 application server
not only deploys your enterprise Java applications but also provide
operational management, diagnostics, and mission-critical
capabilities required by your applications.
The Java EE 6 platform also introduced the Web Profile which is a
subset of the specifications from the entire platform. It is
targeted at developers of modern web applications offering a
reasonably complete stack, composed of standard APIs, and is capable
out-of-the-box of addressing the needs of a large class of Web
applications. As your applications grow, the stack can grow to the
full Java EE 6 platform. The GlassFish Server Web Profile starting
at 33MB (smaller than just the non-standard tcServer) provides most
of the functionality typically required by a web application.
WebLogic provides battle-tested functionality for a high throughput,
low latency, and enterprise grade web application. No individual
managing or patching, all tested and commercially supported for you!
Note that VMWare does have a server, tcServer, but it is
non-standard and not even certified to the level of the standard Web
Profile most customers expect these days. Customers who choose this
risk proprietary lock-in since VMWare does not seem to want to
formally certify with either Java EE 6 Enterprise Platform or with
Java EE 6 Web Profile but of course it would be great if they were
to join the community and help their customers reduce the risk of
deploying on VMWare software.
Some more points to help you decide choose between Java EE 6 and
Freedom to choose container
- There are 14
EE 6 compliant application servers today, with a variety
of open source and commercial offerings. A Java EE 6 application
can be deployed on any of those containers. So if you deployed
your application on GlassFish today and would like to scale up
with your demands then you can deploy the same application to
WebLogic. And because of the portability of a Java EE 6
application, you can even take it a different vendor altogether.
Spring requires a runtime which could be any of these app
servers as well. But why use Spring when all the required
functionality is already baked into the application server
Spring also has a different definition of portability where they
claim to bundle all the libraries in the WAR file and move to
any application server. But we saw earlier how bloated that
archive could be.
The equivalent features in Spring runtime offerings (mainly
tcServer) are not all open source, not as mature, and often
require manual assembly.
Vendor choice - The
Java EE 6 platform is created using the Java Community Process
where all the big players like Oracle, IBM, RedHat, and Apache
are conritbuting to make the platform successful. Each
application server provides the basic Java EE 6 platform
compliance and has its own competitive offerings. This allows
you to choose an application server for deploying your Java EE 6
applications. If you are not happy with the support or feature
of one vendor then you can move your application to a different
vendor because of the portability promise offered by the
Spring is a set of products from a single company, one price
book, one support organization, one sustaining organization, one
sales organization, etc. If any of those cause a customer
headache, where do you go ? Java EE, backed by multiple vendors,
is a safer bet for those that are risk averse.
Production support -
With Spring, typically you need to get support from two vendors
- VMWare and the container provider. With Java EE 6, all of this
is typically provided by one vendor. For example, Oracle offers
commercial support from systems, operating systems, JDK,
application server, and applications on top of them. VMWare
certainly offers complete production support but do you really
want to put all your eggs in one basket ?
Do you really use tcServer ? ;-)
Maintainability - With
Spring, you are likely building your own distribution with
multiple JAR files, integrating, patching, versioning, etc of
all those components. Spring's claim is that multiple JAR files
allow you to go à la carte and pick the latest versions of
different components. But who is responsible for testing whether
all these versions work together ?
Yep, you got it, its YOU!
If something does not work, who patches and maintains the JARs ?
Of course, you!
Commercial support for such a configuration ? On your own!
The Java EE application servers manage all of this for you and
provide a well-tested and commercially supported bundle.
While it is always good to realize that there is something new and
improved that updates and replaces older frameworks like Spring, the
good news is not only does a Java EE 6 container offer what is
described here, most also will let you deploy and run your Spring
applications on them while you go through an upgrade to a more
modern architecture. End result, you get the best of both worlds -
keeping your legacy investment but moving to a more agile,
lightweight world of Java EE 6.
A message to the Spring lovers ...
The complexity in J2EE 1.2, 1.3, and 1.4 led to the genesis of
Spring but that was in 2004. This is 2012 and the name has changed
to "Java EE 6" :-) There are tons of improvements in the Java EE
platform to make it easy-to-use and powerful. Some examples:
Adding @Stateless on a POJO makes it an EJB
EJBs can be packaged in a WAR with no special packaging or
"web.xml" and "faces-config.xml" are optional in most of the
Typesafe dependency injection is now part of the Java EE
Add @Path on a POJO allows you to publish it as a RESTful
EJBs can be used as backing beans for Facelets-driven JSF
pages providing full MVC
Java EE 6 WARs are known to be kilobytes in size and deployed
Tons of other simplifications in the platform and application
So if you moved away from J2EE to Spring many years ago and have not
looked at Java EE 6 (which has been out since Dec 2009) then you
should definitely try it out. Just be at least aware of what other
alternatives are available instead of restricting yourself to one
stack. Here are some workshops and screencasts worth trying:
#37 shows how to build an end-to-end application using
#36 builds the same application using Eclipse
is a 3-4 hours self-paced hands-on workshop that guides you to
build a comprehensive Java EE 6 application using NetBeans
Each city generally has a "spring cleanup" program every year. It
allows you to clean up the mess from your house. For your software
projects, you don't need to wait for an annual event, just get
started and reduce the technical debt now! Move away from your
legacy Spring-based applications to a lighter and more modern
approach of building enterprise Java applications using Java EE 6.
Watch this beautiful presentation that explains how to migrate from
Spring -> Java EE 6:
List of files in the Java EE 6 project:
List of files in the Spring 3.x project:
So, are you excited about Java EE 6 ? Want to get started now ? Here
are some resources:
EE 6 SDK (including runtime, samples, tutorials etc)
Server Open Source Edition 3.1.2 (Community)
GlassFish Server 3.1.2 (Commercial)
EE 6 using WebLogic 12c and NetBeans (Video)
EE 6 with NetBeans and GlassFish (Video)
EE with Eclipse and GlassFish (Video)