Hello,
I'm new to Jackrabbit, so the first thing I'm trying to do is put
together a Model-2 (shared J2EE resource) deployment on Tomcat 5.5
and an example webapp (servlet) that confirms the deployment has been
correctly configured. I figured this would be a good way for me to
get acquainted with using Jackrabbit, and possibly provide an example
that could be distributed by the project. Unfortunately, I haven't
gotten very far.
Following the instructions on the website for the Resource
configuration, I've added the following lines to my $TOMCAT_HOME/conf/
server.xml:
======= Begin Tomcat server.xml =======
<GlobalNamingResources>
...
<Resource name="jcr/globalRepository"
auth="Container"
type="javax.jcr.Repository"
factory="org.apache.jackrabbit.core.jndi.BindableRepositoryFactory"
configFilePath="conf/repository.xml"
repHomeDir="shared/jackrabbit" />
...
</GlobalNamingResources>
======= End Tomcat server.xml =======
And I've added this configuration to the <test-app>/WEB-INF/web.xml:
======= Begin web app web.xml =======
<resource-env-ref>
<description>Jackrabbit Repository</description>
<resource-env-ref-name>jcr/globalRepository</resource-env-
ref-name>
<resource-env-ref-type>javax.jcr.Repository</resource-env-
ref-type>
</resource-env-ref>
======= End web app web.xml =======
Next, I tried creating a <test-app>/WEB-INF/context.xml file that
looks like this:
======= Begin web app context.xml =======
<Context>
<ResourceLink
glabal="jcr/globalRepository" name="jcr/globalRepository"
type="javax.jcr.Repository" />
<Manager pathname="" />
</Context>
======= End web app context.xml =======
However, when I run my servlet, I get:
javax.naming.NamingException: Cannot create resource instance
at org.apache.naming.factory.ResourceEnvFactory.getObjectInstance
(ResourceEnvFactory.java:99)
at javax.naming.spi.NamingManager.getObjectInstance
(NamingManager.java:304)
at org.apache.naming.NamingContext.lookup(NamingContext.java:792)
at org.apache.naming.NamingContext.lookup(NamingContext.java:139)
at org.apache.naming.NamingContext.lookup(NamingContext.java:780)
at org.apache.naming.NamingContext.lookup(NamingContext.java:152)
at edu.ucsc.whisper.jackrabbit_test.JackrabbitTest.doGet
(JackrabbitTest.java:100)
....
So, I tried using the $TOMCAT_HOME/conf/context.xml, and made it look
like this:
======= Begin Tomcat context.xml =======
<!-- The contents of this file will be loaded for each web
application -->
<Context>
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<ResourceLink
glabal="jcr/globalRepository" name="jcr/globalRepository"
type="javax.jcr.Repository" />
<!-- Uncomment this to disable session persistence across Tomcat
restarts -->
<!--
<Manager pathname="" />
-->
</Context>
======= End Tomcat context.xml =======
That works better, in that I don't get an exception. Instead the
lookup() request returns null.
The servlet code currently looks like this:
======= Begin source code =======
public void doGet( HttpServletRequest request,
HttpServletResponse response )
throws IOException, ServletException
{
boolean skipping = false;
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Jackrabbit Configuration Testing</title>");
out.println("</head>");
out.println("<body>");
if( !skipping )
{
out.println("<h3>Getting the Jackrabbit reference via
JNDI</h3>");
try
{
// Get the initial context
Context initialContext = new InitialContext();
out.println( "<p>Got initial context</p>" );
NamingEnumeration<NameClassPair> contextEntries = null;
contextEntries = initialContext.list( "java:comp/
env" );
// snip - printing entries
contextEntries = initialContext.list( "java:comp/env/
jcr" );
// snip - printing entries
// Get the environment context
Context environmentContext = (Context)
initialContext.lookup( "java:comp/env" );
out.println( "<p>Got environment context</p>" );
contextEntries = environmentContext.list( "/" );
// snip - printing entries
contextEntries = environmentContext.list( "/jcr" );
// snip - printing entries
// get values out of the context.
jackrabbitRepository =
(Repository) environmentContext.lookup( "jcr/
globalRepository" );
out.println( "<p>jackrabbitRepository = " +
jackrabbitRepository + "</p>" );
}
catch( Exception e )
{
out.println("<p>Exception thrown: <pre>" );
e.printStackTrace( out );
out.println("</pre></p>");
}
}
out.println("</body>");
out.println("</html>");
}
======= End source code =======
And the web page generated looks like this:
======= Begin HTML output =======
Getting the Jackrabbit reference via JNDI
Got initial context
Entries in java:comp/env:
jcr: org.apache.naming.NamingContext
Entries in java:comp/env/jcr:
globalRepository: org.apache.naming.ResourceLinkRef
Got environment context
Entries in /:
jcr: org.apache.naming.NamingContext
Entries in /jcr:
globalRepository: org.apache.naming.ResourceLinkRef
jackrabbitRepository = null
======= End HTML output =======
So I can see the reference to Jackrabbit is there, but I'm not able
to get it. Perhaps the BindableRepositoryFactory is returning a null
repository? For all I know, this is a JNDI issue with Tomcat. Even
the author of http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-
examples-howto.html seems to have had trouble configuring a
PostgreSQL data source to be global. But if anybody could suggest a
way of debugging this, or flat out knows what the problem is, I'd
love some help. Of course, if such an example already exists
someplace, that'd be great to know too. I found the First Steps
example, but that uses an embedded version... I'm intending to code
essentially the same example, but as a servlet that includes output
showing the success or failure of the various steps (which will
hopefully give users an indication of where their configuration has
failed).
Thanks,
Mark