Merge
This commit is contained in:
commit
83f2efcd66
@ -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>'\u002f'</tt>), then the absolute name of the resource is the
|
||||
* (<code>'\u002f'</code>), then the absolute name of the resource is the
|
||||
* portion of the {@code name} following the {@code '/'}.
|
||||
*
|
||||
* <li> Otherwise, the absolute name is of the following form:
|
||||
@ -2488,7 +2488,7 @@ 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>'\u002e'</tt>).
|
||||
* (<code>'\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>'\u002f'</tt>), then the absolute name of the resource is the
|
||||
* (<code>'\u002f'</code>), then the absolute name of the resource is the
|
||||
* portion of the {@code name} following the {@code '/'}.
|
||||
*
|
||||
* <li> Otherwise, the absolute name is of the following form:
|
||||
@ -2581,7 +2581,7 @@ 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>'\u002e'</tt>).
|
||||
* (<code>'\u002e'</code>).
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
|
@ -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™ 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™ 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™ 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™ 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."
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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(),
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
67
jdk/test/java/net/URLConnection/SetDefaultUseCaches.java
Normal file
67
jdk/test/java/net/URLConnection/SetDefaultUseCaches.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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";
|
||||
};
|
@ -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";
|
||||
};
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
};
|
@ -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";
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
79
jdk/test/java/rmi/testlibrary/RMIRegistryRunner.java
Normal file
79
jdk/test/java/rmi/testlibrary/RMIRegistryRunner.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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;
|
@ -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";
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
};
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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"},
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
@ -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)");
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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");
|
||||
|
284
jdk/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java
Normal file
284
jdk/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java
Normal 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>";
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
236
jdk/test/tools/jar/multiRelease/RuntimeTest.java
Normal file
236
jdk/test/tools/jar/multiRelease/RuntimeTest.java
Normal 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));
|
||||
}
|
||||
}
|
@ -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);
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
8
|
@ -0,0 +1 @@
|
||||
Main-Class: testpackage.Main
|
@ -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());
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
10
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
9
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user