Author: peter_firmstone Date: Thu Feb 21 14:49:33 2013 New Revision: 1448672
URL: http://svn.apache.org/r1448672 Log: Refactoring of PreferredClassProvider and PreferredClassLoader, fixed ClassServer freeze when SecurityException is thrown. Fixed SetLocatorsReplaceSome test when it inadvertantly gets an IP host instead of a string, which breaks the test. Added: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredResources.java - copied, changed from r1444691, river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/loader/pref/internal/PreferredResources.java river/jtsk/skunk/qa_refactor/trunk/test/lib/custard-apple-1.0.2.jar (with props) river/jtsk/skunk/qa_refactor/trunk/test/src/net/jini/core/discovery/ river/jtsk/skunk/qa_refactor/trunk/test/src/net/jini/core/discovery/LookupLocatorTest.java Modified: river/jtsk/skunk/qa_refactor/trunk/qa/harness/policy/qa.policy river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/HeartOfTheMachine.java river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/locatordiscovery/SetLocatorsReplaceSome.java river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/tool/ClassServer.java river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassLoader.java river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/impl/net/UriString.java Modified: river/jtsk/skunk/qa_refactor/trunk/qa/harness/policy/qa.policy URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/harness/policy/qa.policy?rev=1448672&r1=1448671&r2=1448672&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/qa/harness/policy/qa.policy (original) +++ river/jtsk/skunk/qa_refactor/trunk/qa/harness/policy/qa.policy Thu Feb 21 14:49:33 2013 @@ -84,6 +84,7 @@ grant codebase "file:${com.sun.jini.qa.h permission java.io.FilePermission "${com.sun.jini.jsk.home}${/}-", "read"; permission java.io.FilePermission "${com.sun.jini.jsk.home}", "read"; permission java.lang.RuntimePermission "setIO"; + permission java.lang.RuntimePermission "getenv.SOUL"; }; // THE FOLLOWING ARE REQUIRED IF UTILISING A SECURITY MANAGER FROM COMMAND LINE // OR AT START UP. Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/HeartOfTheMachine.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/HeartOfTheMachine.java?rev=1448672&r1=1448671&r2=1448672&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/HeartOfTheMachine.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/HeartOfTheMachine.java Thu Feb 21 14:49:33 2013 @@ -75,7 +75,7 @@ public class HeartOfTheMachine new HeartOfTheMachine(); } catch( Throwable t ) { //System.out.println("Heart NOT started"); - Logger.getAnonymousLogger().severe("Heart NOT started"); + Logger.getLogger("com.sun.jini.qa.harness").severe("Heart NOT started"); } } Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/locatordiscovery/SetLocatorsReplaceSome.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/locatordiscovery/SetLocatorsReplaceSome.java?rev=1448672&r1=1448671&r2=1448672&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/locatordiscovery/SetLocatorsReplaceSome.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/locatordiscovery/SetLocatorsReplaceSome.java Thu Feb 21 14:49:33 2013 @@ -84,10 +84,10 @@ public class SetLocatorsReplaceSome exte String[] oldGroups = oldPair.getGroups(); String oldHost = oldLoc.getHost(); int oldPort = oldLoc.getPort(); - String newHost = new String(oldHost); + String newHost = oldHost; int newPort = oldPort; if( ((i%2) == 0) || changeAll ) {//index is even or changeAll - newHost = new String(oldHost+"-new"); + newHost = "new-" + i; //Completely discard old host name in case it's an IP address. newPort = oldPort+11; }//endif LookupLocator newLoc = QAConfig.getConstrainedLocator(newHost,newPort); Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/tool/ClassServer.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/tool/ClassServer.java?rev=1448672&r1=1448671&r2=1448672&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/tool/ClassServer.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/tool/ClassServer.java Thu Feb 21 14:49:33 2013 @@ -33,6 +33,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; +import java.net.SocketTimeoutException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; @@ -177,7 +178,7 @@ public class ClassServer extends Thread /** Map from String (JAR root) to JarFile[] (JAR class path) */ private Map map; /** Verbosity flag */ - private boolean verbose; + private volatile boolean verbose; /** Stoppable flag */ private boolean stoppable; /** Read permission on dir and all subdirs, for each dir in dirs */ @@ -259,6 +260,7 @@ public class ClassServer extends Thread this.lifeCycle = lifeCycle; server = new ServerSocket(); server.setReuseAddress(true); + server.setSoTimeout(300000); // 5 minutes try { server.bind(new InetSocketAddress(port)); } catch( BindException be ) { @@ -392,19 +394,26 @@ public class ClassServer extends Thread new Object[]{Arrays.asList(dirs), Integer.toString(getPort())}); try { - while (true) { - new Task(server.accept()).start(); + while (!isInterrupted()) { + try { + new Task(server.accept()).start(); + } catch (SocketTimeoutException e){ + // This happens every 5 minutes, it allows ClassServer to + // be interrupted if necessary. + } catch ( SecurityException e){ + logger.log(Level.SEVERE, "Permission denied: ", e); + interrupt(); + } } } catch (IOException e) { - synchronized (this) { - if (verbose) { - e.printStackTrace(); - } - if (!server.isClosed()) - logger.log(Level.SEVERE, "accepting connection", e); - terminate(); - } - } + if (verbose) { + e.printStackTrace(); + } + if (!server.isClosed()) + logger.log(Level.SEVERE, "accepting connection", e); + } finally { + terminate(); + } } /** Close the server socket, causing the thread to terminate. */ Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassLoader.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassLoader.java?rev=1448672&r1=1448671&r2=1448672&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassLoader.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassLoader.java Thu Feb 21 14:49:33 2013 @@ -18,12 +18,11 @@ package net.jini.loader.pref; -import com.sun.jini.loader.pref.internal.PreferredResources; -import java.io.IOException; -import java.io.InputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FilePermission; +import java.io.IOException; +import java.io.InputStream; import java.net.HttpURLConnection; import java.net.JarURLConnection; import java.net.MalformedURLException; @@ -39,15 +38,17 @@ import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; import java.security.Permissions; -import java.security.ProtectionDomain; import java.security.Policy; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +import java.security.ProtectionDomain; import java.security.cert.Certificate; import java.util.Enumeration; -import java.util.Set; import java.util.HashSet; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import net.jini.loader.ClassAnnotation; import net.jini.loader.DownloadPermission; @@ -251,10 +252,9 @@ public class PreferredClassLoader extend private final URLStreamHandler jarHandler; /** PreferredResources for this loader (null if no preferred list) */ - private PreferredResources preferredResources; - - /** true if preferredResources has been successfully initialized */ - private boolean preferredResourcesInitialized = false; + private final PreferredResources preferredResources; + + private final IOException exceptionWhileLoadingPreferred; private static final Permission downloadPermission = new DownloadPermission(); @@ -380,6 +380,61 @@ public class PreferredClassLoader extend */ permissions = new Permissions(); addPermissionsForURLs(urls, permissions, false); + /* + * If a preferred list exists relative to the first URL of this + * loader's path, sets this loader's PreferredResources according + * to that preferred list. If no preferred list exists relative + * to the first URL, leaves this loader's PreferredResources null. + * + * Throws IOException if an I/O exception occurs from which the + * existence of a preferred list relative to the first URL cannot + * be definitely determined. + * + * This method must only be invoked while synchronized on this + * PreferredClassLoader, and it must not be invoked again after it + * has completed successfully. + * + * This was called from privileged context when it as part of a method, + * but we shouldn't need to do that here, any code that can construct + * a ClassLoader has privilege. Note that InputStream is not subject + * to deserialization attacks like ObjectInputStream. + * + * Also synchronization is not required as it is called from within + * the constructor now, this change was made to remove any possiblity + * of deadlock by minimising locking. + */ + IOException except = null; + PreferredResources pref = null; + if (firstURL != null) { + InputStream prefIn = null; + try { + prefIn = getPreferredInputStream(firstURL); + if (prefIn != null) { + try { + pref = new PreferredResources(prefIn); + } finally { + try { + prefIn.close(); + } catch (IOException e) { + } + } + } + } catch (IOException ex) { + Logger.getLogger(PreferredClassLoader.class.getName()).log(Level.SEVERE, null, ex); + except = ex; + } finally { + try { + if (prefIn != null){ + prefIn.close(); + } + } catch (IOException ex) { + Logger.getLogger(PreferredClassLoader.class.getName()).log(Level.SEVERE, null, ex); + } + + } + } + exceptionWhileLoadingPreferred = except; + preferredResources = pref; } /** @@ -460,38 +515,7 @@ public class PreferredClassLoader extend }, acc); } - /** - * If a preferred list exists relative to the first URL of this - * loader's path, sets this loader's PreferredResources according - * to that preferred list. If no preferred list exists relative - * to the first URL, leaves this loader's PreferredResources null. - * - * Throws IOException if an I/O exception occurs from which the - * existence of a preferred list relative to the first URL cannot - * be definitely determined. - * - * This method must only be invoked while synchronized on this - * PreferredClassLoader, and it must not be invoked again after it - * has completed successfully. - **/ - private void initializePreferredResources() throws IOException { - assert Thread.holdsLock(this); - assert preferredResources == null; - - if (firstURL != null) { - InputStream prefIn = getPreferredInputStream(firstURL); - if (prefIn != null) { - try { - preferredResources = new PreferredResources(prefIn); - } finally { - try { - prefIn.close(); - } catch (IOException e) { - } - } - } - } - } + /** * Returns an InputStream from which the preferred list relative @@ -778,32 +802,33 @@ public class PreferredClassLoader extend final boolean isClass) throws IOException { - try { - return ((Boolean) AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws IOException { - boolean b = isPreferredResource0(name, isClass); - return Boolean.valueOf(b); - } - }, acc)).booleanValue(); - - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } + return isPreferredResource0(name, isClass); + // No longer need privilege the preferred list is now downloaded + // during construction. +// try { +// return ((Boolean) AccessController.doPrivileged( +// new PrivilegedExceptionAction() { +// public Object run() throws IOException { +// boolean b = isPreferredResource0(name, isClass); +// return Boolean.valueOf(b); +// } +// }, acc)).booleanValue(); +// +// } catch (PrivilegedActionException e) { +// throw (IOException) e.getException(); +// } } /* * Perform the work to determine if a resource name is preferred. + * + * Synchronized removed to avoid possible ClassLoader deadlock. */ - private synchronized boolean isPreferredResource0(String name, + private boolean isPreferredResource0(String name, boolean isClass) throws IOException { - if (!preferredResourcesInitialized) { - initializePreferredResources(); - preferredResourcesInitialized = true; - } - + if (exceptionWhileLoadingPreferred != null) throw exceptionWhileLoadingPreferred; if (preferredResources == null) { return false; // no preferred list: nothing is preferred } @@ -867,25 +892,19 @@ public class PreferredClassLoader extend * Determine if a resource for a given preferred name exists. If * the resource exists record its new state in the * preferredResources object. - * - * This method must only be invoked while synchronized on this - * PreferredClassLoader. */ private boolean findResourceUpdateState(String name, String resourceName) throws IOException { - assert Thread.holdsLock(this); - boolean resourcePreferred = false; - if (findResource(resourceName) != null) { - /* the resource is know to exist */ + /* the resource is known to exist */ preferredResources.setNameState(resourceName, PreferredResources.NAME_PREFERRED_RESOURCE_EXISTS); - resourcePreferred = true; + return true; } - return resourcePreferred; + return false; } /** Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java?rev=1448672&r1=1448671&r2=1448672&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java Thu Feb 21 14:49:33 2013 @@ -258,7 +258,7 @@ public class PreferredClassProvider exte * value of "java.rmi.server.codebase" property, as cached at class * initialization time. It may contain malformed URLs. */ - private static String codebaseProperty = null; + private static String codebaseProperty; static { String prop = AccessController.doPrivileged( new GetPropertyAction("java.rmi.server.codebase")); @@ -268,22 +268,22 @@ public class PreferredClassProvider exte } /** table of "local" class loaders */ - private static final Map localLoaders = - Collections.synchronizedMap(new WeakHashMap()); + private static final Set<ClassLoader> localLoaders; static { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + Set<Referrer<ClassLoader>> internal = Collections.newSetFromMap(new ConcurrentHashMap<Referrer<ClassLoader>,Boolean>()); + localLoaders = RC.set(internal, Ref.WEAK_IDENTITY, 100L); + AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { + public ClassLoader run() { for (ClassLoader loader = ClassLoader.getSystemClassLoader(); loader != null; loader = loader.getParent()) { - localLoaders.put(loader, null); + localLoaders.add(loader); } return null; } }); } - /** * table mapping codebase URI path and context class loader pairs * to class loader instances. Entries hold class loaders with weak @@ -882,7 +882,7 @@ public class PreferredClassProvider exte * class loader */ private static boolean isLocalLoader(ClassLoader loader) { - return (loader == null || localLoaders.containsKey(loader)); + return (loader == null || localLoaders.contains(loader)); } /** Copied: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredResources.java (from r1444691, river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/loader/pref/internal/PreferredResources.java) URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredResources.java?p2=river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredResources.java&p1=river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/loader/pref/internal/PreferredResources.java&r1=1444691&r2=1448672&rev=1448672&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/loader/pref/internal/PreferredResources.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredResources.java Thu Feb 21 14:49:33 2013 @@ -16,7 +16,7 @@ * limitations under the License. */ -package com.sun.jini.loader.pref.internal; +package net.jini.loader.pref; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -44,11 +44,14 @@ import java.util.TreeSet; * Preferred resources instances hold preferred list expression data * and the preferred state for the resources contained in a given * preferred class loader. + * + * PreferredResouces is thread safe. + * Originally from package com.sun.jini.loader.pref.internal. * * @author Sun Microsystems, Inc. * @since 2.0 */ -public final class PreferredResources { +final class PreferredResources { /** * Constant value that indicates that there is no preference value * for a given name. @@ -90,15 +93,15 @@ public final class PreferredResources { private static final String NAME_PREFIX = "Name:"; /* tables which contain relevant components of preferred names */ - private Map namespacePrefs; - private Map packagePrefs; - private Map completeNamePrefs; + private final Map<String,Object> namespacePrefs; + private final Map<String,Object> packagePrefs; + private final Map<String,Object> completeNamePrefs; /** flag to signal if this preference object is empty */ - private boolean isEmpty = true; + private volatile boolean isEmpty = true; /** default preference setting */ - private Boolean defaultPreference = Boolean.FALSE; + private final Boolean defaultPreference; /** * Create a preference object from a stream of formatted @@ -107,27 +110,22 @@ public final class PreferredResources { * @see PreferredResources */ public PreferredResources(InputStream in) throws IOException { - read(in); - } - - /** - * Read and parse preference information from the parameter input - * stream <code>in</code>. When the method completes, the - * preference expression maps contain preference settings for - * preference names contained in the input stream. - */ - private void read(InputStream in) throws IOException { + /* + * Read and parse preference information from the parameter input + * stream <code>in</code>. When complete, the + * preference expression maps contain preference settings for + * preference names contained in the input stream. + */ BufferedReader br = new BufferedReader (new InputStreamReader(in, "UTF8")); - String line = null; + String line; String name = null; Boolean preference = null; - - /* clear old contents */ - isEmpty = true; - completeNamePrefs = new HashMap(53); - packagePrefs = new HashMap(23); - namespacePrefs = new HashMap(11); + Boolean defaultPreference = Boolean.FALSE; + + completeNamePrefs = new HashMap<String,Object>(53); + packagePrefs = new HashMap<String,Object>(23); + namespacePrefs = new HashMap<String,Object>(11); if ((line = readLineTrimComments(br)) != null) { if (!line.startsWith(HEADER_TITLE)) { @@ -215,6 +213,7 @@ public final class PreferredResources { if (isEmpty) { throw new IOException("Empty preferences list is invalid"); } + this.defaultPreference = defaultPreference; } /** @@ -236,7 +235,7 @@ public final class PreferredResources { /** * Insert a preference expression and value into a given map. */ - private void mapPut(Map map, String name, Object preference) + private void mapPut(Map<String,Object> map, String name, Object preference) throws IOException { isEmpty = false; @@ -274,9 +273,15 @@ public final class PreferredResources { bw.write(PREF_PREFIX + " " + defaultPreference + "\n\n"); /* write out most specific preferences first */ - writeMap(completeNamePrefs, bw, ""); - writeMap(packagePrefs, bw, "/*"); - writeMap(namespacePrefs, bw, "/-"); + synchronized (completeNamePrefs){ + writeMap(completeNamePrefs, bw, ""); + } + synchronized (packagePrefs){ + writeMap(packagePrefs, bw, "/*"); + } + synchronized (namespacePrefs){ + writeMap(namespacePrefs, bw, "/-"); + } bw.flush(); } @@ -285,12 +290,12 @@ public final class PreferredResources { * Write the contents of the map into <code>out</code> using the * preference syntax. */ - private void writeMap(Map prefs, Writer out, String suffix) + private void writeMap(Map<String,Object> prefs, Writer out, String suffix) throws IOException { - Iterator i = (new TreeSet(prefs.keySet())).iterator(); + Iterator<String> i = (new TreeSet<String>(prefs.keySet())).iterator(); while (i.hasNext()) { - Object current = i.next(); + String current = i.next(); out.write(NAME_PREFIX + " " + current + suffix + "\n"); Object value = prefs.get(current); @@ -345,8 +350,9 @@ public final class PreferredResources { throw new IOException("no name specified in preference" + " expression"); } - - completeNamePrefs.put(name, Integer.valueOf(prefState)); + synchronized (completeNamePrefs){ + completeNamePrefs.put(name, Integer.valueOf(prefState)); + } } /** @@ -372,12 +378,14 @@ public final class PreferredResources { public int getNameState(String name, boolean isClass) throws IOException { - Integer state = null; + Integer state; if (isClass) { state = getClassNameState(name); } else { - state = (Integer) completeNamePrefs.get(name); + synchronized (completeNamePrefs){ + state = (Integer) completeNamePrefs.get(name); + } } if (state != null) { return state.intValue(); @@ -402,17 +410,18 @@ public final class PreferredResources { Integer state = null; String container = name; int lastDollar = -1; - do { - state = (Integer) completeNamePrefs.get(container); - if (state == null) { - lastDollar = container.lastIndexOf("$"); - if (lastDollar >= 0) { - container = - container.substring(0, lastDollar) + ".class"; - } - } - } while ((lastDollar >= 0) && (state == null)); - + synchronized(completeNamePrefs){ + do { + state = (Integer) completeNamePrefs.get(container); + if (state == null) { + lastDollar = container.lastIndexOf("$"); + if (lastDollar >= 0) { + container = + container.substring(0, lastDollar) + ".class"; + } + } + } while ((lastDollar >= 0) && (state == null)); + } return state; } @@ -437,10 +446,12 @@ public final class PreferredResources { if (lastSlash >= 0) { String mostSpecific = name.substring(0, lastSlash); if (!mostSpecific.equals("")) { - if (!packagePrefs.isEmpty()) { - wildcardPref = (Boolean) - packagePrefs.get(mostSpecific); - } + synchronized (packagePrefs){ + if (!packagePrefs.isEmpty()) { + wildcardPref = (Boolean) + packagePrefs.get(mostSpecific); + } + } if (wildcardPref == null) { wildcardPref = getNamespacePreference(mostSpecific); } @@ -457,22 +468,23 @@ public final class PreferredResources { */ private Boolean getNamespacePreference(String namespace) { Boolean namespacePref = null; - - if (!namespacePrefs.isEmpty()) { - int lastSlash; - do { - namespacePref = - (Boolean) namespacePrefs.get(namespace); - - lastSlash = namespace.lastIndexOf("/"); - if (lastSlash >= 0) { - namespace = namespace.substring(0, lastSlash); - } - - } while ((lastSlash >= 0) && - (!namespace.equals("")) && - namespacePref == null); - } + synchronized (namespacePrefs){ + if (!namespacePrefs.isEmpty()) { + int lastSlash; + do { + namespacePref = + (Boolean) namespacePrefs.get(namespace); + + lastSlash = namespace.lastIndexOf("/"); + if (lastSlash >= 0) { + namespace = namespace.substring(0, lastSlash); + } + + } while ((lastSlash >= 0) && + (!namespace.equals("")) && + namespacePref == null); + } + } return namespacePref; } } Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/impl/net/UriString.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/impl/net/UriString.java?rev=1448672&r1=1448671&r2=1448672&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/impl/net/UriString.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/impl/net/UriString.java Thu Feb 21 14:49:33 2013 @@ -22,6 +22,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Utility that escapes illegal characters in URI strings according to RFC3986 @@ -32,6 +34,7 @@ import java.util.Map; */ public class UriString { + private static Logger logger = Logger.getLogger("org.apache.river.impl.net"); private static final char [] latin = new char[256]; private static final String [] latinEsc = new String[256]; @@ -494,8 +497,13 @@ public class UriString { path = sb.toString(); } // TODO: query and fragment normalisation. - - return new URI(scheme, uri.getRawUserInfo(), host, uri.getPort(), path, uri.getQuery(), uri.getFragment()); + try { + return new URI(scheme, uri.getRawUserInfo(), host, uri.getPort(), path, uri.getQuery(), uri.getFragment()); + } catch (URISyntaxException e){ + //Somethings gone horribly wrong! Normalisation failed. + logger.log(Level.SEVERE, "Normalisation failed: {0}", e.getMessage()); + return uri; + } } Added: river/jtsk/skunk/qa_refactor/trunk/test/lib/custard-apple-1.0.2.jar URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/test/lib/custard-apple-1.0.2.jar?rev=1448672&view=auto ============================================================================== Binary file - no diff available. Propchange: river/jtsk/skunk/qa_refactor/trunk/test/lib/custard-apple-1.0.2.jar ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: river/jtsk/skunk/qa_refactor/trunk/test/src/net/jini/core/discovery/LookupLocatorTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/test/src/net/jini/core/discovery/LookupLocatorTest.java?rev=1448672&view=auto ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/test/src/net/jini/core/discovery/LookupLocatorTest.java (added) +++ river/jtsk/skunk/qa_refactor/trunk/test/src/net/jini/core/discovery/LookupLocatorTest.java Thu Feb 21 14:49:33 2013 @@ -0,0 +1,71 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package net.jini.core.discovery; + +import java.net.MalformedURLException; +import net.jini.core.lookup.ServiceRegistrar; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author peter + */ +public class LookupLocatorTest { + + public LookupLocatorTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test of getHost method, of class LookupLocator. + */ + @Test + public void testGetHost() throws MalformedURLException { + System.out.println("getHost"); + LookupLocator instance = new LookupLocator("jini://new-1:4171"); + String expResult = "new-1"; + String result = instance.getHost(); + assertEquals(expResult, result); + // TODO review the generated test code and remove the default call to fail. + //fail("The test case is a prototype."); + } + + /** + * Test of getPort method, of class LookupLocator. + */ + @Test + public void testGetPort() throws MalformedURLException { + System.out.println("getPort"); + LookupLocator instance = new LookupLocator("jini://new-1:4171");; + int expResult = 4171; + int result = instance.getPort(); + assertEquals(expResult, result); + // TODO review the generated test code and remove the default call to fail. + //fail("The test case is a prototype."); + } + + +} +
