jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Peter Darton" <pet...@intrinsica.co.uk>
Subject FW: JCR, RMI & WebDAV - draft HOWTO
Date Wed, 07 Dec 2005 14:20:44 GMT
After publicly claiming that getting JCR-RMI/WebDAV working had been a
"learning experience", it was pointed out to me that I should write
about the whole thing so others (Hi John!) might skip over some of the
mistakes I made, so I'll post my innane ramblings here...

I expect a number of issues that I met will have nice explanations that
I either stupidly missed or simply weren't documented.
It would be nice if those people who know more than I do would take the
time to read through this message, and then point out the obvious
mistakes and any better ways of doing things so that others might
benefit.  You never know, making it easier to get involved might bring
more people to the project as a whole...

So, the following could be considered a draft "HOWTO get JCR-RMI-WebDAV

The following instructions are based on the assumption that you're using
Linux, and you've got the "svn" command-line command installed, and
you've got Tomcat running somewhere, but you don't have anything in the
way of existing installed Java development stuff.

1) Java:
 You'll need a JDK.  Personally, I downloaded Java 1.5.0_05 by
downloading the "Netbeans 4.1 with Java 1.5" bundle.
 I installed the JDK into /opt/jdk1.5.0_05/  and Netbeans into

2) Maven:
 Download Maven 1.  Note: That's "Maven 1", not 2.
 Unpack it somewhere.
 (I unpacked to /opt/maven-1.0.2/)
 - Easy mistake: The Maven website has moved onto Maven 2.  Maven 2 is
NOT what you want.  You'll have to locate the link to Maven 1 and
download that instead.  You can guess what I did first time around...

3) Xalan:
 Download Xalan from http://xml.apache.org/xalan-j/downloads.html
 Unpack it somewhere nearby to Maven (I unpacked to /opt/xalan-j_2_7_0/)

4) JCR build using Java 1.5 workaround:
 There's a bug in the maven build under Java 1.5, so you'll need to:
 cd to maven's "lib/endorsed" directory
 create symbolic links to (or copy) xalan.jar and serializer.jar (which
are in the xalan directory).
 I did
   ln -s ../../../xalan-j_2_7_0/serializer.jar
   ln -s ../../../xalan-j_2_7_0/xalan.jar

3) Download & Build Jackrabbit:
 cd to whereever you want a jackrabbit directory created, then do  svn
co http://svn.apache.org/repos/asf/incubator/jackrabbit/trunk jackrabbit
(that'll download the jackrabbit source)  cd jackrabbit/jackrabbit
export PATH=/opt/maven-1.0.2/bin:${PATH}  export
JAVA_HOME=/opt/jdk1.5.0_05  maven clean jar:jar jar:install copy_deps
dist  This will take some time, firstly because it'll download some
other jar files that are needed, and secondly because the unit-tests
aren't instant (you should have time to make tea/coffee).
 cd ../..

4) Build jackrabbit RMI:
 cd jackrabbit/contrib/jcr-rmi
 maven clean dist jar:install
 cd ../../..

5) Build jackrabbit WebDAV:
 cd jackrabbit/contrib/jcr-server/webdav
 maven clean jar jar:install dist
 cd ../server
 maven clean jar jar:install dist
 cd ../client
 maven clean jar jar:install dist
 cd ../webapp
 maven clean jar jar:install dist
 cd ../../../..

7) Installing WebDAV on Tomcat
 I'm going to assume you've already got Apache Tomcat up and running.
Big assumption, I know, but there are existing tutorials for that
(google is your friend).
 I'm going to assume that Tomcat is running on your localhost on port
 Goto http://localhost:8080/manager/html/list
 Scroll down to the bottom to find "Select WAR file to upload" and click
"Browse".  Locate, in jackrabbit/contrib/jcr-server/webapp/target, the
file "jackrabbit-server.war".
 Press "deploy".
 That'll fail to start properly as the build fails to include things
properly, so now scroll up to the top, find "jackrabbit-server" and
click "stop" (NOT undeploy!).
 Now copy xalan.jar and serializer.jar into tomcat's subdirectory

 Ok, we're now into "vague and undefined" territory.
 I then edited
.../webapps/jackrabbit-server/WEB_INF/repository/repository.xml, found
the AccessManager section and appended (immediately after

  <param name="anonymousId" value="anonymous" /> </LoginModule>

 However I'm not entirely convinced this is necessary, as the
SimpleLoginModule doesn't actually do any authentication at all anyway
(it's on the "to do" list).

 Once that's done, you can go back to
http://localhost:8080/manager/html/list and press "start" on
"jackrabbit-server" again.
 The servlet should start up with few complaints.  Log4j will moan about
not being configured properly, but there's nothing you can do about it
(other than fixing the code itself), but there should be no exceptions.
 If you do get exceptions on startup, you'll have to edit the source and
add enough System.out.println statements and printStackTrace() calls to
work out what they mean, as logging doesn't work by default and I didn't
find any method of turning it on (this is probably because the code
started by using Log4j and is transitioning to using something else, and
currently doesn't do either properly).

 - Easy mistake: Beware of using the browser "back" and "forward"
buttons on the .../manager/... Tomcat pages - the browser is unlikely to
warn you about needing to re-send form data, but it will still cause
Tomcat to perform whatever operation you used to take you to that page,
which can be quite embarrasing if you started by "undeploying" an old
copy of "jackrabbit-server".
 - Easy mistake#2: Undeploying the WAR will destroy the alterations
you've just made.  Re-deploying will over-write any existing files
resulting in data-loss.

8) Browsing the repository using a web-browser  Point your browser at
 If the servlet is working, you'll get a boring page showing ".." and
nothing else, as you've not got anything in your repository (yet).

9) Browsing the repository using WebDAV
 Point your WebDAV client at
e.g. On "DAV Explorer":
 - enter in the above URL.
 - It'll prompt for a username and password - tell it anything you like
(except "anonymous").
 - You're in.
 - Note: Earlier versions of Jackrabbit have a bug whereby they return
an invalid HTTP header which DAV Explorer refuses to accept.  See
http://issues.apache.org/jira/browse/JCR-286?page=all for details.
e.g. On MS Windows XP-SP2:
 - If you're using "XP Style", open up "My Network Places" on the start
menu.  If you're using "Classic Style", open up Explorer, go "up" to the
desktop and you'll find "My Network Places" there instead.
 - Within "My Network Places", find "Add Network Place" and (double)
click on it.
 - That'll open an "Add Network Place Wizard".  Click "Next".
 - That'll claim to download things from the internet (it's actually
calling home to microsoft) then it gives you a list (with only one
option).  Highlight "Choose another network location" and click "Next".
 - That'll ask for the "Internet or network address:".  You'll need to
enter "http://localhost:8080/jackrabbit-server/server/default/".  Then
click "Next"
 - That'll prompt for a username and password.  Enter anything at all
(it doesn't matter, as long as you don't claim to be "anonymous").  Make
sure "Remember my password" is ticked.  Click ok (or press return).
 - The wizard will then attempt to open the folder, so if the username
or password is wrong or the server isn't working, it'll then tell you.
If all goes well, it'll then try to open the folder and prompt you for
the username and password again (Yes, it's forgotten already, even
though you told it to remember it, so tell it again).
 - That should result in a folder being displayed.  You should be able
to use this to browse around.
 - Note: If you didn't tell windows to remember the password, you'll
have to enter it in over and over again, instead of just twice.

Note: The WebDAV view of the repository is NOT a normal WebDAV
filestore.  It's a generic JCR being exposed in all its glory, with
nodes and parameters being exposed in a rather "raw" fashion.  Whilst
this lets you see everything, I wouldn't recommend it as a nice easy
user-interface, and the use of : in "filenames" _really_ upsets MS
Windows Explorer.

Note#2: You can also mount the WebDAV view using Novell NetDrive, but it
reveals the same data as seen via the Windows-XP view - not
user-friendly - and contrary to many reports, Novell NetDrive IS NOT
FREE (it's a no-cost add-on if you've already got Netware 6, hence is
downloadable from lots of universities etc for their students because
they're allowed to use it without further charge.  Those of us not using
Novell should limit usage to a 90 day evaluation only)

10) Advanced usage - a remote repository  I believe it's possible to get
the Tomcat servlets to publish the JCR via RMI, but I never figured out
how to do that (the config file syntax wasn't obvious to me at the time,
and the absense of documentation or logging made investigation awkward).
 However, it is relatively easy to run your own "daemon" process that
runs a JCR as a separate process which then grants access to foreign
JVMs via RMI.
 First, you'll need to write a "daemon" (Microsoft-indoctrinated readers
should understand that a "daemon" is what a "service" was called before
microsoft decided to use a different name) program that starts a
repository, registers it with RMI, then sits waiting for someone to tell
it to do something.
 I did try attaching my own, but the list-server just said "ZIP
attachments are not accepted here", and it considers a JAR file to be a
ZIP file too.  I'm willing to email copies of "JcrRmiDaemon.zip" to
anyone who asks, at least in the short term.
 Then you'll need to run it with appropriate arguments, telling it all
about the security policy to use, the jaas.config file etc, and where to
put the repository files.

 Once that's running (i.e. starts and then hangs waiting for orders - if
it returns you to a command-prompt, it's broken), you can then tell the
Tomcat Servlet to use that instead of its own.
 Stop the tomcat servlet "jackrabbit-repository".
 Edit the tomcat file .../webapps/jackrabbit-server/WEB_INF/web.xml
 Delete the "R E P O S I T O R Y   S T A R T U P  S E R V L E T" section
in its entirity (this is the bit that says "If you already have the
repository registered in this appservers JNDI context, or if its
accessible via RMI, you do not need to use this servlet".  We've got an
RMI-accessible JCR, hence we don't need this - our daemon is doing its
job now.
 Scroll down to just above "W E B D A V  S E R V L E T" where you'll see
"<param-name>rmi-uri</param-name>" in a section that is commented out.
Un-comment it so it's now active.  Now set the <param-value> to
rmi://localhost:1099/testRep (assuming that your daemon process is
running on localhost [i.e. same PC as Tomcat], and the daemon is running
on port 1099, and the repository it is running is called testRep).
 Now restart the tomcat servlet "jackrabbit-repository"
 This should start up without complaint.
 Now try accessing the repository via WebDAV and/or your web-browser as
described in step 8 & 9 above - these should still work, and show an
empty repository (well, WebDAV never shows it truly empty, but as empty
as it gets).

11) Really advanced stuff - writing code to hit the repository  I put
together a simple command-line client (also available on request).  It's
devoid of comments (sorry), but should be fairly self-explanetory (and
the code mostly follows that of
http://www-128.ibm.com/developerworks/java/library/j-jcr/ except where
the JCR-RMI interface deviates from the JCR interface).
Using this, you should be able to stuff a file into the repository and
retrieve it _either_ using the command, WebDAV, or the http-browser, and
all remotely too, so you can have a huge array of webservers running
Tomcat, all pointing at a single RMI-repository running on a separate

Footnotes (aka Whinge list):
As a result of going through all of this, I'm left with a number of
questions/wishes.  (i.e. this is a list of complaints that things
weren't as I expected - please don't take it personally)

Q1) Why on earth wasn't JCR designed with remote access in mind?
It would be sensible, would it not, if one could just "plug in" ANY JCR
implementation, local OR remote, and use it without having to modify
one's code - after all, that's the whole point of JCR - to allow people
to write code that can use ANY JCR without code modification.
However, it turns out that you can't - if you want to use a remote JCR
(e.g. via RMI), you need to re-write all your JCR-using code because JCR
_only_ supports local static access and as a result any remote-capable
code is going to have a different interface.
In the case of the RMI-JCR code, one gets arrays where one would expect
Iterators, and getting data in and out of the RMI-JCR is not nearly as
friendly as with the "raw" JCR code itself.
Having to re-code one's application just because the JCR is on a
different machine, or even runnining on a different JVM within the same
machine, is rather missing the whole point of having a _single_
interface that'll work on _any_ compatible repository.
The requirement that one's (client) code co-habits in the same JVM (as
the JCR code) is a serious impediment to scalability.
Maybe there are good reasons why JCR has been limited to local-access
only and isn't networkable, but I found this limitation to be a real

Q2) Why isn't there a web-page for the jcr-contrib code?
One can browse the current JCR code code, its JavaDocs & statistics etc
on the official page.
However, there doesn't appear to be any way of seeing the equivalent
information for the jcr-contrib code, which is in turn seperated into
lots of tiny little projects, e.g. the webdav code is split into 4
projects so you can't even browse from one to the other, or back to the
core code.

Q3) Building with maven
I'm new to maven, so this might be blindingly obvious to a
maven-veteran, but when I invoke a build tool with no arguments, I
rather expect it to EITHER tell me "you need to say what you want to
build, here's a list" OR go ahead and build everything.
What I've found is that maven (at least with these projects) does
neither - it sometimes builds something useful, but usually not.
Worse (MUCH WORSE) still, if one tells it to build lots of things, it
sometimes skips steps leaving modified-code uncompiled (this is why I've
said "clean" in all my calls to maven, otherwise I often ended up with
freshly rebuilt jar files full of the old class files, and none of the
code changes I'd made.  Maybe this is considered normal and reasonable
by maven-veterans, but I consider a build system failing to rebuild code
a "Bad Thing").
So, I would highly recommend that all projects get given some sensible
default targets to cope with folks (like me) who expect that typing
"maven" on its own will do what we need, instead of assuming that
everyone who downloads the code is already intimately familiar with
maven and the code's own build targets.
Note: The JCR core code does this, but it's only one build of the (far
too) many you need - the contrib code isn't in nearly as good shape.

Q4) Developing outside of maven
As you might have gathered from my choice of Java download, I'm
currently using NetBeans to develop software.  Netbeans has a simple
requirement for using external libraries - it wants a JAR of the built
code, and ideally access to the Javadocs and the source code.
It would be REALLY NICE if there was a target that packaged up the
source code into a JAR file, and did the same with the JavaDocs.
I ended up writing a script file to sift through the build area, pull
out the source files, gather them into a single hierarchy and then JAR
the lot (and also turning the JavaDocs into a single JAR file as well).
This way you end up with a nice "portable" build which can be plugged
into anything - I'm sure maven is all very nice, but not everyone is
prepared to adopt an entirely new build system for every project they
get involved with.

Q5) Building everything
Why isn't there a "build everything" command?  Wouldn't that be
relatively easy to do (if not, remind me why maven is used?)?  Would
that not then allow the entire project to be maintained more easily?

Q6) Why no "to do" list?
It took me a long time to discover that the reason there was no
documentation covering which usernames and passwords to use, or how to
configure authentication or authorisation, was because the necessary
code to implement that functionality hadn't been written.
It would be nice if the JCR web-page had a nice obvious link to a search
on the JIRA site that listed all the blatently missing functionality,
and that the issue subjects be re-worded to make things _really_ obvious
what they mean.  Personally, I don't think
http://issues.apache.org/jira/browse/JCR-153 makes it totally obvious
that THERE IS NO SECURITY AT ALL in jackrabbit (yet), and that's _after_
finding the JIRA facility...

Ok, whinges over.

I hope this of some use to people, and saves folks from some of the
"learning experience" that I went through.
If anyone wants to offer a home for the code I tried to attach
(jcrRmiDaemon - 6k, and jcrUtil - 12k), do get in touch.  Same applies
if anyone wants a copy (as long their email will accept jar files).



This e-mail has been scanned for viruses by MCI's Internet Managed Scanning Services - powered
by MessageLabs. For further information visit http://www.mci.com

View raw message