| Installing Funambol and integrating with SOGo » |
Funambol on JBoss
Funambol comes with its own Java and Tomcat installation. However convenient to get things running quickly, this is both a security risk and a waste of memory.
The OS should of course update the system's Java VM when there's a security update available, and since Funambol's Java is not managed by the package manager I would have to do this manually. And I'm too lazy for that.. It is quite simple to replace Funambol's Java with the system's Java, but I decided to take it one step further, and get rid of Tomcat as well, since I already have a JBoss 5 instance running on my server.
This turned out not to be a straightforward configuring change..
...
DataSource Factory
The main obstacle is the way in which datasources are created in Tomcat, and how to replicate that in JBoss.
In Tomcat, the datasource is created through a factory, which is configured like this in its context.xml :
<Resource name="jdbc/fnblds" auth="Container" type="javax.sql.DataSource"
factory="com.funambol.server.db.DataSourceFactory"/>
.. and similar definitions for jdbc/fnblcore and jdbc/fnbluser.
In JBoss however, there is no way to specify the factory class in the datasource config file.
There are two datasources actually used in Funambol. When looking at the code it is clear that the jdbc/fnblcore needs no special treatment in JBoss. It is handled as a javax.sql.DataSource and can be configured as any datasource in JBoss. The jdbc/fnbluser datasource however is explicitly cast to a com.funambol.server.db.RoutingDataSource, so it fails miserably when presenting it with a standard datasource.
To supply Funambol with the right class instance for jdbc/fnbluser, we need an MBean that supplies a RoutingDataSource when the JNDI resource jdbc/fnbluser is requested. An MBean allows you to specify a resource factory class, and that's exactly what we need.
Download routing-ds-mbean.jar and save it to $JBOSS/server/.../lib
DataSource Configuration
The Funambol DataSourceFactory has two code paths for creating the datasource. If it finds a BeanConfiguration for a resource, it instantiates a RoutingDataSource. Otherwise the instantiation of the datasource is delegates to the system default datasource factory. This second path fails on JBoss. So we need to make sure a BeanConfiguration can be found by the DataSourceFactory.
I had to copy fnbluser.xml to a slightly different location in order for it to be picked up by funambol (note the extra /jdbc/):
$FUNAMBOL/config/com/funambol/server/db/jdbc/jdbc/fnbluser.xml
You will also need funambol's server-framework-10.0.0.jar in the $JBOSS/server/.../lib directory, because the MBean uses the factory and the RoutingDataSource classes.
Next, create a new file funambol-ds.xml and define the datasource, the naming alias for jdbc/fnblcore, and our RoutingDataSource factory MBean for jdbc/fnbluser :
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<no-tx-datasource>
<jndi-name>jdbc/fnblds</jndi-name>
<connection-url>jdbc:mysql://localhost/funambol</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<connection-property name="char.encoding">UTF-8</connection-property>
<user-name>funambol</user-name>
<password>secret</password>
</no-tx-datasource>
<mbean code="org.jboss.naming.NamingAlias" name="jboss.jmx:alias=fnblcore">
<attribute name="FromName">java:jdbc/fnblcore</attribute>
<attribute name="ToName">java:jdbc/fnblds</attribute>
</mbean>
<mbean code="nl.outrightsolutions.funambol.support.RoutingDataSource"
name="outrightsolutions.funambol:service=RoutingDataSource">
<attribute name="JndiName">java:jdbc/fnbluser</attribute>
</mbean>
</datasources>
copy this file to $JBOSS/server/.../deploy to activate this datasource.
The jdbc/fnbluser datasource is created on its own by funambol's datasource factory, and as such, it doesn't use the connection url or credentials of the jdbc/fnblds definition. I might change this in a newer version of my MBean, but for now it's easiest to delegate everything to Funambol's configuration and routing features.
Funambol WAR file
Some adjustments need to be made to the WAR file.
Explode funambol webapp and add jboss-web.xml to WEB-INF :
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<resource-ref>
<res-ref-name>jdbc/fnblds</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<mapped-name>java:/jdbc/fnblds</mapped-name>
</resource-ref>
<resource-ref>
<res-ref-name>jdbc/fnblcore</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<mapped-name>java:/jdbc/fnblcore</mapped-name>
</resource-ref>
<resource-ref>
<res-ref-name>jdbc/fnbluser</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<mapped-name>java:/jdbc/fnbluser</mapped-name>
</resource-ref>
</jboss-web>
JBoss 5 complains about some of the elements in WEB-INF/web.xml. Boring. Remove all web-app/servlet/display-name elements.
Remove the following files from WEB-INF/lib (they conflict with JBoss provided xerces)
- xercesImpl-2.6.2.jar
- xml-apis-1.0.b2.jar
- xmlParserAPIs-2.6.2.jar
Then repack the war file.
Other JBoss Configuration
Add the following system variables to $JBOSS/bin/run.conf
funambol.home=/opt/Funambol
Copy the mysql connector you installed in funambol's tomcat to $JBOSS/common/lib
Copy json_simple.jar from $FUNAMBOL/tools/tomcat/lib to $JBOSS/server/.../lib
Final thoughts
Now you should be able to start Funambol on JBoss. I am no expert in Funambol architecture, and there's probably some (add on) components of Funambol that are not working with the above procedure. But I was able to connect with the admin client, and doing a sync against JBoss Funambol with my phone. So basically the ds-server component seems to be working fine.
Let me know if you are having success (or failure) with this howto.