This document describes how to
Deploy Jackrabbit on JBoss with JCA.
Expose the local repository through JNDI and WEBDAV to remote clients.
Access the repository from session beans
Access the repository remotely from a java program, or from a command line tool (contrib/jcr-commands).
Feel free to make changes to this document.
Security
A separate document for security is located under JackrabbitOnJbossSecurity
Custom access manager when using Jboss for security is referenced at SimpleJbossAccessManager
Deploy Jackrabbit with JCA
Checkout a tagged jca-connector release with subversion. For example, from
http://svn.apache.org/repos/asf/jackrabbit/tags/1.2.3/jackrabbit-jca/. If you have not done so already, download the jcr library from sun at
http://jcp.org/aboutJava/communityprocess/final/jsr170/index.html. Install the jar in your maven repository (type mvn install and follow the instructions in the error message).
Edit the pom.xml and add the a dependency for javax.jcr, jcr, version 1.0 with a scope of provided.
This will prevent maven from including it in the rar, but will still download it.
Build the rar file. type "mvn install"
Copy jcr-1.0.jar from your maven 2 repository (~/.m2/repository) to the jboss lib folder
[jboss]/server/default/lib. Remember that you must not include the jcr jar in any local client application at the risk of getting ClassCastExceptions when trying to access the repository through JNDI.
Copy the generated rar file to the deploy folder in jboss.
Customize a jackrabbit datasource
get template from sources or download via web svn:
http://svn.apache.org/repos/asf/jackrabbit/trunk/ edit [jackrabbit-jca]/deploy/jboss/4.x/jcr-ds.xml
change the "homeDir" property to match the folder where you want
jackrabbit to store its files.
Change the rar file name to match actual. (<rar-name>jackrabbit-jca-1.1-SNAPSHOT.rar</rar-name>)
copy the jcr-ds to the deploy folder in jboss
Now, jackrabbit is running and available through JNDI at java:jcr/local.
Code snippet to lookup the local repository
InitialContext ctx = new InitialContext() ;
Repository repo = (Repository) ctx.lookup("java:jcr/local") ;
Expose the local repository through RMI
download jcr-rmi from svn (at
http://svn.apache.org/repos/asf/jackrabbit/tags/1.2.3/jackrabbit-jcr-rmi for example) and build it. copy the generated jar to the jboss deploy folder.
Now a JCR RMI server is running at jnp://localhost:1099/jcrServer
Expose the local repository through Webdav
build or download jcr-webapp from
http://svn.apache.org/repos/asf/jackrabbit/tags/1.2.3/jackrabbit-webapp remove jcr-1.0.jar from the war.
configure jcr-webapp to connect to the local repository. see web.xml
disable repository startup servlet in web.xml.
Change the JNDI Name.
It must match the jndi-name set in jcr-ds.xml. default is "java:jcr/local"
disable JNDI environment variables for creating the initial context.
copy jackrabbit-webapp-1.2.3.war to the deploy folder in jboss as jackrabbit-server.war
Now the webdav server is running at
http://localhost:8080/jackrabbit-server
Access the repository from a session bean
EJB3 example
Container managed transactions
@Stateless
public class TestCMT implements TestCMTBean {
public void test() throws Exception {
InitialContext ctx = new InitialContext() ;
Repository repo = (Repository) ctx.lookup("java:jcr/local") ;
Credentials cred = new SimpleCredentials("user",new char[]{'´p','w','d'}) ;
Session s = repo.login(cred) ;
s.getRootNode().addNode("foo") ;
s.save();
}
}
Bean managed transactions
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class TestBMT implements TestBMTBean {
@Resource
UserTransaction utx ;
public void test() throws Exception {
utx.begin() ;
InitialContext ctx = new InitialContext();
Repository repo = (Repository) ctx.lookup("java:jcr/local");
Credentials cred = new SimpleCredentials("user",new char[]{'´p','w','d'}) ;
Session s = repo.login(cred);
s.getRootNode().addNode("foo");
s.save();
utx.commit() ;
}
}
Access the repository remotely from the command line interface
checkout jcr-commands from subversion
build with "maven jar:jar"
unzip the generated zip file at ./target into a folder of your choice
copy jboss client libraries into the lib folder.
e.g. copy the file [jboss]/client/jbossall-client.jar to [jcr-commands]/lib
run the command line with the script at bin/run.bat
connect to the remote server. command: "jndi jcrServer".
login to the remote repository. command: "login [user] [password]".
type "help" to view the available commands.
type "help [command name]" for a detailed description of the given command.
Common problems faced while configuring jackrabbit on jboss
1. I get following exception when configured jca on jboss
Reason: org.jboss.deployment.DeploymentException: couldn't get oldRarDeployment! jboss.jca:service=RARDeployment,name='jackrabbit-jca-1.0-SNAPSHOT.rar'; - nested throwable: (org.jboss.deployment.DeploymentException: ConnectionDefinition 'javax.jcr.Session' not found in rar .....
Solution: Most probably your jboss doesnt support old rar deployment, you better take the latest source code from svn and build the rar your own and try it. Above mentioned instructions work well with jackrabbit-jca-1.1-SNAPSHOT.rar.
2. I get following exception when trying to connect remote jackrabbit repository using jnp port
javax.naming.CommunicationException [Root exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:...........
Solution: Try running your jboss server with following arguments -Djava.rmi.server.hostname=<server name or ip address>
3. I am using jackrabbit on jboss 4.x and am getting following exception when jackrabbit-server.war gets deployed.
log4j:ERROR "org.jboss.logging.util.OnlyOnceErrorHandler" was loaded by [org.jboss.system.server.NoAnnotationURLClassLoader@1888759]. ERROR [STDERR] log4j:ERROR Could not create an Appender. Reported error follows. ERROR [STDERR] java.lang.ClassCastException ERROR [STDERR] at org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfigurator.java:165)
Solution: There are some classloader issues with jboss, try modifying following attribute value in jbossweb-tomcat55.sar/META-INF/jboss-service.xml
<attribute name="UseJBossWebLoader">true</attribute> Set it 'to true', default is 'false'.
You can also try adding the parameter -Dorg.jboss.logging.Log4jService.catchSystemOut=false to the JBoss startup parameters.
4. In JBoss 4.0.5, I've got the Jackrabbit 1.3 repository configured and I can look it up in the JNDI using a test app, but my WebDav app cannot find the repository eventhough I've followed the instructions and my configuration looks ok...
If you're trying to get the jackrabbit-server.war (WebDAV) to deploy against a Model-2 shared JCA-based repository as per the instructions above on JBoss 4.0.5, you might run into the problem where the servlet complains about an "invalid config". The servlet will dump you're current config to the console/log file:
12:07:31,087 INFO [AbstractConfig] Configuration of BootstrapConfig
12:07:31,087 INFO [AbstractConfig] ----------------------------------------------
12:07:31,090 INFO [AbstractConfig] jndiConfig: org.apache.jackrabbit.j2ee.JNDIConfig@9d2834
12:07:31,090 INFO [AbstractConfig] rmiConfig: org.apache.jackrabbit.j2ee.RMIConfig@baae59
12:07:31,090 INFO [AbstractConfig] repositoryHome: null
12:07:31,090 INFO [AbstractConfig] repositoryConfig: null
12:07:31,091 INFO [AbstractConfig] class: class org.apache.jackrabbit.j2ee.BootstrapConfig
12:07:31,091 INFO [AbstractConfig] valid: true
12:07:31,091 INFO [AbstractConfig] repositoryName: java:jcr/local
12:07:31,091 INFO [AbstractConfig] ----------------------------------------------
12:07:31,091 INFO [AbstractConfig] Configuration of JNDIConfig
12:07:31,091 INFO [AbstractConfig] ----------------------------------------------
12:07:31,091 INFO [AbstractConfig] jndiName: java:jcr/local
12:07:31,091 INFO [AbstractConfig] class: class org.apache.jackrabbit.j2ee.JNDIConfig
12:07:31,091 INFO [AbstractConfig] jndiEnv: {}
12:07:31,091 INFO [AbstractConfig] valid: true
12:07:31,091 INFO [AbstractConfig] jndiEnabled: false
12:07:31,091 INFO [AbstractConfig] ----------------------------------------------
The big hint is "jndiEnabled: false", which in the source code is set to true/false whether or not java.naming.provider.url is specified in your web.xml <init-param> section. So the solution for me was to set the following <init-param> section in the web.xml:
<servlet>
<servlet-name>Repository</servlet-name>
<description>
This servlet provides other servlets and jsps a common way to access
the repository. The repository can be accessed via JNDI, RMI or Webdav.
</description>
<servlet-class>org.apache.jackrabbit.j2ee.RepositoryAccessServlet</servlet-class>
<init-param>
<param-name>repository-name</param-name>
<param-value>java:jcr/local</param-value>
<description>Repository Name that is used to retrieve it via JNDI</description>
</init-param>
<init-param>
<param-name>java.naming.provider.url</param-name>
<param-value>jnp://localhost:1099</param-value>
</init-param>
<init-param>
<param-name>java.naming.factory.initial</param-name>
<param-value>org.jnp.interfaces.NamingContextFactory</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
It's a hack, because the code shouldn't need the JNDI environment details when deployed inside JBoss, but that's all it took to get the WebDAV servlets working in JBoss 4.0.5.