Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

24 May 2012

OSGi, Java EE and CDI Integration Testing with Pax Exam 3

In-container testing is an approach shared by many testing frameworks like Pax Exam, jeeunit, Arquillian and Spring's test context.

Pax Exam 2.x is a mature solution for testing OSGi bundles and applications, jeeunit was created to simplify Java EE 6 integration testing and has been extended to handle stand-alone CDI applications and non-CDI setups based on Tomcat and Spring.

Taking the best of both worlds, the next major release line Pax Exam 3.x is designed to provide a unified testing experience by incorporating additional test containers for Java EE and CDI from jeeunit while staying backward compatible with Pax Exam 2.x for OSGi.

The first public milestone release Pax Exam 3.0.0.M1 is now available from The Central Repository (aka Maven Central), including test containers for GlassFish, OpenWebBeans and Weld.

While jeeunit works with Embedded GlassFish which lacks all OSGi capabilities of the GlassFish server, the Pax Exam GlassFish Container launches GlassFish 3.1.2 on top of an OSGi framework, enabling users to deploy or provision both WAR modules and OSGi bundles, thus providing a test environment for hybrid Java EE/OSGi applications.

A plain old JUnit test class can be turned into an in-container integration test simply by adding a @RunWith(PaxExam.class) annoation and some configuration data in a properties file.

See the Pax Exam 3.0.0.M1 Release Notes for more details and use the OPS4J mailing list ([email protected]) for feedback and support.

01 May 2012

Deconstructing Spring myths

Over the past five years, I have had the pleasure of working on different Java enterprise projects based on OSGi, Java EE and Spring. Among these three platforms, Spring is the one I'm least happy with.

Granted, Spring lets you build complex enterprise applications without too much pain, or else it wouldn't be so popular. In the times of J2EE 1.4, Spring must have felt like a breath of fresh air, and without the competition of Spring and Hibernate, J2EE might not have evolved into what Java EE 6 is today.

But somehow the glory of Spring's founding myth of killing the beast that was J2EE seems to be fading. The former beast is now as manageable and easy to use as Spring ever was, or even more so. Dependency Injection in Java is no longer synonymous with Spring (and in fact never was).

The Spring Framework needs a new raison d'être, and the current strategy seems to be diversification: Projects like Spring Data or Spring Social offer new features that have no equivalent in Java EE or OSGi. And of course, any Spring XYZ project requires the Spring Framework. But looking at the capabilities of the Spring Framework itself, where are the killer features?

Does Spring provide solutions that are smarter or easier to use than equivalent constructs in Java EE?

Here is a list of reasons why I feel more productive on Java EE 6 than on Spring 3.1.

There is no Spring without Java EE


Most debates about Java EE vs Spring sound like an either-or question, but this is a misconception. You can build an application on Java EE without ever using a Spring API, but you can't really build an enterprise application on Spring without using a number of Java EE APIs and implementations.

A typical Spring-based application includes

  • a web container, usually Tomcat, which means Servlet, JSP, EL, all of which is Java EE
  • a service layer, which has the highest chance of being Spring-only, with Spring transactions and Spring dependency injection
  • some web service endpoints, most likely JAX-RS or JAX-WS, which means Java EE again
  • a persistence layer, traditionally Hibernate Native API + Spring templates, but these days there's really no reason for preferring vendor-specific APIs over JPA 2.0
  • some messaging, e.g. with ActiveMQ, which means JMS and thus Java EE again.

Thus, Spring and Java EE applications mostly differ in the following areas only:
  • the web framework (Spring MVC vs. JSF vs. Wicket vs. Vaadin vs. Struts vs.....)
  • Spring Beans vs. EJB
  • Spring Dependency Injection vs. CDI or Java EE 5 @EJB or @Resource injection

In the age of AJAX and component-oriented web frameworks, Spring MVC feels rather old-school. JSF 2.1 has a lot more to offer, and if you prefer an independent web framework like Vaadin, the underlying container does not matter anyway.

Who's afraid of EJBs? All you need is a @Stateless annotation on your Java class, and you get a thread-safe service where all public methods are transactional by default, which is just what you need in most cases.

And finally, CDI is much more powerful that Spring Dependency Injection, due to its seamless scope handling, its event model and its portable extension mechanism.

API vs. Implementation


Spring has no clear separation of API and implementation, neither at specification level nor at code level. The Spring Reference Manual documents the one and only Spring Framework implementation. The Spring Javadocs document each and every class contained in the Spring Framework. It is not easy to distinguish API level classes from container internal classes.

By contrast, Java EE is first and foremost a set of specifications, represented by a collection of thin API JARs or an all-in-one javaee-api.jar. There are different independent implementations by different providers. Provider specific implementation classes are not normally visible to the user.

Vendor Lock-In


Competition is a good thing. When you are having an issue with your application running on a given Java EE server, try another server. This will give you some insight whether or not the issue is caused by your application or the server.

With Spring, there's only Spring. You can't swap framework components. You can't even cherry-pick framework components. There is insufficient separation of concerns. Inherently, there is no reason why a web framework or a NoSQL persistence provider should have to be tied to a given dependency injection container. But you can't use Spring MVC or Spring Data without Spring Core, just like you can't run Microsoft SQL Server without Microsoft Windows.

JAR Hell


Java EE means one-stop shopping for the core functionality of an enterprise software stack. javaee-api.jar provides the interfaces you need to start developing your own applications. All the required runtime environment is provided by the application server.

Yes, the application server runtime does contain a lot of stuff you'll never need. But modern servers like GlassFish 3.x or JBoss AS7 are modular and lazily activate only the stuff you do need, so there is no runtime overhead. And even a monolithic server like Resin 4.x has a surprisingly small footprint.

My current project is a Spring web application deployed on Tomcat. The final WAR has more than 100 JARs in WEB-INF/lib. More than 30 of these JARs are due to Spring itself, its dependencies or other Java EE components not provided by Tomcat.

In other words, by moving from Spring to Java EE, I could drop a third of the dependencies of my application. And I'm not talking about saving 30 megabytes of disk space, but about the effort of maintaining these dependencies and resolving version conflicts of transitive dependencies.

Configuration Hell


The flip side of JAR hell is configuration hell. With Spring, once you have gathered all required components, you also need to configure them. You may get away with an automatic component scan for your own application beans, but there is always a certain amount of manual plumbing for setting up framework beans, and standard features like transaction management or property substitution have to be enabled explicitly.

Most Spring-based projects started before 2010 still use XML configuration which for my taste is hard to read, extremely verbose and hard to refactor. Spring 3.0 first introduced Java configuration as an alternative but left it unfinished. Spring 3.1 finally supports type-safe Java-only configurations. Unfortunately, the reference manual and Spring extensions like Spring Security still promote XML configuration and leave it to the user to figure out the Java equivalents, which can be rather challenging, especially when custom Spring XML namespaces are involved.

With Java EE 6, little or no configuration is required. Transaction management works out of the box. Use an empty beans.xml marker file to enable CDI. Define the data sources and connections pools for your application in your application server's administration console. That's it.

Thread Safety


Spring leaves thread safety up to you. Controllers and services have singleton scope by default, so you can't use instance variables, or you need to protect them explicitly.

With Java EE, stateless EJB are pooled, concurrent requests each get served by a new beans from the pool, so your beans are thread-safe by default, unless you modify static members or global singletons.

Singleton Antipattern


The fact that Spring beans are singletons and not thread-safe by default tends to promote a rather ugly procedural programming style. Suppose you have a service with one public method performing some non-trivial business logic, factored out into a number of private methods.

In a stateless EJB, your private methods can share state in member variables within the same request (i.e. public method call), so in fact, the EJB is not quite as stateless as it may appear.

In a Spring bean, you often see private methods with long parameters lists, since you cannot share state in member variables, so you have to pass it around in method arguments.

Mixing Scopes


Due to these issues with singleton Spring beans, you may want to use the prototype scope, or the request scope in web applications.

Now when you inject a protoype or request scope bean into a singleton bean, Spring does not by default do the right thing to ensure that the injected bean is indeed a different instance per request. You need to resort to method injection or configure a scoped proxy explicitly.

CDI, on other hand, automatically proxies injected beans when needed.

Transactions


Spring itself does not provide global transactions across multiple resources. It can delegate to a JTA transaction manager but does not provide its own implementation.

Working with two or more persistence units in the same application, you need to configure a transaction manager per persistence unit and reference the correct instance in the @Transactional annotation of your service class or method.

In Java EE, transactions are managed by the container by default. EJBs are transactional by default. The container can handle multiple persistence units without further configuration. Global transactions spanning multiple datasources work out of the box if you configure XA datasources.

Load Time Weaving


Some persistence providers require load time weaving, also known as byte code enhancement. The JPA specification defines a hook for this purpose in PersistenceUnitInfo.addTransformer().

With OpenJPA and GlassFish, this works like a charm. Using OpenJPA with Spring and Tomcat, the required set-up is rather a nightmare, so I ended up using build-time enhancement, which is a lot easier to configure, but still requires additional manual configuration.


Summary


Spring has had its merits in giving relief to frustrated J2EE developers. But this is 2012 - compared to Spring, Java EE 6 now provides equivalent or better solutions for most standard tasks in enterprise application development.

Both Java EE and Spring are far from perfect. All in all, Java EE is more integrated and easier to use - not by orders of magnitude, but noticeably so.

And none of this is an eternal truth, tables may turn again within a few years.


25 January 2012

Integration Testing for JBoss AS7, Tomcat and Weld SE

Initially, the jeeunit Integration Testing framework was exclusively focused on Java EE 6, supporting GlassFish 3.x, which was the only Java EE 6 compliant server at that time. Support for Resin 4.x has been added in subsequent releases.

With the current release 0.9.1, jeeunit supports JBoss AS 7, as well as alternative containers and injection methods beyond the scope of Java EE 6. You can now run jeeunit tests on Tomcat 6 and 7 and Weld SE containers.

Tomcat can be combined either with Spring 3.1 or with CDI (Weld Servlet) to inject dependencies into jeeunit tests.

And there's more to come: While jeeunit will continue a life of its own for a while, I'm planning to merge it step by step into Pax Exam, the OSGi testing framework of the OPS4J community.

Pax Exam and jeeunit both implement an in-container testing approach - while Pax Exam focuses on OSGi alone, jeeunit now supports various other containers, but no OSGi at all.

The Pax Exam/jeeunit merger opens interesting perspectives for hybrid applications, i.e. enterprise applications composed of traditional WARs and OSGi bundles. GlassFish 3.x supports this hybrid application model, implementing a subset of the OSGi Enterprise specifications.

For Pax Exam, the road towards the next major release 3.0.0 will be marked by a sequence of milestone releases, each of which is to incoporate a new container adapted from jeeunit.

A Pax Exam GlassFish Test Container is the goal of the first proof-of-concept milestone 3.0.0.M1. This is work in progress on a dedicated branch exam3-milestones in the Pax Exam GitHub repository.

Stay tuned...

21 December 2011

Spring Integration Tests with Real Transactions

Spring's Test Context has a @Transactional annotation for wrapping tests in a transaction started and rolled back by the test container, to keep the tests from modifying the database. This is just what you need for deterministic, repeatable database tests.

On the other hand, due to this approach, the transaction boundaries in your test system differ from the ones in your production system, which can lead to errors in production which were never noticed in your tests suites.

I wouldn't go as far as saying that transactional tests should be considered harmful, but at least you should be aware of the side effects which may or may not be harmless in your specific use case.

For tests with real transactions, you need to take care of cleaning up the database yourself.

JUnit rules are a neat way of doing this. Here is an example:

07 June 2011

Java EE 6 Server Comparison: Introduction

A year and a half after the Java EE 6 specification release, there are now three Open Source servers certified for the Java EE 6 Web Profile:
  • Glassfish 3.x
  • JBoss 6.x
  • Resin 4.0.x
Time to take a look at these three servers in direct comparison and do some experiments, not with a toy or benchmark application developed for this purpose, but with a real-life enterprise application.

01 June 2011

Using CDI from Spring

Spring and Java EE are converging in many areas, mainly due to CDI. In fact, by confining yourself to a suitable subset of annotations and other configuration mechanisms, you can design your persistence and service layers to run either on Java EE 6 or on Spring 3, simply by selecting the appropriate set of libraries.

The web layer is a different story: if your web framework is tightly coupled to either Java EE 6 or Spring, it will be hard or even impossible to simply change the container, but even in the web layer, there are solutions like Apache Wicket which work well both with Spring and Java EE, all you need is some glue code to access the dependency injection container.

I'm currently migrating a web application from Tomcat/Spring to Glassfish, and since this application is based on Spring MVC, I cannot completely replace Spring in this step. The goal of the migration is to drop all Spring dependencies from all components except the web frontend and to somehow make the service beans (stateless session beans and CDI managed beans) visible to the Spring web application context.

13 March 2011

Transparent Asynchronous Remoting via JMS

The Scenario


A client needs to invoke a service interface with the following restrictions:
  • The service implementation is running on a remote machine.
  • This fact is transparent to the client, i.e. any service method invocation is just like a local method invocation.
  • The service methods are executed asychronously on the server, method invocations on the client return immediately (fire-and-forget).
  • All service methods have void return types.
  • The service invocations shall be transported via JMS.

20 February 2011

Building a Web Application with Wicket, Spring and JPA

This is a tutorial on setting up a web application stack with Wicket, Spring and JPA, with a special focus on avoiding Spring XML configuration in favour of Java configuration, and on using the JSR-330 @Inject annotation both in the web and service layers.

Martijn Dashorst's blog on Wicket/Spring/Hibernate configurationwas the starting point for my setup, and as I hate "oodles of XML"  as much as he does, I replaced all the XML bean declarations by a @Configuration class, a new feature in Spring 3.0.x.

22 January 2011

Transparent Asynchronous Remoting

The Scenario


A client needs to invoke a service interface with the following restrictions:
  • The service implementation is running on a remote machine.
  • This fact is transparent to the client, i.e. any service method invocation is just like a local method invocation.
  • The service methods are executed asychronously on the server, method invocations on the client return immediately (fire-and-forget).
  • All service methods have void return types.

The Solution with Java EE 6


With Java EE 6, the solution is quite simple, thanks to the @Asynchronous annotation introduced in EJB 3.1. You simply create a remote session bean and add this annotation to any business method or to the entire class. The container will then execute the given methods asynchronously.

Patrick Champion has a complete example in his blog, so there's no need for me to provide any sample code.

When your client is also a Java EE 6 application, you can simply @Inject the service interface and use a @Produces annotation on an @EJB reference somewhere else to direct the client to the appropriate implementation.

In addition, to avoid hardcoding the service URL in your client, you should define a local JNDI alias in your Java EE 6 container for the address of the remote service implementation, so you can move the remote implementation to another host without recompiling your client.

The Solution with Spring 3.0


Spring does not have an out-of-the box solution for this scenario. Spring Remoting provides transparent proxies for remote services, but these proxies are always synchronous. Since Spring 3.0, there annotation support for asynchronous execution, but this only applies to local beans.

However, it is not hard to combine these two features with some glue code to implement a solution for our scenario.

18 January 2011

reFit: Acceptance Testing for Java EE 6, Spring and OSGi

Even if you don't practice test-driven development, you are certainly familiar with the JUnit family of testing frameworks (including ports to other languages like cppunit, NUnit, or independent but similar approaches like TestNG).

This post is about the Fit framework family, which has a somewhat different focus and is not just another JUnit clone. In a nutshell, Fit represents expected and actual test results in tables, and you do not have to be a programmer to read or write them.

The following table has one column of inputs and two columns of outputs:

Image
Each row of this table can be regarded as an acceptance test case. You can feed this table to a given system and compare the outputs:

Image
It's only a couple of weeks ago I was introduced to Fit in my current project, and I must admit my first thought was "Why don't you just write a @Parameterized JUnit test?"

The answer is, JUnit is for developers, and developers only; Fit is for customers and developers.

You still need a developer to implement the skeleton logic of a test (called fixture in Fit), but anyone can write new test cases by adding rows or columns to a given Fit table.

The Fit method and the original Java implementation were created by Ward Cunningham in or around 2002, the project is hosted on Sourceforge and has been inactive since 2008.

The Fitnesse project integrates Fit with a Wiki, it includes a modified version of the original Fit implementation and is under active development. However, Fit and Fitnesse are incompatible, Fit lets you write your test tables in plain old HTML, whereas Fitnesse supports its own Wiki syntax only.

Our project has a fair amount of plain old HTML Fit tests, and our production code uses Spring, so it was a fairly natural idea to inject Spring beans from the system under test into our Fit test code.

Spring is just one (and not really my favourite) framework for dependency injection (and lots of others things). so I inevitably started thinking about how to use Fit together with Java EE or OSGi.

Thinking was followed by coding (yeah, it can be the other way round sometimes...), and this led to a project called reFit hosted on Google Code.

reFit is based on the latest Fit sources from SourceForge, it provides up-to-date Maven artifacts on Maven Central and integrations with Java EE 6, Spring and OSGi Declarative Services. The Java EE integration reuses parts of my jeeunit project.

In addition, reFit lets you run Fit tests under a JUnit wrapper or from a Maven plugin, both with or without Spring integration. reFit includes ready-to-run example code for Glassfish 3.1, Spring 3, Equinox and Weld SE.

There's more to come, I'm currently experimenting with a Web frontend and a WYSIWYG HTML editor.

For more details, check out the reFit Wiki.

10 December 2010

The Interface Antipattern

Keeping interfaces and implementations separate is a useful design pattern for building modular systems. If your clients only depend on a service interface, you can switch service implementations without your clients even noticing.

Now there can be too much of a good thing, and the quality of a software system is certainly not measured by the ratio of interfaces to classes.

When you are planning to implement a FrobnicatorService, think twice before creating an IFrobnicatorService interface and a FrobnicatorServiceImpl. How many different Frobnicator implementations are there going to be? If you do need at least two implementations with distinct behaviour, then go ahead and create the interface. If there's only one implementation, then don't bother with the interface.

Resist the temptation of speculative generalization: "Oh, there might be a performance bottleneck, and in that case an alternative CacheingFrobnicatorServiceImpl might help, so I really should start with a service interface now." Think twice: you ain't gonna need it.

And if you do need the interface, you can still pull it out when you need it. Most IDEs have an automatic refactoring Extract Interface. (Unfortunately, none of the major Java IDEs seems to have the opposite refactoring Merge Interface and Implementation.)

Even in Java EE, the times of interface inflation are gone with EJB 3.1, thanks to the no-interface local view. For a stateless session bean, it is enough to implement

@Stateless
public class FrobnicatorService {
    
    public void frobnicate() {
        ...
    }
}

Every public method of this class will be part of the implicit local business interface.

In OSGi, a service does not need to have a separate interface, you can register any class as a service. Even when using Declarative Services, don't get fooled by the XML syntax of the Service Component Descriptor:

<service>
  <provide interface="com.example.FrobnicatorService"/>
</service>


The provide element has an interface attribute, but the attribute value can be any old class.

The same is true in Spring: There is no rule forcing you to inject Spring beans only via their interface. Any old class will do, even when working with automatic transaction proxies (just make sure that CGLIB is on your classpath).

So remember the KISS principle and kill some of the interfaces you don't really need!

29 November 2010

Java EE and Spring: Why I couldn't care less

 Java EE or Spring - for an independent software architect, the question is just as relevant as Catholic or Protestant to an atheist. The question has recently been discussed in a number of articles mostly taking one side or the other:

In this post, I'll try to point out why I'm not fully happy with either of the two.

If there's one thing that matters to me, it's modularity. To put my cards on the table, I'm a strong OSGi supporter, but I'm not even religious about that - in fact, Living without OSGi (which is what I've been doing for nine months now) would be a nice headline for one of my next posts.

Seen from outside, Spring and Java EE share a number of shortcomings:

Preaching to the Converted

When did you last visit the official homepages of Java EE or Spring? Take a moment to click on the links and imagine you've never heard about either. After visiting the homepages, you are none the wiser, all you get is the usual marketing blurb and a couple of newsbites completely meaningless to the uninitiated.

Lack of focus

Java EE and Spring both are animals of the rare species Sus ovipara lactifera velluta unknown in English speaking countries which we call eierlegende Wollmilchsau in German. In plain English, they both try to be everything to everyone and end up doing nothing in particular.

In contrast, OSGi has a clear mission statement The Dynamic Module System for Java and provides a link to its key benefits right on its homepage.

Bloat

Ever heard about lean development? Let's have a look at the official Javadocs:
  • Java EE 6: 1597 classes
  • Spring 3.0.5: 2312 classes

Legacy

Backward compatibility is a good thing for veteran users of a framework. Users don't want to change all of their application code just for upgrading to a new framework version.

On the other hand, backward compatibility can be extremely confusing to new users: There's two or three solutions for the same kind of problem, the legacy one is not marked as legacy or deprecated clearly enough, tutorials and example code still use the old style, and you can only resort to your favourite search engine or to trial and error to make things work consistently.

Love Thy User

Don't just list what you can do for your users, ask them what they want you to do for them. Looking at the Java EE and Spring reference documentation, I can see that both frameworks solve lots of problems I've never had in my life.

On the other hand, looking for a solution for some specific standard kind of problem, it is often surprisingly hard to find a comprehensive code example.

User documentation should be structured by user stories, not by technology.

Enough Rope

Both Spring and Java EE give you enough rope to hang yourself. It's easy to write messy and ugly code on top of both frameworks, and I've seen enough of that.

You can write loosely coupled and elegant applications on top of either, but it takes a good architect to set up guidelines and restrict the number of choices.

Development Process Integration

As an application developer, you don't just write code to run on a given framework. You want to run integration tests on your applications, you want to deploy and debug them directly in your favourite IDE, and you want your batch build and continuous integration to be able to deploy your applications.

When choosing a framework, always consider the entire process chain - some lack of tooling for your favourite framework may be reason enough to pick the second best instead.

Modularity

My ideal framework/container/app server - pick any name you like - would allow me to write truly modular applications, enforcing modularity at design time, at compile time, and at run time. The framework itself would be modular, allowing me to pick out those and only those modules actually required by my application.

It would actively support OSGi as the most mature module system for Java, and maybe a few others on top.

I expect some further degree of convergence between Java EE, Spring and OSGi within the next two years or so. There has been a lot slideware and a number of proof-of-concept or early adopter projects, but my feeling is that none of this has reached production quality yet.

To sum up, frameworks in general are alive and kicking, but the age of monolithic all-in-one frameworks is definitely over.

28 November 2010

Java EE 6 Integration Testing with Spring

Half a year ago, I created and published the jeeunit project to fill in some gaps for running integration tests on Java EE 6 components in an embedded EJB container, mainly targeted at Embedded Glassfish 3.x. One of the alternatives I considered and dismissed before writing my own solution was the Spring Test Context.

At the time, I was left with the impression you had to pollute your Java EE components with Spring annotations like @Transactional to make declarative transactions work in the Spring container, and I did not (and still do not) like the idea of writing XML just to create a couple of Java beans and wire them up.

After taking a closer look at Spring 3.0.x these days, I realized a number of facts which are not quite obvious from the Spring reference manual:
  • You can do most of your Spring configuration (but sadly not all of it!) in Java instead of XML, which makes your application context type-safe and easier to read, and gives you refactoring support from your IDE.
  • Spring supports some (but not all) of the Java EE 6 annotations as alternatives to its own flavours.
  • You can run Stateless Session Beans and JPA entities in a Spring container with declarative transactions without introducing dependencies on Spring APIs or annotations.
jeeunit now includes an example project jeeunit-example-test-spring demonstrating this approach. The details are documented in the jeeunit Wiki page Testing on Spring.

This solution is not intended to replace the original in-container-testing approach of jeeunit, because transactional Spring beans and EJBs have different run-time semantics. However, for many integration tests, these differences are irrelevant.

Using the Spring Test Context instead of Embedded Glassfish and jeeunit has two main advantages:
  • Spring starts noticeably faster than Embedded Glassfish.
  • Launching a single test from your suite is much easier than with jeeunit. E.g. in Eclipse, you can simply use Run as JUnit Test just as with plain old unit tests.