This commit is contained in:
Phil Race 2017-01-12 12:14:13 -08:00
commit 83f2efcd66
58 changed files with 2714 additions and 636 deletions

View File

@ -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 @@ public final class Class<T> implements java.io.Serializable,
* <ul>
*
* <li> If the {@code name} begins with a {@code '/'}
* (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
* (<code>'&#92;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 @@ public final class Class<T> implements java.io.Serializable,
*
* <p> Where the {@code modified_package_name} is the package name of this
* object with {@code '/'} substituted for {@code '.'}
* (<tt>'&#92;u002e'</tt>).
* (<code>'&#92;u002e'</code>).
*
* </ul>
*
@ -2570,7 +2570,7 @@ public final class Class<T> implements java.io.Serializable,
* <ul>
*
* <li> If the {@code name} begins with a {@code '/'}
* (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
* (<code>'&#92;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 @@ public final class Class<T> implements java.io.Serializable,
*
* <p> Where the {@code modified_package_name} is the package name of this
* object with {@code '/'} substituted for {@code '.'}
* (<tt>'&#92;u002e'</tt>).
* (<code>'&#92;u002e'</code>).
*
* </ul>
*

View File

@ -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 @@ import sun.security.util.SecurityConstants;
/**
* 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 @@ import sun.security.util.SecurityConstants;
* <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 @@ import sun.security.util.SecurityConstants;
* 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 @@ import sun.security.util.SecurityConstants;
* </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 @@ public abstract class ClassLoader {
*
* <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 @@ public abstract class ClassLoader {
*
* @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 @@ public abstract class ClassLoader {
}
/**
* 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 @@ public abstract class ClassLoader {
* 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 @@ public abstract class ClassLoader {
* <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 @@ public abstract class ClassLoader {
* </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 @@ public abstract class ClassLoader {
* @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 @@ public abstract class ClassLoader {
* 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 @@ public abstract class ClassLoader {
/**
* 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&trade; 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 @@ public abstract class ClassLoader {
* #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 @@ public abstract class ClassLoader {
* 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&trade; Virtual Machine Specification</cite>.
*
* @param protectionDomain
@ -1158,7 +1158,7 @@ public abstract class ClassLoader {
/**
* 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&trade; Language Specification</cite>.
@ -1167,7 +1167,7 @@ public abstract class ClassLoader {
* 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 @@ public abstract class ClassLoader {
* 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 @@ public abstract class ClassLoader {
* 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 @@ public abstract class ClassLoader {
* class.
*
* @param c
* The <tt>Class</tt> object
* The {@code Class} object
*
* @param signers
* The signers for the class
@ -1306,11 +1306,11 @@ public abstract class ClassLoader {
* (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 @@ public abstract class ClassLoader {
* (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 @@ public abstract class ClassLoader {
* @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 @@ public abstract class ClassLoader {
}
/**
* 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 @@ public abstract class ClassLoader {
* @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 @@ public abstract class ClassLoader {
* @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 @@ public abstract class ClassLoader {
/**
* 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 @@ public abstract class ClassLoader {
* @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 @@ public abstract class ClassLoader {
/**
* 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 @@ public abstract class ClassLoader {
/**
* 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 @@ public abstract class ClassLoader {
* <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 @@ public abstract class ClassLoader {
* 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 @@ public abstract class ClassLoader {
*
* @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 @@ public abstract class ClassLoader {
/**
* 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 @@ public abstract class ClassLoader {
/**
* 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 @@ public abstract class ClassLoader {
* #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 @@ public abstract class ClassLoader {
* 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 @@ public abstract class ClassLoader {
*
* @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&trade; 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 @@ public abstract class ClassLoader {
* 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 @@ public abstract class ClassLoader {
/**
* 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."

View File

@ -30,8 +30,10 @@ import java.io.InputStream;
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 @@ public abstract class URLConnection {
*/
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 @@ public abstract class URLConnection {
* <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 @@ public abstract class URLConnection {
*/
protected URLConnection(URL url) {
this.url = url;
if (url == null) {
this.useCaches = defaultUseCaches;
} else {
this.useCaches = getDefaultUseCaches(url.getProtocol());
}
}
/**
@ -981,7 +994,8 @@ public abstract class URLConnection {
* 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 @@ public abstract class URLConnection {
* 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 @@ public abstract class URLConnection {
/**
* 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 @@ public abstract class URLConnection {
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.

View File

@ -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 @@ public class Collections {
private Object readResolve() {
return EMPTY_SET;
}
@Override
public int hashCode() {
return 0;
}
}
/**
@ -4786,6 +4791,10 @@ public class Collections {
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public int hashCode() {
return Objects.hashCode(element);
}
}
/**
@ -4848,6 +4857,10 @@ public class Collections {
public Spliterator<E> spliterator() {
return singletonSpliterator(element);
}
@Override
public int hashCode() {
return 31 + Objects.hashCode(element);
}
}
/**
@ -4970,6 +4983,11 @@ public class Collections {
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public int hashCode() {
return Objects.hashCode(k) ^ Objects.hashCode(v);
}
}
// Miscellaneous

View File

@ -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.BiFunction;
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 @@ class ImmutableCollections {
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 @@ class ImmutableCollections {
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 @@ class ImmutableCollections {
@Override
public E get(int index) {
Objects.checkIndex(index, 1);
// assert index == 0
return e0;
}
@ -140,10 +162,22 @@ class ImmutableCollections {
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 @@ class ImmutableCollections {
}
}
@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 @@ class ImmutableCollections {
}
static final class ListN<E> extends AbstractImmutableList<E> {
@Stable
private final E[] elements;
@SafeVarargs
@ -200,6 +246,25 @@ class ImmutableCollections {
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 @@ class ImmutableCollections {
@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 @@ class ImmutableCollections {
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 @@ class ImmutableCollections {
@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 @@ class ImmutableCollections {
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 @@ class ImmutableCollections {
@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 @@ class ImmutableCollections {
* @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 @@ class ImmutableCollections {
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 @@ class ImmutableCollections {
@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 @@ class ImmutableCollections {
};
}
@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 @@ class ImmutableCollections {
@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 @@ class ImmutableCollections {
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 @@ class ImmutableCollections {
@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 @@ class ImmutableCollections {
private Object writeReplace() {
return new CollSer(CollSer.IMM_MAP, k0, v0);
}
@Override
public int hashCode() {
return k0.hashCode() ^ v0.hashCode();
}
}
/**
@ -541,12 +655,13 @@ class ImmutableCollections {
* @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 @@ class ImmutableCollections {
@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 @@ class ImmutableCollections {
}
// 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) {

View File

@ -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 @@ package java.util;
* @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) {

View File

@ -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 @@ public interface List<E> extends Collection<E> {
@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:

View File

@ -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 @@ public interface Map<K, V> {
@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(),

View File

@ -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 @@ public interface Set<E> extends Collection<E> {
@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:

View File

@ -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 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
}
/**
* 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);
Thread.currentThread().setContextClassLoader(cl);
return registryImpl;
}
/**
* 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) {

View File

@ -1088,34 +1088,58 @@ public class JmodTask {
}
}
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 @@ public class JmodTask {
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 @@ public class JmodTask {
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 @@ public class JmodTask {
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 @@ public class JmodTask {
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 @@ public class JmodTask {
.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 @@ public class JmodTask {
}
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 @@ public class JmodTask {
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 @@ public class JmodTask {
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);
}

View File

@ -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);
}
}

View File

@ -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 @@ public class AltSecurityManager implements Runnable {
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 @@ public class AltSecurityManager implements Runnable {
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 @@ public class AltSecurityManager implements Runnable {
" terminated on time");
}
} finally {
vm.destroy();
vm.cleanup();
vm = null;
}
}

View File

@ -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 @@ public class TestSecurityManager extends SecurityManager {
// 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) {

View File

@ -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";
};

View File

@ -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";
};

View File

@ -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 @@ import java.util.Arrays;
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 @@ public class ClassPathCodebase {
TestLibrary.suggestSecurityManager("java.lang.SecurityManager");
Process rmiregistry = null;
RegistryVM rmiregistry = null;
try {
/*
@ -82,27 +83,13 @@ public class ClassPathCodebase {
* 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 @@ public class ClassPathCodebase {
throw new RuntimeException("TEST FAILED: " + e.toString());
} finally {
if (rmiregistry != null) {
rmiregistry.destroy();
rmiregistry.cleanup();
}
}
}

View File

@ -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";
};

View File

@ -18,6 +18,12 @@ grant {
// 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";
};

View File

@ -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 class Reexport {
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 @@ public class Reexport {
}
}
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;
}
}

View File

@ -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
@ -229,6 +229,22 @@ public class JavaVM {
vm = null;
}
/**
* 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.

View File

@ -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 @@ public class RMID extends JavaVM {
}
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();
@ -209,8 +197,31 @@ public class RMID extends JavaVM {
public static RMID createRMID(OutputStream out, OutputStream err,
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 @@ public class RMID extends JavaVM {
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)

View File

@ -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);
}
}

View File

@ -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 @@ import java.rmi.server.*;
/**
* 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 @@ public class RegistryRunner extends UnicastRemoteObject
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 @@ public class RegistryRunner extends UnicastRemoteObject
} catch (RemoteException re) {
}
e = null;
} catch (java.net.MalformedURLException mfue) {
// will not happen
} catch (NotBoundException nbe) {
@ -97,6 +98,9 @@ public class RegistryRunner extends UnicastRemoteObject
/**
* 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 @@ public class RegistryRunner extends UnicastRemoteObject
}
/**
* 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();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* 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
@ -25,13 +25,15 @@ import java.io.OutputStream;
import java.io.IOException;
/**
* Class to run and control rmiregistry in a sub-process.
* 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 REGISTRY extends JavaVM {
public class RegistryVM extends JavaVM {
private static final double START_TIMEOUT =
20_000 * TestLibrary.getTimeoutFactor();
@ -39,7 +41,7 @@ public class REGISTRY extends JavaVM {
private int port = -1;
private REGISTRY(String runner, OutputStream out, OutputStream err,
private RegistryVM(String runner, OutputStream out, OutputStream err,
String options, int port) {
super(runner, options, Integer.toString(port), out, err);
try {
@ -54,33 +56,86 @@ public class REGISTRY extends JavaVM {
this.port = port;
}
public static REGISTRY createREGISTRY() {
return createREGISTRYWithRunner(DEFAULT_RUNNER, System.out, System.err, "", 0);
/**
* 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);
}
public static REGISTRY createREGISTRY(OutputStream out, OutputStream err,
String options, int port) {
return createREGISTRYWithRunner(DEFAULT_RUNNER, out, err, options, port);
/**
* 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);
}
public static REGISTRY createREGISTRYWithRunner(String runner, String options) {
return createREGISTRYWithRunner(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);
}
public static REGISTRY createREGISTRYWithRunner(String runner, OutputStream out,
/**
* 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";
REGISTRY reg = new REGISTRY(runner, out, err, options, port);
return reg;
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();
@ -96,6 +151,12 @@ public class REGISTRY extends JavaVM {
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);
@ -106,12 +167,16 @@ public class REGISTRY extends JavaVM {
/**
* Shuts down the registry.
*/
public void shutdown() {
@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;

View File

@ -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 @@ public class TestParams {
/** 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 @@ public class TestParams {
defaultRmidPolicy =
testSrc + File.separatorChar + "rmid.security.policy";
defaultRegistryPolicy =
testSrc + File.separatorChar + "registry.security.policy";
defaultGroupPolicy =
testSrc + File.separatorChar + "group.security.policy";

View File

@ -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 @@ public class DGCDeadLock implements Runnable {
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 @@ public class DGCDeadLock implements Runnable {
TestLibrary.bomb("test failed in main()", e);
} finally {
if (testImplVM != null) {
testImplVM.shutdown();
testImplVM.cleanup();
testImplVM = null;
}
}

View File

@ -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";
};

View File

@ -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

View File

@ -879,25 +879,6 @@ public class TestDateTimeFormatterBuilder {
}
}
//-----------------------------------------------------------------------
@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() {
@ -914,48 +895,6 @@ public class TestDateTimeFormatterBuilder {
{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 @@ public class TestDateTimeFormatterBuilder {
private static Temporal date(int y, int m, int d) {
return LocalDate.of(y, m, d);
}
}

View File

@ -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);
}
}

View File

@ -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 @@ import org.testng.annotations.Test;
public class TestDateTimeTextProvider extends AbstractTestPrinterParser {
Locale enUS = new Locale("en", "US");
Locale ptBR = new Locale("pt", "BR");
//-----------------------------------------------------------------------
@DataProvider(name = "Text")
@ -94,14 +93,6 @@ public class TestDateTimeTextProvider extends AbstractTestPrinterParser {
{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 @@ public class TestDateTimeTextProvider extends AbstractTestPrinterParser {
{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 @@ public class TestDateTimeTextProvider extends AbstractTestPrinterParser {
{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 @@ public class TestDateTimeTextProvider extends AbstractTestPrinterParser {
{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"},

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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 static org.testng.Assert.assertTrue;
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 @@ import org.testng.annotations.Test;
*/
@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 @@ public class TestTextParser extends AbstractTestPrinterParser {
};
}
// 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 @@ public class TestTextParser extends AbstractTestPrinterParser {
{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 @@ public class TestTextParser extends AbstractTestPrinterParser {
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);
@ -373,25 +325,6 @@ public class TestTextParser extends AbstractTestPrinterParser {
assertEquals(pos.getErrorIndex(), 0);
}
//-----------------------------------------------------------------------
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);
@ -436,51 +369,4 @@ public class TestTextParser extends AbstractTestPrinterParser {
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));
}
}

View File

@ -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));
}
}

View File

@ -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 @@ import test.java.time.temporal.MockFieldValue;
*/
@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 @@ public class TestTextPrinter extends AbstractTestPrinterParser {
{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 @@ public class TestTextPrinter extends AbstractTestPrinterParser {
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)");

View File

@ -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);
}
}

View File

@ -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 @@ public class SetFactories {
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 @@ public class SetFactories {
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

View File

@ -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 @@ public class MapFactories {
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 @@ public class MapFactories {
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 @@ public class MapFactories {
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");

View File

@ -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>";
}

View File

@ -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 class DeadCachedConnection {
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 @@ public class DeadCachedConnection {
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;
}
}

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1 @@
Main-Class: testpackage.Main

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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
@ -458,6 +458,76 @@ public class JmodTest {
);
}
@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");