JBoss, EJB3, Hibernate and DLL Hell

December 30, 2007 by · 2 Comments
Filed under: java, jboss 

For the last year or so, I’ve been working on a project using JBoss and EJB 3.0. As this is a first, no wonder there were some technical difficulties along the way. This post is the first in a series describing the problems we had, and how we overcame them.

The original task was very simple: Let’s create a small application, demonstrating the usage of all the technologies, and start grow our application from there. Starting with running the tutorials coming with the JBoss EJB3 distribution we saw this problem:

--- MBeans waiting for other MBeans ---
ObjectName: persistence.units:jar=tutorial.jar,unitName=tempdb
  State: FAILED
  Reason: java.lang.RuntimeException: java.lang.NoClassDefFoundError: \
          org/hibernate/MappingNotFoundException
  I Depend On:
    jboss.jca:service=DataSourceBinding,name=DefaultDS
  Depends On Me:
    jboss.j2ee:jar=tutorial.jar,name=ShoppingCartBean,service=EJB3ObjectName: \
           jboss.j2ee:jar=tutorial.jar,name=ShoppingCartBean,service=EJB3
  State: NOTYETINSTALLED  I Depend On:
    persistence.units:jar=tutorial.jar,unitName=tempdb
--- MBEANS THAT ARE THE ROOT CAUSE OF THE PROBLEM ---
ObjectName: persistence.units:jar=tutorial.jar,unitName=tempdb
  State: FAILED
  Reason: java.lang.RuntimeException: java.lang.NoClassDefFoundError: \
          org/hibernate/MappingNotFoundException
I Depend On:
    jboss.jca:service=DataSourceBinding,name=DefaultDS
  Depends On Me:
    jboss.j2ee:jar=tutorial.jar,name=ShoppingCartBean,service=EJB3

This was really puzzling. How can JBoss wants us to deploy a small persistence jar, when it can’t satisfy it’s dependencies? Like in most of these cases, it appeared it was another case of DLL hell. The short solution, for JBossAS 4.0.4GA, is as follows: update the modification time of the files (I did it using “touch”, via cygwin), and then run the at install file of the EJB3 package. I might warn you in advance that the rest of this post is full with all the nagging version differences that gave DLL hell its name…

After searching the hibernate API and subversion repository, I’ve found that the relevant class (org.hibernate.MappingNotFoundException) was added to Hibernate in version 3.2.0.cr3 or 3.2.0.cr4. The version that comes with the EJB3 RC9 is cr4. The version I had in the JBossAS (4.0.4GA) is cr2, which lacked that file.

The EJB3 ant installer should have copied the new version to the JBossAS, but unfortunately the modification time of the JBossAS jars was newer than the EJB3, so ant has ignored the copy request.

So this is how the solution works – using “touch” updates the modification time of the EJB3 jars. This makes them newer than those th JBossAS has and then they were copied correctly.

By the way, if you are using JBossAS 4.0.5, you probably don’t want to do this, but rather keep the original Hibernate jars that came with the JBoss. The reason is that JBossAs 4.0.5 contains the final version of Hibernate (3.2.0.ga), which is newer than the one bundled in the EJB3.

Share

Seam @DataModel Factories

December 22, 2007 by · Leave a Comment
Filed under: java, jboss 

Seam has a great feature called DataModel. In a nutshell, you provide a List, and seam populates a dataTable for you. The great thing about it, is you can provide an injection point marked as DataModelSelection, and when the user clicks on one of the dataTable rows, you have the selected object.

Theoreticaly, you can put the @DataModel annotation on a method or on a field. However, as it turns, by declaring a method as DataModel it will be called for each use of the returned list. This can cause big performance issue, as the list generation often requires fetching the data from back end systems such as the database. The sumple solution for this is to declare the list as a member of the backing bean, and add a factory method for it. In this case, the factory method will be called only when the @DataModel List is null.

For code example, have a look here.

Share

sed porting (or the little r that could)

December 21, 2007 by · 2 Comments
Filed under: linux 

My company is doing mainly mobile consumer applications, sold on almost every mobile platform available. In order to support them, we have servers providing various content, perform book keeping, etc.

About a year ago, we moved one of our servers from FreeBSD to Red Hat Linux. During this move, I’ve learned that not all UNIX’ small utilities were born equal. One of the tasks of this server was to receive content updates and transform them to the proper format read by our applications. All the feeds are in pipe delimited formats, since mobile clients couldn’t handle any fancy format (do I here XML?) very well.

The problem was that somewhere along the line, our content provider has changed some of the codes it uses. Since we needed to support old applications, and didn’t want to update all the applications’ code, we decided to transform the codes back to the original version while creating the new feeds. Now, the feeds at that time were plain text files, the clients would just download. In order to do that, we added a sed command to transform the codes. This command basically ran a lot of s/|1234/|5678/g and worked well, was quick, and didn’t ask for food.

Until we have moved it to the Red Hat. When this command ran on the Linux, the script froze for several minutes, and then an alarming message had appeared: sed: Couldn't re-allocate memory. Tracking the script output while running, we discovered that it tried to replace every character in the original 38,000 lines feed with the “|5678″ strings, and tried to do it about 100 times. Of course, the second s/../../g command had 5 times more characters to replace then the first, and the output was keep growing exponentially.

The fix was rather simple: we escaped the regular expressions so now they look like this s/\|1234/\|5678/g, and more importantly, we discover that if you want to use sed on Linux, you’d better add the -r parameter, which tells sed to use the extended regular expressions in the script.

Needless to mention that all is working well right now.

Share