Tuesday, March 22, 2005

Using JBossPortal RC3

Now that the JBoss organisation has released its 3rd release candidate of JBoss Portal, they are lead in the race for becoming our open source portal provider.

But the requirements for our environment still remain.
We need to connect to a MaxDB database and deploy the portal onto JBoss AS 4.0.2.
So first lets see how I can connect JBpossPortal to a MaxDB database.

Connecting to MaxDB
Reading through the user guide, the steps to deploy JBoss Portal seem fairly simple.
It should be just a matter of creating the database, the database connector file, copying the jboss-portal.sar structure into the deploy directory and starting JBoss.

But obviously it wasn't as simple as that. When starting JBoss I got a NullPointerException:
2005-06-13 13:10:11,709 DEBUG [org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory] Using properties: {user=portal, password=--hidden--}
2005-06-13 13:10:11,709 DEBUG [org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory] Checking driver for URL: jdbc:sapdb://dhu400d.internal.epo.org/portal
2005-06-13 13:10:11,710 DEBUG [org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory] Driver not yet registered for url: jdbc:sapdb://dhu400d.internal.epo.org/portal
2005-06-13 13:10:11,739 DEBUG [org.jboss.resource.connectionmanager.IdleRemover] run: IdleRemover notifying pools, interval: 450000
2005-06-13 13:10:11,782 DEBUG [org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory] Driver already registered for url: jdbc:sapdb://dhu400d.internal.epo.org/portal
2005-06-13 13:10:12,264 INFO [org.hibernate.cfg.SettingsFactory] RDBMS: SAP DB, version: Kernel 7.5.0 Build 018-121-079-776
2005-06-13 13:10:12,264 INFO [org.hibernate.cfg.SettingsFactory] JDBC driver: SAP DB, version: package com.sap.dbtech.jdbc, MaxDB JDBC Driver, MySQL MaxDB, 7.6.0 Build 000-000-003-247
2005-06-13 13:10:12,266 ERROR [org.jboss.portal.core.hibernate.SessionFactoryBinder] Starting failed portal:service=Hibernate
java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:393)
at java.util.Properties.setProperty(Properties.java:102)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:106)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:1509)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1054)
at org.jboss.portal.core.hibernate.SessionFactoryBinder.createSessionFactory(SessionFactoryBinder.java:261)
at org.jboss.portal.core.hibernate.SessionFactoryBinder.startService(SessionFactoryBinder.java:127)
at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:272)
at org.jboss.system.ServiceMBeanSupport.start(ServiceMBeanSupport.java:173)
at org.jboss.portal.server.util.Service.start(Service.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)


This makes working with open source projects so nice, to find out what the problem is, you just have to download the source package, and...

So I downloaded the source package for hibernate, and opened the file org/hibernate/cfg/SettingsFactory.java.
Around line 6 it contains:

if ( props.getProperty( Environment.DIALECT ) == null ) {
props.setProperty( Environment.DIALECT, DIALECTS.getProperty(databaseName) );
}

The constant DIALECTS is a Properties field that contains a mapping between databasenames and SQL dialect class, but it does not contain a mapping for SapDB (or MaxDB for that matter).
The above snippet shows that it is possible to supply the SQL dialect as en environment variable.
So I added -Dhibernate.dialect=org.hibernate.dialect.SAPDBDialect to the JBoss start command, and that did the trick.