But before that, let’s step back and look and why frameworks like Spring was invented in the first place. In my view, primarily it was created as an alternative to J2EE stack, to keep it simplified, POJO centric and testable without the need for a container. Then came in support for various abstractions layers – JDBC, Transactions, ORM, JMS which can be applied POJO in a consistent manner and support for plugging in any web framework , all backed by principle of dependency injection. What it offered was a choice to programmers (and that’s very important) and didn’t restrict it usage to any specific API directly. Using Spring, one could create modular components which could be run against a J2SE environment(derby and local transaction manager for your local test environment) and then promoted to use capabilities offered by J2EE Applications servers like JNDI, JTA and so on.
Over the years, J2EE tried to catch on, tried to create specifications and standardizations which were well adopted and tested by the framework like Spring or ORM providers like Hibernate. Specifications are good, but lot of time goes in creating specifications and it takes even lot more to get these specifications incorporated into the release of J2EE servers and stacks. Though specifications were created, you would still see vendor specific extensions required to run a particular feature. I mean, can you still take an Enterprise application (running on latest J2EE spec), which has couple of EJBs (3.0 or 3.x), uses transaction and JMS services and run it on a server which supports the same J2EE specs. Probably No, Yes, May be with the latest specification, may be with vendor specific extensions (?). Let’s look at the latest release features to find more of this information.
The latest release of J2EE has support for Dependency injection (JSR-299 contexts and Dependency Injection for the Java EE platform specification), which is same as offered by Spring, Bean Validation (standard Bean validation offered by Apache projects, but now using standard annotations), streamlined development (through the use of POJO, JPA for persistence and revised EJB approach) and extensibility to add in vendor specific extensions in a consistent way. If you look at these goals, these matches with principles which I had listed earlier on why Spring was invented, only thing it took J2EE probably too long (probably 6-7 years assuming Spring starting gaining widely adopted in 2003) to arrive at this specification. Even though J2EE has the principles now, it still restricts its usage to that of a container, for instance I can run spring in a standalone environment (J2SE environment with local database and transaction support) as well as promote it to full fledged J2EE application, running on multiple application servers.Also there are no approaches provided on how to test individual components (in and outside the container) using a pure J2EE stack. I seriously feel, there should be specification around testing of components.
To conclude with some thoughts -
- I can achieve everything in Java EE 6 using Spring , but not the other way round.
- I can get Java EE 6 (or 7.x or 8.x ) features in a container that’s doesn’t uses Java EE 6 (or 7.x or 8.x ..) using Spring.
- I don’t think having a vendor specific extension in Java EE 6 can categorize to all vendor requirements, given that getting anything as part of standard usually takes a very long time. The choice needs to be provided, whether I use pure Hibernate APIs or JPA using a standard way.
- J2EE 5.x and now 6.x Spec is good start, but will take a while for J2EE 6.X (and future versions) to be adopted and catch up with Spring.
- J2EE future versions should be streamlined further to Java (POJO) with enterprise services, along with a test driven methodology.
- Finally it’s up to your requirements and what applications you are building.