The eight step guide to felicity (or insanity in some cases)
1. Get the missed jar files
As a result of different licence models we could not ship all necessary
jar files with OJB. Thus you need some extra jar files to make the ejb
examples target run:
- JBoss jar files to support the OJB mbeans (jars depend on used version, so trial and error)
- jboss-j2ee.jar or use j2ee jars fron SUN
- XDoclet jar file and modules for generating ejb's and jboss deployment descriptor (modules: jboss, jmx, ejb, web)
Put these jar files in the lib
directory of OJB if you want to generate the ejb-examples.
2. Bind OJB api-main classes to JNDI
To make the OJB api's accessible via JNDI, we need to bind them to JNDI. How to do
that depends on the used environment. In JBoss you can use mbean
classes
to do that org.apache.ojb.jboss.PBFactory
and org.apache.ojb.jboss.ODMGFactory
.
Let JBoss know about the new mbeans, so declare them in a jboss-service.xml
file:
 |  |  |
 |
<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.apache.ojb.jboss.PBFactory"
name="DefaultDomain:service=PBAPI,name=ojb/PBAPI">
<depends>jboss.jca:service=RARDeployer</depends>
<attribute name="JndiName">ojb/PBAPI</attribute>
</mbean>
<mbean code="org.apache.ojb.jboss.ODMGFactory"
name="DefaultDomain:service=ODMG,name=ojb/defaultODMG">
<depends>jboss.jca:service=RARDeployer</depends>
<attribute name="JndiName">ojb/defaultODMG</attribute>
</mbean>
</server>
|  |
 |  |  |
These step makes OJB accessible via JNDI. In other application server you should do
a similar step and bind the OJB api-main classes to JNDI. The main classes to bind
are:
-
org.apache.ojb.broker.core.PersistenceBrokerFactoryFactory
for PB-api.
Make method PersistenceBrokerFactoryFactory.instance()
accessible.
-
org.apache.ojb.odmg.OJBJ2EE_2
for ODMG-api. Make method
OJBJ2EE_2.getInstance()
accessible.
3. Enclose all libraries OJB depend on and put them into a .sar-directory
Make a ojb.sar
directory under [jboss.home]/server/default/deploy
Add a META-INF
directory under ojb.sar
.
Put a simple MANIFEST.MF
file and the jboss-service.xml
file in this directory.
To make OJB run and (re-)deployable you have to put all libraries
OJB depend on into the ojb.sar
directory:
- The jakarta commons libraries files (all commons-xxx.jar)
- The antlr jar file (antlr-xxx.jar)
(This was tested with jboss 3.2.2)
4. Prepare OJB code base
With bin\build.bat prepare-jboss jar
using windows or
bin/build.sh prepare-jboss jar
we rebuild OJB
jars including the jboss MBeans.
The prepare-jboss
target copy the jboss MBeans to the OJB code
base. After running the jar
target you could find the new
db-ojb-xxx.jar
, including the MBeans, in the dist
directory.
(If you need a OJB jar file without the MBeans, clean the target
directory e.g. by calling the clean
ant target and invoke the
jar
ant target again).
Copy the db-ojb-xxx.jar
file into the ojb.sar
directory.
5. Copy OJB configuration files into the ojb.sar
directory
OJB.properties, repository.dtd, repository.xml, repository_internal.xml, repository_database.xml,
repository_ejb.xml (if you want to run the ejb examples). The repository.xml
should rather look like:
 |  |  |
 |
<?xml version="1.0" encoding="UTF-8"?>
<!-- This is a sample metadata repository for the ObJectBridge
System. Use this file as a template for building your own
mappings-->
<!-- defining entities for include-files -->
<!DOCTYPE descriptor-repository SYSTEM "repository.dtd" [
<!ENTITY database SYSTEM "repository_database.xml">
<!ENTITY internal SYSTEM "repository_internal.xml">
<!ENTITY junit SYSTEM "repository_junit.xml">
<!ENTITY user SYSTEM "repository_user.xml">
<!ENTITY ejb SYSTEM "repository_ejb.xml">
<!ENTITY jdo SYSTEM "repository_jdo.xml">
]>
<descriptor-repository version="1.0"
isolation-level="read-uncommitted">
<!-- include all used database connections -->
&database;
<!-- include ojb internal mappings here -->
&internal;
<!-- include mappings for the EJB-examples -->
&ejb;
</descriptor-repository>
|  |
 |  |  |
6. Adapt OJB.properties file
If the PB-api is the only persistence API being used (no ODMG nor JDO),
and it is only being used in a managed environment, it is
recommended to use a special PersistenceBrokerFactory class, which
enables PersistenceBroker instances to participate in the running JTA
transaction (e.g. this makes PBStateListener proper work in managed
environments and enables use of 'autoSync' property in
ObjectCacheDefaultImpl):
 |  |  |
 |
PersistenceBrokerFactoryClass=
org.apache.ojb.broker.core.PersistenceBrokerFactorySyncImpl
|  |
 |  |  |
Don't use this setting in conjunction with the ODMG-api.
Your OJB.properties file need the following additional settings to work within
managed environments (apply to all used api):
 |  |  |
 |
...
ConnectionFactoryClass=
org.apache.ojb.broker.accesslayer.ConnectionFactoryManagedImpl
...
OJBTxManagerClass=org.apache.ojb.odmg.JTATxManager
...
JTATransactionManagerClass=
org.apache.ojb.otm.transaction.factory.JBossTransactionManagerFactory
|  |
 |  |  |
7a. Declare datasources in the repository (repository_database) file and do additional configuration
Do only use DataSource
from the application server to connect your databases.
NOTE: We strongly recommend to use JBoss 3.2.2 or higher of the 3.x series of JBoss. With earlier versions of
3.x we got Statement/Connection resource problems when running some ejb stress tests. As workaround we
introduce a jboss specific attribute eager-release for version before 3.2.2, but it seems that this
attribute can cause side-effects. Again, this problem seems to be fixed in 3.2.2.
 |  |  |
 |
<!-- Datasource example -->
<jdbc-connection-descriptor
jcd-alias="default"
default-connection="true"
platform="Sapdb"
jdbc-level="2.0"
jndi-datasource-name="java:DefaultDS"
username="sa"
password=""
eager-release="false"
batch-mode="false"
useAutoCommit="0"
ignoreAutoCommitExceptions="false"
>
<object-cache class="org.apache.ojb.broker.cache.ObjectCacheDefaultImpl">
<attribute attribute-name="timeout" attribute-value="900"/>
<attribute attribute-name="autoSync" attribute-value="true"/>
</object-cache>
<sequence-manager className=
"org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl">
</sequence-manager>
</jdbc-connection-descriptor>
|  |
 |  |  |
The attribute useAutoCommit="0"
is mandatory
in managed environments, because it's in most cases not
allowed to change autoCommit state.
In managed environments you can't use the default sequence manager (SequenceManagerHighLowImpl)
of OJB. For alternative sequence manager implemetation see here.
7b. Take care of caching
Very important thing is cache synchronization with the database.
When using the ODMG-api or PB-api (with special PBF (see 6.) setting)
it's possible to use all ObjectCache
implementations as long as OJB doesn't run
in a clustered mode. When the ObjectCacheDefaultImpl
cache implementation was used it's
recommended to enable the autoSync
mode.
In clustered environments (OJB run on different AppServer nodes) you
need a distributed ObjectCache or you should use a local/empty cache like
ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCachePerBrokerImpl
or
ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCacheEmptyImpl
.
The cache is pluggable, so you can write your own ObjectCache implementation to accomplish
your expectations.
More info you can find in
clustering and
ObjectCache topic.
7c. Take care of locking
If the used api supports Object Locking (e.g. ODMG-api), in clustered environments
(OJB run on different AppServer nodes) a distributed lock management is necessary.
[7d. How to deploy ojb test hsqldb database to jboss]
After creating the database with
bin\build.bat prepare-testdb
or bin/build.sh prepare-testdb
.
Take the generated OJB.script
file from .../target/test
and rename the file to default.script
.
Replace the jboss default.script file in
...\jboss-3.x.y\server\default\db\hypersonic
with this file.
8a. Inside your EJB's you can get a handle on the ODMG like this:
 |  |  |
 |
ODMGFactory factory =
(ODMGFactory) context.lookup("java:/ojb/defaultODMG");
odmg = factory.getInstance();
|  |
 |  |  |
8b. Inside your EJB's you can get a handle on the PB like this:
 |  |  |
 |
context = new InitialContext();
pbf = ((PBFactoryIF) context.lookup(
PBFactoryIF.PBFACTORY_JNDI_NAME)).getInstance();
|  |
 |  |  |
Check out the ejb's provided in the OJB distro at: [db-ojb]/src/ejb/org/apache/ojb/ejb
for an example of working beans.
This solution should be re-deployable in jboss.
If you will get any problems, please let me know.
8c. OJB logging within JBoss
Jboss use log4j as standard logging api.
In summary, to use log4j logging with OJB within jBoss,
1) in OJB.properties set
 |  |  |
 |
LoggerClass=org.apache.ojb.broker.util.logging.Log4jLoggerImpl
|  |
 |  |  |
There is no need for a separate log4j.properties file of OJB-specific
log4j settings (in fact the OJB.properties setting LoggerConfigFile is
ignored). Instead, the jBoss log4j configuration file must be used:
2) in JBOSS_HOME/server/default/conf/log4j.xml,
define appenders and add categories to add or filter logging of desired
OJB packages, following the numerous examples in that file. For example,
 |  |  |
 |
<category name="org.apache.ojb">
<priority value="DEBUG" />
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</category>
<category name="org.apache.ojb.broker.metadata.RepositoryXmlHandler">
<priority value="ERROR" />
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</category>
|  |
 |  |  |