Over the last few months I’ve been reading several books about Groovy, Spring, Maven, Hibernate and more. I’ve stated before on this blog that I’m moving towards implementing my application’s model in Groovy and using ColdFusion for the presentation tier for HTML applications or Spring’s BlazeDS integration for Flex applications. And now, with those few months of experience under my belt I can authoritatively say that Enterprise Java is a royal pain.
You see, I actually understand Java just fine. I can read the language and, to me, it’s fairly clear. But, as with my German, I’m much better at reading it than speaking it. The reason isn’t that I can’t write the syntax, but that the supporting technologies are so amorphous and decentralized that they can simply be very difficult to learn. Beyond that, they’re often created with extreme flexibility in mind and that means more complexity.
As an example, I’ve recently been working to create a Java (Groovy, really) based web service. This is a whole world of difference from how you’d do it in ColdFusion. I had already decided to use Spring to configure my application’s model and what I wanted to do was expose a service remotely using a specific WSDL. Spring doesn’t include a way to remotely expose services as a SOAP web service (though a dozen other RMI techniques are supported). While researching this I came across a project called Xfire which provides that functionality for Spring. Now, Xfire has a metric ton of dependencies (seriously, check it out here). And, in the interest of flexibility, Xfire allows you to choose from one of many Stax implementations, whatever that is.
So, just to be clear, there are many ways you can remotely expose services using Spring. And, within a particular option there are many choices for Stax implementations. Oh, and I forgot that there are at least two ways to configure Xfire. Oh, and if you don’t want to use Xfire you could use something like Apache Axis. To ask a rhetorical question, how does a newbie have any hope of making a good choice? It seems that only answer is through trial and error.
The cool thing about this is that after a few days of work I was able to expose a Spring configured service via Xfire and it worked great. That is until I did something it didn’t like and I started getting Null Pointer Errors. So, I decided to throw out Xfire and try Axis. The thing is, I’d lost track of the dependencies in my application. I already had maybe 30 jars that my application depending on just for this one service (not counting the Jboss server and everything it requires). I didn’t know what to throw out any more!
That prompted me to do some research on Maven, which is in some respects is an alternative to Ant. I’m not going to get into a description of how Maven differs from Ant, but I will say that it’s a build tool that automatically manages your dependencies for you. The idea being that rather than downloading bazillion jars manually, you simply write some XML that says your application depends on Spring and Xfire and Maven will then download everything for you, along with each dependency’s dependencies.
So, I spent several days reading up on Maven. The thing about Maven is that it wants you to organize your project in a specific manner. For example, there are certain folders by convention that you write your source code in and it builds to specific target directories, again, by convention. This makes using Eclipse a bit more challenging because Eclipse wants you to sort your directories the way it expects. And, when you start adding in features like the Groovy Feature plugin things start really getting cumbersome.
When using Maven with Eclipse you’ll need to use the m2Eclipse plugin (which depends on two other plugins!). Within Eclipse then you’ll need to use m2Eclipse to create a new project. As a part of that process you specify that you want to create a Groovy project. This works like a charm and you can then use the IDE to create new Groovy classes and tests. But, if you want to use any of the built in features of the IDE to run unit tests then you also have to configure the Groovy feature and get that working. I spent, again, a couple days getting this worked out. As it was, I had Maven configured to build a Groovy project, and when I’d write unit tests Maven would run them just fine. However, if, within the IDE, I were to try to run a test via the Groovy plugin I’d get an error about how it couldn’t find my class.
Through trial and error I have learned that you can run Eclipse from a console. If you do this then the console will output all sorts of logging information. When I was having this last problem I started Eclipse from the command line and looked to see what it was outputting when I tried to run my unit test. It took some reading, but eventually I realized that the IDE was trying to use groovy 1.5.7 while Maven was using Groovy 1.6. As a result, when my code was compiled it depended on Groovy 1.6 and the Unit test was expecting 1.5.7 and wouldn’t run 1.6 code. It makes lots of sense, but figuring this out was a royal pain!
Once I knew that, I was able to upgrade my Eclipse plugin to be the same version as Maven was using and suddenly my project would not only build, but I could manually run unit tests.
I’m not sure if I have a moral in this blog entry or if I’m just ranting. However, I can say that when things start working and can I get that flexibility working in my favor I love it. But, when things are not working and the error messages are less than helpful it can be extremely frustrating. So, be thankful for ColdFusion. But also, don’t give up on these other technologies. They do actually work, but they’re hard to learn all at once.