--- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2477,7 +2477,7 @@
* <ul>
*
* <li> If the {@code name} begins with a {@code '/'}
- * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
+ * (<code>'\u002f'</code>), then the absolute name of the resource is the
* portion of the {@code name} following the {@code '/'}.
*
* <li> Otherwise, the absolute name is of the following form:
@@ -2488,7 +2488,7 @@
*
* <p> Where the {@code modified_package_name} is the package name of this
* object with {@code '/'} substituted for {@code '.'}
- * (<tt>'\u002e'</tt>).
+ * (<code>'\u002e'</code>).
*
* </ul>
*
@@ -2570,7 +2570,7 @@
* <ul>
*
* <li> If the {@code name} begins with a {@code '/'}
- * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
+ * (<code>'\u002f'</code>), then the absolute name of the resource is the
* portion of the {@code name} following the {@code '/'}.
*
* <li> Otherwise, the absolute name is of the following form:
@@ -2581,7 +2581,7 @@
*
* <p> Where the {@code modified_package_name} is the package name of this
* object with {@code '/'} substituted for {@code '.'}
- * (<tt>'\u002e'</tt>).
+ * (<code>'\u002e'</code>).
*
* </ul>
*
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -70,34 +70,34 @@
/**
* A class loader is an object that is responsible for loading classes. The
- * class <tt>ClassLoader</tt> is an abstract class. Given the <a
+ * class {@code ClassLoader} is an abstract class. Given the <a
* href="#name">binary name</a> of a class, a class loader should attempt to
* locate or generate data that constitutes a definition for the class. A
* typical strategy is to transform the name into a file name and then read a
* "class file" of that name from a file system.
*
- * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
- * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
+ * <p> Every {@link java.lang.Class Class} object contains a {@link
+ * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
* it.
*
- * <p> <tt>Class</tt> objects for array classes are not created by class
+ * <p> {@code Class} objects for array classes are not created by class
* loaders, but are created automatically as required by the Java runtime.
* The class loader for an array class, as returned by {@link
* Class#getClassLoader()} is the same as the class loader for its element
* type; if the element type is a primitive type, then the array class has no
* class loader.
*
- * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
+ * <p> Applications implement subclasses of {@code ClassLoader} in order to
* extend the manner in which the Java virtual machine dynamically loads
* classes.
*
* <p> Class loaders may typically be used by security managers to indicate
* security domains.
*
- * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
- * classes and resources. Each instance of <tt>ClassLoader</tt> has an
+ * <p> The {@code ClassLoader} class uses a delegation model to search for
+ * classes and resources. Each instance of {@code ClassLoader} has an
* associated parent class loader. When requested to find a class or
- * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
+ * resource, a {@code ClassLoader} instance will delegate the search for the
* class or resource to its parent class loader before attempting to find the
* class or resource itself.
*
@@ -105,15 +105,15 @@
* <em>{@linkplain #isRegisteredAsParallelCapable() parallel capable}</em> class
* loaders and are required to register themselves at their class initialization
* time by invoking the {@link
- * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
- * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
+ * #registerAsParallelCapable ClassLoader.registerAsParallelCapable}
+ * method. Note that the {@code ClassLoader} class is registered as parallel
* capable by default. However, its subclasses still need to register themselves
* if they are parallel capable.
* In environments in which the delegation model is not strictly
* hierarchical, class loaders need to be parallel capable, otherwise class
* loading can lead to deadlocks because the loader lock is held for the
* duration of the class loading process (see {@link #loadClass
- * <tt>loadClass</tt>} methods).
+ * loadClass} methods).
*
* <h3> <a name="builtinLoaders">Run-time Built-in Class Loaders</a></h3>
*
@@ -143,13 +143,13 @@
* However, some classes may not originate from a file; they may originate
* from other sources, such as the network, or they could be constructed by an
* application. The method {@link #defineClass(String, byte[], int, int)
- * <tt>defineClass</tt>} converts an array of bytes into an instance of class
- * <tt>Class</tt>. Instances of this newly defined class can be created using
- * {@link Class#newInstance <tt>Class.newInstance</tt>}.
+ * defineClass} converts an array of bytes into an instance of class
+ * {@code Class}. Instances of this newly defined class can be created using
+ * {@link Class#newInstance Class.newInstance}.
*
* <p> The methods and constructors of objects created by a class loader may
* reference other classes. To determine the class(es) referred to, the Java
- * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
+ * virtual machine invokes the {@link #loadClass loadClass} method of
* the class loader that originally created the class.
*
* <p> For example, an application could create a network class loader to
@@ -162,9 +162,9 @@
* </pre></blockquote>
*
* <p> The network class loader subclass must define the methods {@link
- * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
+ * #findClass findClass} and {@code loadClassData} to load a class
* from the network. Once it has downloaded the bytes that make up the class,
- * it should use the method {@link #defineClass <tt>defineClass</tt>} to
+ * it should use the method {@link #defineClass defineClass} to
* create a class instance. A sample implementation is:
*
* <blockquote><pre>
@@ -392,7 +392,7 @@
*
* <p> If there is a security manager, its {@link
* SecurityManager#checkCreateClassLoader()
- * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
+ * checkCreateClassLoader} method is invoked. This may result in
* a security exception. </p>
*
* @param parent
@@ -400,7 +400,7 @@
*
* @throws SecurityException
* If a security manager exists and its
- * <tt>checkCreateClassLoader</tt> method doesn't allow creation
+ * {@code checkCreateClassLoader} method doesn't allow creation
* of a new class loader.
*
* @since 1.2
@@ -410,18 +410,18 @@
}
/**
- * Creates a new class loader using the <tt>ClassLoader</tt> returned by
+ * Creates a new class loader using the {@code ClassLoader} returned by
* the method {@link #getSystemClassLoader()
- * <tt>getSystemClassLoader()</tt>} as the parent class loader.
+ * getSystemClassLoader()} as the parent class loader.
*
* <p> If there is a security manager, its {@link
* SecurityManager#checkCreateClassLoader()
- * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
+ * checkCreateClassLoader} method is invoked. This may result in
* a security exception. </p>
*
* @throws SecurityException
* If a security manager exists and its
- * <tt>checkCreateClassLoader</tt> method doesn't allow creation
+ * {@code checkCreateClassLoader} method doesn't allow creation
* of a new class loader.
*/
protected ClassLoader() {
@@ -458,13 +458,13 @@
* This method searches for classes in the same manner as the {@link
* #loadClass(String, boolean)} method. It is invoked by the Java virtual
* machine to resolve class references. Invoking this method is equivalent
- * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
- * false)</tt>}.
+ * to invoking {@link #loadClass(String, boolean) loadClass(name,
+ * false)}.
*
* @param name
* The <a href="#name">binary name</a> of the class
*
- * @return The resulting <tt>Class</tt> object
+ * @return The resulting {@code Class} object
*
* @throws ClassNotFoundException
* If the class was not found
@@ -483,8 +483,8 @@
* <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
* has already been loaded. </p></li>
*
- * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
- * on the parent class loader. If the parent is <tt>null</tt> the class
+ * <li><p> Invoke the {@link #loadClass(String) loadClass} method
+ * on the parent class loader. If the parent is {@code null} the class
* loader built-in to the virtual machine is used, instead. </p></li>
*
* <li><p> Invoke the {@link #findClass(String)} method to find the
@@ -493,23 +493,23 @@
* </ol>
*
* <p> If the class was found using the above steps, and the
- * <tt>resolve</tt> flag is true, this method will then invoke the {@link
- * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
+ * {@code resolve} flag is true, this method will then invoke the {@link
+ * #resolveClass(Class)} method on the resulting {@code Class} object.
*
- * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
+ * <p> Subclasses of {@code ClassLoader} are encouraged to override {@link
* #findClass(String)}, rather than this method. </p>
*
* <p> Unless overridden, this method synchronizes on the result of
- * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
+ * {@link #getClassLoadingLock getClassLoadingLock} method
* during the entire class loading process.
*
* @param name
* The <a href="#name">binary name</a> of the class
*
* @param resolve
- * If <tt>true</tt> then resolve the class
+ * If {@code true} then resolve the class
*
- * @return The resulting <tt>Class</tt> object
+ * @return The resulting {@code Class} object
*
* @throws ClassNotFoundException
* If the class could not be found
@@ -606,7 +606,7 @@
* @return the lock for class loading operations
*
* @throws NullPointerException
- * If registered as parallel capable and <tt>className</tt> is null
+ * If registered as parallel capable and {@code className} is null
*
* @see #loadClass(String, boolean)
*
@@ -667,14 +667,14 @@
* Finds the class with the specified <a href="#name">binary name</a>.
* This method should be overridden by class loader implementations that
* follow the delegation model for loading classes, and will be invoked by
- * the {@link #loadClass <tt>loadClass</tt>} method after checking the
+ * the {@link #loadClass loadClass} method after checking the
* parent class loader for the requested class. The default implementation
- * throws a <tt>ClassNotFoundException</tt>.
+ * throws a {@code ClassNotFoundException}.
*
* @param name
* The <a href="#name">binary name</a> of the class
*
- * @return The resulting <tt>Class</tt> object
+ * @return The resulting {@code Class} object
*
* @throws ClassNotFoundException
* If the class could not be found
@@ -722,32 +722,32 @@
/**
- * Converts an array of bytes into an instance of class <tt>Class</tt>.
- * Before the <tt>Class</tt> can be used it must be resolved. This method
+ * Converts an array of bytes into an instance of class {@code Class}.
+ * Before the {@code Class} can be used it must be resolved. This method
* is deprecated in favor of the version that takes a <a
* href="#name">binary name</a> as its first argument, and is more secure.
*
* @param b
* The bytes that make up the class data. The bytes in positions
- * <tt>off</tt> through <tt>off+len-1</tt> should have the format
+ * {@code off} through {@code off+len-1} should have the format
* of a valid class file as defined by
* <cite>The Java™ Virtual Machine Specification</cite>.
*
* @param off
- * The start offset in <tt>b</tt> of the class data
+ * The start offset in {@code b} of the class data
*
* @param len
* The length of the class data
*
- * @return The <tt>Class</tt> object that was created from the specified
+ * @return The {@code Class} object that was created from the specified
* class data
*
* @throws ClassFormatError
* If the data did not contain a valid class
*
* @throws IndexOutOfBoundsException
- * If either <tt>off</tt> or <tt>len</tt> is negative, or if
- * <tt>off+len</tt> is greater than <tt>b.length</tt>.
+ * If either {@code off} or {@code len} is negative, or if
+ * {@code off+len} is greater than {@code b.length}.
*
* @throws SecurityException
* If an attempt is made to add this class to a package that
@@ -994,11 +994,11 @@
* #defineClass(String, byte[], int, int, ProtectionDomain)}.
*
* <p> An invocation of this method of the form
- * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
- * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
+ * <i>cl</i>{@code .defineClass(}<i>name</i>{@code ,}
+ * <i>bBuffer</i>{@code ,} <i>pd</i>{@code )} yields exactly the same
* result as the statements
*
- *<p> <tt>
+ *<p> <code>
* ...<br>
* byte[] temp = new byte[bBuffer.{@link
* java.nio.ByteBuffer#remaining remaining}()];<br>
@@ -1007,16 +1007,16 @@
* return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
* cl.defineClass}(name, temp, 0,
* temp.length, pd);<br>
- * </tt></p>
+ * </code></p>
*
* @param name
* The expected <a href="#name">binary name</a>. of the class, or
- * <tt>null</tt> if not known
+ * {@code null} if not known
*
* @param b
* The bytes that make up the class data. The bytes from positions
- * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1
- * </tt> should have the format of a valid class file as defined by
+ * {@code b.position()} through {@code b.position() + b.limit() -1
+ * } should have the format of a valid class file as defined by
* <cite>The Java™ Virtual Machine Specification</cite>.
*
* @param protectionDomain
@@ -1158,7 +1158,7 @@
/**
* Links the specified class. This (misleadingly named) method may be
- * used by a class loader to link a class. If the class <tt>c</tt> has
+ * used by a class loader to link a class. If the class {@code c} has
* already been linked, then this method simply returns. Otherwise, the
* class is linked as described in the "Execution" chapter of
* <cite>The Java™ Language Specification</cite>.
@@ -1167,7 +1167,7 @@
* The class to link
*
* @throws NullPointerException
- * If <tt>c</tt> is <tt>null</tt>.
+ * If {@code c} is {@code null}.
*
* @see #defineClass(String, byte[], int, int)
*/
@@ -1182,16 +1182,16 @@
* loading it if necessary.
*
* <p> This method loads the class through the system class loader (see
- * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned
- * might have more than one <tt>ClassLoader</tt> associated with it.
- * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
+ * {@link #getSystemClassLoader()}). The {@code Class} object returned
+ * might have more than one {@code ClassLoader} associated with it.
+ * Subclasses of {@code ClassLoader} need not usually invoke this method,
* because most class loaders need to override just {@link
* #findClass(String)}. </p>
*
* @param name
* The <a href="#name">binary name</a> of the class
*
- * @return The <tt>Class</tt> object for the specified <tt>name</tt>
+ * @return The {@code Class} object for the specified {@code name}
*
* @throws ClassNotFoundException
* If the class could not be found
@@ -1222,12 +1222,12 @@
* Returns the class with the given <a href="#name">binary name</a> if this
* loader has been recorded by the Java virtual machine as an initiating
* loader of a class with that <a href="#name">binary name</a>. Otherwise
- * <tt>null</tt> is returned.
+ * {@code null} is returned.
*
* @param name
* The <a href="#name">binary name</a> of the class
*
- * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has
+ * @return The {@code Class} object, or {@code null} if the class has
* not been loaded
*
* @since 1.1
@@ -1245,7 +1245,7 @@
* class.
*
* @param c
- * The <tt>Class</tt> object
+ * The {@code Class} object
*
* @param signers
* The signers for the class
@@ -1306,11 +1306,11 @@
* (images, audio, text, etc) that can be accessed by class code in a way
* that is independent of the location of the code.
*
- * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
+ * <p> The name of a resource is a '{@code /}'-separated path name that
* identifies the resource.
*
* <p> This method will first search the parent class loader for the
- * resource; if the parent is <tt>null</tt> the path of the class loader
+ * resource; if the parent is {@code null} the path of the class loader
* built-in to the virtual machine is searched. That failing, this method
* will invoke {@link #findResource(String)} to find the resource. </p>
*
@@ -1362,7 +1362,7 @@
* (images, audio, text, etc) that can be accessed by class code in a way
* that is independent of the location of the code.
*
- * <p> The name of a resource is a <tt>/</tt>-separated path name that
+ * <p> The name of a resource is a {@code /}-separated path name that
* identifies the resource.
*
* <p> The delegation order for searching is described in the documentation
@@ -1389,7 +1389,7 @@
* @param name
* The resource name
*
- * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+ * @return An enumeration of {@link java.net.URL URL} objects for
* the resource. If no resources could be found, the enumeration
* will be empty. Resources for which a {@code URL} cannot be
* constructed, are in package that is not opened unconditionally,
@@ -1505,7 +1505,7 @@
}
/**
- * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
+ * Returns an enumeration of {@link java.net.URL URL} objects
* representing all the resources with the given name. Class loader
* implementations should override this method to specify where to load
* resources from.
@@ -1520,7 +1520,7 @@
* @param name
* The resource name
*
- * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+ * @return An enumeration of {@link java.net.URL URL} objects for
* the resource. If no resources could be found, the enumeration
* will be empty. Resources for which a {@code URL} cannot be
* constructed, are in a package that is not opened unconditionally,
@@ -1594,7 +1594,7 @@
* @param name
* The resource name
*
- * @return A {@link java.net.URL <tt>URL</tt>} to the resource; {@code
+ * @return A {@link java.net.URL URL} to the resource; {@code
* null} if the resource could not be found, a URL could not be
* constructed to locate the resource, the resource is in a package
* that is not opened unconditionally or access to the resource is
@@ -1609,8 +1609,8 @@
/**
* Finds all resources of the specified name from the search path used to
* load classes. The resources thus found are returned as an
- * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
- * java.net.URL <tt>URL</tt>} objects.
+ * {@link java.util.Enumeration Enumeration} of {@link
+ * java.net.URL URL} objects.
*
* <p> The search order is described in the documentation for {@link
* #getSystemResource(String)}. </p>
@@ -1625,7 +1625,7 @@
* @param name
* The resource name
*
- * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+ * @return An enumeration of {@link java.net.URL URL} objects for
* the resource. If no resources could be found, the enumeration
* will be empty. Resources for which a {@code URL} cannot be
* constructed, are in a package that is not opened unconditionally,
@@ -1714,11 +1714,11 @@
/**
* Returns the parent class loader for delegation. Some implementations may
- * use <tt>null</tt> to represent the bootstrap class loader. This method
- * will return <tt>null</tt> in such implementations if this class loader's
+ * use {@code null} to represent the bootstrap class loader. This method
+ * will return {@code null} in such implementations if this class loader's
* parent is the bootstrap class loader.
*
- * @return The parent <tt>ClassLoader</tt>
+ * @return The parent {@code ClassLoader}
*
* @throws SecurityException
* If a security manager is present, and the caller's class loader
@@ -1785,7 +1785,7 @@
/**
* Returns the system class loader for delegation. This is the default
- * delegation parent for new <tt>ClassLoader</tt> instances, and is
+ * delegation parent for new {@code ClassLoader} instances, and is
* typically the class loader used to start the application.
*
* <p> This method is first invoked early in the runtime's startup
@@ -1797,12 +1797,12 @@
* <p> The default system class loader is an implementation-dependent
* instance of this class.
*
- * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
+ * <p> If the system property "{@code java.system.class.loader}" is defined
* when this method is first invoked then the value of that property is
* taken to be the name of a class that will be returned as the system
* class loader. The class is loaded using the default system class loader
* and must define a public constructor that takes a single parameter of
- * type <tt>ClassLoader</tt> which is used as the delegation parent. An
+ * type {@code ClassLoader} which is used as the delegation parent. An
* instance is then created using this constructor with the default system
* class loader as the parameter. The resulting class loader is defined
* to be the system class loader. During construction, the class loader
@@ -1825,7 +1825,7 @@
* the application module path then the class path defaults to
* the current working directory.
*
- * @return The system <tt>ClassLoader</tt> for delegation
+ * @return The system {@code ClassLoader} for delegation
*
* @throws SecurityException
* If a security manager is present, and the caller's class loader
@@ -1835,11 +1835,11 @@
*
* @throws IllegalStateException
* If invoked recursively during the construction of the class
- * loader specified by the "<tt>java.system.class.loader</tt>"
+ * loader specified by the "{@code java.system.class.loader}"
* property.
*
* @throws Error
- * If the system property "<tt>java.system.class.loader</tt>"
+ * If the system property "{@code java.system.class.loader}"
* is defined but the named class could not be loaded, the
* provider class does not define the required constructor, or an
* exception is thrown by that constructor when it is invoked. The
@@ -2249,9 +2249,9 @@
/**
* Returns the absolute path name of a native library. The VM invokes this
* method to locate the native libraries that belong to classes loaded with
- * this class loader. If this method returns <tt>null</tt>, the VM
+ * this class loader. If this method returns {@code null}, the VM
* searches the library along the path specified as the
- * "<tt>java.library.path</tt>" property.
+ * "{@code java.library.path}" property.
*
* @param libname
* The library name
@@ -2270,12 +2270,12 @@
/**
* The inner class NativeLibrary denotes a loaded native library instance.
* Every classloader contains a vector of loaded native libraries in the
- * private field <tt>nativeLibraries</tt>. The native libraries loaded
- * into the system are entered into the <tt>systemNativeLibraries</tt>
+ * private field {@code nativeLibraries}. The native libraries loaded
+ * into the system are entered into the {@code systemNativeLibraries}
* vector.
*
* <p> Every native library requires a particular version of JNI. This is
- * denoted by the private <tt>jniVersion</tt> field. This field is set by
+ * denoted by the private {@code jniVersion} field. This field is set by
* the VM when it loads the library, and used by the VM to pass the correct
* version of JNI to the native methods. </p>
*
@@ -2592,8 +2592,8 @@
* #setClassAssertionStatus(String, boolean)}.
*
* @param enabled
- * <tt>true</tt> if classes loaded by this class loader will
- * henceforth have assertions enabled by default, <tt>false</tt>
+ * {@code true} if classes loaded by this class loader will
+ * henceforth have assertions enabled by default, {@code false}
* if they will have assertions disabled by default.
*
* @since 1.4
@@ -2614,16 +2614,16 @@
* any of its "subpackages".
*
* <p> A subpackage of a package named p is any package whose name begins
- * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a
- * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
- * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
+ * with "{@code p.}". For example, {@code javax.swing.text} is a
+ * subpackage of {@code javax.swing}, and both {@code java.util} and
+ * {@code java.lang.reflect} are subpackages of {@code java}.
*
* <p> In the event that multiple package defaults apply to a given class,
* the package default pertaining to the most specific package takes
- * precedence over the others. For example, if <tt>javax.lang</tt> and
- * <tt>javax.lang.reflect</tt> both have package defaults associated with
+ * precedence over the others. For example, if {@code javax.lang} and
+ * {@code javax.lang.reflect} both have package defaults associated with
* them, the latter package default applies to classes in
- * <tt>javax.lang.reflect</tt>.
+ * {@code javax.lang.reflect}.
*
* <p> Package defaults take precedence over the class loader's default
* assertion status, and may be overridden on a per-class basis by invoking
@@ -2631,15 +2631,15 @@
*
* @param packageName
* The name of the package whose package default assertion status
- * is to be set. A <tt>null</tt> value indicates the unnamed
+ * is to be set. A {@code null} value indicates the unnamed
* package that is "current"
* (see section 7.4.2 of
* <cite>The Java™ Language Specification</cite>.)
*
* @param enabled
- * <tt>true</tt> if classes loaded by this classloader and
+ * {@code true} if classes loaded by this classloader and
* belonging to the named package or any of its subpackages will
- * have assertions enabled by default, <tt>false</tt> if they will
+ * have assertions enabled by default, {@code false} if they will
* have assertions disabled by default.
*
* @since 1.4
@@ -2670,8 +2670,8 @@
* assertion status is to be set.
*
* @param enabled
- * <tt>true</tt> if the named class is to have assertions
- * enabled when (and if) it is initialized, <tt>false</tt> if the
+ * {@code true} if the named class is to have assertions
+ * enabled when (and if) it is initialized, {@code false} if the
* class is to have assertions disabled.
*
* @since 1.4
@@ -2687,7 +2687,7 @@
/**
* Sets the default assertion status for this class loader to
- * <tt>false</tt> and discards any package defaults or class assertion
+ * {@code false} and discards any package defaults or class assertion
* status settings associated with the class loader. This method is
* provided so that class loaders can be made to ignore any command line or
* persistent assertion status settings and "start with a clean slate."
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java Thu Jan 12 12:14:13 2017 -0800
@@ -30,8 +30,10 @@
import java.io.OutputStream;
import java.security.PrivilegedAction;
import java.util.Hashtable;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.Date;
import java.util.Iterator;
+import java.util.Locale;
import java.util.Objects;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
@@ -231,7 +233,7 @@
*/
protected boolean allowUserInteraction = defaultAllowUserInteraction;
- private static boolean defaultUseCaches = true;
+ private static volatile boolean defaultUseCaches = true;
/**
* If {@code true}, the protocol is allowed to use caching
@@ -243,12 +245,18 @@
* <p>
* Its default value is the value given in the last invocation of the
* {@code setDefaultUseCaches} method.
+ * <p>
+ * The default setting may be overridden per protocol with
+ * {@link #setDefaultUseCaches(String,boolean)}.
*
* @see java.net.URLConnection#setUseCaches(boolean)
* @see java.net.URLConnection#getUseCaches()
* @see java.net.URLConnection#setDefaultUseCaches(boolean)
*/
- protected boolean useCaches = defaultUseCaches;
+ protected boolean useCaches;
+
+ private static final ConcurrentHashMap<String,Boolean> defaultCaching =
+ new ConcurrentHashMap<>();
/**
* Some protocols support skipping the fetching of the object unless
@@ -460,6 +468,11 @@
*/
protected URLConnection(URL url) {
this.url = url;
+ if (url == null) {
+ this.useCaches = defaultUseCaches;
+ } else {
+ this.useCaches = getDefaultUseCaches(url.getProtocol());
+ }
}
/**
@@ -981,7 +994,8 @@
* is true, the connection is allowed to use whatever caches it can.
* If false, caches are to be ignored.
* The default value comes from DefaultUseCaches, which defaults to
- * true.
+ * true. A default value can also be set per-protocol using
+ * {@link #setDefaultUseCaches(String,boolean)}.
*
* @param usecaches a {@code boolean} indicating whether
* or not to allow caching
@@ -1032,9 +1046,10 @@
* Returns the default value of a {@code URLConnection}'s
* {@code useCaches} flag.
* <p>
- * Ths default is "sticky", being a part of the static state of all
+ * This default is "sticky", being a part of the static state of all
* URLConnections. This flag applies to the next, and all following
- * URLConnections that are created.
+ * URLConnections that are created. This default value can be over-ridden
+ * per protocol using {@link #setDefaultUseCaches(String,boolean)}
*
* @return the default value of a {@code URLConnection}'s
* {@code useCaches} flag.
@@ -1046,7 +1061,8 @@
/**
* Sets the default value of the {@code useCaches} field to the
- * specified value.
+ * specified value. This default value can be over-ridden
+ * per protocol using {@link #setDefaultUseCaches(String,boolean)}
*
* @param defaultusecaches the new value.
* @see #getDefaultUseCaches()
@@ -1055,6 +1071,43 @@
defaultUseCaches = defaultusecaches;
}
+ /**
+ * Sets the default value of the {@code useCaches} field for the named
+ * protocol to the given value. This value overrides any default setting
+ * set by {@link #setDefaultUseCaches(boolean)} for the given protocol.
+ * Successive calls to this method change the setting and affect the
+ * default value for all future connections of that protocol. The protocol
+ * name is case insensitive.
+ *
+ * @param protocol the protocol to set the default for
+ * @param defaultVal whether caching is enabled by default for the given protocol
+ * @since 9
+ */
+ public static void setDefaultUseCaches(String protocol, boolean defaultVal) {
+ protocol = protocol.toLowerCase(Locale.US);
+ defaultCaching.put(protocol, defaultVal);
+ }
+
+ /**
+ * Returns the default value of the {@code useCaches} flag for the given protocol. If
+ * {@link #setDefaultUseCaches(String,boolean)} was called for the given protocol,
+ * then that value is returned. Otherwise, if {@link #setDefaultUseCaches(boolean)}
+ * was called, then that value is returned. If neither method was called,
+ * the return value is {@code true}. The protocol name is case insensitive.
+ *
+ * @param protocol the protocol whose defaultUseCaches setting is required
+ * @return the default value of the {@code useCaches} flag for the given protocol.
+ * @since 9
+ */
+ public static boolean getDefaultUseCaches(String protocol) {
+ Boolean protoDefault = defaultCaching.get(protocol.toLowerCase(Locale.US));
+ if (protoDefault != null) {
+ return protoDefault.booleanValue();
+ } else {
+ return defaultUseCaches;
+ }
+ }
+
/**
* Sets the general request property. If a property with the key already
* exists, overwrite its value with the new value.
--- a/jdk/src/java.base/share/classes/java/util/Collections.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Collections.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -4354,6 +4354,11 @@
private Object readResolve() {
return EMPTY_SET;
}
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
}
/**
@@ -4786,6 +4791,10 @@
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(element);
+ }
}
/**
@@ -4848,6 +4857,10 @@
public Spliterator<E> spliterator() {
return singletonSpliterator(element);
}
+ @Override
+ public int hashCode() {
+ return 31 + Objects.hashCode(element);
+ }
}
/**
@@ -4970,6 +4983,11 @@
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(k) ^ Objects.hashCode(v);
+ }
}
// Miscellaneous
--- a/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
+import jdk.internal.vm.annotation.Stable;
/**
* Container class for immutable collections. Not part of the public API.
@@ -105,6 +106,11 @@
return null; // but the compiler doesn't know this
}
+ @Override
+ public Iterator<E> iterator() {
+ return Collections.emptyIterator();
+ }
+
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("not serial proxy");
}
@@ -112,9 +118,26 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_LIST);
}
+
+ @Override
+ public boolean contains(Object o) {
+ Objects.requireNonNull(o);
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> o) {
+ return o.isEmpty(); // implicit nullcheck of o
+ }
+
+ @Override
+ public int hashCode() {
+ return 1;
+ }
}
static final class List1<E> extends AbstractImmutableList<E> {
+ @Stable
private final E e0;
List1(E e0) {
@@ -129,7 +152,6 @@
@Override
public E get(int index) {
Objects.checkIndex(index, 1);
- // assert index == 0
return e0;
}
@@ -140,10 +162,22 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_LIST, e0);
}
+
+ @Override
+ public boolean contains(Object o) {
+ return o.equals(e0); // implicit nullcheck of o
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 + e0.hashCode();
+ }
}
static final class List2<E> extends AbstractImmutableList<E> {
+ @Stable
private final E e0;
+ @Stable
private final E e1;
List2(E e0, E e1) {
@@ -166,6 +200,17 @@
}
}
+ @Override
+ public boolean contains(Object o) {
+ return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 31 + e0.hashCode();
+ return 31 * hash + e1.hashCode();
+ }
+
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("not serial proxy");
}
@@ -176,6 +221,7 @@
}
static final class ListN<E> extends AbstractImmutableList<E> {
+ @Stable
private final E[] elements;
@SafeVarargs
@@ -200,6 +246,25 @@
return elements[index];
}
+ @Override
+ public boolean contains(Object o) {
+ for (E e : elements) {
+ if (o.equals(e)) { // implicit nullcheck of o
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ for (E e : elements) {
+ hash = 31 * hash + e.hashCode();
+ }
+ return hash;
+ }
+
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("not serial proxy");
}
@@ -238,7 +303,13 @@
@Override
public boolean contains(Object o) {
- return super.contains(Objects.requireNonNull(o));
+ Objects.requireNonNull(o);
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> o) {
+ return o.isEmpty(); // implicit nullcheck of o
}
@Override
@@ -253,9 +324,15 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_SET);
}
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
}
static final class Set1<E> extends AbstractImmutableSet<E> {
+ @Stable
private final E e0;
Set1(E e0) {
@@ -269,7 +346,7 @@
@Override
public boolean contains(Object o) {
- return super.contains(Objects.requireNonNull(o));
+ return o.equals(e0); // implicit nullcheck of o
}
@Override
@@ -284,17 +361,21 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_SET, e0);
}
+
+ @Override
+ public int hashCode() {
+ return e0.hashCode();
+ }
}
static final class Set2<E> extends AbstractImmutableSet<E> {
- private final E e0;
- private final E e1;
+ @Stable
+ final E e0;
+ @Stable
+ final E e1;
Set2(E e0, E e1) {
- Objects.requireNonNull(e0);
- Objects.requireNonNull(e1);
-
- if (e0.equals(e1)) {
+ if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0
throw new IllegalArgumentException("duplicate element: " + e0);
}
@@ -314,7 +395,12 @@
@Override
public boolean contains(Object o) {
- return super.contains(Objects.requireNonNull(o));
+ return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
+ }
+
+ @Override
+ public int hashCode() {
+ return e0.hashCode() + e1.hashCode();
}
@Override
@@ -358,8 +444,10 @@
* @param <E> the element type
*/
static final class SetN<E> extends AbstractImmutableSet<E> {
- private final E[] elements;
- private final int size;
+ @Stable
+ final E[] elements;
+ @Stable
+ final int size;
@SafeVarargs
@SuppressWarnings("unchecked")
@@ -368,8 +456,8 @@
elements = (E[])new Object[EXPAND_FACTOR * input.length];
for (int i = 0; i < input.length; i++) {
- E e = Objects.requireNonNull(input[i]);
- int idx = probe(e);
+ E e = input[i];
+ int idx = probe(e); // implicit nullcheck of e
if (idx >= 0) {
throw new IllegalArgumentException("duplicate element: " + e);
} else {
@@ -385,8 +473,7 @@
@Override
public boolean contains(Object o) {
- Objects.requireNonNull(o);
- return probe(o) >= 0;
+ return probe(o) >= 0; // implicit nullcheck of o
}
@Override
@@ -414,8 +501,21 @@
};
}
+ @Override
+ public int hashCode() {
+ int h = 0;
+ for (E e : elements) {
+ if (e != null) {
+ h += e.hashCode();
+ }
+ }
+ return h;
+ }
+
// returns index at which element is present; or if absent,
- // (-i - 1) where i is location where element should be inserted
+ // (-i - 1) where i is location where element should be inserted.
+ // Callers are relying on this method to perform an implicit nullcheck
+ // of pe
private int probe(Object pe) {
int idx = Math.floorMod(pe.hashCode() ^ SALT, elements.length);
while (true) {
@@ -481,12 +581,14 @@
@Override
public boolean containsKey(Object o) {
- return super.containsKey(Objects.requireNonNull(o));
+ Objects.requireNonNull(o);
+ return false;
}
@Override
public boolean containsValue(Object o) {
- return super.containsValue(Objects.requireNonNull(o));
+ Objects.requireNonNull(o);
+ return false;
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -496,10 +598,17 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_MAP);
}
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
}
static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
+ @Stable
private final K k0;
+ @Stable
private final V v0;
Map1(K k0, V v0) {
@@ -514,12 +623,12 @@
@Override
public boolean containsKey(Object o) {
- return super.containsKey(Objects.requireNonNull(o));
+ return o.equals(k0); // implicit nullcheck of o
}
@Override
public boolean containsValue(Object o) {
- return super.containsValue(Objects.requireNonNull(o));
+ return o.equals(v0); // implicit nullcheck of o
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -529,6 +638,11 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_MAP, k0, v0);
}
+
+ @Override
+ public int hashCode() {
+ return k0.hashCode() ^ v0.hashCode();
+ }
}
/**
@@ -541,12 +655,13 @@
* @param <V> the value type
*/
static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
- private final Object[] table; // pairs of key, value
- private final int size; // number of pairs
+ @Stable
+ final Object[] table; // pairs of key, value
+ @Stable
+ final int size; // number of pairs
MapN(Object... input) {
- Objects.requireNonNull(input);
- if ((input.length & 1) != 0) {
+ if ((input.length & 1) != 0) { // implicit nullcheck of input
throw new InternalError("length is odd");
}
size = input.length >> 1;
@@ -573,12 +688,30 @@
@Override
public boolean containsKey(Object o) {
- return probe(Objects.requireNonNull(o)) >= 0;
+ return probe(o) >= 0; // implicit nullcheck of o
}
@Override
public boolean containsValue(Object o) {
- return super.containsValue(Objects.requireNonNull(o));
+ for (int i = 1; i < table.length; i += 2) {
+ Object v = table[i];
+ if (v != null && o.equals(v)) { // implicit nullcheck of o
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 0;
+ for (int i = 0; i < table.length; i += 2) {
+ Object k = table[i];
+ if (k != null) {
+ hash += k.hashCode() ^ table[i + 1].hashCode();
+ }
+ }
+ return hash;
}
@Override
@@ -638,7 +771,9 @@
}
// returns index at which the probe key is present; or if absent,
- // (-i - 1) where i is location where element should be inserted
+ // (-i - 1) where i is location where element should be inserted.
+ // Callers are relying on this method to perform an implicit nullcheck
+ // of pk.
private int probe(Object pk) {
int idx = Math.floorMod(pk.hashCode() ^ SALT, table.length >> 1) << 1;
while (true) {
--- a/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package java.util;
+import jdk.internal.vm.annotation.Stable;
+
/**
* An immutable container for a key and a value, suitable for use
* in creating and populating {@code Map} instances.
@@ -48,7 +50,9 @@
* @since 9
*/
final class KeyValueHolder<K,V> implements Map.Entry<K,V> {
+ @Stable
final K key;
+ @Stable
final V value;
KeyValueHolder(K k, V v) {
--- a/jdk/src/java.base/share/classes/java/util/List.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/List.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1027,8 +1027,7 @@
@SafeVarargs
@SuppressWarnings("varargs")
static <E> List<E> of(E... elements) {
- Objects.requireNonNull(elements);
- switch (elements.length) {
+ switch (elements.length) { // implicit null check of elements
case 0:
return ImmutableCollections.List0.instance();
case 1:
--- a/jdk/src/java.base/share/classes/java/util/Map.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Map.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1602,8 +1602,7 @@
@SafeVarargs
@SuppressWarnings("varargs")
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
- Objects.requireNonNull(entries);
- if (entries.length == 0) {
+ if (entries.length == 0) { // implicit null check of entries
return ImmutableCollections.Map0.instance();
} else if (entries.length == 1) {
return new ImmutableCollections.Map1<>(entries[0].getKey(),
--- a/jdk/src/java.base/share/classes/java/util/Set.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Set.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -689,8 +689,7 @@
@SafeVarargs
@SuppressWarnings("varargs")
static <E> Set<E> of(E... elements) {
- Objects.requireNonNull(elements);
- switch (elements.length) {
+ switch (elements.length) { // implicit null check of elements
case 0:
return ImmutableCollections.Set0.instance();
case 1:
--- a/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -362,59 +362,81 @@
}
/**
- * Main program to start a registry. <br>
- * The port number can be specified on the command line.
+ * Return a new RegistryImpl on the requested port and export it to serve
+ * registry requests. A classloader is initialized from the system property
+ * "env.class.path" and a security manager is set unless one is already set.
+ * <p>
+ * The returned Registry is fully functional within the current process and
+ * is usable for internal and testing purposes.
+ *
+ * @param regPort port on which the rmiregistry accepts requests;
+ * if 0, an implementation specific port is assigned
+ * @return a RegistryImpl instance
+ * @exception RemoteException If remote operation failed.
+ * @since 9
*/
- public static void main(String args[])
- {
+ public static RegistryImpl createRegistry(int regPort) throws RemoteException {
// Create and install the security manager if one is not installed
// already.
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
+ /*
+ * Fix bugid 4147561: When JDK tools are executed, the value of
+ * the CLASSPATH environment variable for the shell in which they
+ * were invoked is no longer incorporated into the application
+ * class path; CLASSPATH's only effect is to be the value of the
+ * system property "env.class.path". To preserve the previous
+ * (JDK1.1 and JDK1.2beta3) behavior of this tool, however, its
+ * CLASSPATH should still be considered when resolving classes
+ * being unmarshalled. To effect this old behavior, a class
+ * loader that loads from the file path specified in the
+ * "env.class.path" property is created and set to be the context
+ * class loader before the remote object is exported.
+ */
+ String envcp = System.getProperty("env.class.path");
+ if (envcp == null) {
+ envcp = "."; // preserve old default behavior
+ }
+ URL[] urls = pathToURLs(envcp);
+ ClassLoader cl = new URLClassLoader(urls);
+
+ /*
+ * Fix bugid 4242317: Classes defined by this class loader should
+ * be annotated with the value of the "java.rmi.server.codebase"
+ * property, not the "file:" URLs for the CLASSPATH elements.
+ */
+ sun.rmi.server.LoaderHandler.registerCodebaseLoader(cl);
+
+ Thread.currentThread().setContextClassLoader(cl);
+
+ RegistryImpl registryImpl = null;
try {
- /*
- * Fix bugid 4147561: When JDK tools are executed, the value of
- * the CLASSPATH environment variable for the shell in which they
- * were invoked is no longer incorporated into the application
- * class path; CLASSPATH's only effect is to be the value of the
- * system property "env.class.path". To preserve the previous
- * (JDK1.1 and JDK1.2beta3) behavior of this tool, however, its
- * CLASSPATH should still be considered when resolving classes
- * being unmarshalled. To effect this old behavior, a class
- * loader that loads from the file path specified in the
- * "env.class.path" property is created and set to be the context
- * class loader before the remote object is exported.
- */
- String envcp = System.getProperty("env.class.path");
- if (envcp == null) {
- envcp = "."; // preserve old default behavior
- }
- URL[] urls = pathToURLs(envcp);
- ClassLoader cl = new URLClassLoader(urls);
+ registryImpl = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<RegistryImpl>() {
+ public RegistryImpl run() throws RemoteException {
+ return new RegistryImpl(regPort);
+ }
+ }, getAccessControlContext(regPort));
+ } catch (PrivilegedActionException ex) {
+ throw (RemoteException) ex.getException();
+ }
- /*
- * Fix bugid 4242317: Classes defined by this class loader should
- * be annotated with the value of the "java.rmi.server.codebase"
- * property, not the "file:" URLs for the CLASSPATH elements.
- */
- sun.rmi.server.LoaderHandler.registerCodebaseLoader(cl);
+ return registryImpl;
+ }
- Thread.currentThread().setContextClassLoader(cl);
-
+ /**
+ * Main program to start a registry. <br>
+ * The port number can be specified on the command line.
+ */
+ public static void main(String args[])
+ {
+ try {
final int regPort = (args.length >= 1) ? Integer.parseInt(args[0])
: Registry.REGISTRY_PORT;
- try {
- registry = AccessController.doPrivileged(
- new PrivilegedExceptionAction<RegistryImpl>() {
- public RegistryImpl run() throws RemoteException {
- return new RegistryImpl(regPort);
- }
- }, getAccessControlContext(regPort));
- } catch (PrivilegedActionException ex) {
- throw (RemoteException) ex.getException();
- }
+
+ registry = createRegistry(regPort);
// prevent registry from exiting
while (true) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Jan 12 12:14:13 2017 -0800
@@ -1088,34 +1088,58 @@
}
}
- static class ClassPathConverter implements ValueConverter<Path> {
- static final ValueConverter<Path> INSTANCE = new ClassPathConverter();
+ /**
+ * An abstract converter that given a string representing a list of paths,
+ * separated by the File.pathSeparator, returns a List of java.nio.Path's.
+ * Specific subclasses should do whatever validation is required on the
+ * individual path elements, if any.
+ */
+ static abstract class AbstractPathConverter implements ValueConverter<List<Path>> {
+ @Override
+ public List<Path> convert(String value) {
+ List<Path> paths = new ArrayList<>();
+ String[] pathElements = value.split(File.pathSeparator);
+ for (String pathElement : pathElements) {
+ paths.add(toPath(pathElement));
+ }
+ return paths;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Class<List<Path>> valueType() {
+ return (Class<List<Path>>)(Object)List.class;
+ }
+
+ @Override public String valuePattern() { return "path"; }
+
+ abstract Path toPath(String path);
+ }
+
+ static class ClassPathConverter extends AbstractPathConverter {
+ static final ValueConverter<List<Path>> INSTANCE = new ClassPathConverter();
@Override
- public Path convert(String value) {
+ public Path toPath(String value) {
try {
Path path = CWD.resolve(value);
if (Files.notExists(path))
throw new CommandException("err.path.not.found", path);
- if (! (Files.isDirectory(path) ||
- (Files.isRegularFile(path) && path.toString().endsWith(".jar"))))
+ if (!(Files.isDirectory(path) ||
+ (Files.isRegularFile(path) && path.toString().endsWith(".jar"))))
throw new CommandException("err.invalid.class.path.entry", path);
return path;
} catch (InvalidPathException x) {
throw new CommandException("err.path.not.valid", value);
}
}
-
- @Override public Class<Path> valueType() { return Path.class; }
-
- @Override public String valuePattern() { return "path"; }
}
- static class DirPathConverter implements ValueConverter<Path> {
- static final ValueConverter<Path> INSTANCE = new DirPathConverter();
+ static class DirPathConverter extends AbstractPathConverter {
+ static final ValueConverter<List<Path>> INSTANCE = new DirPathConverter();
@Override
- public Path convert(String value) {
+ public Path toPath(String value) {
try {
Path path = CWD.resolve(value);
if (Files.notExists(path))
@@ -1127,10 +1151,6 @@
throw new CommandException("err.path.not.valid", value);
}
}
-
- @Override public Class<Path> valueType() { return Path.class; }
-
- @Override public String valuePattern() { return "path"; }
}
static class ExtractDirPathConverter implements ValueConverter<Path> {
@@ -1142,12 +1162,6 @@
if (Files.exists(path)) {
if (!Files.isDirectory(path))
throw new CommandException("err.cannot.create.dir", path);
- } else {
- try {
- Files.createDirectories(path);
- } catch (IOException ioe) {
- throw new CommandException("err.cannot.create.dir", path);
- }
}
return path;
} catch (InvalidPathException x) {
@@ -1316,22 +1330,19 @@
options = new Options();
parser.formatHelpWith(new JmodHelpFormatter(options));
- OptionSpec<Path> classPath
+ OptionSpec<List<Path>> classPath
= parser.accepts("class-path", getMessage("main.opt.class-path"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(ClassPathConverter.INSTANCE);
- OptionSpec<Path> cmds
+ OptionSpec<List<Path>> cmds
= parser.accepts("cmds", getMessage("main.opt.cmds"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
- OptionSpec<Path> config
+ OptionSpec<List<Path>> config
= parser.accepts("config", getMessage("main.opt.config"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
OptionSpec<Path> dir
@@ -1359,22 +1370,19 @@
OptionSpec<Void> helpExtra
= parser.accepts("help-extra", getMessage("main.opt.help-extra"));
- OptionSpec<Path> headerFiles
+ OptionSpec<List<Path>> headerFiles
= parser.accepts("header-files", getMessage("main.opt.header-files"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
- OptionSpec<Path> libs
+ OptionSpec<List<Path>> libs
= parser.accepts("libs", getMessage("main.opt.libs"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
- OptionSpec<Path> legalNotices
+ OptionSpec<List<Path>> legalNotices
= parser.accepts("legal-notices", getMessage("main.opt.legal-notices"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
@@ -1383,17 +1391,15 @@
.withRequiredArg()
.describedAs(getMessage("main.opt.main-class.arg"));
- OptionSpec<Path> manPages
+ OptionSpec<List<Path>> manPages
= parser.accepts("man-pages", getMessage("main.opt.man-pages"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
- OptionSpec<Path> modulePath
+ OptionSpec<List<Path>> modulePath
= parser.acceptsAll(Set.of("p", "module-path"),
getMessage("main.opt.module-path"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
OptionSpec<Version> moduleVersion
@@ -1452,48 +1458,48 @@
}
if (opts.has(classPath))
- options.classpath = opts.valuesOf(classPath);
+ options.classpath = getLastElement(opts.valuesOf(classPath));
if (opts.has(cmds))
- options.cmds = opts.valuesOf(cmds);
+ options.cmds = getLastElement(opts.valuesOf(cmds));
if (opts.has(config))
- options.configs = opts.valuesOf(config);
+ options.configs = getLastElement(opts.valuesOf(config));
if (opts.has(dir))
- options.extractDir = opts.valueOf(dir);
+ options.extractDir = getLastElement(opts.valuesOf(dir));
if (opts.has(dryrun))
options.dryrun = true;
if (opts.has(excludes))
- options.excludes = opts.valuesOf(excludes);
+ options.excludes = opts.valuesOf(excludes); // excludes is repeatable
if (opts.has(libs))
- options.libs = opts.valuesOf(libs);
+ options.libs = getLastElement(opts.valuesOf(libs));
if (opts.has(headerFiles))
- options.headerFiles = opts.valuesOf(headerFiles);
+ options.headerFiles = getLastElement(opts.valuesOf(headerFiles));
if (opts.has(manPages))
- options.manPages = opts.valuesOf(manPages);
+ options.manPages = getLastElement(opts.valuesOf(manPages));
if (opts.has(legalNotices))
- options.legalNotices = opts.valuesOf(legalNotices);
+ options.legalNotices = getLastElement(opts.valuesOf(legalNotices));
if (opts.has(modulePath)) {
- Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
+ Path[] dirs = getLastElement(opts.valuesOf(modulePath)).toArray(new Path[0]);
options.moduleFinder = new ModulePath(Runtime.version(), true, dirs);
}
if (opts.has(moduleVersion))
- options.moduleVersion = opts.valueOf(moduleVersion);
+ options.moduleVersion = getLastElement(opts.valuesOf(moduleVersion));
if (opts.has(mainClass))
- options.mainClass = opts.valueOf(mainClass);
+ options.mainClass = getLastElement(opts.valuesOf(mainClass));
if (opts.has(osName))
- options.osName = opts.valueOf(osName);
+ options.osName = getLastElement(opts.valuesOf(osName));
if (opts.has(osArch))
- options.osArch = opts.valueOf(osArch);
+ options.osArch = getLastElement(opts.valuesOf(osArch));
if (opts.has(osVersion))
- options.osVersion = opts.valueOf(osVersion);
+ options.osVersion = getLastElement(opts.valuesOf(osVersion));
if (opts.has(warnIfResolved))
- options.moduleResolution = opts.valueOf(warnIfResolved);
+ options.moduleResolution = getLastElement(opts.valuesOf(warnIfResolved));
if (opts.has(doNotResolveByDefault)) {
if (options.moduleResolution == null)
options.moduleResolution = ModuleResolution.empty();
options.moduleResolution = options.moduleResolution.withDoNotResolveByDefault();
}
if (opts.has(hashModules)) {
- options.modulesToHash = opts.valueOf(hashModules);
+ options.modulesToHash = getLastElement(opts.valuesOf(hashModules));
// if storing hashes then the module path is required
if (options.moduleFinder == null)
throw new CommandException("err.modulepath.must.be.specified")
@@ -1531,6 +1537,13 @@
throw new CommandException("err.classpath.must.be.specified").showUsage(true);
if (options.mainClass != null && !isValidJavaIdentifier(options.mainClass))
throw new CommandException("err.invalid.main-class", options.mainClass);
+ if (options.mode.equals(Mode.EXTRACT) && options.extractDir != null) {
+ try {
+ Files.createDirectories(options.extractDir);
+ } catch (IOException ioe) {
+ throw new CommandException("err.cannot.create.dir", options.extractDir);
+ }
+ }
} catch (OptionException e) {
throw new CommandException(e.getMessage());
}
@@ -1558,6 +1571,12 @@
return true;
}
+ static <E> E getLastElement(List<E> list) {
+ if (list.size() == 0)
+ throw new InternalError("Unexpected 0 list size");
+ return list.get(list.size() - 1);
+ }
+
private void reportError(String message) {
out.println(getMessage("error.prefix") + " " + message);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URLConnection/SetDefaultUseCaches.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8163449
+ * @summary Allow per protocol setting for URLConnection defaultUseCaches
+ * @run main/othervm SetDefaultUseCaches
+ */
+
+import java.net.*;
+import java.io.*;
+
+public class SetDefaultUseCaches {
+ static void testAssert(boolean value, boolean comparator) {
+ if (value != comparator) {
+ System.err.println("Expected " + comparator + " Got " + value);
+ throw new RuntimeException("Test failed:");
+ } else
+ System.err.println("OK");
+ }
+
+ public static void main(String s[]) throws Exception {
+ URL url = new URL("http://www.foo.com/");
+ URL url1 = new URL("file:///a/b.txt");
+
+ // check default default is true
+ URLConnection urlc = url.openConnection();
+ testAssert(urlc.getDefaultUseCaches(), true);
+
+ // set default for http to false and check
+ URLConnection.setDefaultUseCaches("HTTP", false);
+
+ urlc = url.openConnection();
+ testAssert(urlc.getDefaultUseCaches(), true);
+ testAssert(urlc.getUseCaches(), false);
+ testAssert(URLConnection.getDefaultUseCaches("http"), false);
+
+ URLConnection urlc1 = url1.openConnection();
+ testAssert(urlc1.getDefaultUseCaches(), true);
+
+ // set default default to false and check other values the same
+ urlc.setDefaultUseCaches(false);
+ urlc1.setDefaultUseCaches("fiLe", true);
+ testAssert(urlc1.getDefaultUseCaches(), false);
+ testAssert(URLConnection.getDefaultUseCaches("fiLE"), true);
+ }
+}
--- a/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,9 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary JavaVM RMID TestSecurityManager
+ * java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider RegistryVM RMIRegistryRunner
+ * TestSecurityManager
* @run main/othervm AltSecurityManager
*/
@@ -44,7 +46,6 @@
* if registry and rmid take too long to exit.
*/
public class AltSecurityManager implements Runnable {
- private final int regPort;
// variable to hold registry and rmid children
static JavaVM vm = null;
@@ -57,31 +58,34 @@
private static final long TIME_OUT =
(long)(15000 * TestLibrary.getTimeoutFactor());
- public AltSecurityManager(int port) {
- if (port <= 0) {
- TestLibrary.bomb("Port must be greater than 0.");
- }
-
- this.regPort = port;
- }
-
public void run() {
try {
if (utilityToStart.equals(REGISTRY_IMPL)) {
- vm = new JavaVM(utilityToStart,
- " -Djava.security.manager=TestSecurityManager",
- Integer.toString(regPort));
+ vm = RegistryVM.createRegistryVMWithRunner(
+ "RMIRegistryRunner",
+ "-Djava.security.manager=TestSecurityManager");
} else if (utilityToStart.contains(ACTIVATION)) {
- vm = new JavaVM(utilityToStart,
- " -Djava.security.manager=TestSecurityManager",
- "-port " + Integer.toString(regPort));
+ vm = RMID.createRMIDOnEphemeralPortWithOptions(
+ "-Djava.security.manager=TestSecurityManager");
} else {
TestLibrary.bomb("Utility to start must be " + REGISTRY_IMPL +
" or " + ACTIVATION);
}
System.err.println("starting " + utilityToStart);
- vm.execute();
+ try {
+ vm.start();
+ throw new RuntimeException("Expected exception did not occur!");
+ } catch (Exception expected) {
+ int exit = vm.waitFor();
+ if (exit != TestSecurityManager.EXIT_VALUE) {
+ throw new RuntimeException(utilityToStart
+ + " exit with an unexpected value "
+ + exit + ".");
+ }
+ System.err.format("Success: starting %s exited with status %d%n",
+ utilityToStart, TestSecurityManager.EXIT_VALUE);
+ }
} catch (Exception e) {
TestLibrary.bomb(e);
@@ -96,8 +100,7 @@
utilityToStart = utility;
try {
- int port = TestLibrary.getUnusedRandomPort();
- Thread thread = new Thread(new AltSecurityManager(port));
+ Thread thread = new Thread(new AltSecurityManager());
System.err.println("expecting RuntimeException for " +
"checkListen in child process");
long start = System.currentTimeMillis();
@@ -116,7 +119,7 @@
" terminated on time");
}
} finally {
- vm.destroy();
+ vm.cleanup();
vm = null;
}
}
--- a/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
/**/
public class TestSecurityManager extends SecurityManager {
+ public static final int EXIT_VALUE = 123;
+
public TestSecurityManager() {
}
@@ -36,7 +38,7 @@
// by the main test process to detect that the proper security
// manager has been installed in the relevant VMs.
//
- System.exit(1);
+ System.exit(EXIT_VALUE);
}
public void checkExit(int status) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/altSecurityManager/registry.security.policy Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,8 @@
+grant {
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+ permission java.util.PropertyPermission "env.class.path", "read";
+ permission java.io.FilePermission ".", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.lang.RuntimePermission "createClassLoader";
+ permission java.lang.RuntimePermission "setContextClassLoader";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/altSecurityManager/rmid.security.policy Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,7 @@
+grant {
+ permission java.lang.RuntimePermission "selectorProvider";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
+ permission java.util.PropertyPermission "test.java.rmi.testlibrary.RMIDSelectorProvider.port", "read";
+ permission java.util.PropertyPermission "test.java.rmi.testlibrary.RMIDSelectorProvider.timeout", "read";
+ permission java.net.SocketPermission "*:1024-", "listen,resolve,connect,accept";
+};
--- a/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary Dummy
+ * @build TestLibrary Dummy RegistryVM RMIRegistryRunner
* @run main/othervm/policy=security.policy
* -Djava.rmi.server.useCodebaseOnly=false ClassPathCodebase
*/
@@ -48,8 +48,9 @@
public class ClassPathCodebase {
- /** wait 10 seconds for the registry process to be ready to call */
- private final static long REGISTRY_WAIT = 15000;
+ /** wait dozens of seconds for the registry process to be ready to call */
+ private static final long REGISTRY_WAIT =
+ (long)(10000 * TestLibrary.getTimeoutFactor());
private final static String dummyClassName = "Dummy";
@@ -64,7 +65,7 @@
TestLibrary.suggestSecurityManager("java.lang.SecurityManager");
- Process rmiregistry = null;
+ RegistryVM rmiregistry = null;
try {
/*
@@ -82,27 +83,13 @@
* Spawn an rmiregistry in the "import" codebase directory.
*/
File rmiregistryDir =
- new File(System.getProperty("user.dir", "."), importCodebase);
-
- String rmiregistryCommand =
- System.getProperty("java.home") + File.separator +
- "bin" + File.separator + "rmiregistry";
-
- int port = TestLibrary.getUnusedRandomPort();
- String cmdarray[] = new String[] {
- rmiregistryCommand,
- "-J-Denv.class.path=.",
- "-J-Djava.rmi.server.codebase=" + exportCodebaseURL,
- Integer.toString(port) };
-
- System.err.println("\nCommand used to spawn rmiregistry process:");
- System.err.println("\t" + Arrays.asList(cmdarray).toString());
-
- rmiregistry = Runtime.getRuntime().exec(cmdarray, null, rmiregistryDir);
-
- // pipe rmiregistry output to our output, for debugging failures
- StreamPipe.plugTogether(rmiregistry.getInputStream(), System.err);
- StreamPipe.plugTogether(rmiregistry.getErrorStream(), System.err);
+ new File(System.getProperty("user.dir", "."), importCodebase);
+ rmiregistry = RegistryVM.createRegistryVMWithRunner("RMIRegistryRunner",
+ " -Denv.class.path=."
+ + " -Djava.rmi.server.codebase=" + exportCodebaseURL
+ + " -Duser.dir=" + rmiregistryDir.getAbsolutePath());
+ rmiregistry.start();
+ int port = rmiregistry.getPort();
/*
* Wait for the registry to initialize and be ready to call.
@@ -174,7 +161,7 @@
throw new RuntimeException("TEST FAILED: " + e.toString());
} finally {
if (rmiregistry != null) {
- rmiregistry.destroy();
+ rmiregistry.cleanup();
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/classPathCodebase/registry.security.policy Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,18 @@
+/*
+ * security policy used by the registry process started by RegistryVM.
+ */
+
+grant {
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+ permission java.util.PropertyPermission "env.class.path", "read";
+ permission java.io.FilePermission ".", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.lang.RuntimePermission "createClassLoader";
+ permission java.lang.RuntimePermission "setContextClassLoader";
+ permission java.io.FilePermission ".-Djava.rmi.server.codebase=file", "read";
+ permission java.io.FilePermission ".${/}-", "read";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
+ permission java.net.SocketPermission "*:1024-", "listen,resolve,connect,accept";
+};
--- a/jdk/test/java/rmi/registry/classPathCodebase/security.policy Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/classPathCodebase/security.policy Thu Jan 12 12:14:13 2017 -0800
@@ -18,6 +18,12 @@
// test needs to use java to exec an rmiregistry
permission java.io.FilePermission "${java.home}${/}bin${/}-", "execute";
- // test needs to communicate with this its registry
+ // test needs to communicate with its registry
permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+ permission java.util.PropertyPermission "java.security.policy", "read";
+ permission java.util.PropertyPermission "java.security.manager", "read";
+
+ // used by TestLibrary to determine extra commandline properties
+ permission java.io.FilePermission "..${/}..${/}test.props", "read";
};
--- a/jdk/test/java/rmi/registry/reexport/Reexport.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/reexport/Reexport.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary REGISTRY RegistryRunner
+ * @build TestLibrary RegistryVM RegistryRunner
* @run main/othervm Reexport
*/
@@ -114,7 +114,7 @@
public static void makeRegistry() {
try {
- subreg = REGISTRY.createREGISTRY();
+ subreg = RegistryVM.createRegistryVM();
subreg.start();
port = subreg.getPort();
System.out.println("Starting registry on port " + port);
@@ -125,12 +125,12 @@
}
}
- private static REGISTRY subreg = null;
+ private static RegistryVM subreg = null;
private static int port = -1;
public static void killRegistry() {
if (subreg != null) {
- subreg.shutdown();
+ subreg.cleanup();
subreg = null;
}
}
--- a/jdk/test/java/rmi/testlibrary/JavaVM.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/testlibrary/JavaVM.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -230,6 +230,22 @@
}
/**
+ * Return exit value for vm process.
+ * @return exit value for vm process
+ * @throws IllegalThreadStateException if the vm process has not yet terminated
+ */
+ public int exitValue() {
+ return vm.exitValue();
+ }
+
+ /**
+ * Destroy the vm process, and do necessary cleanup.
+ */
+ public void cleanup() {
+ destroy();
+ }
+
+ /**
* Destroys the VM, waits for it to terminate, and returns
* its exit status.
*
--- a/jdk/test/java/rmi/testlibrary/REGISTRY.java Thu Jan 12 11:58:01 2017 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.OutputStream;
-import java.io.IOException;
-
-/**
- * Class to run and control rmiregistry in a sub-process.
- *
- * We can't kill a registry if we have too-close control
- * over it. We must make it in a subprocess, and then kill the
- * subprocess when it has served our needs.
- */
-public class REGISTRY extends JavaVM {
-
- private static final double START_TIMEOUT =
- 20_000 * TestLibrary.getTimeoutFactor();
- private static final String DEFAULT_RUNNER = "RegistryRunner";
-
- private int port = -1;
-
- private REGISTRY(String runner, OutputStream out, OutputStream err,
- String options, int port) {
- super(runner, options, Integer.toString(port), out, err);
- try {
- Class runnerClass = Class.forName(runner);
- if (!RegistryRunner.class.isAssignableFrom(runnerClass)) {
- throw new RuntimeException("runner class must be RegistryRunner"
- + " or its sub class");
- }
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException(ex);
- }
- this.port = port;
- }
-
- public static REGISTRY createREGISTRY() {
- return createREGISTRYWithRunner(DEFAULT_RUNNER, System.out, System.err, "", 0);
- }
-
- public static REGISTRY createREGISTRY(OutputStream out, OutputStream err,
- String options, int port) {
- return createREGISTRYWithRunner(DEFAULT_RUNNER, out, err, options, port);
- }
-
- public static REGISTRY createREGISTRYWithRunner(String runner, String options) {
- return createREGISTRYWithRunner(runner, System.out, System.err, options, 0);
- }
-
- public static REGISTRY createREGISTRYWithRunner(String runner, OutputStream out,
- OutputStream err, String options, int port) {
- options += " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED"
- + " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
- + " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
- + " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
- REGISTRY reg = new REGISTRY(runner, out, err, options, port);
- return reg;
- }
-
- /**
- * Starts the registry in a sub-process and waits up to
- * the given timeout period to confirm that it's running,
- * and get the port where it's running.
- */
- public void start() throws IOException {
- super.start();
- long startTime = System.currentTimeMillis();
- long deadline = TestLibrary.computeDeadline(startTime, (long)START_TIMEOUT);
- while (true) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ignore) { }
-
- String output = outputStream.ba.toString();
- port = RegistryRunner.getRegistryPort(output);
- if (port != -1) {
- break;
- }
- if (System.currentTimeMillis() > deadline) {
- TestLibrary.bomb("Failed to start registry, giving up after " +
- (System.currentTimeMillis() - startTime) + "ms.", null);
- }
- }
- }
-
- /**
- * Shuts down the registry.
- */
- public void shutdown() {
- RegistryRunner.requestExit(port);
- }
-
- /**
- * Gets the port where the registry is serving.
- */
- public int getPort() {
- return port;
- }
-}
--- a/jdk/test/java/rmi/testlibrary/RMID.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/testlibrary/RMID.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -140,18 +140,6 @@
}
private static String makeArgs(boolean includePortArg, int port) {
- String propagateManager = null;
-
- // rmid will run with a security manager set, but no policy
- // file - it should not need one.
- if (System.getSecurityManager() == null) {
- propagateManager = MANAGER_OPTION +
- TestParams.defaultSecurityManager;
- } else {
- propagateManager = MANAGER_OPTION +
- System.getSecurityManager().getClass().getName();
- }
-
// getAbsolutePath requires permission to read user.dir
String args =
" -log " + (new File(LOGDIR, log)).getAbsolutePath();
@@ -210,7 +198,30 @@
boolean debugExec, boolean includePortArg,
int port)
{
+ return createRMIDWithOptions(out, err, debugExec, includePortArg, port, "");
+ }
+
+ /**
+ * Create a RMID on a specified port capturing stdout and stderr
+ * with additional command line options and whether to print out
+ * debugging information that is used for spawning activation groups.
+ *
+ * @param out the OutputStream where the normal output of the
+ * rmid subprocess goes
+ * @param err the OutputStream where the error output of the
+ * rmid subprocess goes
+ * @param debugExec whether to print out debugging information
+ * @param includePortArg whether to include port argument
+ * @param port the port on which rmid accepts requests
+ * @param additionalOptions additional command line options
+ * @return a RMID instance
+ */
+ public static RMID createRMIDWithOptions(OutputStream out, OutputStream err,
+ boolean debugExec, boolean includePortArg,
+ int port, String additionalOptions)
+ {
String options = makeOptions(port, debugExec, false);
+ options += " " + additionalOptions;
String args = makeArgs(includePortArg, port);
RMID rmid = new RMID("sun.rmi.server.Activation", options, args,
out, err, port);
@@ -223,6 +234,19 @@
return createRMID(System.out, System.err, true, false, 0);
}
+ /**
+ * Create a RMID on an ephemeral port capturing stdout and stderr
+ * with additional command line options.
+ *
+ * @param additionalOptions additional command line options
+ * @return a RMID instance
+ */
+ public static RMID createRMIDOnEphemeralPortWithOptions(
+ String additionalOptions) {
+ return createRMIDWithOptions(System.out, System.err,
+ true, false, 0, additionalOptions);
+ }
+
public static RMID createRMIDOnEphemeralPort(OutputStream out,
OutputStream err,
boolean debugExec)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/testlibrary/RMIRegistryRunner.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**/
+
+import java.rmi.*;
+import java.rmi.registry.*;
+import java.rmi.server.*;
+
+/**
+ * Class to run a rmiregistry whose VM can be told to exit remotely;
+ * Difference between this class and RegistryRunner is that this class
+ * simulate rmiregistry closer than RegistryRunner.
+ */
+public class RMIRegistryRunner extends RegistryRunner
+{
+ public RMIRegistryRunner() throws RemoteException {
+ }
+
+ /**
+ * port 0 means to use ephemeral port to start registry.
+ *
+ * @param args command line arguments passed in from main
+ * @return the port number on which registry accepts requests
+ */
+ protected static int init(String[] args) {
+ try {
+ if (args.length == 0) {
+ System.err.println("Usage: <port>");
+ System.exit(0);
+ }
+ int port = -1;
+ port = Integer.parseInt(args[0]);
+
+ // call RegistryImpl.createRegistry to simulate rmiregistry.
+ registry = sun.rmi.registry.RegistryImpl.createRegistry(port);
+ if (port == 0) {
+ port = TestLibrary.getRegistryPort(registry);
+ }
+
+ // create a remote object to tell this VM to exit
+ exiter = new RMIRegistryRunner();
+ Naming.rebind("rmi://localhost:" + port +
+ "/RemoteExiter", exiter);
+
+ return port;
+ } catch (Exception e) {
+ System.err.println(e.getMessage());
+ e.printStackTrace();
+ System.exit(1);
+ }
+ return -1;
+ }
+
+ public static void main(String[] args) {
+ int port = init(args);
+ notify(port);
+ }
+}
--- a/jdk/test/java/rmi/testlibrary/RegistryRunner.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/testlibrary/RegistryRunner.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
/**
* Class to run a registry whose VM can be told to exit remotely; using
- * the rmiregistry in this fashion makes tests more robust under
+ * a registry (in a sub-process) in this fashion makes tests more robust under
* windows where Process.destroy() seems not to be 100% reliable.
*/
public class RegistryRunner extends UnicastRemoteObject
@@ -38,8 +38,8 @@
private static final String PORT_LABEL_START = "RegistryRunner.port.start:";
private static final String PORT_LABEL_END = ":RegistryRunner.port.end";
- private static Registry registry = null;
- private static RemoteExiter exiter = null;
+ protected static Registry registry = null;
+ protected static RemoteExiter exiter = null;
public RegistryRunner() throws RemoteException {
}
@@ -72,6 +72,7 @@
} catch (RemoteException re) {
}
e = null;
+
} catch (java.net.MalformedURLException mfue) {
// will not happen
} catch (NotBoundException nbe) {
@@ -97,6 +98,9 @@
/**
* port 0 means to use ephemeral port to start registry.
+ *
+ * @param args command line arguments passed in from main
+ * @return the port number on which registry accepts requests
*/
protected static int init(String[] args) {
try {
@@ -128,13 +132,15 @@
}
/**
- * REGISTRY.start() will filter the output of registry subprocess,
- * when valid port is detected, REGISTRY.start() returns.
+ * RegistryVM.start() will filter the output of registry subprocess,
+ * when valid port is detected, RegistryVM.start() returns.
* So, for subclass, it's important to call this method after registry
* is initialized and necessary remote objects have been bound.
+ *
+ * @param port the port on which registry accepts requests
*/
protected static void notify(int port) {
- // this output is important for REGISTRY to get the port
+ // this output is important for RegistryVM to get the port
// where rmiregistry is serving
System.out.println(PORT_LABEL_START + port + PORT_LABEL_END);
System.out.flush();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/testlibrary/RegistryVM.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * Class to run and control registry/rmiregistry in a sub-process.
+ * The behaviour changes when use different runner, currently
+ * there are 2 built-in runners, RegistryRunner and RMIRegistryRunner.
+ *
+ * We can't kill a registry if we have too-close control
+ * over it. We must make it in a subprocess, and then kill the
+ * subprocess when it has served our needs.
+ */
+public class RegistryVM extends JavaVM {
+
+ private static final double START_TIMEOUT =
+ 20_000 * TestLibrary.getTimeoutFactor();
+ private static final String DEFAULT_RUNNER = "RegistryRunner";
+
+ private int port = -1;
+
+ private RegistryVM(String runner, OutputStream out, OutputStream err,
+ String options, int port) {
+ super(runner, options, Integer.toString(port), out, err);
+ try {
+ Class runnerClass = Class.forName(runner);
+ if (!RegistryRunner.class.isAssignableFrom(runnerClass)) {
+ throw new RuntimeException("runner class must be RegistryRunner"
+ + " or its sub class");
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new RuntimeException(ex);
+ }
+ this.port = port;
+ }
+
+ /**
+ * Create a RegistryVM instance on an ephemeral port.
+ *
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVM() {
+ return createRegistryVMWithRunner(DEFAULT_RUNNER, System.out, System.err, "", 0);
+ }
+
+ /**
+ * Create a RegistryVM instance on an ephemeral port with additional
+ * command line options.
+ *
+ * @param options command line options
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVM(String options) {
+ return createRegistryVMWithRunner(
+ DEFAULT_RUNNER, System.out, System.err, options, 0);
+ }
+
+ /**
+ * Create a RegistryVM instance on a specified port capturing stdout and
+ * stderr with additional command line options.
+ *
+ * @param out the OutputStream where the normal output of the
+ * registry subprocess goes
+ * @param err the OutputStream where the error output of the
+ * registry subprocess goes
+ * @param options the command line options
+ * @param port the port on which Registry accepts requests
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVM(OutputStream out, OutputStream err,
+ String options, int port) {
+ return createRegistryVMWithRunner(DEFAULT_RUNNER, out, err, options, port);
+ }
+
+ /**
+ * Create a RegistryVM instance on an ephemeral port with additional
+ * command line options and a specified runner.
+ *
+ * @param runner the runner class name
+ * @param options command line options
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVMWithRunner(String runner, String options) {
+ return createRegistryVMWithRunner(runner, System.out, System.err, options, 0);
+ }
+
+ /**
+ * Create a RegistryVM instance on a specified port capturing stdout and
+ * stderr with additional command line options and a specified runner.
+ *
+ * @param runner the runner class name
+ * @param out the OutputStream where the normal output of the
+ * registry subprocess goes
+ * @param err the OutputStream where the error output of the
+ * registry subprocess goes
+ * @param options the command line options
+ * @param port the port on which Registry accepts requests
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVMWithRunner(String runner, OutputStream out,
+ OutputStream err, String options, int port) {
+ options += " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED"
+ + " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
+ + " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
+ + " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
+ RegistryVM reg = new RegistryVM(runner, out, err, options, port);
+ reg.setPolicyFile(TestParams.defaultRegistryPolicy);
+ return reg;
+ }
+
+ /**
+ * Starts the registry in a sub-process and waits up to
+ * the given timeout period to confirm that it's running,
+ * and get the port where it's running.
+ *
+ * @throws IOException if fails to start subprocess
+ */
+ public void start() throws IOException {
+ super.start();
+ long startTime = System.currentTimeMillis();
+ long deadline = TestLibrary.computeDeadline(startTime, (long)START_TIMEOUT);
+ while (true) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignore) { }
+
+ String output = outputStream.ba.toString();
+ port = RegistryRunner.getRegistryPort(output);
+ if (port != -1) {
+ break;
+ }
+ try {
+ int exit = vm.exitValue();
+ TestLibrary.bomb("[RegistryVM] registry sub-process exited with status "
+ + exit + ".");
+ } catch (IllegalThreadStateException ignore) { }
+
+ if (System.currentTimeMillis() > deadline) {
+ TestLibrary.bomb("Failed to start registry, giving up after " +
+ (System.currentTimeMillis() - startTime) + "ms.", null);
+ }
+ }
+ }
+
+ /**
+ * Shuts down the registry.
+ */
+ @Override
+ public void cleanup() {
+ RegistryRunner.requestExit(port);
+ super.destroy();
+ }
+
+ /**
+ * Gets the port where the registry is serving.
+ *
+ * @return the port where the registry is serving
+ */
+ public int getPort() {
+ return port;
+ }
+}
--- a/jdk/test/java/rmi/testlibrary/TestParams.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/testlibrary/TestParams.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,9 @@
/** name of default security policy for RMID */
public static final String defaultRmidPolicy;
+ /** name of default security policy for RegistryVM */
+ public static final String defaultRegistryPolicy;
+
/** name of default security policy for activation groups */
public static final String defaultGroupPolicy;
@@ -69,6 +72,9 @@
defaultRmidPolicy =
testSrc + File.separatorChar + "rmid.security.policy";
+ defaultRegistryPolicy =
+ testSrc + File.separatorChar + "registry.security.policy";
+
defaultGroupPolicy =
testSrc + File.separatorChar + "group.security.policy";
--- a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary Test TestImpl REGISTRY RegistryRunner
+ * @build TestLibrary Test TestImpl RegistryVM RegistryRunner
* @run main/othervm/policy=security.policy/timeout=360 DGCDeadLock
*/
@@ -68,21 +68,18 @@
static public void main(String[] args) {
- REGISTRY testImplVM = null;
+ RegistryVM testImplVM = null;
System.err.println("\nregression test for 4118056\n");
TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
try {
- String options = " -Djava.security.policy=" +
- TestParams.defaultPolicy +
- " --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED" +
+ String options = " --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED" +
" -Djava.rmi.dgc.leaseValue=500000" +
" -Dsun.rmi.dgc.checkInterval=" +
- (HOLD_TARGET_TIME - 5000) +
- "" ;
+ (HOLD_TARGET_TIME - 5000);
- testImplVM = REGISTRY.createREGISTRYWithRunner("TestImpl", options);
+ testImplVM = RegistryVM.createRegistryVMWithRunner("TestImpl", options);
testImplVM.start();
registryPort = testImplVM.getPort();
@@ -107,7 +104,7 @@
TestLibrary.bomb("test failed in main()", e);
} finally {
if (testImplVM != null) {
- testImplVM.shutdown();
+ testImplVM.cleanup();
testImplVM = null;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/registry.security.policy Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,27 @@
+/*
+ * security policy used by the registry sub-process
+ */
+
+grant {
+ // used by TestLibrary to determine extra commandline properties
+ permission java.io.FilePermission "..${/}..${/}test.props", "read";
+
+ // property specifically accessed by this test.
+ permission java.util.PropertyPermission "sun.rmi.transport.cleanInterval", "write";
+ permission java.util.PropertyPermission "package.restrict.access.sun", "read";
+ permission java.util.PropertyPermission "package.restrict.access.sun.rmi", "read";
+
+ // test needs to use java to exec an EchoImpl object
+ permission java.io.FilePermission "${java.home}${/}bin${/}java", "execute";
+
+ // used by TestLibrary to determine test environment
+ permission java.util.PropertyPermission "test.*", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.util.PropertyPermission "java.home", "read";
+
+ permission java.util.PropertyPermission "java.security.policy", "read";
+ permission java.util.PropertyPermission "java.security.manager", "read";
+
+ // test needs to export rmid and communicate with objects on arbitrary ports
+ permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+};
--- a/jdk/test/java/time/TEST.properties Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/TEST.properties Thu Jan 12 12:14:13 2017 -0800
@@ -1,7 +1,6 @@
# Threeten test uses TestNG
TestNG.dirs = .
othervm.dirs = tck/java/time/chrono test/java/time/chrono test/java/time/format
-modules = jdk.localedata
lib.dirs = ../../lib/testlibrary
lib.build = jdk.testlibrary.RandomFactory
modules = java.base/java.time:open java.base/java.time.chrono:open java.base/java.time.zone:open
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java Thu Jan 12 12:14:13 2017 -0800
@@ -880,25 +880,6 @@
}
//-----------------------------------------------------------------------
- @DataProvider(name="patternPrint")
- Object[][] data_patternPrint() {
- return new Object[][] {
- {"Q", date(2012, 2, 10), "1"},
- {"QQ", date(2012, 2, 10), "01"},
- {"QQQ", date(2012, 2, 10), "Q1"},
- {"QQQQ", date(2012, 2, 10), "1st quarter"},
- {"QQQQQ", date(2012, 2, 10), "1"},
- };
- }
-
- @Test(dataProvider="patternPrint")
- public void test_appendPattern_patternPrint(String input, Temporal temporal, String expected) throws Exception {
- DateTimeFormatter f = builder.appendPattern(input).toFormatter(Locale.UK);
- String test = f.format(temporal);
- assertEquals(test, expected);
- }
-
- //-----------------------------------------------------------------------
@DataProvider(name="localePatterns")
Object[][] localizedDateTimePatterns() {
return new Object[][] {
@@ -914,48 +895,6 @@
{null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.US, "h:mm:ss a z"},
{null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.US, "h:mm:ss a"},
{null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.US, "h:mm a"},
-
- // French Locale and ISO Chronology
- {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y '\u00e0' HH:mm:ss zzzz"},
- {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y '\u00e0' HH:mm:ss z"},
- {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y '\u00e0' HH:mm:ss"},
- {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y HH:mm"},
- {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y"},
- {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y"},
- {FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y"},
- {FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y"},
- {null, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss zzzz"},
- {null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss z"},
- {null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss"},
- {null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm"},
-
- // Japanese Locale and JapaneseChronology
- {FormatStyle.FULL, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE H\u6642mm\u5206ss\u79d2 zzzz"},
- {FormatStyle.LONG, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss z"},
- {FormatStyle.MEDIUM, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss"},
- {FormatStyle.SHORT, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d H:mm"},
- {FormatStyle.FULL, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
- {FormatStyle.LONG, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
- {FormatStyle.MEDIUM, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
- {FormatStyle.SHORT, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d"},
- {null, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H\u6642mm\u5206ss\u79d2 zzzz"},
- {null, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss z"},
- {null, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss"},
- {null, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm"},
-
- // Chinese Local and Chronology
- {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz ah:mm:ss"},
- {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z ah:mm:ss"},
- {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ah:mm:ss"},
- {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
- {FormatStyle.FULL, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
- {FormatStyle.LONG, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
- {FormatStyle.MEDIUM, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
- {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
- {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz ah:mm:ss"},
- {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z ah:mm:ss"},
- {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm:ss"},
- {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm"},
};
}
@@ -1004,5 +943,4 @@
private static Temporal date(int y, int m, int d) {
return LocalDate.of(y, m, d);
}
-
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilderWithLocale.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of JSR-310 nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+package test.java.time.format;
+
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.FormatStyle;
+import java.time.LocalDate;
+import java.time.temporal.Temporal;
+
+import java.util.Locale;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test DateTimeFormatterBuilder.
+ */
+@Test
+public class TestDateTimeFormatterBuilderWithLocale {
+
+ private DateTimeFormatterBuilder builder;
+
+ @BeforeMethod
+ public void setUp() {
+ builder = new DateTimeFormatterBuilder();
+ }
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name="patternPrint")
+ Object[][] data_patternPrint() {
+ return new Object[][] {
+ {"Q", date(2012, 2, 10), "1"},
+ {"QQ", date(2012, 2, 10), "01"},
+ {"QQQ", date(2012, 2, 10), "Q1"},
+ {"QQQQ", date(2012, 2, 10), "1st quarter"},
+ {"QQQQQ", date(2012, 2, 10), "1"},
+ };
+ }
+
+ @Test(dataProvider="patternPrint")
+ public void test_appendPattern_patternPrint(String input, Temporal temporal, String expected) throws Exception {
+ DateTimeFormatter f = builder.appendPattern(input).toFormatter(Locale.UK);
+ String test = f.format(temporal);
+ assertEquals(test, expected);
+ }
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name="localePatterns")
+ Object[][] localizedDateTimePatterns() {
+ return new Object[][] {
+ // French Locale and ISO Chronology
+ {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y '\u00e0' HH:mm:ss zzzz"},
+ {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y '\u00e0' HH:mm:ss z"},
+ {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y '\u00e0' HH:mm:ss"},
+ {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y HH:mm"},
+ {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y"},
+ {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y"},
+ {FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y"},
+ {FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y"},
+ {null, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss zzzz"},
+ {null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss z"},
+ {null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss"},
+ {null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm"},
+
+ // Japanese Locale and JapaneseChronology
+ {FormatStyle.FULL, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE H\u6642mm\u5206ss\u79d2 zzzz"},
+ {FormatStyle.LONG, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss z"},
+ {FormatStyle.MEDIUM, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss"},
+ {FormatStyle.SHORT, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d H:mm"},
+ {FormatStyle.FULL, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
+ {FormatStyle.LONG, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
+ {FormatStyle.MEDIUM, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
+ {FormatStyle.SHORT, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d"},
+ {null, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H\u6642mm\u5206ss\u79d2 zzzz"},
+ {null, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss z"},
+ {null, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss"},
+ {null, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm"},
+
+ // Chinese Local and Chronology
+ {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz ah:mm:ss"},
+ {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z ah:mm:ss"},
+ {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ah:mm:ss"},
+ {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
+ {FormatStyle.FULL, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
+ {FormatStyle.LONG, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
+ {FormatStyle.MEDIUM, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
+ {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
+ {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz ah:mm:ss"},
+ {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z ah:mm:ss"},
+ {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm:ss"},
+ {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm"},
+ };
+ }
+
+ @Test(dataProvider="localePatterns")
+ public void test_getLocalizedDateTimePattern(FormatStyle dateStyle, FormatStyle timeStyle,
+ Chronology chrono, Locale locale, String expected) {
+ String actual = DateTimeFormatterBuilder.getLocalizedDateTimePattern(dateStyle, timeStyle, chrono, locale);
+ assertEquals(actual, expected, "Pattern " + convertNonAscii(actual));
+ }
+
+ /**
+ * Returns a string that includes non-ascii characters after expanding
+ * the non-ascii characters to their Java language \\uxxxx form.
+ * @param input an input string
+ * @return the encoded string.
+ */
+ private String convertNonAscii(String input) {
+ StringBuilder sb = new StringBuilder(input.length() * 6);
+ for (int i = 0; i < input.length(); i++) {
+ char ch = input.charAt(i);
+ if (ch < 255) {
+ sb.append(ch);
+ } else {
+ sb.append("\\u");
+ sb.append(Integer.toHexString(ch));
+ }
+ }
+ return sb.toString();
+ }
+
+ private static Temporal date(int y, int m, int d) {
+ return LocalDate.of(y, m, d);
+ }
+}
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,6 @@
public class TestDateTimeTextProvider extends AbstractTestPrinterParser {
Locale enUS = new Locale("en", "US");
- Locale ptBR = new Locale("pt", "BR");
//-----------------------------------------------------------------------
@DataProvider(name = "Text")
@@ -94,14 +93,6 @@
{DAY_OF_WEEK, 6, TextStyle.SHORT, enUS, "Sat"},
{DAY_OF_WEEK, 7, TextStyle.SHORT, enUS, "Sun"},
- {DAY_OF_WEEK, 1, TextStyle.SHORT, ptBR, "seg"},
- {DAY_OF_WEEK, 2, TextStyle.SHORT, ptBR, "ter"},
- {DAY_OF_WEEK, 3, TextStyle.SHORT, ptBR, "qua"},
- {DAY_OF_WEEK, 4, TextStyle.SHORT, ptBR, "qui"},
- {DAY_OF_WEEK, 5, TextStyle.SHORT, ptBR, "sex"},
- {DAY_OF_WEEK, 6, TextStyle.SHORT, ptBR, "s\u00E1b"},
- {DAY_OF_WEEK, 7, TextStyle.SHORT, ptBR, "dom"},
-
{DAY_OF_WEEK, 1, TextStyle.FULL, enUS, "Monday"},
{DAY_OF_WEEK, 2, TextStyle.FULL, enUS, "Tuesday"},
{DAY_OF_WEEK, 3, TextStyle.FULL, enUS, "Wednesday"},
@@ -110,14 +101,6 @@
{DAY_OF_WEEK, 6, TextStyle.FULL, enUS, "Saturday"},
{DAY_OF_WEEK, 7, TextStyle.FULL, enUS, "Sunday"},
- {DAY_OF_WEEK, 1, TextStyle.FULL, ptBR, "segunda-feira"},
- {DAY_OF_WEEK, 2, TextStyle.FULL, ptBR, "ter\u00E7a-feira"},
- {DAY_OF_WEEK, 3, TextStyle.FULL, ptBR, "quarta-feira"},
- {DAY_OF_WEEK, 4, TextStyle.FULL, ptBR, "quinta-feira"},
- {DAY_OF_WEEK, 5, TextStyle.FULL, ptBR, "sexta-feira"},
- {DAY_OF_WEEK, 6, TextStyle.FULL, ptBR, "s\u00E1bado"},
- {DAY_OF_WEEK, 7, TextStyle.FULL, ptBR, "domingo"},
-
{MONTH_OF_YEAR, 1, TextStyle.SHORT, enUS, "Jan"},
{MONTH_OF_YEAR, 2, TextStyle.SHORT, enUS, "Feb"},
{MONTH_OF_YEAR, 3, TextStyle.SHORT, enUS, "Mar"},
@@ -131,19 +114,6 @@
{MONTH_OF_YEAR, 11, TextStyle.SHORT, enUS, "Nov"},
{MONTH_OF_YEAR, 12, TextStyle.SHORT, enUS, "Dec"},
- {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"},
- {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"},
- {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"},
- {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"},
- {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"},
- {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"},
- {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"},
- {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"},
- {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"},
- {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"},
- {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"},
- {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"},
-
{MONTH_OF_YEAR, 1, TextStyle.FULL, enUS, "January"},
{MONTH_OF_YEAR, 2, TextStyle.FULL, enUS, "February"},
{MONTH_OF_YEAR, 3, TextStyle.FULL, enUS, "March"},
@@ -157,19 +127,6 @@
{MONTH_OF_YEAR, 11, TextStyle.FULL, enUS, "November"},
{MONTH_OF_YEAR, 12, TextStyle.FULL, enUS, "December"},
- {MONTH_OF_YEAR, 1, TextStyle.FULL, ptBR, "janeiro"},
- {MONTH_OF_YEAR, 2, TextStyle.FULL, ptBR, "fevereiro"},
- {MONTH_OF_YEAR, 3, TextStyle.FULL, ptBR, "mar\u00E7o"},
- {MONTH_OF_YEAR, 4, TextStyle.FULL, ptBR, "abril"},
- {MONTH_OF_YEAR, 5, TextStyle.FULL, ptBR, "maio"},
- {MONTH_OF_YEAR, 6, TextStyle.FULL, ptBR, "junho"},
- {MONTH_OF_YEAR, 7, TextStyle.FULL, ptBR, "julho"},
- {MONTH_OF_YEAR, 8, TextStyle.FULL, ptBR, "agosto"},
- {MONTH_OF_YEAR, 9, TextStyle.FULL, ptBR, "setembro"},
- {MONTH_OF_YEAR, 10, TextStyle.FULL, ptBR, "outubro"},
- {MONTH_OF_YEAR, 11, TextStyle.FULL, ptBR, "novembro"},
- {MONTH_OF_YEAR, 12, TextStyle.FULL, ptBR, "dezembro"},
-
{AMPM_OF_DAY, 0, TextStyle.SHORT, enUS, "AM"},
{AMPM_OF_DAY, 1, TextStyle.SHORT, enUS, "PM"},
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProviderWithLocale.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of JSR-310 nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+
+package test.java.time.format;
+
+import static java.time.temporal.ChronoField.AMPM_OF_DAY;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.time.temporal.TemporalField;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test SimpleDateTimeTextProviderWithLocale.
+ */
+@Test
+public class TestDateTimeTextProviderWithLocale extends AbstractTestPrinterParser {
+
+ Locale enUS = new Locale("en", "US");
+ Locale ptBR = new Locale("pt", "BR");
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name = "Text")
+ Object[][] data_text() {
+ return new Object[][] {
+ {DAY_OF_WEEK, 1, TextStyle.SHORT, ptBR, "seg"},
+ {DAY_OF_WEEK, 2, TextStyle.SHORT, ptBR, "ter"},
+ {DAY_OF_WEEK, 3, TextStyle.SHORT, ptBR, "qua"},
+ {DAY_OF_WEEK, 4, TextStyle.SHORT, ptBR, "qui"},
+ {DAY_OF_WEEK, 5, TextStyle.SHORT, ptBR, "sex"},
+ {DAY_OF_WEEK, 6, TextStyle.SHORT, ptBR, "s\u00E1b"},
+ {DAY_OF_WEEK, 7, TextStyle.SHORT, ptBR, "dom"},
+
+ {DAY_OF_WEEK, 1, TextStyle.FULL, ptBR, "segunda-feira"},
+ {DAY_OF_WEEK, 2, TextStyle.FULL, ptBR, "ter\u00E7a-feira"},
+ {DAY_OF_WEEK, 3, TextStyle.FULL, ptBR, "quarta-feira"},
+ {DAY_OF_WEEK, 4, TextStyle.FULL, ptBR, "quinta-feira"},
+ {DAY_OF_WEEK, 5, TextStyle.FULL, ptBR, "sexta-feira"},
+ {DAY_OF_WEEK, 6, TextStyle.FULL, ptBR, "s\u00E1bado"},
+ {DAY_OF_WEEK, 7, TextStyle.FULL, ptBR, "domingo"},
+
+ {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"},
+ {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"},
+ {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"},
+ {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"},
+ {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"},
+ {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"},
+ {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"},
+ {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"},
+ {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"},
+ {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"},
+ {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"},
+ {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"},
+
+ {MONTH_OF_YEAR, 1, TextStyle.FULL, ptBR, "janeiro"},
+ {MONTH_OF_YEAR, 2, TextStyle.FULL, ptBR, "fevereiro"},
+ {MONTH_OF_YEAR, 3, TextStyle.FULL, ptBR, "mar\u00E7o"},
+ {MONTH_OF_YEAR, 4, TextStyle.FULL, ptBR, "abril"},
+ {MONTH_OF_YEAR, 5, TextStyle.FULL, ptBR, "maio"},
+ {MONTH_OF_YEAR, 6, TextStyle.FULL, ptBR, "junho"},
+ {MONTH_OF_YEAR, 7, TextStyle.FULL, ptBR, "julho"},
+ {MONTH_OF_YEAR, 8, TextStyle.FULL, ptBR, "agosto"},
+ {MONTH_OF_YEAR, 9, TextStyle.FULL, ptBR, "setembro"},
+ {MONTH_OF_YEAR, 10, TextStyle.FULL, ptBR, "outubro"},
+ {MONTH_OF_YEAR, 11, TextStyle.FULL, ptBR, "novembro"},
+ {MONTH_OF_YEAR, 12, TextStyle.FULL, ptBR, "dezembro"},
+
+ };
+ }
+
+ @Test(dataProvider = "Text")
+ public void test_getText(TemporalField field, Number value, TextStyle style, Locale locale, String expected) {
+ DateTimeFormatter fmt = getFormatter(field, style).withLocale(locale);
+ assertEquals(fmt.format(ZonedDateTime.now().with(field, value.longValue())), expected);
+ }
+
+}
--- a/jdk/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java Thu Jan 12 12:14:13 2017 -0800
@@ -20,13 +20,14 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-package test.java.time.format;
-
/*
* @test
+ * @modules jdk.localedata
* @bug 8146750
* @summary Test Narrow and NarrowStandalone month names are retrieved correctly.
*/
+package test.java.time.format;
+
import static org.testng.Assert.assertEquals;
import java.time.DayOfWeek;
--- a/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java Thu Jan 12 12:14:13 2017 -0800
@@ -20,6 +20,13 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
+/*
+ *
+ * @test
+ * @modules jdk.localedata
+ */
+
package test.java.time.format;
import static org.testng.Assert.assertEquals;
--- a/jdk/test/java/time/test/java/time/format/TestTextParser.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestTextParser.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,16 +68,9 @@
import java.text.ParsePosition;
import java.time.DayOfWeek;
-import java.time.chrono.ChronoLocalDate;
-import java.time.chrono.JapaneseChronology;
-import java.time.chrono.HijrahDate;
-import java.time.chrono.JapaneseDate;
-import java.time.chrono.MinguoDate;
-import java.time.chrono.ThaiBuddhistDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
-import java.time.format.SignStyle;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQueries;
@@ -92,8 +85,6 @@
*/
@Test
public class TestTextParser extends AbstractTestPrinterParser {
- static final Locale RUSSIAN = new Locale("ru");
- static final Locale FINNISH = new Locale("fi");
//-----------------------------------------------------------------------
@DataProvider(name="error")
@@ -213,20 +204,6 @@
};
}
- // Test data is dependent on localized resources.
- @DataProvider(name="parseStandaloneText")
- Object[][] providerStandaloneText() {
- // Locale, TemporalField, TextStyle, expected value, input text
- return new Object[][] {
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"},
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, 12, "\u0434\u0435\u043a\u0430\u0431\u0440\u044c"},
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 1, "\u044f\u043d\u0432."},
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 12, "\u0434\u0435\u043a."},
- {FINNISH, DAY_OF_WEEK, TextStyle.FULL_STANDALONE, 2, "tiistai"},
- {FINNISH, DAY_OF_WEEK, TextStyle.SHORT_STANDALONE, 2, "ti"},
- };
- }
-
@DataProvider(name="parseDayOfWeekText")
Object[][] providerDayOfWeekData() {
return new Object[][] {
@@ -234,26 +211,9 @@
{Locale.US, "e", "1", DayOfWeek.SUNDAY},
{Locale.US, "ee", "01", DayOfWeek.SUNDAY},
{Locale.US, "c", "1", DayOfWeek.SUNDAY},
-
- {Locale.UK, "e", "1", DayOfWeek.MONDAY},
- {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
- {Locale.UK, "c", "1", DayOfWeek.MONDAY},
};
}
- // Test data is dependent on localized resources.
- @DataProvider(name="parseLenientText")
- Object[][] providerLenientText() {
- // Locale, TemporalField, expected value, input text
- return new Object[][] {
- {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044f"}, // full format
- {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"}, // full standalone
- {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short format
- {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short standalone
- };
- }
-
-
@Test(dataProvider="parseText")
public void test_parseText(TemporalField field, TextStyle style, int value, String input) throws Exception {
@@ -269,14 +229,6 @@
assertEquals(pos.getIndex(), input.length());
}
- @Test(dataProvider="parseStandaloneText")
- public void test_parseStandaloneText(Locale locale, TemporalField field, TextStyle style, int expectedValue, String input) {
- DateTimeFormatter formatter = getFormatter(field, style).withLocale(locale);
- ParsePosition pos = new ParsePosition(0);
- assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
- assertEquals(pos.getIndex(), input.length());
- }
-
@Test(dataProvider="parseDayOfWeekText")
public void test_parseDayOfWeekText(Locale locale, String pattern, String input, DayOfWeek expected) {
DateTimeFormatter formatter = getPatternFormatter(pattern).withLocale(locale);
@@ -374,25 +326,6 @@
}
//-----------------------------------------------------------------------
- public void test_parse_french_short_strict_full_noMatch() throws Exception {
- setStrict(true);
- ParsePosition pos = new ParsePosition(0);
- getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
- .parseUnresolved("janvier", pos);
- assertEquals(pos.getErrorIndex(), 0);
- }
-
- public void test_parse_french_short_strict_short_match() throws Exception {
- setStrict(true);
- ParsePosition pos = new ParsePosition(0);
- assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
- .parseUnresolved("janv.", pos)
- .getLong(MONTH_OF_YEAR),
- 1L);
- assertEquals(pos.getIndex(), 5);
- }
-
- //-----------------------------------------------------------------------
public void test_parse_full_lenient_full_match() throws Exception {
setStrict(false);
ParsePosition pos = new ParsePosition(0);
@@ -436,51 +369,4 @@
assertEquals(pos.getIndex(), 1);
}
- @Test(dataProvider="parseLenientText")
- public void test_parseLenientText(Locale locale, TemporalField field, int expectedValue, String input) {
- setStrict(false);
- ParsePosition pos = new ParsePosition(0);
- DateTimeFormatter formatter = getFormatter(field).withLocale(locale);
- assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
- assertEquals(pos.getIndex(), input.length());
- }
-
- //-----------------------------------------------------------------------
- @DataProvider(name="parseChronoLocalDate")
- Object[][] provider_chronoLocalDate() {
- return new Object[][] {
- { HijrahDate.now() },
- { JapaneseDate.now() },
- { MinguoDate.now() },
- { ThaiBuddhistDate.now() }};
- }
-
- private static final DateTimeFormatter fmt_chrono =
- new DateTimeFormatterBuilder()
- .optionalStart()
- .appendChronologyId()
- .appendLiteral(' ')
- .optionalEnd()
- .optionalStart()
- .appendText(ChronoField.ERA, TextStyle.SHORT)
- .appendLiteral(' ')
- .optionalEnd()
- .appendValue(ChronoField.YEAR_OF_ERA, 1, 9, SignStyle.NORMAL)
- .appendLiteral('-')
- .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER)
- .appendLiteral('-')
- .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
- .toFormatter();
-
- @Test(dataProvider="parseChronoLocalDate")
- public void test_chronoLocalDate(ChronoLocalDate date) throws Exception {
- System.out.printf(" %s, [fmt=%s]%n", date, fmt_chrono.format(date));
- assertEquals(date, fmt_chrono.parse(fmt_chrono.format(date), ChronoLocalDate::from));
-
- DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[GGG ]yyy-MM-dd")
- .withChronology(date.getChronology());
- System.out.printf(" %s, [fmt=%s]%n", date.toString(), fmt.format(date));
- assertEquals(date, fmt.parse(fmt.format(date), ChronoLocalDate::from));
- }
-
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestTextParserWithLocale.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of JSR-310 nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+
+package test.java.time.format;
+
+import java.text.ParsePosition;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.HijrahDate;
+import java.time.chrono.JapaneseDate;
+import java.time.chrono.MinguoDate;
+import java.time.chrono.ThaiBuddhistDate;
+import java.time.DayOfWeek;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.TextStyle;
+import java.time.format.SignStyle;
+import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalField;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Test TextPrinterParser.
+ */
+@Test
+public class TestTextParserWithLocale extends AbstractTestPrinterParser {
+ static final Locale RUSSIAN = new Locale("ru");
+ static final Locale FINNISH = new Locale("fi");
+
+ @DataProvider(name="parseDayOfWeekText")
+ Object[][] providerDayOfWeekData() {
+ return new Object[][] {
+ // Locale, pattern, input text, expected DayOfWeek
+ {Locale.US, "e", "1", DayOfWeek.SUNDAY},
+ {Locale.US, "ee", "01", DayOfWeek.SUNDAY},
+ {Locale.US, "c", "1", DayOfWeek.SUNDAY},
+
+ {Locale.UK, "e", "1", DayOfWeek.MONDAY},
+ {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
+ {Locale.UK, "c", "1", DayOfWeek.MONDAY},
+ };
+ }
+
+ @Test(dataProvider="parseDayOfWeekText")
+ public void test_parseDayOfWeekText(Locale locale, String pattern, String input, DayOfWeek expected) {
+ DateTimeFormatter formatter = getPatternFormatter(pattern).withLocale(locale);
+ ParsePosition pos = new ParsePosition(0);
+ assertEquals(DayOfWeek.from(formatter.parse(input, pos)), expected);
+ assertEquals(pos.getIndex(), input.length());
+ }
+
+ //--------------------------------------------------------------------
+ // Test data is dependent on localized resources.
+ @DataProvider(name="parseStandaloneText")
+ Object[][] providerStandaloneText() {
+ // Locale, TemporalField, TextStyle, expected value, input text
+ return new Object[][] {
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"},
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, 12, "\u0434\u0435\u043a\u0430\u0431\u0440\u044c"},
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 1, "\u044f\u043d\u0432."},
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 12, "\u0434\u0435\u043a."},
+ {FINNISH, DAY_OF_WEEK, TextStyle.FULL_STANDALONE, 2, "tiistai"},
+ {FINNISH, DAY_OF_WEEK, TextStyle.SHORT_STANDALONE, 2, "ti"},
+ };
+ }
+
+ // Test data is dependent on localized resources.
+ @DataProvider(name="parseLenientText")
+ Object[][] providerLenientText() {
+ // Locale, TemporalField, expected value, input text
+ return new Object[][] {
+ {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044f"}, // full format
+ {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"}, // full standalone
+ {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short format
+ {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short standalone
+ };
+ }
+
+ @Test(dataProvider="parseStandaloneText")
+ public void test_parseStandaloneText(Locale locale, TemporalField field, TextStyle style, int expectedValue, String input) {
+ DateTimeFormatter formatter = getFormatter(field, style).withLocale(locale);
+ ParsePosition pos = new ParsePosition(0);
+ assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
+ assertEquals(pos.getIndex(), input.length());
+ }
+
+ //-----------------------------------------------------------------------
+ public void test_parse_french_short_strict_full_noMatch() throws Exception {
+ setStrict(true);
+ ParsePosition pos = new ParsePosition(0);
+ getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
+ .parseUnresolved("janvier", pos);
+ assertEquals(pos.getErrorIndex(), 0);
+ }
+
+ public void test_parse_french_short_strict_short_match() throws Exception {
+ setStrict(true);
+ ParsePosition pos = new ParsePosition(0);
+ assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
+ .parseUnresolved("janv.", pos)
+ .getLong(MONTH_OF_YEAR),
+ 1L);
+ assertEquals(pos.getIndex(), 5);
+ }
+
+ //-----------------------------------------------------------------------
+
+ @Test(dataProvider="parseLenientText")
+ public void test_parseLenientText(Locale locale, TemporalField field, int expectedValue, String input) {
+ setStrict(false);
+ ParsePosition pos = new ParsePosition(0);
+ DateTimeFormatter formatter = getFormatter(field).withLocale(locale);
+ assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
+ assertEquals(pos.getIndex(), input.length());
+ }
+
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name="parseChronoLocalDate")
+ Object[][] provider_chronoLocalDate() {
+ return new Object[][] {
+ { HijrahDate.now() },
+ { JapaneseDate.now() },
+ { MinguoDate.now() },
+ { ThaiBuddhistDate.now() }};
+ }
+
+ private static final DateTimeFormatter fmt_chrono =
+ new DateTimeFormatterBuilder()
+ .optionalStart()
+ .appendChronologyId()
+ .appendLiteral(' ')
+ .optionalEnd()
+ .optionalStart()
+ .appendText(ChronoField.ERA, TextStyle.SHORT)
+ .appendLiteral(' ')
+ .optionalEnd()
+ .appendValue(ChronoField.YEAR_OF_ERA, 1, 9, SignStyle.NORMAL)
+ .appendLiteral('-')
+ .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER)
+ .appendLiteral('-')
+ .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
+ .toFormatter();
+
+ @Test(dataProvider="parseChronoLocalDate")
+ public void test_chronoLocalDate(ChronoLocalDate date) throws Exception {
+ System.out.printf(" %s, [fmt=%s]%n", date, fmt_chrono.format(date));
+ assertEquals(date, fmt_chrono.parse(fmt_chrono.format(date), ChronoLocalDate::from));
+
+ DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[GGG ]yyy-MM-dd")
+ .withChronology(date.getChronology());
+ System.out.printf(" %s, [fmt=%s]%n", date.toString(), fmt.format(date));
+ assertEquals(date, fmt.parse(fmt.format(date), ChronoLocalDate::from));
+ }
+}
--- a/jdk/test/java/time/test/java/time/format/TestTextPrinter.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestTextPrinter.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -84,8 +84,6 @@
*/
@Test
public class TestTextPrinter extends AbstractTestPrinterParser {
- static final Locale RUSSIAN = new Locale("ru");
- static final Locale FINNISH = new Locale("fi");
//-----------------------------------------------------------------------
@Test(expectedExceptions=DateTimeException.class)
@@ -213,32 +211,6 @@
{Locale.US, "e", "1", DayOfWeek.SUNDAY},
{Locale.US, "ee", "01", DayOfWeek.SUNDAY},
{Locale.US, "c", "1", DayOfWeek.SUNDAY},
-
- {Locale.UK, "e", "1", DayOfWeek.MONDAY},
- {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
- {Locale.UK, "c", "1", DayOfWeek.MONDAY},
- };
- }
-
- @DataProvider(name="print_JapaneseChronology")
- Object[][] provider_japaneseEra() {
- return new Object[][] {
- {ERA, TextStyle.FULL, 2, "Heisei"}, // Note: CLDR doesn't define "wide" Japanese era names.
- {ERA, TextStyle.SHORT, 2, "Heisei"},
- {ERA, TextStyle.NARROW, 2, "H"},
- };
- };
-
- // Test data is dependent on localized resources.
- @DataProvider(name="print_standalone")
- Object[][] provider_StandaloneNames() {
- return new Object[][] {
- // standalone names for 2013-01-01 (Tue)
- // Locale, TemporalField, TextStyle, expected text
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, "\u044f\u043d\u0432\u0430\u0440\u044c"},
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, "\u044f\u043d\u0432."},
- {FINNISH, DAY_OF_WEEK, TextStyle.FULL_STANDALONE, "tiistai"},
- {FINNISH, DAY_OF_WEEK, TextStyle.SHORT_STANDALONE, "ti"},
};
}
@@ -255,30 +227,6 @@
assertEquals(text, expected);
}
- @Test(dataProvider="print_JapaneseChronology")
- public void test_formatJapaneseEra(TemporalField field, TextStyle style, int value, String expected) throws Exception {
- LocalDate ld = LocalDate.of(2013, 1, 31);
- getFormatter(field, style).withChronology(JapaneseChronology.INSTANCE).formatTo(ld, buf);
- assertEquals(buf.toString(), expected);
- }
-
- @Test(dataProvider="print_standalone")
- public void test_standaloneNames(Locale locale, TemporalField field, TextStyle style, String expected) {
- getFormatter(field, style).withLocale(locale).formatTo(LocalDate.of(2013, 1, 1), buf);
- assertEquals(buf.toString(), expected);
- }
-
- //-----------------------------------------------------------------------
- public void test_print_french_long() throws Exception {
- getFormatter(MONTH_OF_YEAR, TextStyle.FULL).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
- assertEquals(buf.toString(), "janvier");
- }
-
- public void test_print_french_short() throws Exception {
- getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
- assertEquals(buf.toString(), "janv.");
- }
-
//-----------------------------------------------------------------------
public void test_toString1() throws Exception {
assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).toString(), "Text(MonthOfYear)");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestTextPrinterWithLocale.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of JSR-310 nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+
+package test.java.time.format;
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.ERA;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.IsoFields.QUARTER_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+
+import java.time.DateTimeException;
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.chrono.JapaneseChronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.time.temporal.TemporalField;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import test.java.time.temporal.MockFieldValue;
+
+/**
+ * Test TextPrinterParserWithLocale.
+ */
+@Test
+public class TestTextPrinterWithLocale extends AbstractTestPrinterParser {
+ static final Locale RUSSIAN = new Locale("ru");
+ static final Locale FINNISH = new Locale("fi");
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name="print_DayOfWeekData")
+ Object[][] providerDayOfWeekData() {
+ return new Object[][] {
+ // Locale, pattern, expected text, input DayOfWeek
+ {Locale.US, "e", "1", DayOfWeek.SUNDAY},
+ {Locale.US, "ee", "01", DayOfWeek.SUNDAY},
+ {Locale.US, "c", "1", DayOfWeek.SUNDAY},
+
+ {Locale.UK, "e", "1", DayOfWeek.MONDAY},
+ {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
+ {Locale.UK, "c", "1", DayOfWeek.MONDAY},
+ };
+ }
+
+ // Test data is dependent on localized resources.
+ @DataProvider(name="print_standalone")
+ Object[][] provider_StandaloneNames() {
+ return new Object[][] {
+ // standalone names for 2013-01-01 (Tue)
+ // Locale, TemporalField, TextStyle, expected text
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, "\u044f\u043d\u0432\u0430\u0440\u044c"},
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, "\u044f\u043d\u0432."},
+ {FINNISH, DAY_OF_WEEK, TextStyle.FULL_STANDALONE, "tiistai"},
+ {FINNISH, DAY_OF_WEEK, TextStyle.SHORT_STANDALONE, "ti"},
+ };
+ }
+
+ @Test(dataProvider="print_DayOfWeekData")
+ public void test_formatDayOfWeek(Locale locale, String pattern, String expected, DayOfWeek dayOfWeek) {
+ DateTimeFormatter formatter = getPatternFormatter(pattern).withLocale(locale);
+ String text = formatter.format(dayOfWeek);
+ assertEquals(text, expected);
+ }
+
+ @Test(dataProvider="print_standalone")
+ public void test_standaloneNames(Locale locale, TemporalField field, TextStyle style, String expected) {
+ getFormatter(field, style).withLocale(locale).formatTo(LocalDate.of(2013, 1, 1), buf);
+ assertEquals(buf.toString(), expected);
+ }
+
+ //-----------------------------------------------------------------------
+ public void test_print_french_long() throws Exception {
+ getFormatter(MONTH_OF_YEAR, TextStyle.FULL).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
+ assertEquals(buf.toString(), "janvier");
+ }
+
+ public void test_print_french_short() throws Exception {
+ getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
+ assertEquals(buf.toString(), "janv.");
+ }
+
+ @DataProvider(name="print_JapaneseChronology")
+ Object[][] provider_japaneseEra() {
+ return new Object[][] {
+ {ERA, TextStyle.FULL, 2, "Heisei"}, // Note: CLDR doesn't define "wide" Japanese era names.
+ {ERA, TextStyle.SHORT, 2, "Heisei"},
+ {ERA, TextStyle.NARROW, 2, "H"},
+ };
+ };
+
+ @Test(dataProvider="print_JapaneseChronology")
+ public void test_formatJapaneseEra(TemporalField field, TextStyle style, int value, String expected) throws Exception {
+ LocalDate ld = LocalDate.of(2013, 1, 31);
+ getFormatter(field, style).withChronology(JapaneseChronology.INSTANCE).formatTo(ld, buf);
+ assertEquals(buf.toString(), expected);
+ }
+}
--- a/jdk/test/java/util/Collection/SetFactories.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/util/Collection/SetFactories.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,6 +103,8 @@
hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i")),
a( Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
+ a( Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
+ Set.of("j", "i", "h", "g", "f", "e", "d", "c", "b", "a")),
a( Set.of(stringArray),
hashSetOf(stringArray))
).iterator();
@@ -183,6 +185,17 @@
Set<String> set = Set.of(array);
}
+ @Test(dataProvider="all")
+ public void hashCodeEqual(Set<String> act, Set<String> exp) {
+ assertEquals(act.hashCode(), exp.hashCode());
+ }
+
+ @Test(dataProvider="all")
+ public void containsAll(Set<String> act, Set<String> exp) {
+ assertTrue(act.containsAll(exp));
+ assertTrue(exp.containsAll(act));
+ }
+
@Test(expectedExceptions=NullPointerException.class)
public void nullDisallowed1() {
Set.of((String)null); // force one-arg overload
--- a/jdk/test/java/util/Map/MapFactories.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/util/Map/MapFactories.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,6 +103,8 @@
a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h"), genMap(8)),
a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i"), genMap(9)),
a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j"), genMap(10)),
+ a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j"),
+ Map.of(4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j", 0, "a", 1, "b", 2, "c", 3, "d")),
a(Map.ofEntries(genEntries(MAX_ENTRIES)), genMap(MAX_ENTRIES))
).iterator();
}
@@ -135,6 +137,18 @@
assertEquals(act, exp);
}
+ @Test(dataProvider="all")
+ public void containsAllKeys(Map<Integer,String> act, Map<Integer,String> exp) {
+ assertTrue(act.keySet().containsAll(exp.keySet()));
+ assertTrue(exp.keySet().containsAll(act.keySet()));
+ }
+
+ @Test(dataProvider="all")
+ public void containsAllValues(Map<Integer,String> act, Map<Integer,String> exp) {
+ assertTrue(act.values().containsAll(exp.values()));
+ assertTrue(exp.values().containsAll(act.values()));
+ }
+
@Test(expectedExceptions=IllegalArgumentException.class)
public void dupKeysDisallowed2() {
Map<Integer, String> map = Map.of(0, "a", 0, "b");
@@ -192,6 +206,11 @@
Map<Integer, String> map = Map.ofEntries(entries);
}
+ @Test(dataProvider="all")
+ public void hashCodeEquals(Map<Integer,String> act, Map<Integer,String> exp) {
+ assertEquals(act.hashCode(), exp.hashCode());
+ }
+
@Test(expectedExceptions=NullPointerException.class)
public void nullKeyDisallowed1() {
Map<Integer, String> map = Map.of(null, "a");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8159058
+ * @summary Test that empty default namespace declaration clears the
+ * default namespace value
+ * @modules java.xml.ws/com.sun.xml.internal.ws.api
+ * java.xml.ws/com.sun.xml.internal.ws.api.message.saaj
+ * java.xml.ws/com.sun.xml.internal.ws.message.stream
+ * @run testng/othervm SaajEmptyNamespaceTest
+ */
+
+import com.sun.xml.internal.ws.api.SOAPVersion;
+import com.sun.xml.internal.ws.api.message.saaj.SAAJFactory;
+import com.sun.xml.internal.ws.message.stream.StreamMessage;
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import javax.xml.namespace.QName;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.w3c.dom.Node;
+
+public class SaajEmptyNamespaceTest {
+
+ /*
+ * Test that SOAP message with default namespace declaration that contains empty
+ * string is properly processed by SAAJ reader.
+ */
+ @Test
+ public void testResetDefaultNamespaceSAAJ() throws Exception {
+ // Create SOAP message from XML string and process it with SAAJ reader
+ XMLStreamReader envelope = XMLInputFactory.newFactory().createXMLStreamReader(
+ new StringReader(INPUT_SOAP_MESSAGE));
+ StreamMessage streamMessage = new StreamMessage(SOAPVersion.SOAP_11,
+ envelope, null);
+ SAAJFactory saajFact = new SAAJFactory();
+ SOAPMessage soapMessage = saajFact.readAsSOAPMessage(SOAPVersion.SOAP_11, streamMessage);
+
+ // Check if constructed object model meets local names and namespace expectations
+ SOAPElement request = (SOAPElement) soapMessage.getSOAPBody().getFirstChild();
+ // Check top body element name
+ Assert.assertEquals(request.getLocalName(), "SampleServiceRequest");
+ // Check top body element namespace
+ Assert.assertEquals(request.getNamespaceURI(), TEST_NS);
+ SOAPElement params = (SOAPElement) request.getFirstChild();
+ // Check first child name
+ Assert.assertEquals(params.getLocalName(), "RequestParams");
+ // Check if first child namespace is null
+ Assert.assertNull(params.getNamespaceURI());
+
+ // Check inner elements of the first child
+ SOAPElement param1 = (SOAPElement) params.getFirstChild();
+ Assert.assertEquals(param1.getLocalName(), "Param1");
+ Assert.assertNull(param1.getNamespaceURI());
+ SOAPElement param2 = (SOAPElement) params.getChildNodes().item(1);
+ Assert.assertEquals(param2.getLocalName(), "Param2");
+ Assert.assertNull(param2.getNamespaceURI());
+ // Check full content of SOAP body
+ Assert.assertEquals(nodeToText(request), EXPECTED_RESULT);
+ }
+
+ /*
+ * Test that adding element with explicitly null namespace URI shall put the
+ * element into global namespace. Namespace declarations are not added explicitly.
+ */
+ @Test
+ public void testAddElementToNullNsNoDeclarations() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", null);
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+ }
+
+ /*
+ * Test that adding element with explicitly empty namespace URI shall put
+ * the element into global namespace. Namespace declarations are not added
+ * explicitly.
+ */
+ @Test
+ public void testAddElementToGlobalNsNoDeclarations() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", "");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+ }
+
+ /*
+ * Test that adding element with explicitly empty namespace URI set via QName
+ * shall put the element into global namespace.
+ */
+ @Test
+ public void testAddElementToNullNsQName() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement(new QName(null, "global-child"));
+ childGlobalNS.addNamespaceDeclaration("", "");
+ SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+ }
+
+ /*
+ * Test that adding element with explicitly empty namespace URI shall put
+ * the element into global namespace.
+ */
+ @Test
+ public void testAddElementToGlobalNs() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", "");
+ childGlobalNS.addNamespaceDeclaration("", "");
+ SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+ }
+
+ /*
+ * Test that adding element with explicitly null namespace URI shall put
+ * the element into global namespace.
+ */
+ @Test
+ public void testAddElementToNullNs() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", null);
+ childGlobalNS.addNamespaceDeclaration("", null);
+ SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+ Assert.assertEquals(TEST_NS, childDefaultNS.getNamespaceURI());
+ }
+
+ /*
+ * Test that adding element with explicitly empty namespace URI via QName
+ * shall put the element in global namespace.
+ */
+ @Test
+ public void testAddElementToGlobalNsQName() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement(new QName("", "global-child"));
+ childGlobalNS.addNamespaceDeclaration("", "");
+ SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(),TEST_NS);
+ }
+
+ // Convert DOM node to text representation
+ private String nodeToText(Node node) throws TransformerException {
+ Transformer trans = TransformerFactory.newInstance().newTransformer();
+ trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ StringWriter writer = new StringWriter();
+ StreamResult result = new StreamResult(writer);
+ trans.transform(new DOMSource(node), result);
+ String bodyContent = writer.toString();
+ System.out.println("SOAP body content read by SAAJ:"+bodyContent);
+ return bodyContent;
+ }
+
+ // Create SOAP message with empty body
+ private static SOAPMessage createSoapMessage() throws SOAPException, UnsupportedEncodingException {
+ String xml = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ +"<SOAP-ENV:Body/></SOAP-ENV:Envelope>";
+ MessageFactory mFactory = MessageFactory.newInstance();
+ SOAPMessage msg = mFactory.createMessage();
+ msg.getSOAPPart().setContent(new StreamSource(new ByteArrayInputStream(xml.getBytes("utf-8"))));
+ return msg;
+ }
+
+ // Namespace value used in tests
+ private static String TEST_NS = "http://example.org/test";
+
+ // Content of SOAP message passed to SAAJ factory
+ private static String INPUT_SOAP_MESSAGE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ + "<s:Body>"
+ + "<SampleServiceRequest xmlns=\"http://example.org/test\""
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ + "<RequestParams xmlns=\"\">"
+ + "<Param1>hogehoge</Param1>"
+ + "<Param2>fugafuga</Param2>"
+ + "</RequestParams>"
+ + "</SampleServiceRequest>"
+ + "</s:Body>"
+ + "</s:Envelope>";
+
+ // Expected body content after SAAJ processing
+ private static String EXPECTED_RESULT = "<SampleServiceRequest"
+ +" xmlns=\"http://example.org/test\">"
+ + "<RequestParams xmlns=\"\">"
+ + "<Param1>hogehoge</Param1>"
+ + "<Param2>fugafuga</Param2>"
+ + "</RequestParams>"
+ + "</SampleServiceRequest>";
+}
--- a/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary REGISTRY RegistryRunner
+ * @build TestLibrary RegistryVM RegistryRunner
* @run main/othervm DeadCachedConnection
*/
@@ -100,7 +100,7 @@
public static int makeRegistry(int port) {
try {
- subreg = REGISTRY.createREGISTRY(System.out, System.err, "", port);
+ subreg = RegistryVM.createRegistryVM(System.out, System.err, "", port);
subreg.start();
int regPort = subreg.getPort();
System.out.println("Starting registry on port " + regPort);
@@ -113,11 +113,11 @@
return -1;
}
- private static REGISTRY subreg = null;
+ private static RegistryVM subreg = null;
public static void killRegistry() throws InterruptedException {
if (subreg != null) {
- subreg.shutdown();
+ subreg.cleanup();
subreg = null;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/RuntimeTest.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test Multi-Release jar usage in runtime
+ * @library /test/lib
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * @build jdk.test.lib.JDKToolFinder jdk.test.lib.JDKToolLauncher
+ * jdk.test.lib.process.OutputAnalyzer
+ * jdk.test.lib.process.ProcessTools
+ * CompilerUtils RuntimeTest
+ * @run testng RuntimeTest
+ */
+
+import static org.testng.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class RuntimeTest {
+ public static final int SUCCESS = 0;
+ private final String src = System.getProperty("test.src", ".");
+ private final String usr = System.getProperty("user.dir", ".");
+
+ @DataProvider(name = "jarFiles")
+ Object[][] jarFiles() {
+ return new Object[][] { { "MV_BOTH.jar", 9, 9, 9 },
+ { "MV_ONLY_9.jar", 9, 9, 9 },
+ { "NON_MV.jar", 8, 8, 8 } };
+ }
+
+ @BeforeClass
+ protected void setUpTest() throws Throwable {
+ compile();
+ Path classes = Paths.get("classes");
+ jar("cfm", "MV_BOTH.jar", "manifest.txt",
+ "-C", classes.resolve("base").toString(), ".",
+ "--release", "9", "-C", classes.resolve("v9").toString(), ".",
+ "--release", "10", "-C", classes.resolve("v10").toString(), ".")
+ .shouldHaveExitValue(0);
+
+ jar("cfm", "MV_ONLY_9.jar", "manifest.txt",
+ "-C", classes.resolve("base").toString(), ".",
+ "--release", "9", "-C", classes.resolve("v9").toString(), ".")
+ .shouldHaveExitValue(0);
+ jar("cfm", "NON_MV.jar", "manifest.txt",
+ "-C", classes.resolve("base").toString(), ".")
+ .shouldHaveExitValue(0);
+ }
+
+ @Test(dataProvider = "jarFiles")
+ public void testClasspath(String jar, int mainVer, int helperVer,
+ int resVer) throws Throwable {
+ String[] command = { "-cp", jar, "testpackage.Main" };
+ System.out.println("Command arguments:" + Arrays.asList(command));
+ System.out.println();
+ java(command).shouldHaveExitValue(SUCCESS)
+ .shouldContain("Main version: " + mainVer)
+ .shouldContain("Helpers version: " + helperVer)
+ .shouldContain("Resource version: " + resVer);
+ }
+
+ @Test(dataProvider = "jarFiles")
+ void testMVJarAsLib(String jar, int mainVer, int helperVer, int resVer)
+ throws Throwable {
+ String[] apps = { "UseByImport", "UseByReflection" };
+ for (String app : apps) {
+ String[] command = {"-cp",
+ jar + File.pathSeparatorChar + "classes/test/", app };
+ System.out.println("Command arguments:" + Arrays.asList(command));
+ System.out.println();
+ java(command).shouldHaveExitValue(SUCCESS)
+ .shouldContain("Main version: " + mainVer)
+ .shouldContain("Helpers version: " + helperVer)
+ .shouldContain("Resource version: " + resVer);
+ }
+ }
+
+ @Test(dataProvider = "jarFiles")
+ void testJavaJar(String jar, int mainVer, int helperVer, int resVer)
+ throws Throwable {
+ String[] command = { "-jar", jar };
+ System.out.println("Command arguments:" + Arrays.asList(command));
+ System.out.println();
+ java(command).shouldHaveExitValue(SUCCESS)
+ .shouldContain("Main version: " + mainVer)
+ .shouldContain("Helpers version: " + helperVer)
+ .shouldContain("Resource version: " + resVer);
+ }
+
+ @Test(dataProvider = "jarFiles")
+ void testURLClassLoader(String jarName, int mainVer, int helperVer,
+ int resVer) throws ClassNotFoundException, NoSuchMethodException,
+ IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, IOException {
+ Path pathToJAR = Paths.get(jarName).toAbsolutePath();
+ URL jarURL1 = new URL("jar:file:" + pathToJAR + "!/");
+ URL jarURL2 = new URL("file:///" + pathToJAR);
+ testURLClassLoaderURL(jarURL1, mainVer, helperVer, resVer);
+ testURLClassLoaderURL(jarURL2, mainVer, helperVer, resVer);
+ }
+
+ private static void testURLClassLoaderURL(URL jarURL,
+ int mainVersionExpected, int helperVersionExpected,
+ int resourceVersionExpected) throws ClassNotFoundException,
+ NoSuchMethodException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException, IOException {
+ System.out.println(
+ "Testing URLClassLoader MV JAR support for URL: " + jarURL);
+ URL[] urls = { jarURL };
+ int mainVersionActual;
+ int helperVersionActual;
+ int resourceVersionActual;
+ try (URLClassLoader cl = URLClassLoader.newInstance(urls)) {
+ Class c = cl.loadClass("testpackage.Main");
+ Method getMainVersion = c.getMethod("getMainVersion");
+ mainVersionActual = (int) getMainVersion.invoke(null);
+ Method getHelperVersion = c.getMethod("getHelperVersion");
+ helperVersionActual = (int) getHelperVersion.invoke(null);
+ try (InputStream ris = cl.getResourceAsStream("versionResource");
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(ris))) {
+ resourceVersionActual = Integer.parseInt(br.readLine());
+ }
+ }
+
+ assertEquals(mainVersionActual, mainVersionExpected,
+ "Test failed: Expected Main class version: "
+ + mainVersionExpected + " Actual version: "
+ + mainVersionActual);
+ assertEquals(helperVersionActual, helperVersionExpected,
+ "Test failed: Expected Helper class version: "
+ + helperVersionExpected + " Actual version: "
+ + helperVersionActual);
+ assertEquals(resourceVersionActual, resourceVersionExpected,
+ "Test failed: Expected resource version: "
+ + resourceVersionExpected + " Actual version: "
+ + resourceVersionActual);
+ }
+
+ @Test(dataProvider = "jarFiles")
+ void testJjs(String jar, int mainVer, int helperVer, int resVer)
+ throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jjs");
+ launcher.addToolArg("-cp").addToolArg(jar)
+ .addToolArg(src + "/data/runtimetest/MVJarJJSTestScript.js");
+ ProcessTools.executeCommand(launcher.getCommand())
+ .shouldHaveExitValue(SUCCESS)
+ .shouldContain("Main version: " + mainVer)
+ .shouldContain("Helpers version: " + helperVer)
+ .shouldContain("Resource version: " + resVer);
+ }
+
+ private static OutputAnalyzer jar(String... args) throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jar");
+ Stream.of(args).forEach(launcher::addToolArg);
+ return ProcessTools.executeCommand(launcher.getCommand());
+ }
+
+ private void compile() throws Throwable {
+ String[] vers = { "base", "v9", "v10" };
+ for (String ver : vers) {
+ Path classes = Paths.get(usr, "classes", ver);
+ Files.createDirectories(classes);
+ Path source = Paths.get(src, "data", "runtimetest", ver);
+ assertTrue(CompilerUtils.compile(source, classes));
+ Files.copy(source.resolve("versionResource"),
+ classes.resolve("versionResource"),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ Path classes = Paths.get(usr, "classes", "test");
+ Files.createDirectory(classes);
+ Path source = Paths.get(src, "data", "runtimetest", "test");
+ assertTrue(
+ CompilerUtils.compile(source, classes, "-cp", "classes/base/"));
+ Files.copy(Paths.get(src, "data", "runtimetest", "manifest.txt"),
+ Paths.get(usr, "manifest.txt"),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ OutputAnalyzer java(String... args) throws Throwable {
+ String java = JDKToolFinder.getJDKTool("java");
+
+ List<String> commands = new ArrayList<>();
+ commands.add(java);
+ Stream.of(args).forEach(x -> commands.add(x));
+ return ProcessTools.executeCommand(new ProcessBuilder(commands));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/MVJarJJSTestScript.js Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+var Main = Java.type("testpackage.Main");
+var mainVersion = Main.getMainVersion();
+var helperVersion = Main.getHelperVersion();
+var resourceVersion = Main.getResourceVersion();
+print("Main version: " + mainVersion);
+print("Helpers version: " + helperVersion);
+print("Resource version: " + resourceVersion);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/base/testpackage/Helper.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package testpackage;
+
+public class Helper {
+
+ private static final int HELPER_VERSION = 8;
+
+ public static int getHelperVersion() {
+ return HELPER_VERSION;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/base/testpackage/Main.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package testpackage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Main {
+
+ private static final int MAIN_VERSION = 8;
+
+ public static void main(String[] args) {
+ System.out.println("Main version: " + getMainVersion());
+ System.out.println("Helpers version: " + getHelperVersion());
+ System.out.println("Resource version: " + getResourceVersion());
+ }
+
+ public static int getMainVersion() {
+ return MAIN_VERSION;
+ }
+
+ public static int getHelperVersion() {
+ return testpackage.Helper.getHelperVersion();
+ }
+
+ public static int getResourceVersion() {
+ ClassLoader cl = Main.class.getClassLoader();
+ InputStream ris = cl.getResourceAsStream("versionResource");
+ if (ris == null) {
+ throw new Error("Test issue: resource versionResource"
+ + " cannot be loaded!");
+ }
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+ return Integer.parseInt(br.readLine());
+ } catch (IOException ioe) {
+ throw new Error("Unexpected issue", ioe);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/base/versionResource Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,1 @@
+8
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/manifest.txt Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,1 @@
+Main-Class: testpackage.Main
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/test/UseByImport.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import testpackage.Main;
+
+/**
+ * This class is used in MVJarAsLibraryTest.java test.
+ * It is a part of the test.
+ */
+public class UseByImport {
+
+ /**
+ * Method for the test execution.
+ * @param args - no args needed
+ */
+ public static void main(String[] args) {
+ System.out.println("Main version: " + Main.getMainVersion());
+ System.out.println("Helpers version: " + Main.getHelperVersion());
+ System.out.println("Resource version: " + Main.getResourceVersion());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/test/UseByReflection.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * This class is used in RuntimeTest.java.
+ */
+public class UseByReflection {
+
+ /**
+ * Method for the test execution.
+ *
+ * @param args - no args needed
+ * @throws java.lang.ClassNotFoundException
+ * @throws java.lang.NoSuchMethodException
+ * @throws java.lang.IllegalAccessException
+ * @throws java.lang.reflect.InvocationTargetException
+ * @throws java.io.IOException
+ */
+ public static void main(String[] args) throws ClassNotFoundException,
+ NoSuchMethodException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException, IOException {
+ Class mainClass = Class.forName("testpackage.Main");
+ Method getMainVersion = mainClass.getMethod("getMainVersion");
+ int mainVersionActual = (int) getMainVersion.invoke(null);
+ Method getHelperVersion = mainClass.getMethod("getHelperVersion");
+ int helperVersionActual = (int) getHelperVersion.invoke(null);
+ ClassLoader cl = UseByReflection.class.getClassLoader();
+ int resourceVersionActual;
+ try (InputStream ris = cl.getResourceAsStream("versionResource");
+ BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+ resourceVersionActual = Integer.parseInt(br.readLine());
+ }
+ System.out.println("Main version: " + mainVersionActual);
+ System.out.println("Helpers version: " + helperVersionActual);
+ System.out.println("Resource version: " + resourceVersionActual);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v10/testpackage/Helper.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package testpackage;
+
+public class Helper {
+
+ private static final int HELPER_VERSION = 10;
+
+ public static int getHelperVersion() {
+ return HELPER_VERSION;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v10/testpackage/Main.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package testpackage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Main {
+
+ private static final int MAIN_VERSION = 10;
+
+ public static void main(String[] args) {
+ System.out.println("Main version: " + getMainVersion());
+ System.out.println("Helpers version: " + getHelperVersion());
+ System.out.println("Resource version: " + getResourceVersion());
+ }
+
+ public static int getMainVersion() {
+ return MAIN_VERSION;
+ }
+
+ public static int getHelperVersion() {
+ return testpackage.Helper.getHelperVersion();
+ }
+
+ public static int getResourceVersion() {
+ ClassLoader cl = Main.class.getClassLoader();
+ InputStream ris = cl.getResourceAsStream("versionResource");
+ if (ris == null) {
+ throw new Error("Test issue: resource versionResource"
+ + " cannot be loaded!");
+ }
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+ return Integer.parseInt(br.readLine());
+ } catch (IOException ioe) {
+ throw new Error("Unexpected issue", ioe);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v10/versionResource Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,1 @@
+10
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v9/testpackage/Helper.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package testpackage;
+
+public class Helper {
+
+ private static final int HELPER_VERSION = 9;
+
+ public static int getHelperVersion() {
+ return HELPER_VERSION;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v9/testpackage/Main.java Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package testpackage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Main {
+
+ private static final int MAIN_VERSION = 9;
+
+ public static void main(String[] args) {
+ System.out.println("Main version: " + getMainVersion());
+ System.out.println("Helpers version: " + getHelperVersion());
+ System.out.println("Resource version: " + getResourceVersion());
+ }
+
+ public static int getMainVersion() {
+ return MAIN_VERSION;
+ }
+
+ public static int getHelperVersion() {
+ return testpackage.Helper.getHelperVersion();
+ }
+
+ public static int getResourceVersion() {
+ ClassLoader cl = Main.class.getClassLoader();
+ InputStream ris = cl.getResourceAsStream("versionResource");
+ if (ris == null) {
+ throw new Error("Test issue: resource versionResource"
+ + " cannot be loaded!");
+ }
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+ return Integer.parseInt(br.readLine());
+ } catch (IOException ioe) {
+ throw new Error("Unexpected issue", ioe);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v9/versionResource Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,1 @@
+9
--- a/jdk/test/tools/jmod/JmodTest.java Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/tools/jmod/JmodTest.java Thu Jan 12 12:14:13 2017 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8142968 8166568 8166286 8170618
+ * @bug 8142968 8166568 8166286 8170618 8168149
* @summary Basic test for jmod
* @library /lib/testlibrary
* @modules jdk.compiler
@@ -459,6 +459,76 @@
}
@Test
+ public void testLastOneWins() throws IOException {
+ Path workDir = Paths.get("lastOneWins");
+ if (Files.exists(workDir))
+ FileUtils.deleteFileTreeWithRetry(workDir);
+ Files.createDirectory(workDir);
+ Path jmod = MODS_DIR.resolve("lastOneWins.jmod");
+ FileUtils.deleteFileIfExistsWithRetry(jmod);
+ Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
+ Path bp = EXPLODED_DIR.resolve("foo").resolve("bin");
+ Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");
+ Path cf = EXPLODED_DIR.resolve("foo").resolve("conf");
+
+ Path shouldNotBeAdded = workDir.resolve("shouldNotBeAdded");
+ Files.createDirectory(shouldNotBeAdded);
+ Files.write(shouldNotBeAdded.resolve("aFile"), "hello".getBytes(UTF_8));
+
+ // Pairs of options. For options with required arguments the last one
+ // should win ( first should be effectively ignored, but may still be
+ // validated ).
+ jmod("create",
+ "--conf", shouldNotBeAdded.toString(),
+ "--conf", cf.toString(),
+ "--cmds", shouldNotBeAdded.toString(),
+ "--cmds", bp.toString(),
+ "--libs", shouldNotBeAdded.toString(),
+ "--libs", lp.toString(),
+ "--class-path", shouldNotBeAdded.toString(),
+ "--class-path", cp.toString(),
+ "--main-class", "does.NotExist",
+ "--main-class", "jdk.test.foo.Foo",
+ "--module-version", "00001",
+ "--module-version", "5.4.3",
+ "--do-not-resolve-by-default",
+ "--do-not-resolve-by-default",
+ "--warn-if-resolved=incubating",
+ "--warn-if-resolved=deprecated",
+ MODS_DIR.resolve("lastOneWins.jmod").toString())
+ .assertSuccess()
+ .resultChecker(r -> {
+ ModuleDescriptor md = getModuleDescriptor(jmod);
+ Optional<String> omc = md.mainClass();
+ assertTrue(omc.isPresent());
+ assertEquals(omc.get(), "jdk.test.foo.Foo");
+ Optional<Version> ov = md.version();
+ assertTrue(ov.isPresent());
+ assertEquals(ov.get().toString(), "5.4.3");
+
+ try (Stream<String> s1 = findFiles(lp).map(p -> LIBS_PREFIX + p);
+ Stream<String> s2 = findFiles(cp).map(p -> CLASSES_PREFIX + p);
+ Stream<String> s3 = findFiles(bp).map(p -> CMDS_PREFIX + p);
+ Stream<String> s4 = findFiles(cf).map(p -> CONFIGS_PREFIX + p)) {
+ Set<String> expectedFilenames = Stream.concat(Stream.concat(s1,s2),
+ Stream.concat(s3, s4))
+ .collect(toSet());
+ assertJmodContent(jmod, expectedFilenames);
+ }
+ });
+
+ jmod("extract",
+ "--dir", "blah",
+ "--dir", "lastOneWinsExtractDir",
+ jmod.toString())
+ .assertSuccess()
+ .resultChecker(r -> {
+ assertTrue(Files.exists(Paths.get("lastOneWinsExtractDir")));
+ assertTrue(Files.notExists(Paths.get("blah")));
+ });
+ }
+
+ @Test
public void testPackagesAttribute() throws IOException {
Path jmod = MODS_DIR.resolve("foo.jmod");
FileUtils.deleteFileIfExistsWithRetry(jmod);