I have started a hibernate (version 3.2) project that is invoked remotely from a third-party product. I would prefer not to name the product right now and just describe the general parameters of the problem. The documentation for this products says that "... objects [are] executed remotely and run on a separate, external JVM ...".
My hibernate app at this point is a bare minimum of one class, com.blues.brothers.Elwood (the package name has been changed to protect the guilty), which calls a by-the-numbers persistence.HibernateUtil class to get a Session which would manage a single entity class, com.blues.brothers.Jake. I created this basic structure as a standalone application and it worked fine. The problems occur when this application, wrapped in a jar, is invoked from the third-party product. It can't find the hibernate.cfg.xml file which is in the root of the jar directory structure.
I got around that by moving the hibernate.cfg.xml file to another location and passing a File object reference of it to the Configuration.configure method. Then hibernate couldn't find the entity class configuration xml file. I got around that by having Elwood invoke the Configuration.addResource("com/blues/brothers/Jake.cfg.xml", this.getClass.getClassLoader). Now it could find the entity class configuration xml but when I try to get a Session it complains that it can't find the com.blues.brothers.Jake class:
Caused by: org.hibernate.MappingException: entity class not found: com.blues.brothers.Jake
at org.hibernate.mapping.PersistentClass.getMappedClass(PersistentClass.java:99)
at org.hibernate.tuple.PropertyFactory.getGetter(PropertyFactory.java:168)
at org.hibernate.tuple.PropertyFactory.buildIdentifierProperty(PropertyFactory.java:44)
at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:118)
at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:425)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:109)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:226)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1218)
at persistence.HibernateUtil.getSessionFactory(HibernateUtil.java:49)
at com.blues.brothers.Elwood.doStuff(Elwood.java:43)
... 19 more
Caused by: java.lang.ClassNotFoundException: com.blues.brothers.Jake
at java.net.URLClassLoader.findClass(URLClassLoader.java(Compiled Code))
at java.lang.ClassLoader.loadClass(ClassLoader.java(Compiled Code))
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java(Compiled Code))
at java.lang.ClassLoader.loadClass(ClassLoader.java(Compiled Code))
at java.lang.Class.forName1(Native Method)
at java.lang.Class.forName(Class.java(Compiled Code))
at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:100)
at org.hibernate.mapping.PersistentClass.getMappedClass(PersistentClass.java:96)
I have changed the name of the package and class names but the structure is the same. Again, this works fine as a standalone application.
Fundamentally, is there a way "reorient" hibernate to anchor it's sense of the root of the classpath to be the root of the jar file it is running in? I suspect that Spring might might offer a solution but I am hoping there is a relatively straightforward approach that would let me get started developing this application first.
I tried adding <property name="current_session_context_class">thread</property> to the hibernate.cfg.xml file but it didn't solve this problem; it was pretty much a shot in the dark.
Admittedly, I am not the slickest java programmer around. I did look in the source code and the final method in the chain is:
public static Class classForName(String name) throws ClassNotFoundException {
try {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if ( contextClassLoader != null ) {
return contextClassLoader.loadClass(name);
}
}
catch ( Throwable t ) {
}
return Class.forName( name );
}
It seems that Thread is used as the reference but I need to have hibernate use the local JVM instead, if that actually makes any sense.
Again, it works fine standalone so it's not a basic configuration issue.
_________________ ... and this too shall be deprecated
|