Return-Path: X-Original-To: apmail-river-commits-archive@www.apache.org Delivered-To: apmail-river-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 908E59955 for ; Tue, 17 Jan 2012 12:46:20 +0000 (UTC) Received: (qmail 87969 invoked by uid 500); 17 Jan 2012 12:46:20 -0000 Delivered-To: apmail-river-commits-archive@river.apache.org Received: (qmail 87919 invoked by uid 500); 17 Jan 2012 12:46:19 -0000 Mailing-List: contact commits-help@river.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@river.apache.org Delivered-To: mailing list commits@river.apache.org Received: (qmail 87899 invoked by uid 99); 17 Jan 2012 12:46:19 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Jan 2012 12:46:19 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Jan 2012 12:46:17 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 35A222388860; Tue, 17 Jan 2012 12:45:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1232399 - in /river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river: api/security/ impl/util/ Date: Tue, 17 Jan 2012 12:45:56 -0000 To: commits@river.apache.org From: peter_firmstone@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120117124557.35A222388860@eris.apache.org> Author: peter_firmstone Date: Tue Jan 17 12:45:56 2012 New Revision: 1232399 URL: http://svn.apache.org/viewvc?rev=1232399&view=rev Log: sun.security.provider.PolicyFile has issues with PrivilegedAction's when DelegateCombinerSecurityManager and Security are on the call stack (picked up in the privileged context), this can cause a infinitely circular call stack, back to the policy as it attempts to retrieve the permissions for the DelegateCombinerSecurityManager and net.jini.security.Security ProtectionDomain, until a StackOverflowError is thrown. Modified checked context to ignore the ProtectionDomain for DelegatCombinerSecurityManager and net.jini.security.Security. Consider moving SecurityManager into jsk-policy.jar Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DefaultPolicyParser.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java?rev=1232399&r1=1232398&r2=1232399&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java Tue Jan 17 12:45:56 2012 @@ -20,9 +20,11 @@ package org.apache.river.api.security; import java.io.InvalidObjectException; import java.io.ObjectInputStream; +import java.security.AccessController; import java.security.CodeSource; import java.security.Permission; import java.security.Principal; +import java.security.PrivilegedAction; /** * @@ -39,7 +41,7 @@ class CodeSourceGrant extends Certificat super( cs != null? cs.getCertificates(): null, pals, perm); this.cs = cs != null? normalizeCodeSource(cs) : null; int hash = 3; - hash = 67 * hash + (this.cs != null ? this.cs.hashCode() : 0); + hash = 67 * hash + (this.cs != null ? this.cs.hashCode() : 0); // This may cause network or file access. hash = 67 * hash + (super.hashCode()); hashCode = hash; } @@ -54,15 +56,23 @@ class CodeSourceGrant extends Certificat if (o == null) return false; if (o == this) return true; if (o.hashCode() != this.hashCode()) return false; + Boolean result = Boolean.FALSE; if (o instanceof CodeSourceGrant){ - CodeSourceGrant c = (CodeSourceGrant) o; if ( !super.equals(o)) return false; - if ( cs == c.cs) return true; - if ( cs != null ) { - if (cs.equals(c.cs)) return true; - } + final CodeSourceGrant c = (CodeSourceGrant) o; + if ( cs == c.cs) return true; + result = AccessController.doPrivileged( + new PrivilegedAction(){ + public Boolean run(){ + if ( cs != null ) { + if (cs.equals(c.cs)) return Boolean.TRUE; + } + return Boolean.FALSE; + } + } + ); } - return false; + return result.booleanValue(); } @Override @@ -89,14 +99,23 @@ class CodeSourceGrant extends Certificat * imply() method. */ @Override - public boolean implies(CodeSource codeSource, Principal[] p) { + public boolean implies(final CodeSource codeSource, Principal[] p) { if ( !implies(p)) return false; // sun.security.provider.PolicyFile compatibility for null CodeSource. // see com.sun.jini.test.spec.policyprovider.dynamicPolicyProvider.GrantPrincipal test. if ( codeSource == null ) return false; if ( cs == null || nullCS.equals(cs)) return true; - return cs.implies(normalizeCodeSource(codeSource)); - } + Boolean result = AccessController.doPrivileged(new PrivilegedAction(){ + + @Override + public Boolean run() { + Boolean outcome = cs.implies(normalizeCodeSource(codeSource)) ? Boolean.TRUE : Boolean.FALSE; + return outcome; + } + + }); + return result; + } @Override public PermissionGrantBuilder getBuilderTemplate() { Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java?rev=1232399&r1=1232398&r2=1232399&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java Tue Jan 17 12:45:56 2012 @@ -20,9 +20,11 @@ package org.apache.river.api.security; import java.io.InvalidObjectException; import java.io.ObjectInputStream; +import java.security.AccessController; import java.security.CodeSource; import java.security.Permission; import java.security.Principal; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -65,15 +67,24 @@ class CodeSourceSetGrant extends Certifi if (o == null) return false; if (o == this) return true; if (o.hashCode() != this.hashCode()) return false; + Boolean result = Boolean.FALSE; if (o instanceof CodeSourceSetGrant){ - CodeSourceSetGrant c = (CodeSourceSetGrant) o; + final CodeSourceSetGrant c = (CodeSourceSetGrant) o; if ( !super.equals(o)) return false; - if ( cs == c.cs) return true; - if ( cs != null ) { - if (cs.equals(c.cs)) return true; - } + result = AccessController.doPrivileged( + new PrivilegedAction(){ + @Override + public Boolean run() { + if ( cs == c.cs) return Boolean.TRUE; + if ( cs != null ) { + if (cs.equals(c.cs)) return Boolean.TRUE; + } + return Boolean.FALSE; + } + } + ); } - return false; + return result.booleanValue(); } @Override @@ -106,14 +117,22 @@ class CodeSourceSetGrant extends Certifi // see com.sun.jini.test.spec.policyprovider.dynamicPolicyProvider.GrantPrincipal test. if ( codeSource == null ) return false; if ( cs == null || cs.isEmpty()) return true; - codeSource = normalizeCodeSource(codeSource); - Iterator it = cs.iterator(); - while (it.hasNext()){ - CodeSource c = it.next(); - if (c == null ) return true; - if (c.implies(codeSource)) return true; - } - return false; + final CodeSource normalizedCodeSource = normalizeCodeSource(codeSource); + Boolean result = AccessController.doPrivileged( + new PrivilegedAction(){ + @Override + public Boolean run() { + Iterator it = cs.iterator(); + while (it.hasNext()){ + CodeSource c = it.next(); + if (c == null ) return Boolean.TRUE; + if (c.implies(normalizedCodeSource)) return Boolean.TRUE; + } + return Boolean.FALSE; + } + } + ); + return result.booleanValue(); } @Override Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DefaultPolicyParser.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DefaultPolicyParser.java?rev=1232399&r1=1232398&r2=1232399&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DefaultPolicyParser.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DefaultPolicyParser.java Tue Jan 17 12:45:56 2012 @@ -84,14 +84,14 @@ class DefaultPolicyParser implements Pol * {@link org.apache.river.imp.security.policy.util.DefaultPolicyScanner DefaultPolicyScanner} * is used. */ - DefaultPolicyParser() { + public DefaultPolicyParser() { scanner = new DefaultPolicyScanner(); } /** * Extension constructor for plugging-in custom scanner. */ - public DefaultPolicyParser(DefaultPolicyScanner s) { + DefaultPolicyParser(DefaultPolicyScanner s) { this.scanner = s; } @@ -445,7 +445,7 @@ class DefaultPolicyParser implements Pol * @throws Exception if KeyStore is null * or if it failed to provide a certificate */ - protected Certificate[] resolveSigners(KeyStore ks, String signers) + Certificate[] resolveSigners(KeyStore ks, String signers) throws Exception { if (ks == null) { throw new KeyStoreException(Messages.getString("security.146", //$NON-NLS-1$ @@ -472,7 +472,7 @@ class DefaultPolicyParser implements Pol * @throws CertificateException if found certificate is not * an X509Certificate */ - protected Principal getPrincipalByAlias(KeyStore ks, String alias) + Principal getPrincipalByAlias(KeyStore ks, String alias) throws KeyStoreException, CertificateException { if (ks == null) { @@ -504,7 +504,7 @@ class DefaultPolicyParser implements Pol * @param resolve flag enabling/disabling property expansion * @return the first successfully loaded KeyStore or null */ - protected KeyStore initKeyStore(Listkeystores, + KeyStore initKeyStore(Listkeystores, URL base, Properties system, boolean resolve) { for (int i = 0; i < keystores.size(); i++) { try { Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java?rev=1232399&r1=1232398&r2=1232399&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java Tue Jan 17 12:45:56 2012 @@ -28,6 +28,7 @@ import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.security.SecurityPermission; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.HashSet; @@ -87,16 +88,22 @@ extends SecurityManager implements Deleg private final Comparator> permCompare; private final AccessControlContext SMConstructorContext; private final AccessControlContext SMPrivilegedContext; + private final ProtectionDomain privilegedDomain; private final ThreadLocal threadContext; private final ThreadLocal inTrustedCodeRecursiveCall; + private final Object lock; + private volatile int revocation_id; public DelegateCombinerSecurityManager(){ super(); + lock = new Object(); + revocation_id = 0; // Get context before this becomes a SecurityManager. // super() checked the permission to create a SecurityManager. SMConstructorContext = AccessController.getContext(); ProtectionDomain [] context = new ProtectionDomain[1]; - context[0] = this.getClass().getProtectionDomain(); + privilegedDomain = this.getClass().getProtectionDomain(); + context[0] = privilegedDomain; SMPrivilegedContext = new AccessControlContext(context); dc = new DelegateDomainCombiner(); ConcurrentMap, @@ -143,10 +150,22 @@ extends SecurityManager implements Deleg * This bug may cause contention between ProtectionDomain implies * calls, also it could be a point of attack for Denial of service, * since the lock used is a static class lock. This bug has been fixed - * in jdk7. + * in jdk8(b15). */ } + @Override + public Object getSecurityContext() { + Object context = null; + inTrustedCodeRecursiveCall.set(Boolean.TRUE); + try { + context = Security.getContext(); + }finally { + inTrustedCodeRecursiveCall.set(Boolean.FALSE); // Must always happen, no matter what. + } + return context; + } + /** * Throws a SecurityException if the requested * access, specified by the given permission, is not permitted based @@ -162,15 +181,9 @@ extends SecurityManager implements Deleg */ @Override public void checkPermission(Permission perm) throws SecurityException { - Object context = null; Boolean call = inTrustedCodeRecursiveCall.get(); if (call == Boolean.TRUE) return; // In Security and Policy static methods we trust. - inTrustedCodeRecursiveCall.set(Boolean.TRUE); - try { - context = Security.getContext(); - }finally { - inTrustedCodeRecursiveCall.set(Boolean.FALSE); // Must always happen, no matter what. - } + Object context = getSecurityContext(); checkPermission(perm, context); } @@ -231,6 +244,9 @@ extends SecurityManager implements Deleg if (existed != null) checkedPerms = existed; } if (checkedPerms.contains(perm)) return; // don't need to check again. + // Record the current transaction_id to avoid populating cache with + // old successful checks. + int rev_id = revocation_id; // Cache the created AccessControlContext. AccessControlContext delegateContext = contextCache.get(executionContext); if (delegateContext == null ) { @@ -263,7 +279,12 @@ extends SecurityManager implements Deleg delegateContext.checkPermission(perm); // Throws SecurityException. /* It's ok to cache SocketPermission if we use a comparator */ // If we get to here, no exceptions were thrown, caller has permission. - checkedPerms.add(perm); + if ( rev_id == revocation_id) { + checkedPerms.add(perm); + // Because the revocation_id is not an atomic check, it might change + // after we've just added the permission, if so remove it. + if ( rev_id != revocation_id) checkedPerms.remove(perm); + } } /** @@ -282,6 +303,21 @@ extends SecurityManager implements Deleg // the policy will prevent any being re-added, since these have already // been removed from the policy. g.checkGuard(this); + synchronized (lock){ + // Order of operation, permission check records revocation id + // before consulting policy, if an interleaved policy operation + // then revokes permission, it notifies the SecurityManager after + // the policy state has changed. It is not safe to cache any + // permission check that commenced before the policy + // revocation completes. + // After this is incremented, it is safe to clear the cache or + // remove stale entries, the SecurityManager may continue to + // allow revoked permissions to be cached until this method + // completes, after which it must comply with any revocation. + // All threads with method local references to the new revocation + // id will have consulted the policy only after its state was altered. + revocation_id++; + } if (perms == null){ checked.clear(); return; @@ -335,14 +371,45 @@ extends SecurityManager implements Deleg * The AccessControlContext instance will be the new instance * we just created moments earlier, but with the context returned * by this DomainCombiner. + * + * The SecurityManager's ProtectionDomain must be removed + * from the Context, for the following case: + * + * If using sun.security.provider.PolicyFile, the policy will + * cache it's own domain prior to it being instantiated and it + * may perform a PrivilegedAction when it's + * getPermissions(ProtectionDomain pd) is called and the + * ProtectionDomain isn't in the policy cache. + * However, DelegateCombinerSecurityManager and + * net.jini.security.Security cannot cache their shared + * ProtectionDomain, relying on the underlying policy instead. + * + * When a standard java permission check + * is made, the AccessController picks up the domain of + * DelegateCombinerSecurityManager and net.jini.security.Security, + * as well as that of the policy provider. Since the policy + * provider will cache it's own ProtectionDomain, but not that + * of the SecurityManager and Security, a infinite circular call + * loop will preceed until a StackOverflowError occurs. + * + * This will be caused by PolicyFile, attempting to determine + * which permissions apply to the ProtectionDomain of + * DelegateCombinerSecurityManager and Security, then asking + * the SecurityManager if it has a FilePermission. + * + * The policy provider org.apache.river.security.ConcurrentPolicyFile + * has no such issue, unless using CodeSource based PermissionGrant's. */ - // I don't believe it's safe to modify the existing array. - // I think it's the same context array from the original AccessControlContext - // we've duplicated, so modifing it would risk contaminating the - // call stack context. - // No defensive copying is performed. + int l = assignedDomains.length; + List list = new ArrayList(l); + for (int i = 0; i < l ; i++){ + if (assignedDomains[i] != privilegedDomain){ + list.add(assignedDomains[i]); + } + } + ProtectionDomain [] context = list.toArray(new ProtectionDomain[list.size()]); DelegateProtectionDomain[] delegated = new DelegateProtectionDomain[1]; - delegated[0] = new DelegateProtectionDomain(assignedDomains); + delegated[0] = new DelegateProtectionDomain(context); return delegated; } } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java?rev=1232399&r1=1232398&r2=1232399&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java Tue Jan 17 12:45:56 2012 @@ -26,11 +26,19 @@ import java.util.Collection; /** * PermissionGrant's are expected to be effectively immutable, - * threadsafe and have a good hashCode implementation to perform well in + * thread safe and have a good hashCode implementation to perform well in * Collections. * * You shouldn't pass around PermissionGrant's to just anyone as they can - * provide an attacker with information about which Permission's may be granted. + * provide an attacker with information about which Permissions may be granted. + * + * Caveat Implementor: PermissionGrant's cannot perform privileged actions, + * whilst being used by the policy to make policy decisions, any privileged + * actions should performed prior to creating a PermissionGrant. + * Only PermissionGrant's belonging to the same ProtectionDomain as the + * active Policy can perform PrivilegedAction's, since the Policy caches it's + * own domain Permissions during initialisation, it doesn't consult + * PermissionGrant's after. * * @author Peter Firmstone */ Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java?rev=1232399&r1=1232398&r2=1232399&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java Tue Jan 17 12:45:56 2012 @@ -53,10 +53,10 @@ public abstract class PermissionGrantBui * the CodeSource. This has been provided for strict compatibility * with the standard Java Policy, where a DNS lookup may be performed * to determine if CodeSource.implies(CodeSource). In addition, to - * resolve a File URL, will require disk access. + * resolve a File URL, it will require disk access. * - * This is very bad for Policy performance, so it's use should be - * kept to an absolute minimum, it's use is discouraged. + * This is very bad for Policy performance, it's use is discouraged, + * so much so, it may removed. * * @deprecated use URI instead. */ Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java?rev=1232399&r1=1232398&r2=1232399&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java Tue Jan 17 12:45:56 2012 @@ -187,29 +187,29 @@ class PrincipalGrant implements Permissi } /** - * Utility Method, really belongs somewhere else, but most subclasses use it. + * Utility Method, really belongs somewhere else, but CodeSource subclasses use it. * @param codeSource * @return */ @Deprecated CodeSource normalizeCodeSource(CodeSource codeSource) { if (codeSource == null ) return null; - URI codeSourceURL = null; + URI codeSourceURI = null; try { - codeSourceURL = PolicyUtils.normalizeURL(codeSource.getLocation()); + codeSourceURI = PolicyUtils.normalizeURL(codeSource.getLocation()); } catch (URISyntaxException ex) { ex.printStackTrace(System.err); } CodeSource result = codeSource; try { - if ( codeSourceURL != null && codeSourceURL.toURL() != codeSource.getLocation()) { + if ( codeSourceURI != null && codeSourceURI.toURL() != codeSource.getLocation()) { // URL was normalized - recreate codeSource with new URL CodeSigner[] signers = codeSource.getCodeSigners(); if (signers == null) { - result = new CodeSource(codeSourceURL.toURL(), codeSource + result = new CodeSource(codeSourceURI.toURL(), codeSource .getCertificates()); } else { - result = new CodeSource(codeSourceURL.toURL(), signers); + result = new CodeSource(codeSourceURI.toURL(), signers); } } } catch (MalformedURLException ex) { Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java?rev=1232399&r1=1232398&r2=1232399&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java Tue Jan 17 12:45:56 2012 @@ -19,7 +19,6 @@ package org.apache.river.impl.util; import java.lang.ref.Reference; -import java.lang.Comparable; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -132,6 +131,8 @@ import java.util.concurrent.ConcurrentNa * strongly referenced, then changed to the correct reference type. This * will still occur, even if the Collection is immutable. *

+ * Map's don't currently support Serialization. + *

* RC stands for Reference Collection and is abbreviated due to the length of * generic parameter arguments typically required. *

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java?rev=1232399&r1=1232398&r2=1232399&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java Tue Jan 17 12:45:56 2012 @@ -18,7 +18,6 @@ package org.apache.river.impl.util; -import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.util.AbstractMap; import java.util.Collection;