HqlToken exception in dm Server

If you’re using Hibernate in WebLogic, some of you may have come across a class loading problem, because WebLogic includes Antlr 2.7 on its main classpath, and when you start application that requires antlr as well, you will end up with strange class loading and casting exceptions.
OSGi should really solve all this, shouldn’t it? We no longer have monolithic classpaths, we have bundles with isolated classpaths and the OSGi runtime provides the lifecycle management and dependency resolution services. Well, in case of Hibernate, it is not that simple. Let’s say you have a typical web application with the repository tier implemented in Hibernate. The bundlified Hibernate distribution (courtesy of the SpringSource Enterprise Bundle Repository) correctly depends on Antlr 2.7; and so–to satisfy the dependency–you make your repository bundle depend on the appropriate Antlr bundle, and all seems to be working. Until you use more complex HQL query; that is one that does not begin with select, but with delete or update.
You see, Hibernate uses Antlr to translate the HQL into an abstract syntax tree. The root of the problem is that it [Hibernate] passes a name of its internal class to Antlr. Antlr then tries to load the class using the provided name and use this class in the vertices of the AST. Naturally, in OSGi, this is a problem, because the Antlr bundle does not depend on Hibernate. The error message is then quite obvious ClassNotFoundException: HqlToken, but this exception is thrown from Antlr rather than from Hibernate or the rest your application.
The dm Server’s extensions to the OSGi standard allow us to specify PAR-wide resolution context, which solves this problem.
In practice, you have to place both your repository and webapp bundles in a PAR; in your repository’s MANIFEST.MF, you need to specify

...
Import-Bundle: ...,
 com.springsource.org.hibernate;version="[3.3.1.GA,3.3.1.GA]";
 import-scope:=application,
...

and finally, in your webapp, you need to include dependency on Hibernate in its MANIFEST.MF.
In summary, you need to:

  • Mark the Hibernate Import-Bundle entry with import-scope:=application in repository,
  • Include Hibernate in Import-Bundle in webapp

These two simple steps solve the
ClassNotFoundException: org.hibernate.hql.ast.HqlToken web applications that use Hibernate in dm Server 2.0.

Tags: , , , ,

Leave a Reply