I am using the JackRabbit JCA Resource Adapter (http://jackrabbit.apache.org/jackrabbit-jca-resource-adapter.html) to access JCR repositories using explicit JNDI lookups, but I am facing some classloading problems on this environment.
I've created an Example Project to show the issues I am facing.
To Reproduce the issues you need to follow the step-by-step instructions:
Step 1 - Get JackRabbit JCA (version 2.3.3) on link http://www.apache.org/dyn/closer.cgi/jackrabbit/2.3.3/jackrabbit-jca-2.3.3.rar.
Step 2 - Deploy jackrabbit-jca on Glassfish.
2 - a) Specify the application name to jackrabbit-jca.
Application Name: jackrabbit-jca
Step 3 - Create a Connector Connection Pool, use the following configuration:
Pool Name: cp_jcr_repository
Resource Adapter: jackrabbit-jca
Connection Definition: javax.jcr.Repository
3 - a) As Additional Property, specify just the HomeDir parameter:
Step 4 - Create a new Connector Resource:
Jndi Name: jcr/Repository
Pool Name: cp_jcr_repository
Step 5 - Unzip the Example Project (attached) in a directory.
5 - a) Package the Example Project (Root module) using Maven.
3 different EARs will be created:
No Jackrabbit dependencies
(It should be possible to get the jackrabbit repository from JackRabbit-JCA resource adapter using explicit JNDI)
jackrabbit-commons and jackrabbit-core dependences
(this EAR has all jackrabbit dependences itself and it works but a "proxy" using Stateless session being is needed probably because of classloading issues when JMX invocations are used)
- EAR3 (this is the most similar to the real world use case)
It has jackrabbit-jcr-commons dependency
(It should be possible to get the JCR repository using JCRUtils.getRepository(String uri) but it does not work)
Step 6 - Deploy one of the EARs modules on Glassfish.
All these 3 EARs packages just one EJB module.
The EJB module has one stateless ejb and one enabled JMX singleton ejb called JMXServiceActivator (The JMXServiceActivator is registered in managed bean server as app.JMXServiceActivator).
A jmx client may be used to launch the JMXServiceActivator methods:
a - getRepositoryUsingExplicitJNDI(String jndiName);
b - getRepositoryUsingJCRUtils(String jndiName);
c - getRepositoryUsingExplicitJNDIWithoutProxy(String jndiName);
d - getRepositoryUsingJCRUtilsWithoutProxy(String jndiName);
Step 7 - Call one of the JMXServiceActivator methods using a JMX client (such as jconsole).
Step 8- Check the server.log the resulted behaviour.
After discussing with glassfish developers (Sahoo and Jagadish), I've created glassfish-application.xml and glassfish-resources.xml files to try to inform to Glassfish I need the Jackrabbit libraries/modules inside jackrabbit-jca available to my EAR. At least from my observations, inserting these files on EAR3 module didn't change anything.
I am getting the following results:
EAR1: Methods 1 and 3 should work (2 and 4 would work if the jackrabbit-jcr-commons module inside jackrabbit-jca was accessible), but none of the methods works.
EAR2: All 4 methods should work on EAR2, but only 1 and 2 works (probably problems related to JMX avoid these methods to work correctly, but it is not the focus of this issue).
EAR3 (this use case is the most similar to my real world project): All methods should work, but none works.
As I said, the focus on this issue is to make the classloader finds the libraries inside the resource adapter, the problem related to JMX is not the big problem (at least for now since I've used a "workaround" proxy).
So, I am really interested to make the method getRepositoryUsingJCRUtils(String jndiName) (method b) from EAR3 application work.
To understand the problem, I explain the behavior I observed and why it fails:
When JcrUtils.getRepository is called, the EJB pass the uri parameter with jndi scheme (jndi:jcr/Repository), "JcrUtils" search for providers and it finds JndiRepositoryFactory provider (inside jackrabbit-jcr-commons dependency that exists in EAR3 lib's directory). The JndiRepositoryFactory performs an explicit JNDI lookup to jcr/Repository.
The JCARepositoryManager invokes JcrUtils.getRepository again but it pass a Map of parameters containing the parameters found in the Connection pool configuration (cp_jcr_repository). Then, ServiceRegistry.lookupProviders(RepositoryFactory.class) is called, but the classloader used doesn't find the org.apache.jackrabbit.client.RepositoryFactoryImpl (this class belongs to jackrabbit-jcr-client module shipped inside jackrabbit-jca resource adapter).
Note: JackRabbit source code may be checked out from a subversion repository in https://svn.apache.org/repos/asf/jackrabbit/tags/2.3.3 .