13 Replies Latest reply: Aug 31, 2011 1:15 PM by Danny C RSS

Problem with Jcr 2.0 style of looking up Repository instance using JNDI

Danny C Newbie

Hi ,

 

      I am using Modeshape-2.6.0-Beta2 and currently testing using Glassfish V3.1.1 with a Web App and having problem of looking up Repository instance using the following code with error dump. This error is similar to a last year forum dicussion ( http://community.jboss.org/thread/155998 ) but not sure if it has been fixed or it is a new issue. Anybody, appreciate your help . Thanks in advance.

 

Note:

Under the same environment, have tested the following of obtaining Repository instance:


1. Using jcr 1.0 style - OK

eg.

InitialContext initCtx = new InitialContext();

Context envCtx = (Context) initCtx.lookup("java:comp/env");

Repository repository = (Repository) envCtx.lookup("jcr/local");

 

2. Using CDI injection using Seam-Jcr-3.0.0-Alpha2 - OK

eg. 

@Inject 

@JcrConfiguration(name = "org.modeshape.jcr.URL", value = "file:///C:/test/configRepository.xml?repositoryName=Cars")

Repository repository;

 

3. Using jcr 2.0 style

OK if using  ->  configUrl = "file:///C:/test/configRepository.xml?repositoryName=Cars";

Fail if using -> configUrl = "jndi:jcr/local?repositoryName=Cars";


* Codes is shown below*

 

 

web.xml

=============================================================================================

<resource-env-ref>

    <description>Repository</description>

    <resource-env-ref-name>jcr/local</resource-env-ref-name>

    <resource-env-ref-type>javax.jcr.Repository</resource-env-ref-type>

</resource-env-ref>

 

 

 

[Glassfish]\domains\domain1\config\domain.xml

=============================================================================================

<custom-resource res-type="javax.jcr.Repository"  jndi-name="jcr/local" factory-class="org.modeshape.jcr.JndiRepositoryFactory">

    <property name="repositoryName" value="Cars"></property>

    <property name="auth" value="Container"></property>

    <property name="configFile" value="configRepository.xml"></property>

</custom-resource>

 

 

 

Codes

=============================================================================================

String configUrl = "jndi:jcr/local?repositoryName=Cars";

Map<String, String> parameters = Collections.singletonMap("org.modeshape.jcr.URL", configUrl);

 

//Getting Repository via Repository Factory - jcr 2.0 style

for (RepositoryFactory factory : ServiceLoader.load(RepositoryFactory.class)) {

     System.out.println("Trying to load Repository #" + i++ + " using: " + factory.toString()); //for debug

     repository = factory.getRepository(parameters);

      if (repository != null) {

                    break;

     }

}

 

System.out.println("Repository = " + repository); <----------------------factory.getRepository(parameters) actually return NULL over here !

session = repository.login(); <----------------------FAIL ! Program stop here mainly because repository is NULL (Pls refer to Errors dump below)

 

 

 

 

Errors

=============================================================================================

INFO: Trying to load Repository #1 using: org.modeshape.jcr.JcrRepositoryFactory@74a7e7

INFO: JcrEngine starting...

INFO: JcrEngine started in 3681 ms

INFO: Completed starting the "Cars" repository

INFO: Repository = null    <--------------------- It seem like Cars repository started but the factory return a NULL repository, not sure why ?

WARNING: StandardWrapperValve[test1]: PWC1406: Servlet.service() for servlet test1 threw exception

java.lang.NullPointerException

    at test.Test1.testJndiLookup(Test1.java:144)

    at test.Test1.processRequest(Test1.java:90)

    at test.Test1.doGet(Test1.java:299)

    at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)

    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)

    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)

    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)

    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)

    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)

    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)

    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)

    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)

    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)

    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)

    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)

    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)

    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)

    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)

    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)

    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)

    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)

    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)

    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)

    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)

    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)

    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)

    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)

    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)

    at java.lang.Thread.run(Thread.java:722)

  • 1. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Randall Hauch Master

    I pretty sure we fixed that issue, but I can't find the JIRA issue for it (and it's not referenced in the forums). I've logged a new one (see MODE-1242) and this will get fixed today and will be the upcoming 2.6.0.Final release.

     

    I also see that there's some confusion over the difference between putting a single Repository instance in JNDI (which is what the JCR 1.0 style usage expects, and what the JndiRepositoryFactory class does) vs putting the ModeShape engine into JNDI (which is what the JCR 2.0 style of RepositoryFactory expects). That means that JndiRepositoryFactory shouldn't be used with the JCR 2.0 style of lookup. I've logged another JIRA (see MODE-1243) to change JndiRepositoryFactory to be register the engine if no "repositoryName" property is specified.

     

    When 2.6.0.Final comes out, you'd be able to use JndiRepositoryFactory to register the engine in JNDI:

     

    <custom-resource res-type="javax.jcr.Repository"  jndi-name="jcr/local" factory-class="org.modeshape.jcr.JndiRepositoryFactory">
        <property name="auth" value="Container"></property>
        <property name="configFile" value="configRepository.xml"></property>
    </custom-resource>
    

     

    and then use the RepositoryFactory approach to find the repository using JCR 2.0-style lookups:

     

    String configUrl = "jndi:jcr/local?repositoryName=Cars";  // URL to engine, with named repository
    Map<String, String> parameters = Collections.singletonMap("org.modeshape.jcr.URL", configUrl);
    
    for (RepositoryFactory factory : ServiceLoader.load(RepositoryFactory.class)) {
        repository = factory.getRepository(parameters);
        if (repository != null) break;
    }
    

     

    Of course, you'll still be able to register a particular Repository in JNDI:

     

    <custom-resource res-type="javax.jcr.Repository"  jndi-name="jcr/local/Cars" factory-class="org.modeshape.jcr.JndiRepositoryFactory">
        <property name="repositoryName" value="Cars"></property>
        <property name="auth" value="Container"></property>
        <property name="configFile" value="configRepository.xml"></property>
    </custom-resource>
    

     

    and still use either JCR 1.0-style lookups:

     

    InitialContext initCtx = new InitialContext();
    Context envCtx = (Context) initCtx.lookup("java:comp/env");
    Repository repository = (Repository) envCtx.lookup("jcr/local");
    

     

    and/or JCR 2.0-style lookups:

     

    String configUrl = "jndi:jcr/local/Cars"; // URL to repository
    Map<String, String> parameters = Collections.singletonMap("org.modeshape.jcr.URL", configUrl);
    
    for (RepositoryFactory factory : ServiceLoader.load(RepositoryFactory.class)) {
        repository = factory.getRepository(parameters);
        if (repository != null) break;
    }
    

     

    In the meantime, there are a couple of things you can do until 2.6.0.Final comes out:

     

    1) Use the JCR 1.0-style of lookup with the JndiRepositoryFactory; or

     

    2) Use the JCR 2.0-style of lookup, but use a custom "javax.naming.spi.ObjectFactory" implementation to register the ModeShape engine in JNDI. I'll commit my fix for MODE-1243 today, and will add a link to the updated JndiRepositoryFactory class if you want to copy and use it before 2.6.0.Final comes out. Note, however, that you won't be able to use JCR 1.0-style lookups with this approach until 2.6.0.Final comes out.

     

    Hope this helps!

  • 2. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Randall Hauch Master

    Fixes for MODE-1242 and MODE-1243 were committed into the 'master' branch and will be in the upcoming 2.6.0.Final release.

     

    In the meantime, here are the changes that I made to the JndiRepositoryFactory class to register the engine in JNDI if the repository name is not provided. (The full file is here.)

     

    If you'd like to try this fix before 2.6.0.Final is available, then

     

    1) copy, compile and place this updated class on your classpath

     

    2) change the "conf/context.xml" fragment to this:

     

    <Resource name="jcr/local" 
              auth="Container"
              type="org.modeshape.jcr.api.Repositories"
              factory="org.modeshape.jcr.JndiRepositoryFactory"
              configFile="/resource/path/to/configuration.xml" />
    

     

    and make sure your application's "web.xml" file contains this:

     

    <resource-env-ref>
       <description>ModeShape Engine</description>
       <resource-env-ref-name>jcr/local</resource-env-ref-name>
       <resource-env-ref-type>org.modeshape.jcr.api.Repositories</resource-env-ref-type>
    </resource-env-ref>
    

     

    Your application can then use the JCR-2.0-style of looking up references:

     

    String configUrl = "jndi:jcr/local?repositoryName=Cars";  // Note this URL!
    Map<String, String> parameters = Collections.singletonMap("org.modeshape.jcr.URL", configUrl);
    for (RepositoryFactory factory : ServiceLoader.load(RepositoryFactory.class)) {
        repository = factory.getRepository(parameters);
        if (repository != null) break;
    }
    

     

    d) if you also want to use the JCR-1.0-style lookups, you add the following to the "conf/context.xml" file:

     

    <Resource name="jcr/local/Cars" 
              auth="Container"
              type="javax.jcr.Repository"
              factory="org.modeshape.jcr.JndiRepositoryFactory"
              configFile="/resource/path/to/configuration.xml"
              repositoryName="Cars" />
    

     

    and add this to your application's "web.xml":

     

    <resource-env-ref>
       <description>Repository</description>
       <resource-env-ref-name>jcr/local/Cars</resource-env-ref-name>
       <resource-env-ref-type>javax.jcr.Repository</resource-env-ref-type>
    </resource-env-ref>
    

     

    Your application can then find the JCR repository in JNDI directly:

     

    InitialContext initCtx = new InitialContext();
    Context envCtx = (Context) initCtx.lookup("java:comp/env");
    Repository repository = (Repository) envCtx.lookup("jcr/local/Cars");
    

     

     

    When 2.6.0.Final comes out and you're registering Repository instances directly, you'll also be able to use the JCR-2.0-style of looking up Repository instances directly:

     

    String configUrl = "jndi:jcr/local/Cars";  // Note this URL!
    Map<String, String> parameters = Collections.singletonMap("org.modeshape.jcr.URL", configUrl);
    for (RepositoryFactory factory : ServiceLoader.load(RepositoryFactory.class)) {
        repository = factory.getRepository(parameters);
        if (repository != null) break;
    }
    

     

     

    Hope this helps!

  • 3. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Danny C Newbie

    Hi Randall,

     

    Thank for your quick fix, I will try out the new class and config, really waiting forward for this "jndi:jcr/local/Cars" .Will update here later. Thanks.

  • 4. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Danny C Newbie

    Hi Randall,

     

    I have rebuilt Modeshape Jars using the latest Modeshape source Git-clone today. Using Jcr-2.0 style, the repository return is still NULL . Below is the result codes run inside a servlet with Glassfish 3.1.1:

     

     

    web.xml (Changes after MODE-1242 and MODE-1243)

    =============================================================================================

    <resource-env-ref>

        <description>Repository</description>

        <resource-env-ref-name>jcr/local</resource-env-ref-name>

        <resource-env-ref-type>org.modeshape.jcr.api.Repositories</resource-env-ref-type>

    </resource-env-ref>

     

     

    [Glassfish]\domains\domain1\config\domain.xml (Changes after MODE-1242 and MODE-1243)

    =============================================================================================

    <custom-resource res-type="org.modeshape.jcr.api.Repositories" description="Modeshape-Latest" jndi-name="jcr/local" factory-class="org.modeshape.jcr.JndiRepositoryFactory">

        <property name="auth" value="Container"></property>

        <property name="configFile" value="configRepository.xml"></property>

    </custom-resource>

     

    Codes

    =============================================================================================

    String configUrl = "jndi:jcr/local?repositoryName=Cars";

    Map<String, String> parameters = Collections.singletonMap("org.modeshape.jcr.URL", configUrl);

     

    //Getting Repository via Repository Factory - jcr 2.0 style

    for (RepositoryFactory factory : ServiceLoader.load(RepositoryFactory.class)) {

         System.out.println("Trying to load Repository #" + i++ + " using: " + factory.toString()); //for debug

         repository = factory.getRepository(parameters);

          if (repository != null) {

                        break;

         }

    }

     

    Errors

    =============================================================================================

    INFO: Trying to load Repository #1 using: org.modeshape.jcr.JcrRepositoryFactory@1b55e4e

    INFO: JcrEngine starting...

    INFO: JcrEngine started in 3461 ms

    INFO: Repository = null

    SEVERE: java.lang.NullPointerException

        at test.Test1.testContextLookup2(Test1.java:201)

        at test.Test1.processRequest(Test1.java:103)

        at test.Test1.doGet(Test1.java:642)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

        at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)

        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)

        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)

        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)

        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)

        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)

        at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)

        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)

        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)

        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)

        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)

        at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)

        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)

        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)

        at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)

        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)

        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)

        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)

        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)

        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)

        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)

        at com.sun.grizzly.ContextTask.run(ContextTask.java:71)

        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)

        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)

        at java.lang.Thread.run(Thread.java:722)

  • 5. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Danny C Newbie

    Hi Randall,

     

    I am using the latest Modeshape source Git-clone 25 Aug 2011 (Not Modeshape-2.6.0-b2) and maven3 build the binary after MODE-1243 & MODE-1242 commited, below is the summary of testing:

     

    1. Using JCR 2.0 Style   -  The error is : factory.getRepository(parameters) return a NULL repository instance

        * As shown in previous discussion entry *

     

    2. Using JCR 1.0 Style   -  The error is : Error starting the "Cars" repository (check the configuration)

        * As shown below *

     

    * Pls noted, just to simplify testing,  I am doing both Jcr 1.0 and Jcr 2.0 testing using only a single JNDI named jcr/local in which I am switching back and forth between Jcr 1.0 and Jcr2.0 style by changing the necessary entries inside web.xml and domain.xml and the Glassfish is restarted everytime and then the web test app is redeployed everytime before each test result is obtained.

     

           I am not sure if this is a isolated case only happen with Glassfish 3.1.1 or what. I haven't test it with Jboss As 7.0.0-Final. Need more time to migrate everything to Jboss World as I am currently using Netbean 7.0.1 and Glassfish 3.1.1.

     

    Pls help. Thank in advance.

     

     

    web.xml

    =============================================================================================

    <resource-env-ref>

            <description>Repository</description>

            <resource-env-ref-name>jcr/local</resource-env-ref-name>

            <resource-env-ref-type>javax.jcr.Repository</resource-env-ref-type>

    </resource-env-ref>

     

    [Glassfish]\domains\domain1\config\domain.xml

    =============================================================================================

    <custom-resource res-type="javax.jcr.Repository" description="Modeshape" jndi-name="jcr/local" factory-class="org.modeshape.jcr.JndiRepositoryFactory">

        <property name="repositoryName" value="Cars"></property>

        <property name="auth" value="Container"></property>

        <property name="configFile" value="configRepository.xml"></property>

    </custom-resource>

     

     

    Codes

    =============================================================================================

         InitialContext initCtx = new InitialContext();

         Context envCtx = (Context) initCtx.lookup("java:comp/env");

         Repository repository = (Repository) envCtx.lookup("jcr/local");

     

     

    Errors

    =============================================================================================

    INFO: JcrEngine starting...

    INFO: JcrEngine started in 2723 ms

    SEVERE: javax.naming.CommunicationException: Communication exception for SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming, com.sun.enterprise.naming.logicalName=java:comp/env/jcr/local} [Root exception is javax.jcr.RepositoryException: Error starting the "Cars" repository (check the configuration): Error starting the "Cars" repository (check the configuration): org/modeshape/search/lucene/IndexRules$Factory]

        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:542)

  • 6. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Danny C Newbie

    Hi Randall,

     

         Finally, looking up repository instance with both Jcr 1.0 and Jcr 2.0 style work OK after including the following libraries from the latest Modeshape 2.6 source build ie: [Modeshape 2.6 Source]\deploy\jbossas\modeshape-jbossas-web-rest-war\target\modeshape-test\WEB-INF\lib

     

    - lucene-core-3.1.0.jar

    - lucene-analyzers-3.1.0.jar

    - lucene-regex-3.0.3.jar

    - lucene-misc-3.1.0.jar

    - modeshape-cnd-2.6-SNAPSHOT.jar

     

    1. Using JCR 1.0 Style - OK

        - Previously , while running using jcr 1.0 style, it gives some hints of missing lucene & cnd library.


    2. Using JCR 2.0 Style - OK

        - Previously , while running using jcr 2.0 style, no hints of missing lucene & cnd library. Perhaps the exceptions has been suppressed.

     

       *** Behavior Observed ***

          For JCR 2.0 Style, one behavior observed is that if we exclude the "repositoryName" property from Server's "conf/context.xml" file then we can look up which repository instance we want using "jndi:jcr/local?repositoryName=MyRepo" or "jndi:jcr/local?repositoryName=MyRepo2" and so on.

    .

          If we somehow include the "repositoryName" property inside Server's "conf/context.xml" file, then the "MyRepo" defined with "jndi:jcr/local?repositoryName=MyRepo" will just be ignored and the JcrEngine will start and return only the repository instance defined inside "repositoryName" property inside the "conf/context.xml" file . Furthermore, if we try to include a non existing repository with the "repositoryName" property inside the "conf/context.xml" file, the JcrEngine will return a null repository no matter if "jndi:jcr/local?repositoryName=MyRepo" does really exist. That mean the "repositoryName" property inside Server's "conf/context.xml" file (If included) , will always take precedence over  "jndi:jcr/local?repositoryName=MyRepo"

     

     


  • 7. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Randall Hauch Master

          If we somehow include the "repositoryName" property inside Server's "conf/context.xml" file, then the "MyRepo" defined with "jndi:jcr/local?repositoryName=MyRepo" will just be ignored and the JcrEngine will start and return only the repository instance defined inside "repositoryName" property inside the "conf/context.xml" file . Furthermore, if we try to include a non existing repository with the "repositoryName" property inside the "conf/context.xml" file, the JcrEngine will return a null repository no matter if "jndi:jcr/local?repositoryName=MyRepo" does really exist. That mean the "repositoryName" property inside Server's "conf/context.xml" file (If included) , will always take precedence over  "jndi:jcr/local?repositoryName=MyRepo"

    IIUC, you're suggesting that you can't have these two fragments inside the server's "conf/context.xml" file?

     

     

    <Resource name="jcr/local" 
              auth="Container"
              type="org.modeshape.jcr.api.Repositories"
              factory="org.modeshape.jcr.JndiRepositoryFactory"
              configFile="/resource/path/to/configuration.xml" />
    

     

    and

     

    <Resource name="jcr/local/Cars" 
              auth="Container"
              type="javax.jcr.Repository"
              factory="org.modeshape.jcr.JndiRepositoryFactory"
              configFile="/resource/path/to/configuration.xml"
              repositoryName="Cars" />
    

     

    because if you do then JCR-2.0-style RepositoryFactory lookups (which depend on the first one and use a URI like "jndi:jcr/local?repositoryName=MyRepo") will not work?

  • 8. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Danny C Newbie

    No, I am talking about only a Single fragment inside the server conf/context file using only the JCR 2.0 style (Not using both Jcr 1.0 + Jcr 2.0 style together as mentioned)

     


    1.) Let say if we have the following fragment WITHOUT the repositoryName="SomeRepo":

     

    <Resource name="jcr/local"
              auth="Container"
              type="org.modeshape.jcr.api.Repositories"
              factory="org.modeshape.jcr.JndiRepositoryFactory"
              configFile="/resource/path/to/configuration.xml" />

     

    Then the below sample jndi lookup inside our codes using serviceloader work OK as expected :

     

    "jndi:jcr/local?repositoryName=MyRepo1"     //For this we got MyRepo1

    "jndi:jcr/local?repositoryName=MyRepo2"     //For this we got MyRepo2

    "jndi:jcr/local?repositoryName=OtherRepo"   //and so on...

     

     

    2.) Let say if we have the following fragment WITH the repositoryName="SomeRepo":

    <Resource name="jcr/local"
              auth="Container"
              type="org.modeshape.jcr.api.Repositories"
              factory="org.modeshape.jcr.JndiRepositoryFactory"
              configFile="/resource/path/to/configuration.xml"

              repositoryName="SomeRepo" />


    Then whatever repository name defined in our jndi lookup codes eg. "jndi:jcr/local?repositoryName=MyRepo1" has no effect at all, and the Factory always return us the  "SomeRepo" repository. Furthermore, if "SomeRepo" is invalid, the Factory simply return us NULL repository. We won't get "MyRepo1".

     

     

        Of course, we can happily just exclude the repositoryName="SomeRepo" inside the fragment, then our Jndi lookup code will always work OK but I am not sure if this is the intended planned repository lookup behavior.

  • 9. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Randall Hauch Master

    1.) Let say if we have the following fragment WITHOUT the repositoryName="SomeRepo":

     

    <Resource name="jcr/local"
              auth="Container"
              type="org.modeshape.jcr.api.Repositories"
              factory="org.modeshape.jcr.JndiRepositoryFactory"
              configFile="/resource/path/to/configuration.xml" />

     

    Then the below sample jndi lookup inside our codes using serviceloader work OK as expected :

     

    "jndi:jcr/local?repositoryName=MyRepo1"     //For this we got MyRepo1

    "jndi:jcr/local?repositoryName=MyRepo2"     //For this we got MyRepo2

    "jndi:jcr/local?repositoryName=OtherRepo"   //and so on...

     

    Good. This is as expected/designed, because it is registering the ModeShape engine in JNDI at "jcr/local". You should use this style of fragment if and only if your application is using the JCR 2.0-style lookup of Repository instances (using the ServiceLoader and RepositoryFactory).

     

    2.) Let say if we have the following fragment WITH the repositoryName="SomeRepo":

    <Resource name="jcr/local"
              auth="Container"
              type="org.modeshape.jcr.api.Repositories"
              factory="org.modeshape.jcr.JndiRepositoryFactory"
              configFile="/resource/path/to/configuration.xml"

              repositoryName="SomeRepo" />


    Then whatever repository name defined in our jndi lookup codes eg. "jndi:jcr/local?repositoryName=MyRepo1" has no effect at all, and the Factory always return us the  "SomeRepo" repository. Furthermore, if "SomeRepo" is invalid, the Factory simply return us NULL repository. We won't get "MyRepo1".

     

    This fragment registers the repository named "SomeRepository" in JNDI at "jcr/local". This means that any JNDI URI beginning with "jndi:jcr/local" will always return the "SomeRepository" repository because that is what is registered at "jcr/local".

     

    You should use this style of fragment if and only if your application is going to use the JCR 1.0-style of lookup - that is, look in JNDI for a specific Repository instance at the given location.

     

    If your application(s) want to use both, then you should be able to use both styles of fragments, but beware the "name" value (e.g., the JNDI location) in the second form should be unique. Note that in your two examples above, both fragments are registering different objects at "jcr/local", and if both fragments were indeed used then I'd suggest changing the "name" property of the second fragment to have a value of "jcr/local/SomeRepo". (If you look closely at my earlier reply, you'd see that the first-style fragment is registering the engine at "jcr/local" and the second-style fragment is registering the "Cars" repository at "jcr/local/Cars".)

     

    I apologize if my earlier instructions didn't make this clear and resulted in a lot of extra work for you!

     

    Best regards.

  • 10. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Danny C Newbie

    Hi Randall,

     

        Actually your earlier instructions is indeed very clear showing that for JCR 2.0 style, there is no  repositoryName="SomeRepo" needed in the fragment. It is just that during the testing, I purposely put that repositoryName="" and observing the behavior which I am sharing here. No Big deal.  Our current focus is using Jcr 2.0 style only. So, the rule of thumb is for Jcr 2.0 style, we better forget the repositoryName property inside the fragment unless we would like to fix the repository at the system side.  Thanks.

  • 11. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Randall Hauch Master

    It is just that during the testing, I purposely put that repositoryName="" and observing the behavior which I am sharing here.

    Gotcha.

     

    I do have to say that the code I recently put into our JndiRepositoryFactory could be doing something a bit different. Right now, it is returning the Repository instance (which will be registered into JNDI) if and only if the repositoryName contains at least one non-whitespace character (see starting on line 194). However, if the repositoryName is null or empty or contains only whitespace, we always return the engine.

     

    I've reopened MODE-1243 to look at the "type" property to determine whether to return a (possibly null) Repository object or the engine (regardless of the value of the "repositoryName", which should only be used if the "type" property is "javax.jcr.Repository").

     

    Thanks for helping to clarify what this behavior should be.

  • 12. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Randall Hauch Master

    I just committed another round of improvements to the JndiRepositoryFactory (for MODE-1243). I think these changes improve the logic and the additional log messages should hopefully help out when the JNDI factory is mis-configured.

     

    Now, if the "type" is "javax.jcr.Repository", the factory always tries to register a repository instance, and it verifies that the "repositoryName" value matches an existing repository in the engine; an error message is logged if the "repositoryName" is missing or names a non-existant repository.

     

    If the "type" value is "org.modeshape.jcr.api.Repositories", the engine will always be registered; a warning will be logged if a "repositoryName" is specified.

     

    If no "type" value is specified (after all, it really is required), then a warning stating such is logged and the factory will register a repository if and only if the "repositoryName" property is specified; otherwise, the engine is registered in JNDI.

     

    Again, please note that it is possible to have multiple fragments to register the engine and/or multiple repositories. Just be sure that you're using different JNDI names for each of the fragments!

  • 13. Re: Problem with Jcr 2.0 style of looking up Repository instance using JNDI
    Danny C Newbie

       Using a new "type" property to select if we want a "Engine" or "Repository Instance" returned by the Factory has made everythings clear and flexible. I have just rebuilt using latest Modeshape 2.6.0 source and tested for each scenarios mentioned above using Jcr 2.0 style and it all work OK with proper logging messages. Thanks.