atom feed10 messages in org.apache.sling.usersSwapping Postgres for Derby
FromSent OnAttachments
Tony GiacconeJun 11, 2010 1:14 pm 
Felix MeschbergerJun 14, 2010 1:12 am 
Tony GiacconeJun 14, 2010 5:51 am 
Felix MeschbergerJun 14, 2010 5:58 am 
Jos SnellingsJun 14, 2010 8:47 pm 
Felix MeschbergerJun 15, 2010 1:12 am 
Jos SnellingsJun 15, 2010 1:22 am 
Felix MeschbergerJun 15, 2010 1:29 am 
Jos SnellingsJun 15, 2010 2:36 am 
Jos SnellingsJun 15, 2010 11:35 pm 
Subject:Swapping Postgres for Derby
From:Tony Giaccone (tgia@masslight.net)
Date:Jun 11, 2010 1:14:26 pm
List:org.apache.sling.users

I asked for a bit of assistance to help me swap out the Derby persistence
manager in Sling for a Database backed system.

I was advised to look at the OSGi bundles for JDBC drivers and to get a better
understanding of how that driver the Felix OSGi container is used by Sling..

What follows is the process I used, and how I managed to be successful. I hope
that anyone else who needs to follow this path will find this helpful and give you the specific
advice you need to make this swap out.

Mind you there are some problems with this path. The main one being that none of
the maven testing works. It looks like this happens because the Derby DB is initialized to blank
each time it spins up while Postgress keeps state. I really haven't looked in detail at why this is,
that is just my supposition. However, I was able to successfully deploy sling into glass fish and create
nodes which are backed by data in the database. For now, that's good enough for me.

My intent in this was to do the minimum necessary to get this to work. As a
result I have not tried to remove any of the existing structure that supported using Derby. I that effort
was only going to make the process that more difficult. And made it that much more unlikely to succeed
for someone who knows as little as I do. What I did was augment the build process to include
the artifacts necessary to use the DatabasePersistance manager and Postgres. Once I have this working on
my local build, I'll look into what it takes to do the same, and I expect that will be easy, for
Oracle.

There is an assumption here that you have a copy of postgres running on your
local machine, and that it's on the standard postgres port and that you have a schema set up for
Sling/Jackrabbit to use and an Postgress userid with access to that database.

Typical warnings apply, I know very little about Sling or Jackrabbit, I'm about
as novice as you can be with both of these, as a result your milage may vary. I've done no testing on
this, the only reason I know it works is that jackrabbit created the tables in the DB Schema. With all that
said here's the process that seems to be working for me. The sling files I've modified are in bold.

The first change I made was to go to a pom file:

sling/bundles/jcr/jackrabbit-server/pom.xml

This file is integral to how the derby code gets loaded. So I just duplicated
the line but changed it to the driver for postgresql.

org.apache.derby.jdbc;resolution:=optional, org.postgresql.Driver;resolution:=optional,

Once this was done the next step was to ensure that the postgres drivers got
loaded. To get them loaded they must be part of an OSGi bundle. My first attempts to get this
working relied on bundles that had been suggested to me from springsource.com

http://www.springsource.com/repository/app/bundle/version/detail?name=com.springsource.org.postgresql.jdbc3&version=8.3.603&searchType=bundlesByName&searchQuery=postgres

I was NOT able to get those drivers/bundles working. I don't think the Manifest
files contained in those jar files are correct. I burned the better part of two days (I was totally
ignorant, and still am mostly ignorant about OSGi). That ignorance only made the process more complicated.

This pdf helped immensely.

http://jonas.ow2.org/JONAS_5_2_0_M1/doc/doc-en/pdf/howto_install_jdbc_driver.pdf

To get bundles that would work, I did the following. I downloaded the postgres
jdbc drivers. I also downloaded the bnd tool (http://www.aqute.biz/Code/Bnd)

I used the bnd tool to wrap both sets of drivers.

$ bnd wrap postgresql-8.4-701.jdbc3.jar $ mv postgresql-8.4-701.jdbc3.bar postgresql-8.4-701.jdbc3-bnd.jar $ bnd wrap postgresql-8.4-701.jdbc4.jar $ mv postgresql-8.4-701.jdbc4.bar postgresql-8.4-701.jdbc4-bnd.jar

In this way I had both level 3 and level 4 drivers available. I wasn't sure
which ones I was going to need. I then inserted them into my local maven repository.

$ mvn install:install-file -DgroupId=postgresql -DartifactId=postgresql
-Dversion=8.4.701.jdbc4 \ -Dpackaging=jar -Dfile=postgresql-8.4-701.jdbc4-bnd.jar $ mvn install:install-file -DgroupId=postgresql -DartifactId=postgresql
-Dversion=8.4.701.jdbc3 \ -Dpackaging=jar -Dfile=postgresql-8.4-701.jdbc3-bnd.jar

Now the bundles where in my repository, and ready to be used. They have unique
names I appended -bnd to the file names so that they are obviously different. From the
jar files.

To get the jdbc jar files into the right place in launchpad, I had to add the
bundle to the build so that they would be included.

I did this by modifying this file:

sling/launchpad/builder/src/main/bundles/list.xml

Look for this line:

<startLevel level="15">

add this bundle:

<bundle> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>8.4.701.jdbc4</version> </bundle>

Make the following change:

in this file:

sling/bundles/jcr/jackrabbit-server/src/main/resources/repository.xml

change this stanza of XML (it occurs twice in this file):

<PersistenceManager
class="org.apache.jackrabbit.core.persistence.db.DerbyPersistenceManager"> <param name="url" value="jdbc:derby:${wsp.home}/db;create=true"/> <param name="schemaObjectPrefix" value="${wsp.name}_"/> <param name="shutdownOnClose" value="true"/> </PersistenceManager>

To this:

<PersistenceManager
class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager"> <param name="driver" value="org.postgresql.Driver"/> <param name="url" value="jdbc:postgresql://localhost:5432/YourDBSchema"/> <param name="schema" value="postgresql"/> <param name="user" value="YourUser"/> <param name="password" value="YourUserPWD"/> <param name="schemaObjectPrefix" value="public"/> <param name="externalBLOBs" value="false"/> </PersistenceManager>

In this stanza of XML make the following substitutions for your DB

YourDBSchema is the name of your Postgres Database Schema

YourUser is the userid of a valid Postgres User YourUserPwd is the password for that User.

You'll need to change one last file:

bundles/commons/testing/src/main/resources/jackrabbit-test-config.xml

This file also has the derby stanza:

<PersistenceManager
class="org.apache.jackrabbit.core.persistence.db.DerbyPersistenceManager"> <param name="url" value="jdbc:derby:${wsp.home}/db;create=true"/> <param name="schemaObjectPrefix" value="${wsp.name}_"/> <param name="shutdownOnClose" value="true"/> </PersistenceManager>

You'll need to change this file as well, it needs to be changed to the same
stanza of XML you used in the repository.xml file.

<PersistenceManager
class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager"> <param name="driver" value="org.postgresql.Driver"/> <param name="url"
value="jdbc:postgresql://localhost:5432/YourDBSchema"/> <param name="schema" value="postgresql"/> <param name="user" value="YourUser"/> <param name="password" value="YourUserPWD"/> <param name="schemaObjectPrefix" vvalue="jcr_${wsp.name}_"/> <param name="externalBLOBs" value="false"/> </PersistenceManager>

This one took a little while to figure out. As it seems to be in the testing
hierarchy and so shouldn't find it's way into the deployed war file, but it does..

It's the source of the following files:

sling/bundles/jcr/resource/target/repository/repository.xml sling/bundles/jcr/resource/target/repository/workspaces/default/workspace.xml

Finally do a build of Sling..

You will have to disable tests. It seems that the testing process counts on
derby to empty out the database each time a new test is started. As a result, tests fail when
you try to build with Postgres as the back end.

mvn -Dmaven.test.skip=true install

You'll find the typical build artifacts in:

sling/launchpad/builder/target

change the war file from:

org.apache.sling.launchpad-6-SNAPSHOT.war

to: sling.war

then deploy, in my case, in to glassfish.

I hope that helps someone else who feels the need for a back end that's based on something other then Derby.