Aug 18, 2008

Jackrabbit on JBoss with JNDI & RMI

We recently decided to use JCR, specifically, it's Apache implementation, JackRabbit. What's already done, is a web application running on Tomcat servlet container. One of the most obvious ways to tie those two, is to deploy JackRabbit on JBoss and expose it via JNDI.

Configuring JBoss Server


First, you need to download JBoss Application Server. Its installation in Ubuntu is as easy as extracting the downloaded jar/zip to the directory where you want JBoss to sit, and setting the JBOSS_HOME variable to that directory in ~/.bashrc.

To deploy JackRabbit, you need to obtain jackrabbit-jca.rar and jackrabbit-rmi.jar from JackRabbit downloads page and jcr-1.0.jar.

Note: The .rar archive contains all JackRabbit dependencies, including concurrent.jar.

You will also need to download the jcr-ds.xml. Edit the file so the <rar-name>jackrabbit-jca.rar</rar-name> property would contain the actual name of the rar you've downloaded (I had jackrabbit-jca-1.4.rar) and the homeDir property would point to the directory where you want JackRabbit to store its stuff.

To complete deployment, you now need to put jackrabbit-jca.rar, jackrabbit-rmi.jar and jcr-ds.xml files to $JBOSS_HOME/server/default/deploy and jcr-1.0.jar to $JBOSS_HOME/server/default/lib.

Note: Apparently, you should be careful about renaming the jcr-ds.xml file. I tried to name it “jcr-ds-1.4.xml” and kept getting JackRabbit deployed incompletely. Once I renamed it back to “jcr-ds.xml”, everything went smoothly.

To start JBoss, do $JBOSS_HOME/bin/run.sh.

Configuring Client


Now you might wanna check your JCR repository. You will need to create a simple function I found in the mail archive:

private static Session getJackrabbitSession() throws RepositoryException {
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL, "jnp://localhost:1099");
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");

try {
InitialContext ctx = new InitialContext(env);
ClientAdapterFactory adapter = new ClientAdapterFactory();
RemoteRepository rr;
rr = (RemoteRepository) ctx.lookup("jnp://localhost:1099/jcrServer");
Repository repository = adapter.getRepository(rr);
Credentials credJBoss = new SimpleCredentials("username", "password".toCharArray());
return repository.login(credJBoss);
} catch (NamingException ex) {
ex.printStackTrace();
}

return null;
}


For that code to work, you will need jcr-1.0.jar, jackrabbit-jcr-rmi.jar, jnp-client.jar and jboss-common.jar libraries in your classpath. The latter two can be found in $JBOSS_HOME/client and $JBOSS_HOME/lib respectively.

If you've done everything correct, and are lucky enough, the “first hops” from Jackrabbit introduction should work fine, with appropriate changes to obtaining Session object done.

6 comments:

steven said...

can i change the 'homeDir' of jcr-ds.xml to point to a remote location which requires user authentication?

sp said...

I'm afraid I can't help you with that at the moment, so you have to wait until someone replies in the Jackrabbit mailing list.

chochis said...

Jboss deployable filenames are a littlebit tricky, because it really works with extensions, so, if, 1.4 seems bad for jboss (because of course it doesnt end with .xml). So should use 1-4.xml instead.

sp said...

Thanks for comment, chochis.

I had my "jcr-ds" file named "jcr-ds-1.4.xml", so either JBoss is searching for the first dot from the start of the name, (which looks more like a bug to me), or I'm not understanding something correctly (:

Zakir said...

For data sources jboss expect -ds.xml in the end of file name, so *-ds.xml can be deployed as a data source. In other words jcr-1.4-ds.xml can be deployed where as jcr-ds-1.4.xml won't

Nomis said...

thanks for snippet, I tried it with JKR 1.6.0 and Jboss 5 which I got to work with some simple changes to the jars included on the client side.

instead of jboss-common.jar which has the Logger class use jboss-logging-spi.jar
and also include jackrabbit-api-1.6.0.jar, also note that jackrabbit-jcr-rmi-1.5.0.jar should be used I don't think 1.6.0 is part of the 1.6.0 release.