arminw 2005/07/24 16:56:11 Modified: src/java/org/apache/ojb/broker/core Tag: OJB_1_0_RELEASE PersistenceBrokerFactoryBaseImpl.java PersistenceBrokerFactoryDefaultImpl.java PersistenceBrokerFactoryIF.java PersistenceBrokerThreadMapping.java src/java/org/apache/ojb/broker Tag: OJB_1_0_RELEASE PersistenceBrokerFactory.java Log: add shutdown method to solve problems with re/hotdeployment of OJB in servlet/ejb-container, see user list thread (OJB ThreadLocal usage and reuse of thread instances in appServer)
http://www.mail-archive.com/ojb-user%40db.apache.org/msg14002.html Revision Changes Path No revision No revision 1.3.2.2 +17 -1 db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryBaseImpl.java Index: PersistenceBrokerFactoryBaseImpl.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryBaseImpl.java,v retrieving revision 1.3.2.1 retrieving revision 1.3.2.2 diff -u -r1.3.2.1 -r1.3.2.2 --- PersistenceBrokerFactoryBaseImpl.java 7 May 2005 16:51:09 -0000 1.3.2.1 +++ PersistenceBrokerFactoryBaseImpl.java 24 Jul 2005 23:56:11 -0000 1.3.2.2 @@ -19,6 +19,7 @@ import org.apache.ojb.broker.PBKey; import org.apache.ojb.broker.PersistenceBroker; import org.apache.ojb.broker.PersistenceBrokerInternal; +import org.apache.ojb.broker.accesslayer.ConnectionFactoryFactory; import org.apache.ojb.broker.metadata.MetadataManager; import org.apache.ojb.broker.util.BrokerHelper; import org.apache.ojb.broker.util.ClassHelper; @@ -185,4 +186,19 @@ { return 0; } + + public void shutdown() + { + try + { + ConnectionFactoryFactory.getInstance().createConnectionFactory().releaseAllResources(); + PersistenceBrokerThreadMapping.shutdown(); + MetadataManager.getInstance().shutdown(); + } + catch(RuntimeException e) + { + log.error("Error while shutdown of OJB", e); + throw e; + } + } } 1.11.2.2 +18 -5 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.11.2.1 retrieving revision 1.11.2.2 diff -u -r1.11.2.1 -r1.11.2.2 --- PersistenceBrokerFactoryDefaultImpl.java 7 May 2005 16:51:09 -0000 1.11.2.1 +++ PersistenceBrokerFactoryDefaultImpl.java 24 Jul 2005 23:56:11 -0000 1.11.2.2 @@ -159,16 +159,29 @@ super.releaseAllInstances(); try { - brokerPool.clear(); - // TODO: should we setup a new pool instance? - //brokerPool = this.createPool(); + brokerPool.close(); + brokerPool = this.createPool(); } catch (Exception e) { - log.error("Clearing of broker pool failed", e); + log.error("Error while release all pooled broker instances and refresh pool", e); } } + public void shutdown() + { + try + { + brokerPool.close(); + brokerPool = null; + } + catch(Exception e) + { + log.error("Error while shutdown of broker pool", e); + } + super.shutdown(); + } + public int activePersistenceBroker() { return brokerPool.getNumActive(); 1.4.2.2 +11 -1 db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryIF.java Index: PersistenceBrokerFactoryIF.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryIF.java,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -u -r1.4.2.1 -r1.4.2.2 --- PersistenceBrokerFactoryIF.java 7 May 2005 16:51:09 -0000 1.4.2.1 +++ PersistenceBrokerFactoryIF.java 24 Jul 2005 23:56:11 -0000 1.4.2.2 @@ -89,4 +89,14 @@ * instances. */ public int activePersistenceBroker(); + + /** + * Shutdown method for OJB, kills all running processes within OJB - after + * shutdown OJB can no longer be used. + * <br/> + * This method is introduced to solve hot/redeployment problems (memory leaks) caused by + * the usage of [EMAIL PROTECTED] ThreadLocal} instances in OJB source and the reuse of threads + * by the container (e.g. servlet- or ejb-container). + */ + public void shutdown(); } 1.6.2.2 +63 -14 db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerThreadMapping.java Index: PersistenceBrokerThreadMapping.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerThreadMapping.java,v retrieving revision 1.6.2.1 retrieving revision 1.6.2.2 diff -u -r1.6.2.1 -r1.6.2.2 --- PersistenceBrokerThreadMapping.java 7 May 2005 16:51:09 -0000 1.6.2.1 +++ PersistenceBrokerThreadMapping.java 24 Jul 2005 23:56:11 -0000 1.6.2.2 @@ -15,7 +15,9 @@ * limitations under the License. */ +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.WeakHashMap; @@ -35,26 +37,42 @@ public class PersistenceBrokerThreadMapping { /** + * A Collection of all HashMaps added to the <CODE>ThreadLocal currentBrokerMap</CODE> that are still -alive-. + * If all the PersistenceBrokers are always correctly closed, the Collection should remain empty. + * The Collection is iterated trough when calling the <CODE>shutdown()</CODE> method and all the maps that are + * still alive will be cleared. + */ + private static Collection loadedHMs = new HashSet(); + + /** * The hashmap that maps PBKeys to current brokers for the thread - **/ + */ private static ThreadLocal currentBrokerMap = new ThreadLocal(); + /** + * Mark a PersistenceBroker as preferred choice for current Thread + * + * @param key The PBKey the broker is associated to + * @param broker The PersistenceBroker to mark as current + */ public static void setCurrentPersistenceBroker(PBKey key, PersistenceBrokerInternal broker) - throws PBFactoryException + throws PBFactoryException { HashMap map = (HashMap) currentBrokerMap.get(); WeakHashMap set = null; - if (map == null) + if(map == null) { map = new HashMap(); currentBrokerMap.set(map); + + loadedHMs.add(map); } else { set = (WeakHashMap) map.get(key); } - if (set == null) + if(set == null) { // We emulate weak HashSet using WeakHashMap set = new WeakHashMap(); @@ -63,17 +81,32 @@ set.put(broker, null); } + /** + * Unmark a PersistenceBroker as preferred choice for current Thread + * + * @param key The PBKey the broker is associated to + * @param broker The PersistenceBroker to unmark + */ public static void unsetCurrentPersistenceBroker(PBKey key, PersistenceBrokerInternal broker) - throws PBFactoryException + throws PBFactoryException { HashMap map = (HashMap) currentBrokerMap.get(); WeakHashMap set = null; - if (map != null) + if(map != null) { set = (WeakHashMap) map.get(key); - if (set != null) + if(set != null) { set.remove(broker); + if(set.isEmpty()) + { + map.remove(key); + } + } + if(map.isEmpty()) + { + currentBrokerMap.set(null); + loadedHMs.remove(map); } } } @@ -81,42 +114,58 @@ /** * Return the current open [EMAIL PROTECTED] org.apache.ojb.broker.PersistenceBroker} * instance for the given [EMAIL PROTECTED] org.apache.ojb.broker.PBKey}, if any. + * * @param key * @return null if no open [EMAIL PROTECTED] org.apache.ojb.broker.PersistenceBroker} found. */ public static PersistenceBrokerInternal currentPersistenceBroker(PBKey key) - throws PBFactoryException, PersistenceBrokerException + throws PBFactoryException, PersistenceBrokerException { HashMap map = (HashMap) currentBrokerMap.get(); WeakHashMap set; PersistenceBrokerInternal broker = null; - if (map == null) + if(map == null) { return null; } set = (WeakHashMap) map.get(key); - if (set == null) + if(set == null) { return null; } // seek for an open broker, preferably in transaction - for (Iterator it = set.keySet().iterator(); it.hasNext(); ) + for(Iterator it = set.keySet().iterator(); it.hasNext();) { PersistenceBrokerInternal tmp = (PersistenceBrokerInternal) it.next(); - if (tmp == null || tmp.isClosed()) + if(tmp == null || tmp.isClosed()) { it.remove(); continue; } broker = tmp; - if (tmp.isInTransaction()) + if(tmp.isInTransaction()) { break; // the best choice found } } return broker; } + + /** + * Clean up static fields and any registered ThreadLocal contents to grant a clean + * shutdown/reload of OJB within re/hot-deployable applications. + */ + public static void shutdown() + { + for(Iterator it = loadedHMs.iterator(); it.hasNext();) + { + ((HashMap) it.next()).clear(); + } + loadedHMs.clear(); + loadedHMs = null; + currentBrokerMap = null; + } } No revision No revision 1.23.2.1 +9 -1 db-ojb/src/java/org/apache/ojb/broker/PersistenceBrokerFactory.java Index: PersistenceBrokerFactory.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/PersistenceBrokerFactory.java,v retrieving revision 1.23 retrieving revision 1.23.2.1 diff -u -r1.23 -r1.23.2.1 --- PersistenceBrokerFactory.java 4 Apr 2004 23:53:30 -0000 1.23 +++ PersistenceBrokerFactory.java 24 Jul 2005 23:56:11 -0000 1.23.2.1 @@ -93,4 +93,12 @@ { PersistenceBrokerFactoryFactory.instance().releaseAllInstances(); } + + /** + * @see org.apache.ojb.broker.core.PersistenceBrokerFactoryIF#shutdown() + */ + public static void shutdown() + { + PersistenceBrokerFactoryFactory.instance().shutdown(); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]