Hello again,
Exposing a resource with JNDI is not trivial, especially with Tomcat. Here's
my recipe to globally expose a single Repository in Tomcat 6 (can't tell for
Tomcat 7) - by the way, "global" exposure means to all deployed webapps, but
only inside Tomcat. External applications will have to use a communication
protocol like RMI or DAV.
In server.xml, define a global resource [1] :
<GlobalNamingResources>
<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" />
<Resource name="JCR" auth="Container" type="javax.jcr.Repository"
factory="org.apache.jackrabbit.core.jndi.BindableRepositoryFactory"
configFilePath="/opt/jackrabbit/repository.xml"
repHomeDir="/opt/jackrabbit/repository" />
</GlobalNamingResources>
In context.xml (global in Tomcat conf directory, or in your webapp's
META-INF directory), tells Tomcat to make the global resource available to
the webapp [2] :
<Context>
<ResourceLink name="JCR" global="JCR" type="javax.jcr.Repository"/>
</Context>
In your application's web.xml, add a resource reference. Beware, there's a
trap, notice the java:comp/env/ before the resource name !
<resource-ref>
<res-ref-name>java:comp/env/JCR</res-ref-name>
<res-type>javax.jcr.Repository</res-type>
<res-auth>Container</res-auth>
</resource-ref>
And finally, lookup the Repository. I prefer using Spring for this :
<bean id="repository"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/JCR</value>
</property>
</bean>
But a classic Java JNDI call will do as well [3].
[1] http://tomcat.apache.org/tomcat-6.0-doc/config/globalresources.html
[2] http://tomcat.apache.org/tomcat-6.0-doc/config/context.html#Resource
Links
[3]
http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html#Using_resources
On Mon, Aug 1, 2011 at 6:39 PM, Francisco Carriedo Scher <
[email protected]> wrote:
> Hi there,
>
> i have a JR repository up and running and now i want to obtain the (already
> running) repository instance through JNDI to use it through simple Java
> classes in other projects. By default the repository is available through
> JNDI only locally to the webapp, which is not enough for my case.
>
> Now, i followed the instructions to turn it globally available (even simple
> Java applications running out of the Tomcat 7 server i am using) without
> success. Note that I followed the Tomcat 7 instructions to enable JNDI
> resources aswell.
>
> I paste here the relevant pieces of code for this issue:
> *
> Context.xml (Tomcat 7 server)*
>
> <Resource name="repositoryname" auth="Container"
> type="javax.jcr.Repository"
>
>
> factory="org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory"
> />
>
> Web.xml (Web application)
>
> <resource-env-ref>
> <description>Object Factory for the Repository</description>
> <resource-env-ref-name>repositoryname</resource-env-ref-name>
> <resource-env-ref-type>javax.jcr.Repository</resource-env-ref-type>
> </resource-env-ref>
>
> *bootstrap.properties*
>
> # Repository configuration settings (will be adjusted by installer)
>
> repository.config=/dev/raizrepositorio/repository.xml
> repository.home=/dev/raizrepositorio/repository
> #repository.name=jackrabbit.repository
> repository.name=repositoryname
>
> # RMI Settings
> rmi.enabled=true
> rmi.port=0
> rmi.host=localhost
> # If the URI is not specified, it's composed as follows:
> #rmi.uri=//${rmi.host}:${rmi.port}/${repository.name}
>
> # JNDI Settings
> # all properties starting with 'java.naming.' will go into the
> # environment of the initial context
> jndi.enabled=true
> # if the name is not specified, it's initialized with the repository.name
> #jndi.name=${repository.name}
> jndi.name=repositoryname
> java.naming.provider.url=jnp://localhost:1099
>
> java.naming.factory.initial=org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory
>
>
> *Plain Java class trying to obtain the Repository object through JNDI*
>
> Hashtable env = new Hashtable();
> env.put(Context.PROVIDER_URL, "jnp://localhost:1099");
> env.put(Context.INITIAL_CONTEXT_FACTORY,
> "org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory");
>
> Context initCtx = new InitialContext(env);
> Context envCtx = (Context) initCtx.lookup("java:comp/env");
> Repository repo = (Repository) envCtx.lookup("repositoryname");
>
>
> Any clue on how to detect what is going wrong (object not registered in
> JNDI
> directory, object not correctly requested, initial misconfigured
> context...).
>
> By the way, i assume that the retrieved object will be the initialized
> instance created as the JR webapp is fired up, isn't it?
>
>
> Thanks in advance for your attention!
>
>
> P.S.: for those who paid attention to my previous emails to this list: the
> answer is comming, it is not trivial to write, so it will still take a
> little bit, but will come because i find my case helpfull for other
> newbies.
> I thank you all once more!
>