Saturday, April 3, 2010

Java EE 6 with Fine Beers - Beer 2

This is the 2nd of several articles reporting my experiences while migrating an enterprise  application to Glassfish V3.

This post will cover the issues around migrating JSF 1.2 + RichFaces 3.x applications to Glassfish V3.

Not so hard to face it

We where happy with our JSF / RichFaces applications running in V2. Richfaces delivers high quality RIA components at a very affordable learning curve, for developers familiar to JSF.

When using Galssfish V2/Java EE 5/JSF/Facelets stack we need to include the Facelets JAR into our web application, and to activate it in faces-config.xml, more specifically with a view handler configuration.  Before migrating the application I studied JSF topics in Java EE 6 Tutorial, and found this important statement:

"As of JavaServer Faces 2.0, Facelets is a part of JavaServer Faces specification and also the preferred presentation technology"

It means that we do not need to include Facelts JAR, nor configure its view handler in faces-config.xml. So I did in the immigrant JSF application, and deployed it to V3. The error I received when I requested the JSF applications by the web browser was:
javax.servlet.ServletException: PWC1232: Exceeded maximum depth for nested request dispatches: 20

It forced me to do some research, and soon I realized that RichFaces 3.x is not compatible to JSF 2.0. We could not wait for RichFaces 4 release - that will be JSF 2 compatible - as we are very dependent on RichFaces components. Pressure meter rising...

With a further research I found some folks facing the same issue here
and a wiki explanation here

Both explain how to do a class loader trick, via sun-web.xml, to force Glassfish V3 to use Mojarra 1.2 (JSF 1.2 reference implementation) and to keep the environment RichFaces-friendly.

It sounds nice and safe, as long as your WAR module is going to be deployed as an independent application. I discovery that this work around limits Java EE dependency injection when I read:

In my case, the WAR module is deployed inside an EAR, and receive EJBs and Resource injections from sibling modules. So I managed to find more options.

Fortunatelly I received good news via twitter: RichFaces 3.3.3 beta had just been released, and there was a work around to JSF 2:

The article teaches how to turn off the view handler with a context-param in web.xml:
param-value: true

It didn't work right away, but at some point in the article's thread we have "Facelets 1.1.15 should still be used because of dependencies in RichFaces from the Tag Handlers classes."
Facelets 1.1.15, huh ? Researching a little further it came to me:

This last post elucidates the need to include jsf-facelets-1.1.15.B1.jar into WEB-INF/lib in addition to disable the Facelets View Handler. Notice, however that I didn't include jsf-api.2.x nor jsf-imp.2.x (as the proposed solution does) because it is already present in Glassfish V3.

And that's what I had to do in order to enjoy RichFaces powerful Ajax components with JSF 2.0 and Glassfish V3. We need to celebrate it with a Brazilian bier, don't we ?

Black Princess Gold

Type: Pilsen
Price: $$
Harmonizes with: Lamb

Roo Replay

During the Roo demo at Spring Casual Class I made a mistake, when running Roo Shell in a different directory than had been planned. So, the Roo artifacts were created where I did not want. When I noticed the error I quit Roo Shell, moved to the correct directory and warned: "We'll have a replay of the commands", taking the opportunity to reinforce how it's really quick to build software with Roo Shell.

And "Don't tell me that it has a replay command" came from the middle of the audience. Yes I do - I could have used the log.roo file and script command. At that the time I preferred to do it all again by Roo Shell, but I briefly touched on the "replay". This feature, in my opinion, is one of the most valuable and has helped me a lot during the projects, and during my learning curve with Roo. Let's talk about it, and also make for the example I used during Spring Casual Class.

Every time we execute commands by Roo Shell we have a history, recorded in the log.roo, which is located in the root of the project. This file can be used to repeat previously executed commands (in the same or another project). The steps are:  

1 - Create a copy of the log.roo with another name, keeping the extension and save it in the root of the project which should be executed. 
2 - Edit the file, removing commands that do not matter, renaming fields and classes as needed. We can also add new commands. 
3 - Open the Roo Shell and run: script yourfile.roo

The commands will run on your project and the file will be updated with log.roo latter commands.

Try it out: 

1 - Create some directory 
2 - Save the content below is such directory as a file named casualclass.roo 
3 - cd to such directory an run Roo Shell, and then type : script casualclass.roo

project --topLevelPackage globalcode.casualclass
persistence setup --database HYPERSONIC_IN_MEMORY --provider HIBERNATE
entity --class ~.model.DesiredTalks
field string --fieldName description --sizeMin 5 --sizeMax 40 --notNull
field date --fieldName bestDate --type java.util.Date --persistenceType JPA_DATE --future
finder list --class ~.model.
finder add findDesiredTalksByDescriptionLike
controller all --package ~.web
perform eclipse

Sunday, March 7, 2010

Java EE 6 with Fine Beers - Beer 1

This is the first of several articles reporting my experiences while migrating an enterprise  application to Glassfish V3.

This post will cover one specific migration challenge: A partial migration supported by remote JMS connections.

Thank God there is Loose Coupling

About one year and half ago, in order to amend a diversity of integrations with on-line services of our business partners, I preferred to modularize the architecture by controlling slave integration modules with JMS. That's the way I designed and how it was implemented:

Once the slave modules have straightforward responsibilities they were chosen to be moved first to the new home. The plan was to keep the main application in the old Glassfish for a while, using JMS to communicate.

The question is:  How to configure MessageDriven Beans (V3 hosted) to consume from remote (V2 hosted) destinations ?

I was not able to find all the answers in Glassfish documentation. Indeed it gave me good directions, and it was helpful as reference. Interestingly the solution was clearly found in Java EE 5 tutorial, that depicts the issue of remote JMS resources using Glassfish:
An Application Example That Consumes Messages from a Remote Server.

Here is the bottom line of the configuration:

  • The original Connection Factory and the original destinations are kept in V2.
  • A "proxy" connection factory is created in V3, using the same name and referencing the original one, through AddressList property.
  • The JMS destinations used by slaves were duplicated (dummy, same jndi name) in V3.
  • In Glassfih, MDBs had to configured to use to a specific connection factory (the proxy) with sun-ejb-jar.xml, the proprietary deployment descriptor
The proxy connection factory can be created in V3 using CLI (asadmin):

create-jms-resource --property AddressList=V2-host-ip --restype javax.jms.ConnectionFactory remote-connection-factory-jndi-name

The sun-ejb-jar.xml files have to be provided as follow:

  • The main application doesn't need a change, it will continue to use its original JMS resources.
  • Slave Modules only needed to include configurations in sun-ejb-jar.xml, with no source code changes.
  • At the time that main application moves to V3 the only thing we need is to remove the AddressList property, turning the proxy connection factory into a real one.
  • As a positive side effect of this partial migration scenario, we improved scalability, hosting components into different servers.

Last but Not Least
As I had promised let's celebrate this migration move with a nice Brazilian beer:

Eisenbahn (Rail Road, in German)

Type: Pilsen
Price: $$
Harmonizes with:  Sea Food, Some kinds of cheese: Brie, Camembert, Gruyère, Emmental

Java EE 6 with Fine Beers - Introduction

Moving Pictures
I'm going to register experiences of migrating an enterprise application from Glassfish V2 to V3.

I believe that each successful migration effort has to be celebrated with a Brazilian beer. As I don't upgrade Java EE versions every day, I'm going to toast with gourmet beers. I sincerely expect to be contested by beer connoisseurs in the case I'm wrong.

It all begun when our infrastructure decided to upgrade servers to a newer set of aligned open source software versions. Guess what, JDK 5 and Glassfish V2 that had served us so well were pointed out to be replaced by Open JDK 6 and Glassfish 2.1.1. That's a picture of what we have to move:
  • ~ 60 Session Beans (6 SOAP endpoints)
  • ~ 50 JPA Entities
  • ~ 36 Servlets
  • ~ 10 JSF Managed Beans / 14 Facelets view components
  • An every week increasing number of Messaged Driven Beans
I knew the theory: GF 2.1.1 is Java EE 5 compatible, so the migration is supposed to be smoth. And I also knew that theory and practice are the same only in theory. Therefore, the best to be done was to prepare a migration plan. It was December 2009, Java EE 6 had been finished, and Glassfish V3 had been released as final version. At that point I realized that we could take advantage of migration effort and move to V3, unleashing development with Java EE 6 goodies.

So lets move on to Java EE 6 with Glassfish V3
Stay tuned ...

Records from Spring Brazil Casual Class

On Feb 26 I had the priviledge to collaborate with Spring Brazil Casual Class, and with the launch of Spring Brazil User Group.

My role was to demonstrate the use of Spring Roo, as I staded before.

From Spring Brazil User Group we have the slide casts available in Portuguese:
Here are some pictures, from my camera:

This is dr Spock, talking about Spring Platform.

The audience, thrilled with Roo.
(The best feedback was: "Business Analysts cannot know that such tool exists!")

This is me, showing file system entries generated by Roo

Hands On ! Very quick demos with Roo Shel.
(We barely need a mouse)

In future posts I intend to share some good experiences about development with Roo.
See you.

Monday, February 8, 2010

Spring Casual Class

In Brazil there is a cool Java meeting called Casual Class, promoted by Globalcode. It happens each two months, focusing on some subject, with points of view of three or four professionals.

Afterwards we have pizza, beer, wine, and networking.

We have already talked about JavaOne 2009, Robotics, Java EE 6, Cloud Computing. Next Feb 26 it will happen again, and the subject will be Spring. My colleagues will talk about Spring 3.0, Spring Tools, and Spring in Cloud Computing. In the same meeting we're going to launch SBUG: Spring Brazil User Group.

I'll be there too, talking about Spring Roo.

Considering that there is a lot of good stuff available in English, I don't intend to show here basic Spring Roo usage. But as an appetizer for may Brazilian fellows I have just written a post in Portuguese and it is available at Globalcoders blog.


Wednesday, January 20, 2010

New Technologies, Old Problems

I am involved in several projects that require integration with business partners webservices. By adopting JAX-WS 2.1 stack supported by NetBeans/Galssfish our applications easily benefit from Java representations of operations and data structures with which we must interact. JAX-WS has also allowed speed to expose functionality implemented in Java, for internal applications developed on other platforms.

All this ease of integration can cheer us up at first, so we extensively use these benefits. The pitfalls lie in:
 - to ignore the coupling with external data models upon consuming webservices
 - to allow the transitivity of the internal data model upon providing webservices

The fact is that a webservice contract of today may become obsolete in a few months. Of course there are patterns of service-oriented architectures, adopted on the provider of webservices that minimize the impact of such developments. An interesting practice I have observed is the versioning of services. When a new version of service is available the old version is still functioning, for one or two developments.

However, the raise of a new service version reflects new business needs, and webservice consumers will be forced to migrate soon or late. From this point of view the older versions maintenance just delays the impact of evolution.

If the consumer established indirect dependency with the representations generated by Java tools such as JAX-WS, it will be protected from the impact of development of consumed services. The idea is not new, and is well discussed in a Jens Coldewey paper, particularly in the topic Subsystem-Façade (a reinterpretation of the GoF Facade pattern).

Considering the service to be consumed and its data structure as a subsystem, we avoid the direct use of classes generated by JAX-WS. In addition to using a Facade component to convert the data structures of the service consumed for the internal structures of a consumer application, we've find room for another integration practice , which I have named 'wrapper', and I want to comment in a future post.

The same principle of subsystem separation is applied when we assume the role of services provider via JAX-WS. Whereas our internal data model can evolve, it is not used directly in the interface of the offered services. We oppose the transitivity of our internal data model, according to the Value Object design pattern: create a custom data model, that intends to remain stable for services consumers, along internal changes.

I believe that these practices can be taken when creating web services in Java using other mechanisms such as JAX-RS for REST, or even with the precursors JAX-RPC and Apache Axis.

To expose webservices without transitivity there is also the Contact-First approach, used by Spring Web Services. Such approach can also be used in JAX-WS. In this case we define the schema of data and operations exposed in the first place, placing the generation of Java artifacts as a secondary activity.