cancel
Showing results for 
Search instead for 
Did you mean: 

JNDI in Tomcat unavailable in Alfresco

rdanner
Champ in-the-making
Champ in-the-making
Just thought this might be important to some of you.

Due to the packaging of the naming-*jar files in the Alfresco war file it is not possible to get the java:comp/env context.

If you remove these jars things work as they would typically with Tomcat.  Note – other things may break. I have discussed it with a few folks and the impact of removing these jars is that LDAP related functionality will break.  I have not confirmed this.
23 REPLIES 23

hema
Champ in-the-making
Champ in-the-making
I am still stuck with that.
Is it really possible to use JNDI to look up for JCR Repository(alfresco) from a standalone program?

Any comments will help.

Thanks again,
Hema

vijay_alfresco
Champ in-the-making
Champ in-the-making
Hi Hima,

Just follow this wiki

http://wiki.alfresco.com/wiki/Install_Extension_without_a_Compile_-_Plugin

I could run standalone with these instructions

for the context and root node, just follow the jcrRmiTest.jsp.

Thanks,
Vijay

hema
Champ in-the-making
Champ in-the-making
Hi Vijay,

Thanks for your reply.
I did try out RMI extension and it works. But I am having performance issues with this approach. I am unable to have multiple threads.
So I wanted to go JNDI route. Do you have any advice.

Thanks again,
Hema

rdanner
Champ in-the-making
Champ in-the-making
Hi Vijay,

Thanks for your reply.
I did try out RMI extension and it works. But I am having performance issues with this approach. I am unable to have multiple threads.
So I wanted to go JNDI route. Do you have any advice.

Thanks again,
Hema


The multiple thread issue has been taken care of by Lenard Fuller with thread pool.  The downside of the solution is that the system is not very scalable. We've long since abandoned our use of JCR/RMI where I work.  

JNDI/JCR is pretty easy to set up.  The biggest issue I have found is that the apache naming jars are included in the alfresco package and that clobbers JNDI in tomcat (go figure …. I lost some hair before I figured that one out)

How far along are you?  how can we help?

hema
Champ in-the-making
Champ in-the-making
Thanks Russ.

JCR-RMI was pretty straight forward and very easy to setup. But unfortunately we could not make it scale in our application. Hence looking for other routes.

Scenario:
I have alfresco(web-client) running on tomcat. And I am trying to use my local application to probe the alfresco repo to get results(search, list,..)
What I need:
I need a the context to the running repository.

What I did :
private static Repository getRepository() {
       Object vRetComponent = null;
        Context vNamingContext =  null;
   
        try {
            /*
             * Retrieve Repository */
             vNamingContext = new InitialContext();
             System.out.println("after context");
             vNamingContext = (Context)vNamingContext.lookup("java:comp/env");
             vRetComponent = vNamingContext.lookup("jcr/baseRepository");
        } catch (Exception e) {
            System.out.println("A Repository Exception occurred " + e);
        }
        return (Repository)vRetComponent;
}

my jndi.properties:
java.naming.factory.initial = org.apache.naming.java.javaURLContextFactory
java.naming.factory.url.pkgs = org.apache.naming
java.naming.provider.url = http://<mylocalIP>:1099

Result:
NameNotFoundException: java:comp not bound by the context


I think I am missing something here. I have added the Resource to server.xml  under <tomcat_home> . But I don't know where to put the ResourceLink . I have removed the naming-*.jars from alfresco/WEB-INF/lib .
I don't know how to make my application and alfresco web application share the resource,lib  and context.

Can you please help on this.

Thanks a lot again.
Hema

rdanner
Champ in-the-making
Champ in-the-making
Thanks Russ.

JCR-RMI was pretty straight forward and very easy to setup. But unfortunately we could not make it scale in our application. Hence looking for other routes.

Scenario:
I have alfresco(web-client) running on tomcat. And I am trying to use my local application to probe the alfresco repo to get results(search, list,..)
What I need:
I need a the context to the running repository.

What I did :
private static Repository getRepository() {
       Object vRetComponent = null;
        Context vNamingContext =  null;
   
        try {
            /*
             * Retrieve Repository */
             vNamingContext = new InitialContext();
             System.out.println("after context");
             vNamingContext = (Context)vNamingContext.lookup("java:comp/env");
             vRetComponent = vNamingContext.lookup("jcr/baseRepository");
        } catch (Exception e) {
            System.out.println("A Repository Exception occurred " + e);
        }
        return (Repository)vRetComponent;
}

my jndi.properties:
java.naming.factory.initial = org.apache.naming.java.javaURLContextFactory
java.naming.factory.url.pkgs = org.apache.naming
java.naming.provider.url = http://<mylocalIP>:1099

Result:
NameNotFoundException: java:comp not bound by the context


I think I am missing something here. I have added the Resource to server.xml  under <tomcat_home> . But I don't know where to put the ResourceLink . I have removed the naming-*.jars from alfresco/WEB-INF/lib .
I don't know how to make my application and alfresco web application share the resource,lib  and context.

Can you please help on this.

Thanks a lot again.
Hema

You need something to put JCR in to JNDI as well as something to get it out.  We actually use three components per se

We have an Proxy that the server puts in JNDI when the server loads
For example this is our Server XML's global naming section



<GlobalNamingResources>

   <Resource name="initialization/initializaionService"
              scope="Shareable"
              auth="Container"
              type="xtendj.javax.service.init.InitializationService"
              factory="xtendj.javax.service.init.jndi.ServiceNamingObjectFactory" />

   <Resource name="scheduling/scheduler"
              scope="Shareable"
              auth="Container"
              type="legoj.scheduler.Scheduler"
              factory="xtendj.javax.service.jndi.spi.ServiceNamingObjectFactory"
              serviceType="legoj.scheduler.Scheduler"
              proxyType="xtendj.javax.service.jndi.ProxyNonBlockingJndiService" />

   <Resource name="servlet/servletPipeline"
              scope="Shareable"
              auth="Container"
              type="legoj.pipeline.servlet.ServletProcessorChain"
              factory="xtendj.javax.service.jndi.spi.ServiceNamingObjectFactory"
              serviceType="legoj.pipeline.servlet.ServletProcessorChain"
              proxyType="xtendj.javax.service.jndi.ProxyNonBlockingJndiService" />

   <Resource name="jcr/baseRepository"
             scope="Shareable"
             auth="Container"
             type="javax.jcr.Repository"
             factory="org.alfresco.jcr.jndi.JndiJcrObjectFactory"
             jcrRepositoryName="baseAlfrescoRepository"
             proxyType="nonblocking"/>

   <Resource name="content/alfrescoAdapter"
              scope="Shareable"
              auth="Container"
              type="legoj.repository.content.RepositoryAdapter"
              factory="xtendj.javax.service.jndi.spi.ServiceNamingObjectFactory"
              serviceType="legoj.repository.content.RepositoryAdapter"
              proxyType="xtendj.javax.service.jndi.ProxyNonBlockingJndiService" />

   <Resource name="content/contentServices"
              scope="Shareable"
              auth="Container"
              type="legoj.repository.content.services.ContentRepositoryServices"
              factory="xtendj.javax.service.jndi.spi.ServiceNamingObjectFactory"
              serviceType="legoj.repository.content.services.ContentRepositoryServices"
              proxyType="xtendj.javax.service.jndi.ProxyNonBlockingJndiService" />

<Resource name="targeting/targeterDirectory"
              scope="Shareable"
              auth="Container"
              type="legoj.targeter.TargeterDirectory"
              factory="xtendj.javax.service.jndi.spi.ServiceNamingObjectFactory"
              serviceType="legoj.targeter.TargeterDirectory"
              proxyType="xtendj.javax.service.jndi.ProxyNonBlockingJndiService" />

    <Resource name="content/renderedContentProviderDirectory"
              scope="Shareable"
              auth="Container"
              type="legoj.content.provider.directory.RenderedContentProviderDirectory"
              factory="xtendj.javax.service.jndi.spi.ServiceNamingObjectFactory"
              serviceType="legoj.content.provider.directory.RenderedContentProviderDirectory"
              proxyType="xtendj.javax.service.jndi.ProxyNonBlockingJndiService" />

        <Resource name="content/rankingService"
              scope="Shareable"
              auth="Container"
              type="legoj.content.ranking.ContentRankingServices"
              factory="xtendj.javax.service.jndi.spi.ServiceNamingObjectFactory"
              serviceType="legoj.content.ranking.ContentRankingServices"
              proxyType="xtendj.javax.service.jndi.ProxyNonBlockingJndiService" />




    <!– Test entry for demonstration purposes –>
    <Environment name="simpleValue" type="java.lang.Integer" value="30"/>

    <!– Editable user database that can also be used by
         UserDatabaseRealm to authenticate users –>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
       description="User database that can be updated and saved"
           factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
          pathname="conf/tomcat-users.xml" />

  </GlobalNamingResources>

There are probably two things that here you need to pay attention to.  First is the JCR declaration and the second is the initialization component.  The upside of running along side of Alfresco (in contrast of ontop of alfresco) is that upgrades to Alfresco are much more simple.  Especially in the Pre-AMP era.  The down side is that you need external configuration like this, and furthermore you need something to solve for a possible startup race condition where your app starts before Alfresco starts – but your application needs alfresco. We use a simple initialization service to solve this problem.  The initialization service doesn't have deep knowledge of the applications… when an app or service implementation starts up one of the spring components that starts grabs the init service and tells it… call me back when the following names report they are started (names you configure in spring).  When the component gets the call back it continues the start up of it's app or service.



The next component is the context XML.  For simplicity we put our configuration in the server wide context.xml



   <ResourceLink global="initialization/initializaionService"
                  name="initialization/initializaionService"
                  type="xtendj.javax.service.init.InitializationService"/>
                 
    <ResourceLink global="jcr/baseRepository"
                  name="jcr/baseRepository"
                  type="javax.jcr.Repository"/>

   <ResourceLink global="content/alfrescoAdapter"
                  name="content/alfrescoAdapter"
                  type="legoj.repository.content.RepositoryAdapter"/>
                 
   <ResourceLink global="scheduling/scheduler"
                  name="scheduling/scheduler"
                  type="legoj.scheduler.Scheduler"/>

   <ResourceLink global="servlet/servletPipeline"
                  name="servlet/servletPipeline"
                  type="legoj.pipeline.servlet.ServletProcessorChain"/>

   <ResourceLink global="content/contentServices"
                  name="content/contentServices"
                  type="legoj.repository.content.services.ContentRepositoryServices"/>

   <ResourceLink global="targeting/targeterDirectory"
                  name="targeting/targeterDirectory"
                  type="legoj.targeter.TargeterDirectory"/>

   <ResourceLink global="content/renderedContentProviderDirectory"
                  name="content/renderedContentProviderDirectory"
                  type="legoj.content.provider.directory.RenderedContentProviderDirectory"/>

   <ResourceLink global="content/rankingService"
                  name="content/rankingService"
                  type="legoj.content.ranking.ContentRankingServices"/>


The rest is just spring components:
Something in Alfresco to push it's JCR or Foundation Services in to JNDI and somthing in the consumer to pull it down (like the code you shared)

When we push something in to JNDI it doesn't really look like we are to the application.  They are simply registering a service with a directory (which happens to expose the service in JNDI)

You are going to want to minimize the amount of JNDI knowledge.  Your end points don't want to know about JNDI … they probably want to talk to a directory or a registry of some sort … which has the JNDI knowlege.

Just some thoughts…. hope this is helpful…

raju_myadam
Champ in-the-making
Champ in-the-making
Hello Russ,

I have installed the alfresco-jcr-jndi-v5.zip and configured as per the instructions in both Tomcat and JBoss. When I try to run the I am getting following error in both servers-

Mar 25, 2008 3:20:45 PM org.alfresco.jcr.jndi.ProxyNonBlockingJndiJcrRepository login
SEVERE: underlying repository is null, cannot delegate activity

Do I need to do anything else? Please help me out.

Regards,
Raju

rdanner
Champ in-the-making
Champ in-the-making
I suspect there is an error further up stream in your error log –  the proxy isnt getting the handle to the underlying repository adapter – so either it hasn't been installed in alfresco properly, JNDI is being blocked by the naming jars in the distro, or there is some other error up stream.

raju_myadam
Champ in-the-making
Champ in-the-making
Thank for your reply.
I have installed as per the readme.txt for tomcat server.
1. Expose the prepository as a global resource (server.xml in tomcat):
<Resource name="jcr/baseRepository"
           scope="Shareable"
           auth="Container"
           type="javax.jcr.Repository"
           factory="org.alfresco.jcr.jndi.JndiJcrObjectFactory"
           jcrRepositoryName="baseAlfrescoRepository"/>
          

2. In the context.xml of the application that will consume the JCR: Note, no mention of alfresco          
   <ResourceLink global="jcr/baseRepository" name="jcr/baseRepository" type="javax.jcr.Repository"/>
3. put jcr-api-jndi-context.xml in WEB-INF\classes\alfresco\extension

Do I need to do anything else?

Regards,
Raju

raju_myadam
Champ in-the-making
Champ in-the-making
forgot to mention in my previous post. I am not seeing any errors in the log file.