Bert Ertman and Paul Bakker of Luminis have written a multi-part article that covers migrating Spring Applications to Java EE 6 technology. It also consists of sample code a working project. In the series Paul and Bert discuss the rationale for migrating your applications from Spring to Java EE 6 and show you real examples of upgrading the web UI, replacing the data access layer, migrating AOP to CDI interceptors, migrating JMX, how to deal with JDBC templates, and as an added bonus will demonstrate how to perform integration tests of you Java EE 6 application using Arquillian.
See the PDF here “Migrating Spring to Java EE 6 – Part 1″ or read online below.
PART 1 – Introduction
Over the past couple of years there has been a growing interest in all things Java EE. Generally speaking Java EE 5 to some extent, but Java EE 6 in particular marked the re-birth of Java EE’s credibility with developers. While Java EE is considered to be hot again, people wonder whether to jump on this train. Back in the days around 2003/2004, J2EE was at the height of its unpopularity. Developers hated its ivory tower specification process and its blindness to solving real-world problems. By that time a book came out that radically changed the way that enterprise Java development would be done for the next five years. This book of course was the “J2EE Design and Development” book, later followed by the “J2EE without EJB” book, both from Rod Johnson et all.
Developers loved these books and their way of presenting better solutions to the real-world problems they were facing at that time. In fact people still love those books without realizing that the world has changed dramatically ever since. The reality check here is to wonder whether the rhetorics set forth by Rod Johnson in his 2003/2004 books are still actual today. In our opinion all of the problems presented in the book can now be easily solved using standard, boiler-plate free, configuration-by-exception, easy to comprehend, lightweight POJO-based Java EE technologies. So if you still care about those books, the best way to show your appreciation is probably to use them as your monitor stand.
There are two ways to approaching the Spring vs. Java EE discussion nowadays. You are either in the situation that you have to build a green field enterprise application and you ponder what gear to stuff into your toolbox. Or you are facing a serious legacy enterprise application upgrade issue. Upgrading six or seven year old Java technology, being it Spring or J2EE inflicts a lot of pain anyway. The discussion whether or not to use Spring vs. Java EE for new enterprise Java applications is a no-brainer in our opinion. It took a while but Java EE has finally made the leap to be a standard, lightweight, fitting solutions to the vast majority of real-world development challenges in the mainstream enterprise applications space. You should have no single reason beyond choosing the standard. The question whether Spring or Java EE is the better solution is not the main focus of this series of articles. We want to present you an approach on how to tackle the problem of upgrading your legacy Spring applications from the past. It is important to understand that there are means to an end. In other words we don’t encourage you to take the migration all the way or else it wouldn’t be complete. Our intention is to present you with a migration path that you can head onto for just as many steps as you are willing to take. There can be all sorts of valid reasons not to take the migration all the way. These can be based on available time, money, and expertise. We are sure though that if you find yourself stuck with a legacy Spring application and wonder how to move forward from this point on towards a modernized enterprise application that is considered fit enough to last at least another five years, this series of articles will present you with hands-on, ready-to-use examples.
Before we start talking about what a migration path for legacy Spring applications would look like, it is valid to ask yourself the imminent question “why should I migrate my application in the first place?”. This is definitely a valid question and there are multiple answers to this one. First off, Spring was born out of frustration with mainstream technology, has been a hugely successful – do no evil – Open Source project, and has since then fallen a prey to the hungry minds of Venture Capitalists and finally into the hands of a virtualization company called VMware. Within the Java world VMware is probably best known for being able to run Windows on your Mac, and we’re not even sure if that is a good thing to be remembered of. Despite various efforts Spring nor any of its sub-projects has ever become a true Java standard. While the different companies and individuals behind the Spring framework have been doing some work in the JCP their voting behavior on important JSRs is peculiar to say the least. From how we see it, neither the Spring framework, nor the companies behind SpringSource have any benefit of truly standardizing it ever. This is of course a political motive and most developers don’t care about that at all, so let’s move on to more technical arguments of why a migration is a good solution for your problem. The technical reason is that upgrading your old-school Spring applications, even to modern Spring-based solutions, requires a lot of work anyway. Some technologies that might be used in the original application might even be considered end-of-life soon, or worse, are already part of a dark past.
When we mention “old-school Spring apps” we picture lots of complex XML configuration, an outdated ORM solution like JDBC templates, Kodo, or TopLink, and an old fashioned approach towards the web using a deprecated extension based Web MVC SimpleFormController. Just to give you an example.
Can you still find developers that master the techniques and frameworks used in the application? And if so, can you still find them say in another five years? From our own experience we have also seen applications that show ‘tells’ of each and every year that maintenance took place. We could tell from the use of different web an/or ORM frameworks and techniques that were all used within the same applications as a representative of the current most popular framework of that time. Ploughing through this framework erosion is tedious, boring, and above all complicated work leaving much room for mistakes causing even more damage to the application. And so this calls for an extreme makeover approach. Parts of the application have to be radically renewed, sometimes from the ground up. While you are confronted with that, why not take a little extra step and take it to the standard?
If you still have some concerns whether Java EE is suited for the job we encourage you to read on and get some misunderstandings out of the way first. We already discussed some of the J2EE problems of the past. However, some developers completely stopped looking at new developments in the Java EE space and might have lost track of the current state of technology. It is not the aim of this article to introduce you to Java EE 6, but as a quick refresher, let’s take a look at some key technologies of both Spring and Java EE 6 and see how they compare and moreover to see how Java EE caught up on Spring.
Some of the complaints of the past include the statement that Java EE has become fat and bloated. Some people even rebranded Java EE to Java Evil Edition. Is this still true today? You can of course take our word for it, but it is probably best to take a look at modern application server startup times. Firing up the latest JBoss AS 7 Application Server from scratch and deploying a full blown Java EE 6 application into the server takes somewhere between two and five seconds on a standard machine. This is in the same league as a Tomcat / Spring combo. There is a dramatic difference however if you consider the size of the deployment archive as well. A fairly standard Java EE 6 application will take up about 100 kilobytes while a comparable Spring application weighs in at a whopping 30 Megabytes! The Java EE 6 application is of course benefiting heavily from the fact that all Java EE 6 APIs are provided by the Application Server runtime. One of our favorite quotes is from JBoss’ own Andrew Lee Rubinger stating that “nowhere in the Java EE spec does it say that Java EE servers should be heavyweight and slow..”. Exactly true!
From a technical standpoint it is interesting to take a look at some of the technology capabilities that Java EE lacked in the past and that have put Spring in the driver’s seat. Let’s start with one of the most important reasons for developers to resort to Spring in the past: Inversion of Control (IoC) or whats more popularly known as Dependency Injection (DI). According to Wikipedia Inversion of Control is a style of software construction where reusable generic code controls the execution of problem-specific code. It carries the strong connotation that the reusable code and the problem-specific code are developed independently, which often results in a single integrated application. Inversion of Control is sometimes referred to as the “Hollywood Principle: Don’t call us, we’ll call you”, because implementations typically rely on callbacks.
Although IoC is commonly thought off to be invented by the Spring framework authors, it is in fact an old design paradigm which was mentioned in official publications in the late eighties of the previous century. What the Spring framework did however is putting the IoC pattern to use in Java to heavily reduce coupling in enterprise Java implementations leading to much better testable code. It took quite a while for Java EE to catch up but finally as part of Java EE 6, the Context and Dependency Injection (CDI) specification was introduced to the Java platform, which has a very powerful contextual DI model adding extensibility of injectable enterprise services along the way. If you don’t know about CDI yet, you are really missing out!
Aspect Oriented Programming
Another technique that was popularized by the Spring framework is Aspect Oriented Programming (AOP). In AOP the object oriented nature of the programming language is extended by a technique that weaves some cross-cutting concerns into the application at compile time or at runtime. Typical examples of cross-cutting concerns are logging and security, but it can be used for anything. A common pitfall when taking AOP too far is that your code might end up all asymmetric and unreadable. This is due to the fact that the aspect and its implementation are not in the same place. Determining what a piece of code will do at runtime at a glance will be really hard. This does not make AOP useless. If you use it responsibly and in the right amount it might prove to be a very powerful way to achieve separation of concerns and reusability. We often refer to that as “AOP Light” and this is exactly what Java EE Interceptors do for example. The implementation of interceptors on EJBs for example is somewhat limited making it harder to burn your fingers on too much AOP. In a way this is very much comparable to lightweight AOP in Spring AOP as well. The intercepter model was introduced in Java EE 5 and combining it with CDI (which was introduced in Java EE 6) creates a very powerful interceptor model that will give you a clean separation of concerns and greatly reduces the amount of code duplication in your application.
We already touched upon the subject of testing when we discussed IoC. Testing in J2EE was hard if not impossible. Mainly this was due to the fact that most J2EE components required lots of runtime services to be available in order to function properly. This is the death of a testable design. As Java EE returned to a POJO-based approach to enterprise components, testability increased a lot. Still also Java EE components require runtime services. In order to truly be able to test a Java EE component in its natural surrounding – the application server – we need a mocking framework. Or maybe not? Not that long ago a new revelation on the testing horizon has surfaced. Its name is Arquillian. With Arquillian we can get rid of mocking frameworks and test Java EE components in their natural environment. Before running a unit test Arquillian creates a so-called micro deployment containing the Java EE component under test and its direct dependencies and creates a small deployable archive, deploys it into a running container or temporarily starts one, runs the tests and undeploys the archive from the container. Arquillian does not force an alternative way of unit testing upon you, but integrates non-intrusively with your favorite testing framework, e.g. JUnit. Arquillian is the ultimate companion to Java EE when it comes to testing. There is some good documentation with lots of examples available for Arquillian but as part of this article series we will show you how to write some basic integration tests of your own.
Finally, we all have nightmares from firing up overweight tooling providing UML-savvy, crappy wizards that only worked once – when you were lucky – in order to do some decent productive development. Your computer felt like a car being trampled upon by a monster truck. Thankfully, this is now truly something from the past. All three major Java IDEs offer decent support for developing Java EE components without violating your computer’s resources. Developing Java EE applications is no longer tight to single vendor’s tooling solutions but you can use your IDE of choice, a little bit of Maven, and the application server of your liking. Setting up a Java EE project based on Maven from scratch is a breeze with tools like JBoss Forge which is pretty much compatible with all respected frameworks and application servers out there.
Comparing Spring and Java EE capabilities
For your convenience we listed a capabilities comparison matrix below to map Spring’s technology to that of Java EE.
|Dependency Injection||Spring Container||CDI|
|Transactions||AOP / annotations||EJB|
|Web framework||Spring Web MVC||JSF|
|AOP||AspectJ (limited to Spring beans)||Interceptors|
|Messaging||JMS||JMS / CDI|
|Data Access||JDBC templates / other ORM / JPA||JPA|
|RESTful Web Services||Spring Web MVC (3.0)||JAX-RS|
|Integration testing||Spring Test framework||Arquillian *|
* Not part of the Java EE specification
As a summary to what you have been reading so far it is safe to say that apparently it can all be done using plain vanilla lightweight Java EE. This leaves us with the migration issue at hand.
What would be the best way to move forward and start the migration? Some might be tempted to completely throw away the legacy application and start all over again. While this might appeal as an attractive solution and if time nor money constraints are an obstacle this might work. However for most realistic situations this is clearly not an option. What we do need is a gradual way of renovating the application without it collapsing on us on the way. Therefore we need a recipe that moves us forward step by step. The recipe should also allow for your own creativity and it should be possible to end the migration at any step that you would like. We came up with the following steps:
1. Upgrade Spring to the latest version
2. Replace old or out-dated frameworks (e.g. ORM, web frameworks) within Spring
3. Run Spring and Java EE container side-by-side
4. Replace Spring entirely
5. Remove Spring container
In the next part of the series we will elaborate on the migration approach and then take you through the different steps by showing you real-world examples of the migration in progress. There will be code examples and a link to a special GitHub project where you can take the project for a migration spin of your own, or subsequently apply all the change sets that we’ve prepared in order to demo your way through parts of the migration process.
- Bert Ertman & Paul Bakker
About the authors
Bert Ertman (@BertErtman) is a Fellow at Luminis in the Netherlands and a Sun/Oracle recognized Java Champion. Besides his day-job he is a JUG Leader for the Netherlands Java User Group (3500 members).
Paul Bakker (@pbakker) is a senior developer at Luminis Technologies in the Netherlands and a contributor on the JBoss Seam, Arquillian, and Forge projects.
Both authors have extensive experience in building enterprise applications using a variety of technologies ranging from the pre-J2EE, J2EE, Spring, and modern Java EE technologies. They have been discussing the use of new enterprise technologies regularly and had endless discussions on Spring vs. Java EE. Currently, they believe that both new, green field, enterprise applications, and large-scale maintenance migration on legacy apps can be done best using Java EE 6 technology. The authors have been evangelizing Java EE (6) technology at various conferences around the world, including J-Fall, Jfokus, Devoxx, and JavaOne. This series of articles is based upon their well-received JavaOne 2011 presentation titled “Best Practices for Migrating Spring to Java EE 6”.
Disclaimer: The views and opinions expressed in this article are those of the authors and do not necessarily reflect the official policy or position of Red Hat, Inc. Examples of analysis performed within this article are only examples. Assumptions made within the analysis are not reflective of the position of Red Hat, Inc.