You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2004/01/09 20:29:37 UTC

cvs commit: db-ojb/src/connector/main/org/apache/ojb/jboss PBFactory.java ODMGFactory.java

arminw      2004/01/09 11:29:37

  Modified:    xdocs    deployment.xml
               src/test/org/apache/ojb OJB.properties
               src/java/org/apache/ojb/broker/core
                        PersistenceBrokerFactoryDefaultImpl.java
               src/connector/main/org/apache/ojb/jboss PBFactory.java
                        ODMGFactory.java
  Added:       src/java/org/apache/ojb/broker/core
                        PersistenceBrokerFactorySyncImpl.java
  Log:
  - add new PBF that allows to participate PB instances in JTA transaction
  using Synchronization
  
  - update documentation and OJB.properties
  
  - some beautification
  
  Revision  Changes    Path
  1.29      +96 -52    db-ojb/xdocs/deployment.xml
  
  Index: deployment.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/xdocs/deployment.xml,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- deployment.xml	15 Dec 2003 10:19:32 -0000	1.28
  +++ deployment.xml	9 Jan 2004 19:29:36 -0000	1.29
  @@ -32,7 +32,7 @@
       <li>
           <a href="#Deployment in EJB based applications">Deployment in EJB based applications</a>
           <ul>
  -            <li><a href="#Instructions for JBoss">Instructions for JBoss</a></li>
  +            <li><a href="#Example: Instructions for JBoss">Example: Instructions for JBoss</a></li>
               <li><a href="#Build the OJB sample session beans">Build the OJB sample session beans</a></li>
               <li><a href="#Instructions for Weblogic">Instructions for Weblogic</a></li>
           </ul>
  @@ -237,14 +237,23 @@
   <p>
   The instructions to make OJB running within your application server
   should be similar for all server. So the following instructions for JBoss
  -should be useful for all users.
  +should be useful for all user. E.g. most <code>OJB.properties</code> file settings
  +are the same for all application server.
   </p>
  +<P>
  +    There are some topics you should examine very carefully:
  +    <ul>
  +        <li><b>Caching</b>: </li>
  +        <li><b>Connection handling</b></li>
  +        <li><b>Locking</b></li>
  +    </ul>
  +</P>
   
   
   
  -<subsection name="Instructions for JBoss">
  +<subsection name="Example: Instructions for JBoss">
   <br/>
  -<i>The eight step guide to felicity</i>
  +<font size="-1"><i>The eight step guide to felicity (or insanity in some cases)</i></font>
   <br/>
   <p>
   <b>1. Get the missed jar files</b>
  @@ -253,27 +262,22 @@
   jar files with OJB. Thus you need some extra jar files to make the ejb
   examples target run:
   <ul>
  -    <li>jboss-common.jar</li>
  -    <li>jboss-j2ee.jar (or use j2ee jars fron SUN)</li>
  -    <li>jboss-jmx.jar</li>
  -    <li>jboss-system.jar</li>
  -    <li>xdoclet.jar and modules for generating ejb's</li>
  +    <li>JBoss jar files to support the OJB mbeans (jars depend on used version, so trial and error)</li>
  +    <li>jboss-j2ee.jar or use j2ee jars fron SUN</li>
  +    <li>XDoclet jar file and modules for generating ejb's and jboss deployment descriptor (modules: jboss, jmx, ejb, web)</li>
   </ul>
  -Put these jar files in the <code>lib</code> directory of OJB.
  +Put these jar files in the <code>lib</code> directory of OJB if you want to generate the ejb-examples.
   </p>
   
   
   <p>
  -<b>2. Make a .sar directory</b>
  -<br/>
  -Make a <code>ojb.sar</code> directory under <code>[jboss.home]/server/default/deploy</code>
  +<b>2. Bind OJB api-main classes to JNDI</b>
   <br/>
  -Add a <code>META-INF</code> directory under <code>ojb.sar</code>.
  -<br/>
  -Put a simple <code>MANIFEST.MF</code> files and a <code>jboss-service.xml</code>
  -file in this directory.
  +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 <code>mbean</code> classes
  +    to do that <code>org.apache.ojb.jboss.PBFactory</code> and <code>org.apache.ojb.jboss.ODMGFactory</code>.
   <br/>
  -The <code>jboss-service</code> file looks like:
  +Let JBoss know about the new mbeans, so declare tem in a <code>jboss-service.xml</code> file:
   <source><![CDATA[
   <?xml version="1.0" encoding="UTF-8"?>
   
  @@ -292,24 +296,42 @@
   </server>
   ]]></source>
   
  -This entries make OJB accessible via JNDI.
  +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:
  +    <ul>
  +        <li>
  +            <code>org.apache.ojb.broker.core.PersistenceBrokerFactoryFactory</code> for PB-api.
  +            Make method <code>PersistenceBrokerFactoryFactory.instance()</code> accessible.
  +        </li>
  +        <li>
  +            <code>org.apache.ojb.odmg.OJBJ2EE_2</code> for ODMG-api. Make method
  +            <code>OJBJ2EE_2.getInstance()</code> accessible.
  +        </li>
  +    </ul>
   </p>
   
   
   <p>
  -<b>3. Put libraries to .sar-directory</b>
  +<b>3. Enclose all libraries OJB depend on and put them into a .sar-directory</b>
  +<br/>
  +Make a <code>ojb.sar</code> directory under <code>[jboss.home]/server/default/deploy</code>
  +<br/>
  +Add a <code>META-INF</code> directory under <code>ojb.sar</code>.
  +<br/>
  +Put a simple <code>MANIFEST.MF</code> file and the <code>jboss-service.xml</code>
  +file in this directory.
   <br/>
  -To make OJB run and (re-)deployable you have to put the
  -jars OJB depend on to the <code>ojb.sar</code> directory:
  +To make OJB run and (re-)deployable you have to put all libraries
  +OJB depend on into the <code>ojb.sar</code> directory:
   <ul>
   <li>The jakarta commons libraries files (all commons-xxx.jar)</li>
  -<li>The antlr jar files (all antlrxxx.jar)</li>
  +<li>The antlr jar file (antlr-xxx.jar)</li>
   </ul>
  -(This was tested with jboss 3.0.6)
  +(This was tested with jboss 3.2.2)
   </p>
  -<p>
  -
   
  +<p>
   <b>4. Prepare OJB code base</b>
   <br/>
   With <code>bin\build.bat prepare-jboss jar</code>
  @@ -320,8 +342,11 @@
   The <code>prepare-jboss</code> target copy the jboss MBeans to the OJB code
   base. After running the <code>jar</code> target you could find the new
   <code>db-ojb-xxx.jar</code>, including the MBeans, in the <code>dist</code>
  -directory (If you need a OJB jar file without the MBeans, clean <code>target</code>
  -directory and invoke the <code>jar</code> ant target).
  +directory.
  +<br/>
  +(If you need a OJB jar file without the MBeans, clean the <code>target</code>
  +directory e.g. by calling the <code>clean</code> ant target and invoke the
  +<code>jar</code> ant target again).
   <br/>
   Copy the <code>db-ojb-xxx.jar</code> file into the <code>ojb.sar</code> directory.
   </p>
  @@ -370,8 +395,19 @@
   <p>
   <a name="jboss-ojb.properties"/>
   <b>6. Adapt OJB.properties file</b>
  -<br/>
  -Your OJB.properties file need the following settings:
  +<p>
  +If <b>only</b> the PB-api was used in managed environment, it's recommended to use
  +a special PersistenceBrokerFactory class, 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):
  +<source>
  +PersistenceBrokerFactoryClass=
  +org.apache.ojb.broker.core.PersistenceBrokerFactorySyncImpl
  +</source>
  +Don't use this setting in conjunction with the ODMG-api.
  +</p>
  +<p>
  +Your OJB.properties file need the following additional settings:
   <source><![CDATA[
   ...
   ConnectionFactoryClass=
  @@ -384,27 +420,11 @@
   JTATransactionManagerClass=
   org.apache.ojb.otm.transaction.factory.JBossTransactionManagerFactory
   ]]></source>
  -<p>
  -Using the PB-api it is recommended to use
  -<br/><code>ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCachePerBrokerImpl</code>
  -<br/>or
  -<br/><code>ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCacheEmptyImpl</code>.
  -<br/>
  -because PB-api do not use JTA-Synchronization like ODMG-api implementation.
   </p>
  -When using the ODMG-api and the application server is not clustered it's possible
  -to use all <code>ObjectCache</code> implementations. In clustered environments you
  -need a distributed ObjectCache or you should use a local/empty cache like
  -<br/><code>ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCachePerBrokerImpl</code>
  -<br/>or
  -<br/><code>ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCacheEmptyImpl</code>.
  -More info you can find in
  -<a href="howto-work-with-clustering.html">clustering</a> and
  -<a href="objectcache.html">ObjectCache</a> topic.
   </p>
   
   <p>
  -<b>7. Declare datasources in the repository (repository_database) file</b>
  +<b>7. Declare datasources in the repository (repository_database) file and do additional configuration</b>
   <br/>
   Do only use <code>DataSource</code> from the application server to connect your databases.
   <br/>
  @@ -429,6 +449,10 @@
       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">
  @@ -439,7 +463,28 @@
   in managed environments, because it's in most cases not
   allowed to change autoCommit state.
   </p>
  -
  +<p>
  +    In managed environments you can't use the default sequence manager (SequenceManagerHighLowImpl)
  +    of OJB. For alternative sequence manager implemetation <a href="sequencemanager.html">see here</a>.
  +</p>
  +<p>
  +Most important thing is cache synchronization with the database.
  +When using the ODMG-api or PB-api (with <a href="#jboss-ojb.properties">special PBF (see 6.)</a> setting)
  +it's possible to use all <code>ObjectCache</code> implementations as long as OJB doesn't run
  +in a clustered mode. When the <code>ObjectCacheDefaultImpl</code> cache implementation was used it's
  +recommended to enable the <code>autoSync</code> mode.
  +<br/>
  +In clustered environments (OJB run on different AppServer nodes) you
  +need a distributed ObjectCache or you should use a local/empty cache like
  +<br/><code>ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCachePerBrokerImpl</code>
  +<br/>or
  +<br/><code>ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCacheEmptyImpl</code>.
  +<p>
  +More info you can find in
  +<a href="howto-work-with-clustering.html">clustering</a> and
  +<a href="objectcache.html">ObjectCache</a> topic.
  +</p>
  +</p>
   
   <p>
   <b>7b. How to deploy ojb test hsqldb database to jboss</b>
  @@ -711,7 +756,8 @@
   when the JNDI lookup was done.
   </p>
   <p>
  -Write an OJB startup class:
  +Write an OJB startup class can look like (I couldn't test this sample class, so
  +don't know if it will work ;-)):
   <a name="pb.factory"/>
   <source>
   package org.apache.ojb.weblogic;
  @@ -734,11 +780,9 @@
   {
       private String defaultPropsFile =
           "org/apache/ojb/weblogic/OJB.properties";
  -    private T3ServicesDef services;
   
       public void setServices (T3ServicesDef services)
       {
  -        this.services = services;
       }
   
       public PersistenceBrokerFactoryIF getInstance()
  
  
  
  1.60      +6 -2      db-ojb/src/test/org/apache/ojb/OJB.properties
  
  Index: OJB.properties
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/OJB.properties,v
  retrieving revision 1.59
  retrieving revision 1.60
  diff -u -r1.59 -r1.60
  --- OJB.properties	6 Dec 2003 19:06:41 -0000	1.59
  +++ OJB.properties	9 Jan 2004 19:29:37 -0000	1.60
  @@ -32,6 +32,11 @@
   # The PersistenceBrokerFactoryClass entry decides which concrete
   # PersistenceBrokerFactory implemention is to be used.
   PersistenceBrokerFactoryClass=org.apache.ojb.broker.core.PersistenceBrokerFactoryDefaultImpl
  +# If in managed environment *only* the PB-api was used it's recommended to use this factory
  +# to enable the PersistenceBroker instances to participate in the JTA transaction. This makes
  +# e.g. PBStateListener work properly in managed environments.
  +#PersistenceBrokerFactoryClass=org.apache.ojb.broker.core.PersistenceBrokerFactorySyncImpl
  +#
   #
   # The PersistenceBrokerClass entry decides which concrete PersistenceBroker
   # implementation is to be served by the PersistenceBrokerFactory.
  @@ -41,7 +46,6 @@
   # This is an implementation that uses Prevayler (prevayler.sf.net) as the persistent storage.
   # Using this implementation OJB works as a simple OODBMS
   #PersistenceBrokerClass=org.apache.ojb.broker.prevayler.PBPrevaylerImpl
  -#
   #
   #----------------------------------------------------------------------------------------
   # PersistenceBroker pool
  
  
  
  1.7       +10 -2     db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryDefaultImpl.java
  
  Index: PersistenceBrokerFactoryDefaultImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryDefaultImpl.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- PersistenceBrokerFactoryDefaultImpl.java	4 Jan 2004 18:20:31 -0000	1.6
  +++ PersistenceBrokerFactoryDefaultImpl.java	9 Jan 2004 19:29:37 -0000	1.7
  @@ -122,7 +122,7 @@
       public PersistenceBroker createPersistenceBroker(PBKey pbKey) throws PBFactoryException
       {
           if (log.isDebugEnabled()) log.debug("Obtain broker from pool, used PBKey is " + pbKey);
  -        PersistenceBroker broker;
  +        PersistenceBroker broker = null;
   
           /*
           try to find a valid PBKey, if given key does not full match
  @@ -145,6 +145,14 @@
           }
           catch (Exception e)
           {
  +            try
  +            {
  +                // if something going wrong, tryto close broker
  +                if(broker != null) broker.close();
  +            }
  +            catch (Exception ignore)
  +            {
  +            }
               throw new PBFactoryException("Borrow broker from pool failed, using PBKey " + pbKey, e);
           }
           return broker;
  
  
  
  1.1                  db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactorySyncImpl.java
  
  Index: PersistenceBrokerFactorySyncImpl.java
  ===================================================================
  package org.apache.ojb.broker.core;
  
  import javax.transaction.RollbackException;
  import javax.transaction.Status;
  import javax.transaction.Synchronization;
  import javax.transaction.SystemException;
  import javax.transaction.Transaction;
  import javax.transaction.TransactionManager;
  import java.lang.reflect.Field;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.WeakHashMap;
  
  import org.apache.commons.pool.KeyedObjectPool;
  import org.apache.ojb.broker.PBFactoryException;
  import org.apache.ojb.broker.PersistenceBroker;
  import org.apache.ojb.broker.TransactionAbortedException;
  import org.apache.ojb.broker.TransactionInProgressException;
  import org.apache.ojb.broker.TransactionNotInProgressException;
  import org.apache.ojb.broker.accesslayer.ConnectionManagerIF;
  import org.apache.ojb.broker.util.logging.Logger;
  import org.apache.ojb.broker.util.logging.LoggerFactory;
  import org.apache.ojb.odmg.transaction.TransactionManagerFactoryException;
  import org.apache.ojb.odmg.transaction.TransactionManagerFactoryFactory;
  
  /**
   * Workaround for participate the PB-api in JTA {@link javax.transaction.Transaction transaction} by
   * implementing the {@link javax.transaction.Synchronization} interface.
   * <br/>
   * This may will be deprecated when we implemented a full JCA compliant connector.
   * <br/>
   * When a new {@link PersistenceBroker} instance is created in method {@link #wrapBrokerWithPoolingHandle}
   * the given PB instance is wrapped with {@link PersistenceBrokerSync} before it was put to the PB-pool.
   * When a PB instance was requested class try to lookup the current JTA transaction in
   * {@link #wrapRequestedBrokerInstance} before the pooled PB instance was wrapped with the PB handle.
   * If a running tx was found the PB instance was registered with the transaction using the
   * {@link Synchronization} interface.
   *
   * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
   * @version $Id: PersistenceBrokerFactorySyncImpl.java,v 1.1 2004/01/09 19:29:37 arminw Exp $
   */
  public class PersistenceBrokerFactorySyncImpl extends PersistenceBrokerFactoryDefaultImpl
  {
      private Logger log = LoggerFactory.getLogger(PersistenceBrokerFactorySyncImpl.class);
      private TransactionManager txMan;
      private TxRegistry txRegistry;
  
      public PersistenceBrokerFactorySyncImpl()
      {
          super();
          try
          {
              txMan = TransactionManagerFactoryFactory.instance().getTransactionManager();
          }
          catch (TransactionManagerFactoryException e)
          {
              throw new PBFactoryException("Can't instantiate TransactionManager of managed environment", e);
          }
          txRegistry = new TxRegistry();
      }
  
      protected PersistenceBroker wrapBrokerWithPoolingHandle(PersistenceBroker broker, KeyedObjectPool pool)
      {
          // wrap real PB instance with an extended version of pooling PB
          return new PersistenceBrokerSync(broker, pool);
      }
  
      protected PersistenceBroker wrapRequestedBrokerInstance(PersistenceBroker broker)
      {
          // all PB instance should be of this type
          if (!(broker instanceof PersistenceBrokerSync))
          {
              throw new PBFactoryException("Expect instance of " + PersistenceBrokerSync.class
                      + ", found " + broker.getClass());
          }
          /*
          Before we return the PB handle, we jump into the running JTA tx
          */
          PersistenceBrokerSync pb = (PersistenceBrokerSync) broker;
          try
          {
              // search for an active tx
              Transaction tx = searchForValidTx();
              if (tx != null)
              {
                  txRegistry.register(tx, pb);
                  try
                  {
                      pb.internBegin();
                  }
                  catch (Exception e)
                  {
                      /*
                      if something going wrong with pb-tx, we rollback the
                      whole JTA tx
                      */
                      log.error("Unexpected exception when start intern pb-tx", e);
                      try
                      {
                          tx.setRollbackOnly();
                      }
                      catch (Throwable ignore)
                      {
                      }
                      throw new PBFactoryException("Unexpected exception when start intern pb-tx", e);
                  }
              }
          }
          catch (Exception e)
          {
              throw new PBFactoryException("Error while try to participate in JTA transaction", e);
          }
          return super.wrapRequestedBrokerInstance(broker);
      }
  
      private Transaction searchForValidTx() throws SystemException
      {
          Transaction tx = txMan.getTransaction();
          if (tx != null)
          {
              int status = tx.getStatus();
              if (status != Status.STATUS_ACTIVE && status != Status.STATUS_NO_TRANSACTION)
              {
                  throw new PBFactoryException("Transaction synchronization failed - wrong" +
                          " status of external JTA tx. Expected was an 'active' or 'no transaction'"
                          + ", found status is '" + getStatusFlagAsString(status) + "'");
              }
          }
          return tx;
      }
  
      /**
       * Returns a string representation of the given
       * {@link javax.transaction.Status} flag.
       */
      private static String getStatusFlagAsString(int status)
      {
          String statusName = "no match, unknown status!";
          try
          {
              Field[] fields = Status.class.getDeclaredFields();
              for (int i = 0; i < fields.length; i++)
              {
                  if (fields[i].getInt(null) == status)
                  {
                      statusName = fields[i].getName();
                      break;
                  }
              }
          }
          catch (Exception e)
          {
              statusName = "no match, unknown status!";
          }
          return statusName;
      }
  
      //****************************************************
      // inner class
      //****************************************************
      public static class PersistenceBrokerSync extends PoolablePersistenceBroker implements Synchronization
      {
          private Logger log = LoggerFactory.getLogger(PersistenceBrokerSync.class);
  
          public PersistenceBrokerSync(PersistenceBroker broker, KeyedObjectPool pool)
          {
              super(broker, pool);
          }
  
          public void beforeCompletion()
          {
              if (log.isDebugEnabled()) log.debug("beforeCompletion was called, nothing to do");
              ConnectionManagerIF cm = serviceConnectionManager();
              if(cm.isBatchMode()) cm.executeBatch();
              // close connection immediately to avoid bad reports from server con-pool
              cm.releaseConnection();
          }
  
          public void afterCompletion(int status)
          {
              if (log.isDebugEnabled()) log.debug("afterCompletion was called");
              /*
              we only commit if tx was successfully committed
              */
              try
              {
                  if (status != Status.STATUS_COMMITTED)
                  {
                      log.error("Abort PB-tx, status of JTA tx is " + getStatusFlagAsString(status));
                      internAbort();
                  }
                  else
                  {
                      if (log.isDebugEnabled()) log.debug("Commit PB-tx");
                      internCommit();
                  }
              }
              finally
              {
                  // returns the underlying PB instance to pool
                  doRealClose();
              }
          }
  
          private void internBegin()
          {
              super.beginTransaction();
          }
  
          private void internCommit()
          {
              super.commitTransaction();
          }
  
          private void internAbort()
          {
              super.abortTransaction();
          }
  
          private void doRealClose()
          {
              if (log.isDebugEnabled()) log.debug("Now do real close of PB instance");
              super.close();
          }
  
          public boolean close()
          {
              if (log.isDebugEnabled()) log.debug("PB close was called, but do not real close PB instance");
              /*
              don't really close (return to pool) the underlying PB instance. As recently
              as the JTA was completed we can return PB instance to pool
              */
              return true;
          }
  
          public void beginTransaction() throws TransactionInProgressException, TransactionAbortedException
          {
              throw new UnsupportedOperationException("In managed environments only JTA transaction demarcation allowed");
          }
  
          public void commitTransaction() throws TransactionNotInProgressException, TransactionAbortedException
          {
              throw new UnsupportedOperationException("In managed environments only JTA transaction demarcation allowed");
          }
  
          public void abortTransaction() throws TransactionNotInProgressException
          {
              throw new UnsupportedOperationException("In managed environments only JTA transaction demarcation allowed");
          }
      }
  
      //****************************************************
      // inner class
      //****************************************************
      /**
       * This class collects all PB instances requested in the scope of one transaction
       */
      class TransactionBox implements Synchronization
      {
          List syncList = new ArrayList();
          boolean isLocked = false;
          boolean isClosed = false;
  
          public TransactionBox()
          {
          }
  
          void add(Synchronization syncObj)
          {
              if (isLocked)
              {
                  throw new PBFactoryException("Can't associate object with JTA transaction, because tx-completion started");
              }
              syncList.add(syncObj);
          }
  
          public void afterCompletion(int status)
          {
              boolean failures = false;
              Synchronization synchronization = null;
              for (Iterator iterator = syncList.iterator(); iterator.hasNext();)
              {
                  try
                  {
                      synchronization = (Synchronization) iterator.next();
                      synchronization.afterCompletion(status);
                  }
                  catch (Exception e)
                  {
                      failures = true;
                      log.error("Unexpected error when perform Synchronization#afterCompletion method" +
                              " call on object " + synchronization, e);
                  }
              }
              isClosed = true;
              if (failures)
              {
                  throw new PBFactoryException("Unexpected error occured while performing" +
                          " Synchronization#afterCompletion method");
              }
          }
  
          public void beforeCompletion()
          {
              boolean failures = false;
              Synchronization synchronization = null;
              for (Iterator iterator = syncList.iterator(); iterator.hasNext();)
              {
                  try
                  {
                      synchronization = (Synchronization) iterator.next();
                      synchronization.beforeCompletion();
                  }
                  catch (Exception e)
                  {
                      failures = true;
                      log.error("Unexpected error when perform Synchronization#beforeCompletion method" +
                              " call on object " + synchronization, e);
                  }
              }
              isLocked = true;
              if (failures)
              {
                  throw new PBFactoryException("Unexpected error occured while performing" +
                          " Synchronization#beforeCompletion method");
              }
          }
      }
  
      //****************************************************
      // inner class
      //****************************************************
      /**
       * Maps all {@link TransactionBox} instances based on {@link Transaction} object identity.
       *
       * TODO: Not sure if we should held TransactionBox instances per thread or per transaction object identity.
       * As far as I know it is possible in JTA that thread A starts a tx and thread B commits the tx, thus I
       * start with tx identity as key in registry
       */
      class TxRegistry
      {
          Map txBoxMap;
  
          public TxRegistry()
          {
              txBoxMap = Collections.synchronizedMap(new WeakHashMap());
          }
  
          void register(Transaction tx, Synchronization syncObject) throws RollbackException, SystemException
          {
              TransactionBox txBox = (TransactionBox) txBoxMap.get(tx);
              if (txBox == null || txBox.isClosed)
              {
                  // if environment reuse tx instances we can find closed TransactionBox instances
                  if (txBox != null) txBoxMap.remove(tx);
                  txBox = new TransactionBox();
                  tx.registerSynchronization(txBox);
                  txBoxMap.put(tx, txBox);
              }
              txBox.add(syncObject);
          }
      }
  }
  
  
  
  1.3       +3 -2      db-ojb/src/connector/main/org/apache/ojb/jboss/PBFactory.java
  
  Index: PBFactory.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/connector/main/org/apache/ojb/jboss/PBFactory.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PBFactory.java	26 Apr 2003 23:18:26 -0000	1.2
  +++ PBFactory.java	9 Jan 2004 19:29:37 -0000	1.3
  @@ -97,8 +97,9 @@
           {
               e.printStackTrace();
           }
  -        getLog().info("PBFactory: "+this.getClass().getName()+" / "+this.getServiceName().toString());
  -        getLog().info("Lookup PBFactory via '"+JAVA_NAMESPACE+_jndiName+"'");
  +        System.out.println("** OJB-PB MBean integration");
  +        System.out.println("** PBFactory: "+this.getClass().getName()+" / "+this.getServiceName().toString());
  +        System.out.println("** Lookup PersistenceBrokerFactory via '"+JAVA_NAMESPACE+_jndiName+"'");
       }
   
       public void stopService()
  
  
  
  1.2       +1 -4      db-ojb/src/connector/main/org/apache/ojb/jboss/ODMGFactory.java
  
  Index: ODMGFactory.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/connector/main/org/apache/ojb/jboss/ODMGFactory.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ODMGFactory.java	13 Feb 2003 18:21:20 -0000	1.1
  +++ ODMGFactory.java	9 Jan 2004 19:29:37 -0000	1.2
  @@ -72,9 +72,6 @@
       private static final String JAVA_NAMESPACE = "java:/";
   
       private String jndiName;
  -    private String repository;
  -    private String user;
  -    private String password;
   
       public ODMGFactory()
       {
  @@ -94,7 +91,7 @@
               throw e;
           }
           System.out.println("** OJB-ODMG MBean integration");
  -        System.out.println("** ODMGFactory: " + this.getClass().getName() + " / " + this.getServiceName().toString());
  +        System.out.println("** ODMGFactory: " + this.getClass().getName();
           System.out.println("** Use ODMGFactory via lookup:");
           System.out.println("** ODMGFactory factory = (ODMGFactory) ctx.lookup(" + JAVA_NAMESPACE + jndiName + ")");
           System.out.println("** Implementation odmg = factory.getInstance();");
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org