I never thought that I have to write about this topic again, but I have to since a couple months ago I have to justify a decision of using Spring Framework in an enterprise environment. The decision to be made was whether we are going for JEE or using Spring Framework. The constraint was very clear:
- We need to support both batch and web apps.
- For web apps we only can use an old OAS (Oracle Application Server) with JEE 1.4.
- Commercial support has to be available for the framework and the runtime environment.
- We are going to update the app server for JEE 6 or 7 soon, so it should be possible to have a smooth migration.
- We would like to minimize the use of our home grown frameworks.
Still there was such a quarrel in the team because there are already some JEE web apps run in OAS upgraded with JBoss Weld CDI 1.0. Normally JBoss Weld 1.0 won't run out of the box in OAS but with some patches we got it run. The problem with all those web apps is we had a lot of our own CDI extensions to fulfill enterprise features (declarative transaction management for services, caching, security) which already a part of Spring Framework a long time ago.
So it's time to google this topic "JEE vs. Spring Framework" to see whether the dispute between them still exists.
Spring Framework Bashing 2012 and 2013
- Web apps
- Batch apps
- Since JEE 7 and JTA 1.2 business logic component with transaction demarcation does not need to be an EJB component anymore. But what about asynchronous method execution? For this purpose you still need Message Driven Beans (MDB) in EJB container. So EJB is still alive. This is where Spring Framework has its advantage. Everything like business logic components with asynchronous method execution and utilities is always POJOs, no different at all and it is available today. The counterpart of MDB is MDP (Message Driven POJOs) in Spring Framework.
- Security mechanism like authentication and authorization in JEE 7 (JAAS) is still inflexible. If you use JAAS it is dependent on the chosen JEE container. In contrary Spring Security is flexible and you can use it in all runtime environments available. The good news is that Spring Security can be integrated easily in JEE 7 apps.
- Since Spring Batch 3.x supports JEE 7 batch standard and this framework is the longest batch framework available in the market you maybe will use Spring Batch as your JEE batch implementation. It is an additional complexity in case I would use Spring Batch 3.x and I need to reuse business logic components written in EJB. Do I have to run my Spring Batch app within an EJB or JEE container? Using pure Spring Batch makes everything simpler and easier.
- Open Source application server with commercial support and reasonable price can only be found from JBoss / Wildfly and TomEE. Also a JEE batch app needs a JEE container.
- Apps based on Spring Framework can run everywhere (pure Servlet or JEE containers like Jetty, Tomcat, VMware vFabric tc Server, now Pivotal tc Server, JBoss, Wildfly, TomEE) as long as your apps can access the implementations of services like JMS, transaction and cache. Spring Batch apps can run just within the plain Java SE.
The Problem with JEE and My Solution: "One Runtime Environment with Standardized APIs and Simple Implementation Dependencies"
- We only need one runtime enviroment standard. That is what we know today with Servlet container (Tomcat, Jetty and others). This is the one and only application server or operating system we need for our enterprise applications.
- We have all those standardization of APIs like JPA, JMS, CDI, Batch and others. The specification of those APIs should be completely loosely coupling. At the end as an end user you want to mix and match those APIs as you need them. The implementation of those APIs can be done like today through a normal framework implementation just like Hibernate (JPA), ActiveMQ (JMS), JBoss Weld (CDI), Spring Batch (Batch) and others.
Spring Framework supports the idea of one runtime environment and mix and match APIs since the beginning:
- You can use any runtime environments or containers which supports Servlet specification like Tomcat, Jetty or JBoss or others.
- You can mix and match all those standardized APIs like JPA, JMS, Batch (JSR-352), CDI (not complete but some of the specs like JSR-330 and JSR-250).
- To use the APIs you have to include the implementations of the API specifications by yourself using standardize dependency mechanism for Java.
- You get a lot of nice helpers to "glue" APIs together to build a nice programming model on the top.
- Web app: the runtime environment (Web Container) does not include all the APIs implementations. The web app needs to include the dependencies by themselves (WEB-INF/lib directory).
- Batch app: no special runtime environment, just standard JVM. The batch app needs to include the dependencies by themselves (-classpath in Java execution parameter).
- Drop the umbrella standard JEE.
- Concentrate on one and only one runtime environment specification, the Servlet specification.
- Concentrate on APIs standardization like JPA, JTA, JMS, CDI, Batch and others and make them loosely coupled. Let the version of the APIs to be used mixed and matched.
- Use the standard dependency mechanism of Java to include the implementations within the web and batch apps.
- Don't forget the Security APIs, just copy them from Spring Security analog to Batch APIs using Spring Batch.
At the end we chose Spring Framework. We will use all available standardized APIs with the best implementations we can get. To be able to mix and match the version of APIs in each web and batch app we will manage the dependencies within the apps itself using standardize Java mechanism.