You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2009/04/21 13:41:36 UTC

svn commit: r767119 - in /jackrabbit/branches/1.5: ./ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ jackrabbit-core/sr...

Author: jukka
Date: Tue Apr 21 11:41:35 2009
New Revision: 767119

URL: http://svn.apache.org/viewvc?rev=767119&view=rev
Log:
1.5: Merged revisions 152831, 757364 and 761267 (JCR-1216)

Added:
    jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/SessionGarbageCollectedTest.java
      - copied unchanged from r757364, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/SessionGarbageCollectedTest.java
Modified:
    jackrabbit/branches/1.5/   (props changed)
    jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
    jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransientRepository.java
    jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/StateChangeDispatcher.java
    jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java
    jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/SkipDeniedNodesTest.java

Propchange: jackrabbit/branches/1.5/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Apr 21 11:41:35 2009
@@ -1,2 +1,2 @@
 /jackrabbit/branches/1.3:631261
-/jackrabbit/trunk:703899-704158,704165,704167,704324,704358,704361,704864,704933,704939,705010,705033,705243,705496,705522,705579,705925,705932,705934,705937-705938,705961,706242,706273,706285-706286,706562,706606,706649,706655,706660,706697,706918,707303-707304,707307,707310,707630,708206,708598,708609,708613,708619,708634,708840,708863,708909,708929,708943,709115,709142,709207,709211,710047,711238,711566-711567,711595,711841-711843,712984-712985,713037,713059,713065,713072,713076,713162,713214,713956,713958,713964,713971,713975,714034,718218,718249-718250,718371,718376,718566,718632,718981,719225,719282,719575-719577,719579,719585-719586,719588,719592,720455,720484,720492,720524,720533,720540,720673,720679,720687,720784,720940,720969,721186,721191,721194,721235,721387-721389,721470,721495,722068-722069,722463,722465,722467,722470,722825,723281,723346,723728,723784,724300,724387,725292,727376,727388,727390,727395,727397,727402,727492,727701,728022,731896,731934,731941,73234
 7,732678,732686,732689,732693,732703,732715-732716,732719,732728,732730,732734-732738,732740,732742-732743,732745,732867,732883,733057-733059,733061,733080,734092,734366,734375,734400,734709,735401,736021,736030,736274,736276,736650-736651,736653-736656,736658,736680,737695,738087,738119,738121,738419,738422,738474,738512,739210,739212,739226,740262,740734,740736-740738,740747,740749-740750,741052,741100,741121,741206,741208-741210,741213,741509,741524,741652,741803,742382,742538,743295,743713,743718,743726,743734,743738,744883-744884,744889,744895,744911,744935,744940,744954,744956,745041,745051,745053,745056,745060,745120,745500,745534,745824,745849,746301-746302,746486,746602-746603,746609,746666,746747-746748,747325,747347,747358-747360,747362,747365,747368,747372,747785,747839,748232-748233,748247,748486,749237,749448,749622,749953,749965,750011,750437,752036-752039,752044,752046-752051,752053-752054,752056,752058-752060,752063-752067,752115,752131,752414-752415,752478,
 752543-752545,752809,752840-752841,753225-753228,753232,753244,755582,756378,756403,756405,756409,756429,756442,756444,757698,757775-757776,757814,757854,757856,757862,758263,758265,758349,758354,758629,758632,758634-758636,758639-758642,758646,758649,758653-758654,759880,760386,760479,761634,761645,761690-761691,761715,762671,762675,762700,762702,762731,762737,762755,762780-762781,762789,762793,762797,762802,762804,762808,762813-762814,762817-762818,762821-762823,763146,763160,763188,763205,763215,763242,763244,763248,763617,765322,765328,765337,765532,765551,765554,765556,765585
+/jackrabbit/trunk:703899-704158,704165,704167,704324,704358,704361,704864,704933,704939,705010,705033,705243,705496,705522,705579,705925,705932,705934,705937-705938,705961,706242,706273,706285-706286,706562,706606,706649,706655,706660,706697,706918,707303-707304,707307,707310,707630,708206,708598,708609,708613,708619,708634,708840,708863,708909,708929,708943,709115,709142,709207,709211,710047,711238,711566-711567,711595,711841-711843,712984-712985,713037,713059,713065,713072,713076,713162,713214,713956,713958,713964,713971,713975,714034,718218,718249-718250,718371,718376,718566,718632,718981,719225,719282,719575-719577,719579,719585-719586,719588,719592,720455,720484,720492,720524,720533,720540,720673,720679,720687,720784,720940,720969,721186,721191,721194,721235,721387-721389,721470,721495,722068-722069,722463,722465,722467,722470,722825,723281,723346,723728,723784,724300,724387,725292,727376,727388,727390,727395,727397,727402,727492,727701,728022,731896,731934,731941,73234
 7,732678,732686,732689,732693,732703,732715-732716,732719,732728,732730,732734-732738,732740,732742-732743,732745,732867,732883,733057-733059,733061,733080,734092,734366,734375,734400,734709,735401,736021,736030,736274,736276,736650-736651,736653-736656,736658,736680,737695,738087,738119,738121,738419,738422,738474,738512,739210,739212,739226,740262,740734,740736-740738,740747,740749-740750,741052,741100,741121,741206,741208-741210,741213,741509,741524,741652,741803,742382,742538,743295,743713,743718,743726,743734,743738,744883-744884,744889,744895,744911,744935,744940,744954,744956,745041,745051,745053,745056,745060,745120,745500,745534,745824,745849,746301-746302,746486,746602-746603,746609,746666,746747-746748,747325,747347,747358-747360,747362,747365,747368,747372,747785,747839,748232-748233,748247,748486,749237,749448,749622,749953,749965,750011,750437,752036-752039,752044,752046-752051,752053-752054,752056,752058-752060,752063-752067,752115,752131,752414-752415,752478,
 752543-752545,752809,752831,752840-752841,753225-753228,753232,753244,755582,756378,756403,756405,756409,756429,756442,756444,757364,757698,757775-757776,757814,757854,757856,757862,758263,758265,758349,758354,758629,758632,758634-758636,758639-758642,758646,758649,758653-758654,759880,760386,760479,761267,761279-761280,761282-761283,761292,761634,761645,761690-761691,761715,762671,762675,762700,762702,762731,762737,762755,762780-762781,762789,762793,762797,762802,762804,762808,762813-762814,762817-762818,762821-762823,763146,763160,763188,763205,763215,763242,763244,763248,763617,765322,765328,765337,765532,765551,765554,765556,765585

Modified: jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java?rev=767119&r1=767118&r2=767119&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java Tue Apr 21 11:41:35 2009
@@ -231,6 +231,12 @@
      * Retention and Hold Manager
      */
     private RetentionManager retentionManager;
+        
+    /**
+     * The stack trace knows who opened this session. It is logged
+     * if the session is finalized, but Session.logout() was never called.
+     */
+    private Exception openStackTrace = new Exception("Stack Trace");
 
     /**
      * Protected constructor.
@@ -1556,5 +1562,17 @@
         ps.println();
         itemStateMgr.dump(ps);
     }
+    
+    /**
+     * Finalize the session. If the application doesn't close Session.logout(), 
+     * the session is closed automatically; however a warning is written to the log file, 
+     * together with the stack trace of where the session was opened.
+     */
+    public void finalize() {
+        if (alive) {
+            log.warn("Unclosed session detected. The session was opened here: ", openStackTrace);
+            logout();
+        }
+    }
 
 }

Modified: jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransientRepository.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransientRepository.java?rev=767119&r1=767118&r2=767119&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransientRepository.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransientRepository.java Tue Apr 21 11:41:35 2009
@@ -25,14 +25,14 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
-import java.util.Set;
 
 import javax.jcr.Credentials;
-import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.api.JackrabbitRepository;
 import org.apache.jackrabbit.core.config.ConfigurationException;
@@ -57,11 +57,6 @@
         LoggerFactory.getLogger(TransientRepository.class);
 
     /**
-     * Buffer size for copying the default repository configuration file.
-     */
-    private static final int BUFFER_SIZE = 4096;
-
-    /**
      * Resource path of the default repository configuration file.
      */
     private static final String DEFAULT_REPOSITORY_XML = "repository.xml";
@@ -123,7 +118,7 @@
      * repository instance is automatically shut down until a new session
      * is opened.
      */
-    private final Set sessions;
+    private final Map sessions = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.WEAK);
 
     /**
      * The static repository descriptors. The default {@link RepositoryImpl}
@@ -142,7 +137,6 @@
     public TransientRepository(RepositoryFactory factory) throws IOException {
         this.factory = factory;
         this.repository = null;
-        this.sessions = new HashSet();
         this.descriptors = new Properties();
 
         // FIXME: The current RepositoryImpl class does not allow static
@@ -331,9 +325,9 @@
 
         try {
             logger.debug("Opening a new session");
-            Session session = repository.login(credentials, workspaceName);
-            sessions.add(session);
-            ((SessionImpl) session).addListener(this);
+            SessionImpl session = (SessionImpl) repository.login(credentials, workspaceName);
+            sessions.put(session, session);
+            session.addListener(this);
             logger.info("Session opened");
 
             return session;
@@ -393,7 +387,7 @@
      * @see Session#logout()
      */
     public synchronized void shutdown() {
-        Iterator iterator = new HashSet(sessions).iterator();
+        Iterator iterator = new HashSet(sessions.keySet()).iterator();
         while (iterator.hasNext()) {
             Session session = (Session) iterator.next();
             session.logout();
@@ -410,7 +404,7 @@
      * @see SessionListener#loggedOut(SessionImpl)
      */
     public synchronized void loggedOut(SessionImpl session) {
-        assert sessions.contains(session);
+        assert sessions.containsKey(session);
         sessions.remove(session);
         logger.info("Session closed");
         if (sessions.isEmpty()) {

Modified: jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/StateChangeDispatcher.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/StateChangeDispatcher.java?rev=767119&r1=767118&r2=767119&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/StateChangeDispatcher.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/StateChangeDispatcher.java Tue Apr 21 11:41:35 2009
@@ -20,6 +20,8 @@
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.spi.Name;
 
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
 import java.util.Collection;
 import java.util.Iterator;
 
@@ -30,12 +32,14 @@
 public class StateChangeDispatcher {
 
     /**
-     * Simple item state listeners
+     * Simple item state listeners.
+     * A copy on write array list is used so that no synchronization is required.
      */
     private final Collection listeners = new CopyOnWriteArrayList();
 
     /**
      * Node state listeners
+     * A copy on write array list is used so that no synchronization is required.
      */
     private final transient Collection nsListeners = new CopyOnWriteArrayList();
 
@@ -44,14 +48,29 @@
      * @param listener the new listener to be informed on modifications
      */
     public void addListener(ItemStateListener listener) {
-        assert (!listeners.contains(listener));
-        listeners.add(listener);
+        assert getReference(listeners, listener) == null;
+        listeners.add(new WeakReference(listener));
 
         if (listener instanceof NodeStateListener) {
-            assert (!nsListeners.contains(listener));
-            nsListeners.add(listener);
+            assert getReference(nsListeners, listener) == null;
+            nsListeners.add(new WeakReference(listener));
         }
     }
+    
+    private Reference getReference(Collection coll, ItemStateListener listener) {
+        Iterator iter = coll.iterator();
+        while (iter.hasNext()) {
+            Reference ref = (Reference) iter.next();
+            Object o = ref.get();
+            if (o == listener) {
+                return ref;
+            } else if (o == null) {
+                // clean up unreferenced objects
+                coll.remove(ref);
+            }
+        }
+        return null;
+    }
 
     /**
      * Remove an <code>ItemStateListener</code>
@@ -59,9 +78,9 @@
      */
     public void removeListener(ItemStateListener listener) {
         if (listener instanceof NodeStateListener) {
-            nsListeners.remove(listener);
+            nsListeners.remove(getReference(nsListeners, listener));
         }
-        listeners.remove(listener);
+        listeners.remove(getReference(listeners, listener));
     }
 
     /**
@@ -71,7 +90,11 @@
     public void notifyStateCreated(ItemState created) {
         Iterator iter = listeners.iterator();
         while (iter.hasNext()) {
-            ((ItemStateListener) iter.next()).stateCreated(created);
+            Reference ref = (Reference) iter.next();
+            ItemStateListener l = (ItemStateListener) ref.get();
+            if (l != null) {
+                l.stateCreated(created);
+            }
         }
     }
 
@@ -82,7 +105,11 @@
     public void notifyStateModified(ItemState modified) {
         Iterator iter = listeners.iterator();
         while (iter.hasNext()) {
-            ((ItemStateListener) iter.next()).stateModified(modified);
+            Reference ref = (Reference) iter.next();
+            ItemStateListener l = (ItemStateListener) ref.get();
+            if (l != null) {
+                l.stateModified(modified);
+            }
         }
     }
 
@@ -93,7 +120,11 @@
     public void notifyStateDestroyed(ItemState destroyed) {
         Iterator iter = listeners.iterator();
         while (iter.hasNext()) {
-            ((ItemStateListener) iter.next()).stateDestroyed(destroyed);
+            Reference ref = (Reference) iter.next();
+            ItemStateListener l = (ItemStateListener) ref.get();
+            if (l != null) {
+                l.stateDestroyed(destroyed);
+            }            
         }
     }
 
@@ -104,7 +135,11 @@
     public void notifyStateDiscarded(ItemState discarded) {
         Iterator iter = listeners.iterator();
         while (iter.hasNext()) {
-            ((ItemStateListener) iter.next()).stateDiscarded(discarded);
+            Reference ref = (Reference) iter.next();
+            ItemStateListener l = (ItemStateListener) ref.get();
+            if (l != null) {
+                l.stateDiscarded(discarded);
+            }               
         }
     }
 
@@ -118,7 +153,11 @@
     public void notifyNodeAdded(NodeState state, Name name, int index, NodeId id) {
         Iterator iter = nsListeners.iterator();
         while (iter.hasNext()) {
-            ((NodeStateListener) iter.next()).nodeAdded(state, name, index, id);
+            Reference ref = (Reference) iter.next();
+            NodeStateListener n = (NodeStateListener) ref.get();
+            if (n != null) {
+                n.nodeAdded(state, name, index, id);
+            }                 
         }
     }
 
@@ -129,7 +168,11 @@
     public void notifyNodesReplaced(NodeState state) {
         Iterator iter = nsListeners.iterator();
         while (iter.hasNext()) {
-            ((NodeStateListener) iter.next()).nodesReplaced(state);
+            Reference ref = (Reference) iter.next();
+            NodeStateListener n = (NodeStateListener) ref.get();
+            if (n != null) {
+                n.nodesReplaced(state);
+            }              
         }
     }
 
@@ -140,7 +183,11 @@
     public void notifyNodeModified(NodeState state) {
         Iterator iter = nsListeners.iterator();
         while (iter.hasNext()) {
-            ((NodeStateListener) iter.next()).nodeModified(state);
+            Reference ref = (Reference) iter.next();
+            NodeStateListener n = (NodeStateListener) ref.get();
+            if (n != null) {
+                n.nodeModified(state);
+            }               
         }
     }
 
@@ -154,7 +201,11 @@
     public void notifyNodeRemoved(NodeState state, Name name, int index, NodeId id) {
         Iterator iter = nsListeners.iterator();
         while (iter.hasNext()) {
-            ((NodeStateListener) iter.next()).nodeRemoved(state, name, index, id);
+            Reference ref = (Reference) iter.next();
+            NodeStateListener n = (NodeStateListener) ref.get();
+            if (n != null) {
+                n.nodeRemoved(state, name, index, id);
+            }               
         }
     }
 

Modified: jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java?rev=767119&r1=767118&r2=767119&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java Tue Apr 21 11:41:35 2009
@@ -38,6 +38,7 @@
         suite.addTestSuite(XATest.class);
         suite.addTestSuite(RestoreAndCheckoutTest.class);
         suite.addTestSuite(NodeImplTest.class);
+        suite.addTestSuite(SessionGarbageCollectedTest.class);
 
         return suite;
     }

Modified: jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/SkipDeniedNodesTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/SkipDeniedNodesTest.java?rev=767119&r1=767118&r2=767119&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/SkipDeniedNodesTest.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/SkipDeniedNodesTest.java Tue Apr 21 11:41:35 2009
@@ -68,6 +68,11 @@
         acMgr.setPolicy(n2.getPath(), acl);
         superuser.save();
     }
+    
+    protected void tearDown() throws Exception {
+        anonymous.logout();
+        super.tearDown();
+    }
 
     public void testSkipNodes() throws RepositoryException {
         Node testNode = (Node) anonymous.getItem(testRoot);