Skip to content

Spring and Java EE

by Frans van Buul on April 18th, 2010

Let me start with a confession: I have never written an application using the Spring Framework (henceforth “Spring”). I’m used to writing ‘plain’ Java EE apps. Several colleagues have been telling me that Spring is really great, and that I should check it out. So I did.

After examining it for a while, I have come to believe that Spring is a high-quality product. Its creators have demonstrated thought leadership and have been an extremely positive influence in the development of enterprise Java. Also, I’ve noted that Spring developers tend to be very happy with the framework they’re using. This must mean that Spring is doing something right.

However, I’ve also encountered a lot of false arguments being put forward in favor of Spring. Some being made out of ignorance, some being simple propaganda. In this post, I will defend several theses to rebut these false arguments.

I believe it’s important that any technical decision is made with the best possible reasoning. This post is intended to be helpful in the decision making process on whether and how to use Spring. It is not, and should not be taken as, a rant against Spring.

Contents

As this post has grown a bit large, you may want to use this table of contents to navigate through it. The historical background section is primarily intended for those new to this debate; other readers may want to skip this.

Historical background

Spring relates to the Java EE specification (more on the nature of this relation later on). The Java EE specification is a collection of technologies, such as Servlet, JTA, JMS, and, importantly, EJB. “Java EE” is its current name, the latest and greatest version is 6. The previous version was Java EE 5. Java EE 6 is still very new (only the reference implementation is available), and Java EE 5 is currently the widely used version. Before Java EE 5, another name and version scheme was used: Java EE 5’s predecessors are called J2EE 1.4, J2EE 1.3, etc. I will use the name “Java EE” when I’m not referring to a specific version.

Problems surrounding the EJB part of Java EE are Spring’s raison d’être. Therefore, it’s useful to zoom in on this part of the Java EE specification.

The basic idea of EJB is that the programmer defines classes who’s instances are not managed directly by the program, but by an application container. This applies to business logic (session beans) and data (entity beans). In this way, the container can manage instance pooling, transactions, thread safety, remote access, persistence etc, thus relieving the programmer of writing such code.

While this idea is fine, it was very poorly executed in EJB 1.x and 2.x. The specification was far too complex, in particular because a single EJB 1.x/2.x bean requires several Java classes. It is now widely agreed upon that the POJO programming model should be preferred instead. Also, EJB 1.x/2.x required a lot of lookup code to wire beans together, since it did not feature Dependency Injection (DI). The required boilerplate code was a bad thing in itself, but the lack of DI also had a negative impact on testability of EJB code, which was becoming more important due to the advent of Agile methodologies.

Spring started as a framework for creating Java EE applications without using the problematic EJB specification, following Rod Johnson’s 2002 book. Spring addresses many of the problems of EJB 1.x/2.x. It features a POJO programming model, DI, and Aspect-oriented Programming (AOP). This is enabled by an Inversion of Control (IoC) container. Because it does not use EJB, it does not require a full Java EE application server. Spring web applications can be developed on a (much simpler) Servlet container, for which Apache Tomcat is both widely-used and the reference implementation.

In addition to these core functionalities, Spring has many modules for other tasks, e.g. data access and transaction management. Among other things, Spring offers APIs that unify and improve several possible implementation technologies. The DAO support is an example of this. In this manner, Spring also supports using technologies that are part of Java EE.

In 2006, the Java EE 5 specification, including EJB 3.0, was released. At the time of writing, this version is widely in use and there are some 13 implementations available, under a variety of licenses. EJB 3.0 has addressed many of the shortcomings of EJB 2.x, taking a lot of inspiration from Rod Johnson’s work. It supports a POJO programming model, DI and, to some extent, AOP. Of course, EJB 3.0 is not identical to Spring. There are many comparisons available, personally I think this paper by Rod Coffin provides a nice overview.

Back to table of contents

1. Spring and Java EE are competitors

These is a lot of debate on the question of whether Spring and Java EE are even competitors. Spring is positioned both as an alternative to Java EE (in particular for the EJB part), and as an add-on. I believe Java EE and Spring are clearly competitors.

Technically, Spring may run atop a Java EE application server, and it offers abstractions of services that are offered by a Java EE application server. This is the basis for the claim that Spring is a complement to Java EE, rather than a competitor.

However, the fact that Spring can technically run on top of a Java EE container, does not mean that it isn’t, at the same time, a competitor. The point to understand here is that EJB is not simply one of the dozens of technologies available within Java EE, that can be replaced by something else. EJB is at the very core of the programming model. It is the IoC container of Java EE. If you take this away, you take away the control of the application server over the application, and the Java EE programming model is essentially gone.

The title of Rod Johnson’s 2004 book J2EE Development without EJB doesn’t really make sense anymore in the 2010 world. Spring doesn’t work on top of Java EE: it offers an alternative programming model, while re-using some of the technologies that are also used in Java EE. The Spring white paper cites the book title as saying “that Java EE itself is still a valid model”. I think that’s meaningless.

The Spring white paper makes the point that there is no “Enterprise Service Abstraction” in EJB3. I think this again shows that Spring and Java EE are competitors. From a Spring perspective, the technologies that it re-uses from Java EE, are somewhat arbitrary choices that happen to be available in Java EE environments. In a non-Java EE environment, other alternatives may be used. This makes an abstraction layer desirable. From a Java EE perspective, the Java EE API’s itself are the abstraction layer. For example, JPA is an abstraction layer through which Hibernate, Toplink, EclipseLink, OpenJPA etc. may be accessed. From this pure-Java EE perspective, Spring implements the “Yet Another Useless Layer” anti-pattern.

As said before, Spring and Java EE can technically be combined. But I think it’s undesirable from an architectural perspective. If you write an application that fully uses Spring, but runs on top of a Java EE application server, you are wasting a lot of the functionality of the application server. (A point made by Adam Bien.) If you write an application that uses both Spring and Java EE API’s, you will get a very complicated and hard to maintain application architecture. It will take a lot of coordination between programmers to avoid that one and the same thing is done “the Spring way” in one part of the application and “the Java EE way” in another part.

The illustrations below may help make this point clear. I think that pure-Java EE and pure-Spring are valid programming models. The combination is a waste of money, at best. This makes Java EE and Spring competitors.

Back to table of contents

2. Spring is not, in any way, a standard

If some technology is a standard, this by itself is a powerful argument for using it. Using a standard is typically associated with positive qualities such as avoiding vendor lock-in, having sufficient availability of expert staff, being future proof, ensuring interoperability, lowering costs, etc. If you’re an architect or manager being held accountable for technology choices, you will have a much easier time defending you’re going to follow a standard, than defending you’re going to use something else.

A technology standard typically is a specification agreed upon by important stakeholders, that can be implemented by multiple vendors. Java EE is a standard in this sense. Spring is not a standard in this sense (nor does anyone claim that it is). Spring is a product. There is no specification seperate from the implementation. There is no alternative product with the same interface. If you have written an application using the Spring interfaces, you are bound to using the Spring product.

A technology can also be a standard in a different sense. It can be a “de-facto standard” simply because everyone is using it. Spring proponents frequently claim that Spring is a standard in this de-facto sense. This is simply not true. According to the VMware press release on the acquisition of SpringSource, Spring is “supporting half of all enterprise Java projects”. This indicates that Spring is popular and widely-used. It also indicates that half of all enterprise Java projects don’t use Spring. Therefore, the label “de-facto standard” is not jusitified: it would require a much higher market share than Spring actually has.

To summarize: Spring is not a standard, in any sense of the word. This is in itself not an argument against using Spring. But I think it’s unfair to try to convince people to use Spring by making the false claim that it is a standard.

Back to table of contents

3. Application server functionality is useful for writing a server application

One of the arguments brought forward for Spring is the fact that is doesn’t require a “heavyweight”, “bloated”, or “monolithic” application server. (For instance, this point is made many times in Beginning Spring Framework 2.)

I think that Java EE application servers are very useful. I believe that one of the most common problems in Java EE applications is that they are not using the application server functionality to the extent that they ought to. For instance, I often see application configuration being placed in regular .properties files (unknown to the application server) rather than in deployment descriptors (enabling the application server to use deployment plans, viewing property values through a web interface, doing injection of the values etc.).

The point of both Spring and Java EE is that the programmer leaves a lot of stuff to the container rather than doing it for himself. Then, it must be possible to manage this container at run time (configuring data sources, examining application performance, etc). Such a manageable container is called an application server.

Spring has done, for some time, without an application server. This is no longer the case. SpringSource provides its own application server called SpringSource tc Server. This server now has a new “Spring Edition”, that enables “fine grain monitoring of deployed applications and unparalleled visibility into the execution of Spring-powered applications”. This is what Java EE application servers have been offering for a long time. At the same time, traditional Java EE application servers are moving to support Spring (see the Spring white paper).

The point here is that application servers are useful when writing server applications. You will likely need one if you write mission-critical enterprise Java applications. If you’re using Spring, you’ll probably want a Spring application server. If you’re using Java EE, you need a Java EE application server.

Back to table of contents

4. Spring is commercial software

This point is trivial, but important enough to make: Spring is developed by the company SpringSource (previously called Interface21), now owned by VMWare.

Many seem to think of Spring as a kind of open-source, community-based alternative to “big money” vendors like Oracle and IBM. Again, Beginning Spring Framework 2 makes this point extensively, but the feeling seems widely spread within the Spring/Java community. Spring seems to be regarded as the technical, developer’s choice, whereas Java EE is the choice of “managers” with “interests”.

The fact is that SpringSource is part of the “big money” scene. VMWare bought SpringSource for USD 362 million in cash and approximately USD 58 million in stock and options. SpringSource is not a charity. The Spring Framework itself is open source and free to use, but VMWare/SpringSource have a clear view on how to make a good business model out of it, and how Spring will support VMWare’s overall strategy. This, of course, is perfectly legitimate. But there is no fundamental difference in this regard between VMWare/SpringSource, RedHat/JBoss, Oracle (having acquired BEA), or IBM.

The facts are simple: Java EE is an open standard for which implementations are available under a variety of licenses. Spring Framework is a commercial open-source product. It is irrational to let “anti-big-money” emotions play a role in a decision to use Spring.

Back to table of contents

5. Unit testing in Spring and Java EE are similar

An argument frequently made in favor of Spring, is that Spring would enable unit testing which is nearly impossible in Java EE. This is simply not true: unit testing in Spring and Java EE are very similar.

Both Spring and Java EE define containers that manage the life cycle of objects defined by Java classes, and perform functions such as dependency injection. The Spring or Java EE container knows what to do because it is instructed by either XML-configuration or Java-annotations. This architecture influences unit testing.

The simplest kind of unit tests can do without the container. Any required dependency injection would then be performed explicitly in the unit test code, typically using mock objects. This kind of test would be appropriate if there really is a complex algorithm to be tested within a class. However, in many business applications, algorithms themselves are pretty simple. Nearly every meaningful unit test is also some kind of integration test, requiring several classes to work together, often involving calls to a database. Such a test requires the container to be actively managing the life cycle of the objects.

The key factor required for unit testing, is that it should be possible to run this container embedded within the unit test code. This has always been possible with Spring, and has, for a long time, been impossible with Java EE. However, this has changed: with products like OpenEJB and JBoss MicroContainer, embedded Java EE containers for use within unit tests have become available.

Currently, Java EE and Spring unit testing capabilities are similar.

Back to table of contents

6. Spring and Java EE complexity are similar

Spring is frequently advertised as a “less complex” alternative to Java EE. The historical roots of this idea are clear: EJB 1.x/2.x were obviously very complex, and Spring provided a simpler alternative.

It is hard to assess whether or not this is still the case. The EJB 1.x/2.x complexity was obvious to anyone, but in general, complexity is a pretty subjective term. We all tend to find stuff that we are familiar with to be less complex than stuff that is new to us. One thing you could do to compare Spring and Java EE complexity, is comparing the number of classes (including classes, interfaces and annotations) in their published Javadoc. Doing this gives the following results:

Java EE 5 1046
Java EE 6 1666
Spring 2.5 1942
Spring 3.0 2286

Obviously, counting the number of classes is a very crude measure of complexity. Still, it has some value, because apparently, the creators of Java EE / Spring thought that these classes were relevant to the application programmer and therefore should be made public and documented.

I believe that the importance of these figures lies not in their difference, but in their similarity. They are all in the same ballpark and they are growing. This indicates that Java EE and Spring complexity are similar. Within the requirements and constraints that apply to both Java EE and Spring, this seems to be the kind of complexity that results.

Back to table of contents

Conclusion

Both Spring and Java EE are viable frameworks for writing enterprise Java applications. Historically speaking, there was a very clear case for using Spring instead of EJB, and Spring could be seen as a complement to Java EE. Currently, Java EE and Spring are competitors. Combining them has strong disadvantages.

Many of the arguments that have traditionally been brought forward in favor of Spring are invalid or outdated, because they target disadvantages of J2EE 1.4 and prior versions, rather than Java EE 5/6. Of course, Spring users may find that they don’t like the way the POJO model, DI or AOP are supported in Java EE 5/6. But the original argument that this is not supported by Java EE is simply gone, and the remaining argument, if present, is much weaker.

I don’t think there is a good, general argument that could be made for saying that either Java EE or Spring is better. The choice should be made by taking into account the particular requirements and technology strategy of the organizations building and using the application.

Back to table of contents

From → Opinion

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS