users@glassfish.java.net

Re: JackRabbit JCA Classloading issues

From: Bernhard Thalmayr <bernhard.thalmayr_at_painstakingminds.com>
Date: Tue, 20 Dec 2011 22:07:17 +0100

I had similar issue and discussion some weeks ago.

GlassFish will only load the adapter classes if one of your JEE deployment
descriptors (web.xml ,ejb-jar.xml) has a resource-ref element for the
adapter.

I worked around this by deploying the resource-adapter separately.

-Bernhard

On Tue, Dec 20, 2011 at 7:09 PM, Gustavo Henrique Orair <
gustavo.orair_at_gmail.com> wrote:

> I checked the j2EE6 specification for classloading behaviour.
> In section 8.3.2 - EJB Container Class Loading Requirements it states:
>
> "*Components in the EJB container must have access to the following
> classes and resources.
> (*...)
> ** The contents of all jar files included in each resource adapter
> archive (rar file) deployed separately to the application server, if that
> resource adapter is used to satisfy any resource references in the module.
> (...)"
>
> *So, the behaviour I found in Glassfish seems like not J2EE6 compliant.
>
> Should I file a bug?
>
>
>
> ---------------------------------------------------------------------------------------------------------------------
> Gustavo Henrique Orair
> Mestre em Ciência da Computação - MSc in Computer Science
> Universidade Federal de Minas Gerais
> Celular/Cell phone: 55-31-85157887
>
> ------------------------------------------------------------------------------------------------------------------
>
>
> 2011/12/19 Gustavo Henrique Orair <gustavo.orair_at_gmail.com>
>
>> I have some issues with Glassfish ClassLoader.
>>
>> I am using JackRabbit JCA (Resource Adapter for JCR Repositories) to
>> provide JCR repositories (JSR-283).
>>
>> I have many problems and all looks like related to classloading.
>>
>> It looks like that Glassfish ClassLoader do not find the libraries inside
>> the jackrabbit JCA rar.
>> JackRabbit JCA is shipped with JackRabbit Core inside that provides the
>> "server implementation". But the class with this implementation is not
>> found by the classloader.
>>
>> I will try to explain what I found trying to solve this problem and the
>> workarounds I've used and see if someone may help me to understand better
>> the problems and how to solve them (or file a bug).
>>
>> JackRabbit JCA is a Resource Adapter. You may create connection pool for
>> a specific JCR Repository providing some parameters such as HomeDir (the
>> directory where the repository is found).
>> JackRabbit JCA based on these parameters specified uses
>> org.apache.jackrabbit.client.RepositoryFactoryImpl class. This
>> RepositoryFactoryImpl class just get the parameters specified and check the
>> existence of the HomeDir parameter. When this HomeDir parameter is found,
>> it try to load the class org.apache.jackrabbit.core.RepositoryFactoryImpl
>> dynamically (provided in jackrabbit-core inside the jackrabbit-jca). The
>> code used to load org.apache.jackrabbit.core.RepositoryFactoryImpl is
>> similar to:
>> Class<?> repositoryFactoryClass =
>> Class.forName("org.apache.jackrabbit.core.RepositoryFactoryImpl",
>> true,Thread.currentThread().getContextClassLoader());
>> repositoryFactory = repositoryFactoryClass.newInstance();
>>
>> If the clients perform explicit JNDI lookups, the
>> org.apache.jackrabbit.client.RepositoryFactoryImpl is not being found.
>>
>>
>> Another very common option for the clients to access the JCR repository
>> is to use JcrUtils.getRepository(String uri) provided in
>> jackrabbit-jcr-commons (specifying a "jndi:jcr/Repository" uri) . This
>> utility basically search using ServiceRegistry.lookupProviders for
>> RepositoryFactory providers that accepts the parameters specified. Code:
>> Iterator<RepositoryFactory> iterator =
>> ServiceRegistry.lookupProviders(RepositoryFactory.class);
>>
>> Using this utility, the code fails again (it really make an explicit JNDI
>> lookup inside JndiRepositoryFactory class).
>>
>> Since these classes were not being found inside JackRabbit JCA, I tried
>> as a workaround to add jackrabbit-core and jackrabbit-commons modules
>> inside the EAR.
>> I was able to get the repository but I needed another workaround.
>> I added JMX methods to a singleton EJB to make the tests easier (and
>> study JMX classloader issues).
>> If I invoke JCRUtils.getRepository directly from this singleton EJB, the
>> RepositoryFactory implementations are not found.
>> So, I did a following workaround: Created a Stateless Session bean. The
>> Singleton EJB works like a "proxy" and just delegate the methods from
>> Singleton ejb to the stateless ejb. Using this workround, finally I could
>> successfully get a JCR repository using JNDI. Additional note: if the
>> delegation is done to static methods defined in the stateless ejb, the
>> workaround doesn't work.
>>
>>
>> To make easier to reproduce these problems,
>> I have created a small EJB module with the stateless and the singleton
>> ejb as discussed.
>> This EJB module has a Singleton JMXServiceActivator. The
>> JMXServiceActivator is registered in managed bean server as
>> app.JMXServiceActivator and you can use jmx client (such as jconsole) to
>> launch the following methos:
>> 1 - getRepositoryUsingExplicitJNDI(String jndiName);
>> 2 - getRepositoryUsingJCRUtils(String jndiName);
>> 3 - getRepositoryUsingExplicitJNDIWithoutProxy(String jndiName);
>> 4 - getRepositoryUsingJCRUtilsWithoutProxy(String jndiName);
>>
>> After, I created 3 different client EARs to check all these issues
>> (attached in this e-mail):
>> 1 - EAR
>> No Jackrabbit dependencies
>> (It should be possible to get the jackrabbit repository using explicit
>> JNDI)
>> 2 - EAR2
>> jackrabbit-commons and jackrabbit-core dependences
>> (it really can get the JCR repository but a "proxy" using Stateless
>> session being is needed to make it work)
>> 3 - EAR3
>> Just jackrabbit-commons dependency
>> (It should be possible to get the JCR repository using
>> JCRUtils.getRepository(String uri) but it does not work)
>>
>> I am doing something wrong?
>> Are these really Classloading bugs?
>> Is this just an unique bug or there are multiple bugs involved?
>>
>>
>>
>>
>> ---------------------------------------------------------------------------------------------------------------------
>> Gustavo Henrique Orair
>> Mestre em Ciência da Computação - MSc in Computer Science
>> Universidade Federal de Minas Gerais
>> Celular/Cell phone: 55-31-85157887
>>
>> ------------------------------------------------------------------------------------------------------------------
>>
>
>


-- 
IT-Consulting Bernhard Thalmayr
- Painstaking Minds -
83620 Vagen (Munich area)
Germany