You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2012/01/17 13:45:56 UTC
svn commit: r1232399 - in
/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river: api/security/
impl/util/
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<Boolean>(){
+ 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<Boolean>(){
+
+ @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<Boolean>(){
+ @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<CodeSource> 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<Boolean>(){
+ @Override
+ public Boolean run() {
+ Iterator<CodeSource> 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 <code>null</code>
* 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 <code>null</code>
*/
- protected KeyStore initKeyStore(List<KeystoreEntry>keystores,
+ KeyStore initKeyStore(List<KeystoreEntry>keystores,
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<Referrer<Permission>> permCompare;
private final AccessControlContext SMConstructorContext;
private final AccessControlContext SMPrivilegedContext;
+ private final ProtectionDomain privilegedDomain;
private final ThreadLocal<SecurityContext> threadContext;
private final ThreadLocal<Boolean> 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<Referrer<AccessControlContext>,
@@ -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 <code>SecurityException</code> 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<ProtectionDomain> list = new ArrayList<ProtectionDomain>(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.
* </p><p>
+ * Map's don't currently support Serialization.
+ * </p><p>
* RC stands for Reference Collection and is abbreviated due to the length of
* generic parameter arguments typically required.
* </p>
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;