Now that I have your attention, I'd like to discuss issues we are experiencing when
trying to modularize the Hibernate portfolio and make it work in AS 7.1.
## Disclaimer
I perfectly understand all the coolness about modularity (speed, easier dependency
isolation etc). I have also carefully read :
-
https://community.jboss.org/wiki/ModuleCompatibleClassloadingGuide
-
https://community.jboss.org/wiki/ModularSerialization
But these tend to avoid the more complex cases of portable libraries that ought to run
even outside AS 7 but have a wide variety of class and resource loading needs.
I am not a complete modularity bozo but I am definitely not familiar with JBoss Modules
nor similar solution.
## Requirements / Landscape
Hibernate ORM uses the notion of service registry and integrator object that help during
the integration or customization of the engine behavior by third-party frameworks.
Enlistment of Integrators is done via the service locator pattern (a service file in
META-INF/services/ that is looked up and contain the implementation class(es) at stake.
Hibernate Envers is one of those customizer that depends on Hibernate ORM. Note that the
core of Hibernate ORM does not depend on Hibernate Envers. The service locator file is
contained in Hibernate Envers JAR.
Hibernate OGM likewise, heavily customizes ORM and depends on Hibernate ORM classes - the
reverse is not true. The service locator file is contained in Hibernate OGM JAR.
Hibernate Search optionally depend on Hibernate ORM and JPA. The core of Hibernate Search
is independent but an Hibernate Search ORM module has an integrator implementation. On top
of that, Hibernate Search optionally depend on some JPA classes and behaves differently if
they are there - we look them up in the classpath by reflection.
On top of that, these projects do load resources (config files, classes):
- from what Jason calls a Deployment classloader (the user application classes and
resources really) - entities, custom analyzer implementations, resources files etc. A user
could even write a custom Integrator and use the service locator pattern from his
application.
- from direct dependencies (Lucene is a declared dependency of Hibernate Search)
- from dependencies of the deployment: for example an app developer adds the phonetic
analyzer as a dependency of his application and ask Hibernate Search to use it
- from modules that use these projects. Modeshape and Capedwarf are being modularized and
are making use of Hibernate Search as a module. Properly loading the necessary classes
located in Modeshape or Capedwarf's module but from Hibernate Search's engine
proves to be very hard in our current approach.
All of these projects should be able to run outside JBoss AS 7, so a modular friendly
solution should somehow be abstracted and generic enough.
## What solution?
More and more projects are being modularized including ones with complex resource loading
dependencies like the ones I have described. AFAIK Infinispan is even in a worse situation
as clustering and late class binding is at stake but let's put this one aside.
I'd love to get a reference design outcome from this thread that could be copied
across all these projects and future ones like Bean Validation.
Today, we mostly use the good old and simple TCCL model which works fine if the jars are
directly embedded in the app but fail the minute we start to move these dependencies into
modules. Sanne, Strong, Scott Marlow and I are using dangerous amount of Advil to try and
make everything work as expected. Some help would be awesome.
To sum up:
- can the Hibernate portfolio be supported within JBoss Module and how?
- what kind of ClassloaderService contract should we use within these projects to be
modular friendly (JBoss Modules and others)?
- would such contract be generic enough to be extrapolated to JSRs in need of modular
friendliness?
- how to solve the chicken and egg issue of the bootstrapping: if we need to pass a
ClassloaderService impl? How do we do that best in a modular environment without forcing
the application developer to implement such godforsaken ClassloaderService contract or
even worse pass directly to us the right classloader for each call.
Thanks,
Emmanuel