Hi all, I hope anyone of you can help b/c this issue is driving me nuts.
Hibernate version: version 3.2.6, Feb 7, 2008
Scenario:
- I have an application using hibernate as abstraction layer. The application uses a plug-in approach, meaning that plug-in jars can be added during runtime.
- As the plug-ins may need to access db-tables not intended by the base, I ship resources definitions and the mapped classes along with the plug-in jar.
- The plug-ins including the the hibernate resources are loaded by <my custom URL classloader> upon startup (before the sessionFactory is configured)
- The classes and resources contained in the plug-in jars are accessible through <my custom URLClassloader> only.
Problem:
- The resource can be loaded via <my custom URLClassloader>
- The class can also be loaded via <my custom URLClassloader> (Loaded class: com.werum.wxi.plugin.test.NaInfoSapToWlt)
However, calling the following throws an exception as shown in the stack trace below. The reason is, that hibernate uses the passed classLoader reference to acquire the resource but not to instance the class.
Code:
hibernateConfiguration.addResource(<the hibernate resource file .hbm.xml>, <myCustomURLClassloader>);
The snipped of Configuration.addResource shows that the passed classLoader is used to extract the resource, but it is not passed on to 'addInputStream' which finally instances the mapped class.
(the same applies for Configuration.addClass(...) btw.)Code:
public Configuration addResource(String resourceName, ClassLoader classLoader) throws MappingException {
log.info( "Reading mappings from resource: " + resourceName );
InputStream rsrc = classLoader.getResourceAsStream( resourceName );
if ( rsrc == null ) {
throw new MappingNotFoundException( "resource", resourceName );
}
try {
return addInputStream( rsrc );
}
catch (MappingException me) {
throw new InvalidMappingException( "resource", resourceName, me );
}
}
Stack trace:
org.hibernate.InvalidMappingException: Could not parse mapping document from resource com/werum/wxi/plugin/test/NaInfoSapToWlt.hbm.xml
at org.hibernate.cfg.Configuration.addResource(Configuration.java:545)
at org.hibernate.cfg.Configuration.addClass(Configuration.java:592)
at com.werum.wxi.common.plugin.PlugInLoader.registerHbms(PlugInLoader.java:254)
at com.werum.wxi.common.plugin.PlugInLoader.addDirectory(PlugInLoader.java:158)
at com.werum.wxi.common.plugin.PlugInLoader.addDirectory(PlugInLoader.java:163)
at com.werum.wxi.common.Environment.<init>(Environment.java:100)
at com.werum.wxi.common.Environment.getInstance(Environment.java:234)
at com.werum.wxi.common.WXIProcess.<init>(WXIProcess.java:66)
at com.werum.wxi.server.WXIServer.<init>(WXIServer.java:62)
at com.werum.wxi.server.WXIServer.main(WXIServer.java:95)
Caused by: org.hibernate.MappingException: class com.werum.wxi.plugin.test.NaInfoSapToWlt not found while looking for property: messageId
at org.hibernate.util.ReflectHelper.reflectedPropertyClass(ReflectHelper.java:74)
at org.hibernate.mapping.SimpleValue.setTypeUsingReflection(SimpleValue.java:279)
at org.hibernate.cfg.HbmBinder.bindSimpleId(HbmBinder.java:401)
at org.hibernate.cfg.HbmBinder.bindRootPersistentClassCommonValues(HbmBinder.java:334)
at org.hibernate.cfg.HbmBinder.bindRootClass(HbmBinder.java:273)
at org.hibernate.cfg.HbmBinder.bindRoot(HbmBinder.java:144)
at org.hibernate.cfg.Configuration.add(Configuration.java:675)
at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:510)
at org.hibernate.cfg.Configuration.addResource(Configuration.java:542)
... 9 more
Caused by: java.lang.ClassNotFoundException: com.werum.wxi.plugin.test.NaInfoSapToWlt
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:100)
at org.hibernate.util.ReflectHelper.reflectedPropertyClass(ReflectHelper.java:70)
... 17 moreI've read a lot about hibernate and class loader issues on the web but couldn't find any solution. Some people even suggested, that there is none.
Is that really the truth? I mean, there must be a way to get hibernate to use a certain class loader, right?!
Code:
Ok, smart people ... let's here your solutions!