Author: peter_firmstone Date: Sat May 4 20:55:15 2013 New Revision: 1479174
URL: http://svn.apache.org/r1479174 Log: Ensured that Distributed object's are constructed using privileges equivalent to CodeSource(null, null), very minimal to avoid the ability to prevent remote processes from creating privileged objects. See SerialReflectionFactory. Updated UriTest Ensured visibility of test fields by changing to final or volatile. Changed LookupDropProxyTaskRace test so it isn't run by default, it must be run manually. Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/servicediscovery/event/LookupDropProxyTaskRace.td river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/AbstractBaseTest.java river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/event/ModifyAttrServiceChanged.java river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/Distributed.java river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectInputStream.java river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectOutputStream.java river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/security/URIGrantTest.java Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/servicediscovery/event/LookupDropProxyTaskRace.td URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/servicediscovery/event/LookupDropProxyTaskRace.td?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/servicediscovery/event/LookupDropProxyTaskRace.td (original) +++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/servicediscovery/event/LookupDropProxyTaskRace.td Sat May 4 20:55:15 2013 @@ -1,3 +1,4 @@ +com.sun.jini.qa.harness.verifier=com.sun.jini.qa.harness.SkipTestVerifier include0=../servicediscovery.properties testClass=LookupDropProxyTaskRace testCategories=servicediscovery,servicediscovery_impl,servicediscoveryevent,implservicediscovery,implservicediscoveryevent Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/AbstractBaseTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/AbstractBaseTest.java?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/AbstractBaseTest.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/AbstractBaseTest.java Sat May 4 20:55:15 2013 @@ -245,7 +245,7 @@ abstract public class AbstractBaseTest e private int nAdded = 0; private int nRemoved = 0; private int nChanged = 0; - private Object lock = new Object(); + private final Object lock = new Object(); public SrvcListener(QAConfig util, String classname) { this.util = util; this.classname = classname; @@ -253,8 +253,7 @@ abstract public class AbstractBaseTest e public void serviceAdded(ServiceDiscoveryEvent event) { ServiceItem srvcItem = event.getPostEventServiceItem(); ServiceID srvcID = srvcItem.serviceID; - logger.log(Level.FINE, ""+nAdded+" -- serviceAdded()-" - +srvcItem.service+"-"+srvcID); + logger.log(Level.FINE, "{0} -- serviceAdded()-{1}-{2}", new Object[]{nAdded, srvcItem.service, srvcID}); synchronized(lock) { nAdded++; } @@ -262,8 +261,7 @@ abstract public class AbstractBaseTest e public void serviceRemoved(ServiceDiscoveryEvent event) { ServiceItem srvcItem = event.getPreEventServiceItem(); ServiceID srvcID = srvcItem.serviceID; - logger.log(Level.FINE, ""+nRemoved+" -- serviceRemoved()-" - +srvcItem.service+"-"+srvcID); + logger.log(Level.FINE, "{0} -- serviceRemoved()-{1}-{2}", new Object[]{nRemoved, srvcItem.service, srvcID}); synchronized(lock) { nRemoved++; } @@ -271,8 +269,7 @@ abstract public class AbstractBaseTest e public void serviceChanged(ServiceDiscoveryEvent event) { ServiceItem srvcItem = event.getPreEventServiceItem(); ServiceID srvcID = srvcItem.serviceID; - logger.log(Level.FINE, ""+nChanged+" -- serviceChanged()-" - +srvcItem.service+"-"+srvcID); + logger.log(Level.FINE, "{0} -- serviceChanged()-{1}-{2}", new Object[]{nChanged, srvcItem.service, srvcID}); synchronized(lock) { nChanged++; } @@ -296,11 +293,23 @@ abstract public class AbstractBaseTest e /* Data structure representing information about a services registration */ public static class RegInfo { - public ServiceID srvcID; - public ServiceRegistration srvcReg; - public Lease srvcLease; - public Entry[] srvcAttrs; - public ServiceRegistrar lookupProxy;//lookup that granted srvcReg + public final ServiceID srvcID; + public final ServiceRegistration srvcReg; + public final Lease srvcLease; + public final Entry[] srvcAttrs; + public final ServiceRegistrar lookupProxy;//lookup that granted srvcReg + + public RegInfo(ServiceID svcID, + ServiceRegistration svcReg, + Lease svcLease, + Entry[] svcAttr, + ServiceRegistrar lookupPrxy){ + srvcID = svcID; + srvcReg = svcReg; + srvcLease = svcLease; + srvcAttrs = svcAttr; + lookupProxy = lookupPrxy; + } }//end class RegInfo /* Listener which receives notifications when a service lease expires @@ -336,10 +345,10 @@ abstract public class AbstractBaseTest e * of the registration process, this thread will exit. */ protected class RegisterThread extends Thread { - private int startVal; - private int nSrvcs; - private int nAttrs; - private long delay; + private final int startVal; + private final int nSrvcs; + private final int nAttrs; + private final long delay; public RegisterThread(int nSrvcs, int nAttrs, long waitDur) { super("RegisterThread"); setDaemon(true); @@ -378,37 +387,37 @@ abstract public class AbstractBaseTest e protected final static long SERVICE_ID_VARIANT = (0x2L << 62); protected final static int SERVICE_BASE_VALUE = 978; - protected String testDesc + protected volatile String testDesc = "AbstractBaseTest for ServiceDiscoveryManager.lookup()" +" -- number of services -- "; - protected String[] subCategories; + protected volatile String[] subCategories; - protected boolean createSDMduringConstruction = true; - protected boolean waitForLookupDiscovery = true; + protected volatile boolean createSDMduringConstruction = true; + protected volatile boolean waitForLookupDiscovery = true; - protected ServiceDiscoveryManager srvcDiscoveryMgr = null; - protected ArrayList sdmList = new ArrayList(1); - protected ArrayList cacheList = new ArrayList(1); + protected volatile ServiceDiscoveryManager srvcDiscoveryMgr = null; + protected final ArrayList sdmList = new ArrayList(1); + protected final ArrayList cacheList = new ArrayList(1); - protected ServiceTemplate template = null; - protected ServiceItemFilter firstStageFilter = null; - protected ServiceItemFilter secondStageFilter = null; + protected volatile ServiceTemplate template = null; + protected volatile ServiceItemFilter firstStageFilter = null; + protected volatile ServiceItemFilter secondStageFilter = null; - protected LeaseRenewalManager leaseRenewalMgr = null; - private DesiredExpirationListener leaseListener; - protected ArrayList leaseList = new ArrayList(1); + protected volatile LeaseRenewalManager leaseRenewalMgr = null; + private volatile DesiredExpirationListener leaseListener; + protected final ArrayList<Lease> leaseList = new ArrayList<Lease>(1); - protected long discardWait = 0; + protected volatile long discardWait = 0; protected LookupListener mainListener = null; - protected HashMap regInfoMap = new HashMap(1); - protected int regCompletionDelay = 5*1000; //milliseconds - protected int terminateDelay = 7*1000; //milliseconds + protected final HashMap regInfoMap = new HashMap(1); + protected volatile int regCompletionDelay = 5*1000; //milliseconds + protected volatile int terminateDelay = 7*1000; //milliseconds - protected int nSecsServiceEvent = 40; - protected int nSecsRemoteCall = 5; + protected volatile int nSecsServiceEvent = 40; + protected volatile int nSecsRemoteCall = 5; /** * Override default values specified by the base class. @@ -771,9 +780,9 @@ abstract public class AbstractBaseTest e */ int nLookups = ( (lusList.size() <= 0) ? 0 : (lusList.size() - (i%(lusList.size())) ) ); - ArrayList regInfoList = new ArrayList(nLookups); + ArrayList<RegInfo> regInfoList = new ArrayList<RegInfo>(nLookups); for(int j=0;j<nLookups;j++) { - RegInfo regInfo = new RegInfo(); +// RegInfo regInfo = new RegInfo(); int jndx = (lusList.size()-1) - j; ServiceRegistrar lookupProxy = (ServiceRegistrar)lusList.get(jndx); @@ -800,10 +809,10 @@ abstract public class AbstractBaseTest e } catch (TestException e) { throw new RemoteException("Configuration error", e); } - regInfo.srvcID = srvcID; - regInfo.srvcReg = srvcReg; - regInfo.srvcLease = srvcLease; - regInfo.lookupProxy = lookupProxy; +// regInfo.srvcID = srvcID; +// regInfo.srvcReg = srvcReg; +// regInfo.srvcLease = srvcLease; +// regInfo.lookupProxy = lookupProxy; /* Renew the service's lease until the test is complete */ leaseRenewalMgr.renewUntil(srvcLease, Lease.FOREVER, //expiration @@ -815,8 +824,8 @@ abstract public class AbstractBaseTest e /* Store the new lease for clean up at the end of the test */ leaseList.add(srvcLease); //add the new lease /* Create and set attribute(s) for service just registered */ + Entry[] srvcAttrs = new Entry[nAttrs]; if(nAttrs > 0) { - regInfo.srvcAttrs = new Entry[nAttrs]; Entry[] attrs = new Entry[nAttrs]; for(int k=0;k<nAttrs;k++) { logger.log(Level.FINE, "registering attribute "+k @@ -826,10 +835,12 @@ abstract public class AbstractBaseTest e } else { // placeholder for future attributes attrs[k] = new TestServiceIntAttr(attrVal); }//endif - regInfo.srvcAttrs[k] = attrs[k]; + srvcAttrs[k] = attrs[k]; }//end loop srvcReg.setAttributes(attrs); }//endif + // Create RegInfo here. + RegInfo regInfo = new RegInfo(srvcID, srvcReg, srvcLease, srvcAttrs, lookupProxy); regInfoList.add(regInfo); }//end loop (j) - service registration loop synchronized(regInfoMap) { Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/event/ModifyAttrServiceChanged.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/event/ModifyAttrServiceChanged.java?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/event/ModifyAttrServiceChanged.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/servicediscovery/event/ModifyAttrServiceChanged.java Sat May 4 20:55:15 2013 @@ -275,8 +275,9 @@ public class ModifyAttrServiceChanged ex " modifying attributes in lookup service -- " +loc); changeAttributes(srvcReg,oldAttrs,chngAttr); - regInfo.srvcAttrs = chngAttr; - regInfoList.set(i,regInfo); +// regInfo.srvcAttrs = chngAttr; + RegInfo newRegInfo = new RegInfo(regInfo.srvcID, regInfo.srvcReg, regInfo.srvcLease, chngAttr, regInfo.lookupProxy); + regInfoList.set(i,newRegInfo); }//end loop(i) pair.setValue( regInfoList ); }//end loop(itr) Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java Sat May 4 20:55:15 2013 @@ -3877,7 +3877,7 @@ public class ServiceDiscoveryManager { (COMPONENT_NAME, "discardWait", long.class, - init.discardWait)).longValue(); + init.discardWait)); /* Discovery manager */ init.discMgr = discoveryMgr; if(init.discMgr == null) { Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/Distributed.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/Distributed.java?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/Distributed.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/Distributed.java Sat May 4 20:55:15 2013 @@ -43,8 +43,18 @@ package org.apache.river.api.io; * escape during construction, distributed objects will be exposed to multiple * threads on multiple nodes, without synchronization or transactions. * <p> + * Distributed objects are thread safe and immutable. + * <p> * Do not use Distributed if you don't intend to honor this contract, use * Serializable instead. + * <p> + * Distributed Objects are created remotely using an AccessControlContext with one + * ProtectionDomain containing a CodeSource with a null location and null + * Certificates. Only permissions granted to any location will apply. + * Minimal privilege is required to prevent remote instantiation + * of ClassLoader, Policy, SecurityManager, or any other type of object with + * security checks performed during construction. + * <p> * * @author Peter Firmstone. */ Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectInputStream.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectInputStream.java?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectInputStream.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectInputStream.java Sat May 4 20:55:15 2013 @@ -49,7 +49,7 @@ public class DistributedObjectInputStrea super.enableResolveObject(true); } - protected final Object resolveObject(Object o) throws IOException{ + protected Object resolveObject(Object o) throws IOException{ if (o instanceof SerialReflectionFactory) return ((SerialReflectionFactory)o).create(); return o; } Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectOutputStream.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectOutputStream.java?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectOutputStream.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/DistributedObjectOutputStream.java Sat May 4 20:55:15 2013 @@ -38,7 +38,7 @@ public class DistributedObjectOutputStre super(out); } - protected final Object replaceObject(Object o){ + protected Object replaceObject(Object o){ if (o instanceof Distributed) return ((Distributed)o).substitute(); return o; } Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java Sat May 4 20:55:15 2013 @@ -25,7 +25,16 @@ import java.io.StreamCorruptedException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.CodeSource; import java.security.Guard; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.security.ProtectionDomain; +import java.security.cert.Certificate; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Distributed form, required for reflective calls to instantiate objects remotely, @@ -113,6 +122,13 @@ public final class SerialReflectionFacto * Constructor parameters must either be Serializable, Externalizable or * Distributed objects. * <p> + * Creation is performed using only privileges granted to all CodeSource's, + * if there are no default grants set by the policy administrator, the + * creation will be performed with no privileges enabled. + * <p> + * To avoid security vulnerabilities, policy grants to any CodeSource + * should be very limited. + * <p> * * @param factoryClassOrObject will be used for constructor, factory static method, * or builder Object. @@ -134,38 +150,47 @@ public final class SerialReflectionFacto } Object create() throws IOException { - Method m; - Constructor c; - Class clazz; - boolean object; - if (classOrObject instanceof Class) { - clazz = (Class) classOrObject; - object = false; - } - else { - clazz = classOrObject.getClass(); - object = true; - } - try { - if (method != null){ - m = clazz.getMethod(method, parameterTypes); - if (object) return m.invoke(classOrObject, parameters); - return m.invoke(null, parameters); - } else { - c = clazz.getConstructor(parameterTypes); - return c.newInstance(parameters); + // Perform creation with minimum privileges, so remote code cannot + // create URLClassLoader etc. + // a CodeSource with null URL is used instead of a null CodeSource so + // that an administrator can grant limited default privileges if desired. + // Eg to read a default system property. + AccessControlContext acc; + ProtectionDomain [] pd = new ProtectionDomain[1]; + pd[0] = new ProtectionDomain(new CodeSource(null,(Certificate[]) null), null); + acc = new AccessControlContext(pd); + try { + return AccessController.doPrivileged(new PrivilegedExceptionAction(){ + + @Override + public Object run() throws Exception { + Method m; + Constructor c; + Class clazz; + boolean object; + if (classOrObject instanceof Class) { + clazz = (Class) classOrObject; + object = false; + } + else { + clazz = classOrObject.getClass(); + object = true; + } + if (method != null){ + m = clazz.getMethod(method, parameterTypes); + if (object) return m.invoke(classOrObject, parameters); + return m.invoke(null, parameters); + } else { + c = clazz.getConstructor(parameterTypes); + return c.newInstance(parameters); + } + } } - } catch (InstantiationException ex) { - throw new IOException(ex); - } catch (IllegalAccessException ex) { - throw new SecurityException(ex); - } catch (IllegalArgumentException ex) { + , acc); + } catch (PrivilegedActionException ex) { + Logger.getLogger(SerialReflectionFactory.class.getName()).log(Level.SEVERE, null, ex); throw new IOException(ex); - } catch (InvocationTargetException ex) { - throw new IOException(ex); - } catch (NoSuchMethodException ex) { - throw new IOException(ex); - } + } } // Inherit documentation Modified: river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/net/UriTest.java Sat May 4 20:55:15 2013 @@ -19,6 +19,7 @@ package org.apache.river.api.net; import java.net.MalformedURLException; import java.net.URISyntaxException; +import junit.framework.Assert; import junit.framework.TestCase; public class UriTest extends TestCase { @@ -1412,6 +1413,13 @@ public class UriTest extends TestCase { uri2 = uri1.normalize(); assertSame("Failed to return same Uri after normalization", uri1, uri2); } + + public void test_parseAndCreate() throws URISyntaxException { + System.out.println("URI parse and create test"); + Uri result = Uri.parseAndCreate("HTTP://river.apache.ORG/foo%7ebar/file%3clib"); + Uri expResult = new Uri("http://river.apache.org/foo~bar/file%3Clib"); + assertEquals(expResult, result); + } /** * @tests java.net.URI#parseServerAuthority() @@ -1846,5 +1854,23 @@ public class UriTest extends TestCase { } } + public void test_implies() throws Exception { + System.out.println("Test implies"); + Uri grant = Uri.parseAndCreate("file:///foo/*"); + Uri otherGrant = Uri.parseAndCreate("file:/foo/*"); + Uri implied = Uri.parseAndCreate("file:/foo/bar"); + Uri alsoImplied = Uri.parseAndCreate("file:///foo/bar"); + Assert.assertTrue(grant.implies(implied)); + Assert.assertTrue(grant.implies(alsoImplied)); + Assert.assertTrue(otherGrant.implies(implied)); + Assert.assertTrue(otherGrant.implies(alsoImplied)); + grant = Uri.parseAndCreate("file:/C:/USERS/PETER/DOCUMENTS/NETBEANSPROJECTS/PETERCONCURRENTPOLICY/QA/-"); + implied = Uri.parseAndCreate("file:/C:/USERS/PETER/DOCUMENTS/NETBEANSPROJECTS/PETERCONCURRENTPOLICY/QA/LIB/JINIHARNESS.JAR"); + System.out.println(grant); + System.out.println(implied); + boolean result = grant.implies(implied); + System.out.println(result); + Assert.assertTrue(result); + } } Modified: river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/security/URIGrantTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/security/URIGrantTest.java?rev=1479174&r1=1479173&r2=1479174&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/security/URIGrantTest.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/security/URIGrantTest.java Sat May 4 20:55:15 2013 @@ -66,26 +66,6 @@ public class URIGrantTest { @After public void tearDown() { } - - @Test - public void testImplies() throws URISyntaxException { - System.out.println("Test implies"); - Uri grant = Uri.parseAndCreate("file:///foo/*"); - Uri otherGrant = Uri.parseAndCreate("file:/foo/*"); - Uri implied = Uri.parseAndCreate("file:/foo/bar"); - Uri alsoImplied = Uri.parseAndCreate("file:///foo/bar"); - Assert.assertTrue(instance.implies(grant, implied)); - Assert.assertTrue(instance.implies(grant,alsoImplied)); - Assert.assertTrue(instance.implies(otherGrant, implied)); - Assert.assertTrue(instance.implies(otherGrant, alsoImplied)); - grant = Uri.parseAndCreate("file:/C:/USERS/PETER/DOCUMENTS/NETBEANSPROJECTS/PETERCONCURRENTPOLICY/QA/-"); - implied = Uri.parseAndCreate("file:/C:/USERS/PETER/DOCUMENTS/NETBEANSPROJECTS/PETERCONCURRENTPOLICY/QA/LIB/JINIHARNESS.JAR"); - System.out.println(grant); - System.out.println(implied); - boolean result = instance.implies(grant, implied); - System.out.println(result); - Assert.assertTrue(result); - } @Test public void testImpliesPD() throws URISyntaxException {