users@glassfish.java.net

Re: JackRabbit JCA Classloading issues

From: Gustavo Henrique Orair <gustavo.orair_at_gmail.com>
Date: Wed, 21 Dec 2011 13:43:58 -0200

Hi Jagadish,

I really can't inject these resources in my ejb, this is motivated because
in fact I am using a StorageFacade that may use a JcrStorage implementation
or another storage implementation such as FSStorage. This is decided
dynamically based on properties files. So, I really want to know how to get
the JCR repository from the JackRabbit JCA using explicit JNDI lookup.

If I really understand the problem, the best workaround from me would be
insert in EAR's descriptor application.xml (or glassfish-resources.xml ???)
a "fake" injection just to tell Glassfish that I want to get resources
using explicit JNDI lookup that references the JackRabbit JCA Resource
Adapter inside the EAR's modules.

I read http://docs.oracle.com/cd/E18930_01/html/821-2418/bealr.html#gjjyyand
searched for this resource-adapter-mid but I couldn't realize how
exactly could I do that.
May someone point me how to do that?




Anyway, If you are really concerned why I need to make the explicit JNDI
lookups, I will try to explain better the problem.
My code has a Crawler class used to download documents from internet, these
crawlers instances may be used both in a J2EE and J2SE environment. These
crawlers just download the documents and storage them using a
StorageFacade. There are two implementations of the StorageFacade:
JCRStorage and FSStorage. The crawlers read a properties file to chose
which implementation to be used. This feature is important for us because I
do not need to change and compile code if I use different environments, I
just need to change the properties file.

If the JCRStorage is used, it get from another properties file the URI to
be accessed and use the JcrUtils.getRepository method to access the JCR
Repository. Again, this approach make possible to use the same binary
without changing the code and compiling in both J2EE environment and J2SE
environment. If I decided to change from a JackRabbit JCA get using
explicit JNDI lookup to a Jackrabbit WebDav Server, I just need to change
one properties file. Notice that this code used in the JCRStorage
implementation uses just code from jackrabbit-jcr-commons module that is
not tied to the JackRabbit implementation. It makes my framework very easy
to change the JCR implementation. I would need just the
jackrabbit-jcr-commons dependency inside my EAR and this would be the
unique JackRabbit dependency inside the EAR.

Actually, in production environment, I have a CrawlerManager EJB that
creates, executes and manage the lifecycle of the Crawlers instances. In
this environment I configure the StorageFacade to use JCRStorage
implementation and the uri to be accessed:
# Inform the Storage facade to get the JCR repository by an explicit Jndi
lookup by the name jcr/Repository
uri=jndi:jcr/Repository
It results in an explicit JNDI lookup for the JCR Repository.
The Jcr Repository is really accessed inside a class that may be used as
J2SE and I cannot inject the repository.
I need just make the explicit JNDI lookup works.

---------------------------------------------------------------------------------------------------------------------
                               Gustavo Henrique Orair
------------------------------------------------------------------------------------------------------------------


2011/12/21 Jagadish Prasath Ramu <jagadish.ramu_at_oracle.com>

> Hi Gustavo,
>
> If you have a <resource-ref> to a connector-resource of JackRabbit-RAR
> in the application (either via @Resource or via the descriptor as Sahoo
> stated), the application will be able to see the RAR classes. (Thread
> context classloader should be application's classloader in this case and
> it will have RAR's classloader in the parent's chain).
>
> Yes, "derived" is the default class-loading policy. You can try setting
> it to "global" to see whether it works fine. Later, once you have the
> <resource-ref> defined the application's descriptor (or @Resource), the
> RAR will be available to the application.
>
> Reference:
> http://docs.oracle.com/cd/E18930_01/html/821-2418/bealr.html#gjjyy
>
>
> Thanks,
> -Jagadish
> On Wed, 2011-12-21 at 11:23 -0200, Gustavo Henrique Orair wrote:
> > Hi Sahoo, thanks for your prompt response!
> >
> > Regarding your comment about my ejb seems to be accessing jackrabbit
> > jca rar classes directly, my ejb uses just the JcrUtils.getRepository
> > code. This class is provided by the jackrabbit-jcr-commons module.
> > Inside this jackrabbit-jcr-commons module there is also a
> > JndiRepositoryFactory class, this class should be found by the
> > ServiceRegistry.lookupProviders(RepositoryFactory.class) and make an
> > explicit JNDI lookup (as I used an URI with jndi: scheme). My ejb just
> > need the jackrabbit-jcr-commons dependency and in fact, using this
> > approach, I am not tied to JackRabbit implementation and could use any
> > other JCR implementation (jackrabbit-jcr-commons module just use JCR
> > API code). This is exactly the EAR3 use case I have provided in my
> > first e-mail. Based on your concerns, this use case seems to fail
> > because the explicit JNDI lookup couldn't get the JCR Repository.
> >
> > The problem seems to be really concerned (as you said in your first
> > e-mail) as how org.apache.jackrabbit.client.RepositoryFactoryImpl
> > class (inside jackrabbit-api module shipped with JackRabbit-JCA) try
> > to load the org.apache.jackrabbit.core.RepositoryFactoryImpl class
> > (inside jackrabbit-core module shipped with JackRabbit-JCA) since it
> > uses Thread.currentThread().getContextClassLoader() instead of the
> > default classLoader. Notice that the
> > org.apache.jackrabbit.client.RepositoryFactoryImpl class is used in
> > multiple different environments, not just J2EE or Glassfish, etc.
> >
> > My conclusion is that Glassfish's default class loading policy
> > (derived) is incompatible with classloading policy expected by the
> > jackrabbit-api module.
> >
> > Anyway, I will give your suggestion a try and change the code from
> > org.apache.jackrabbit.client.RepositoryFactoryImpl class inside
> > jackrabbit-api module to use the default classloader instead of
> > Thread.currentThread().getContextClassLoader() while loading the
> > org.apache.jackrabbit.core.RepositoryFactoryImpl class. But Apache
> > Jackrabbit developers will probably argue this would break all other
> > uses of this class in other environments.
> >
> >
> ---------------------------------------------------------------------------------------------------------------------
> > 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/20 Sahoo <sanjeeb.sahoo_at_oracle.com>
> > No, it is not a bug. Your ejb modules does not have any
> > resource references that are satisfied by jackrabbit rar. Your
> > ejb seems to be accessing jackrabbit jca rar classes directly
> > using jackrabbit API called JCRUtils and GlassFish has no idea
> > that this dependency comes from jackrabbit rar. Add @Resource
> > to your ejb to a jackrabbit rar supplied connection factory
> > for the class loader to detect the dependency.
> >
> > Sahoo
> >
> > On Tuesday 20 December 2011 11:39 PM, Gustavo Henrique Orair
> > 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?
> >
> >
> >
>
>
>