Tuesday, June 7, 2011

Mixing J2EE 6 and Scala, a first shot

I must confess I do admire a lot people recognized as craftsmen, all from different domains like Martin Fowler, James Coplien, Uncle Bob,Martijn Verburg, Martin Odersky, Jonas Boner. I like to follow Corey Haines adventures, listen to Venkat Subramaniam presentations... Apologies to the many others I forget.
In the desert land of french IT service it is hard to get satisfaction in our everyday projects, and we have very few opportunities to cross the path of such masters . Personally my only satisfactions come from my own learning from the masters... alas from book, videos, articles.Few chats with one of them in a twitter exchange is worth all the gold on earth.
Stop self-pitying, hopefully, all the time out of the daily job can be dedicated to exploration, discovery...and blog buddies =D

Recently we tried o to promote J2EE 6, hoping that the current client would accept to finally switch to a universally adopted standard, we once more had to start dealing with a mess, some big ball of muddy mixed services and strange God objects. Tough play. Fortunately J2EE 6 is lighter (pruning), easier to use (optional XML, more AOP), richer in terms of API, really more business oriented than the 5.0 level was, and it really gazes to a brighter cloudy future.
Naturally, I came to acquire a copy of a J2EE 6 book in order to upgrade my knowledge from the 5.0 version up to the 6.0 one, in a more friendly approach. I chose Antonio Goncalves' Beginning JavaEE6 with GlassFish 3, 2nd Edition. Don't be foolished by the title. Although every naive java developer can start with the content, every astute J2EE developer can find in almost every page valuable information. Reading this gold mine will help you in grabbing good habits and fully adopting the 6.0 standard peacefully. So, this is a good way to escape from the everyday routine.

As I promised myself to try to deliver something on a regular base(shame on me I am late, too few hours during the day), I did not want to re-do a carbon copy of Mr Goncalves book content. There are still so many presentations exposing J2EE6 and its benefits.
Like a lot of developers I have some difficulties in self organization so I planned to work on a kind of small personal planning board (very, very light kanban one). A J2EE application would be a good approach. In the mean time it came to me how difficult it was to study so many things in parallel (too many books). I have started practicing Scala, upgrading to J2EE6, recently started playing with Clojure, and still gazing to Lisp and Erlang

Why not gathering the J2EE6 adventure and the Scala one, for a while ? It may be ambitious. Maybe not. So before even trying to attempt a Reenskaugh/CoplienDCI approach, selecting my Use Cases, identifying the Roles, planning some form of architecture, I have to set up an environment, a working skeleton as defined by Nat Pryce and Steve Freeman in Growing object Oriented software guided by tests. This approach would allow me to define a broad picture of a working environment mixing Scala and J2EE 6.

How can I start ? The most important thing to do is to start. After all incredible people like David Pollackmust have been starting somewhere before becoming experts in application servers design like Lift.

I want to work in a J2EE6 environment using the Scala language. So let set a Maven 3.0 environment to work with my IntelliJ 10.5. I am going through this experience the hard way: I will set the dependencies as the sum of all the dependencies needed both in a J2EE project, and inScala project. For a very first baby step I will focus on creating an entity, paired with some managing EJB service. What I want is a working shell. An embedded environment for TDD. Second step (I hope in some upcoming article) will be to make the stuff deployable.

Let the entity be an elementary task, then I will create a task service.

The javax.persistence and javax.ejb dependencies reference the J2EE standards definitions. The eclipse link dependency is the JPA 2.0 implementation I chose, following Antonio's recommendations.

For test scope only I set a reference to the Glassfish embedded container. The embedded container appeared in J2EE 6 in order to simplify the development of unitary tests on EJB components but in a standard J2SE context providing the same managed environment - so facilities (transaction, CDI, AOP, security...) -as the one found into application servers.

The Scala library is the 2.8.1 as I have to work with the Scala Maven plugin. Discussing about plugins configuration I defined the following build configuration:

For clarity purpose, as a first shot, I chose to annotate my Scala fields. As Scala definitions are short, I found more elegant to leave the annotations on the same lines as the field declarations.
Naturally I flagged the definition template with the @Entity annotation. Then I cheated, anticipating a named query dedicated to the selection of all persisted tasks.
How fine and simple is this class template definition, all the beauty of Scala in the uniform access principle application: "It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to remove" (A. de Saint Exupery)

Hurrah, I've got an entity... written in Scala.

Now I want a service to manage this basic skeleton task. How will I query the service in an embedded mode ? I need this very nice stuff introduced in J2EE 6 and destined to ease the integration tests: an embedded EJB container !!! As a reference implementation, Glassfish does provide one (the purpose of the reference in the testing scope).
All I have to to then, is to :

The service is flagged as a stateless local bean, hosting an injected entity manager (Dependency injection is cool when sticking to a standard).
Because I don't know how to proceed for now, I decided not to wrapp the java List in a Scala one (maybe you can help me on that point)

On behalf of the service, the container will manage the transactions during the entity manager invocations.
In upcoming steps I will want to query my service remotely. In a standard Java approach, this would require the definition of an interface flagged with a @Remote annotation. But we know that a 100% abstract Scala trait compiles as an interface.

Although it is embedded, we are still working with a container, so the transaction type appears to be JTA. The logging level is fixed to FINE as I like to understand what happens.
Note that the database connection properties makes part of the j2ee 6 standard:

javax.persistence.jdbc.driver

javax.persistence.jdbc.url

javax.persistence.jdbc.user

javax.persistence.jdbc.password

I chose a drop-and-create-tables ddl-generation schema so to get rid of my database table after test.

Everything's ready. Engage. I open a command console and hit

mvn clean test

Test is automatically run. I have a test failure. Ah right. Some problem with the name service binding. Since J2EE 6, apparently, an agreement has been found onto a global uniform naming convention into the JNDI namespace:

For the moment I have to trust my environment when it tells me he ran the test, persisted and re-loaded my task. But a real complete environment requires to be able to produce a fully deployable application set >_<.
This will be the next step and I will then be able to run an external client and create records in more permanent database.

One moment, before going to bed, I want to check my remote interface (my Scala trait) is really compiled as an interface. After running:

3
comments:

I just had an interesting exchange on twitter with Heiko Seeberger from Typesafe who was kind enough to read the article.

He pointed out - quoting - that "using #Scala for #JEE 6 won't work for real world examples. At least not for CDI." than that "The #Scala compiler creates too many public fields / final public methods for proxy based solutions like CDI."

I really thank him very much about this fruitful exchange. This will encourage me to go deeper into the exploration of CDI into a more standard way. The richness of this exchange is very valuable and will guide me into my upcoming experimentation.