8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 1994, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when an application tries to call an abstract method.
* Normally, this error is caught by the compiler; this error can
* only occur at run time if the definition of some class has
* incompatibly changed since the currently executing method was last
* compiled.
*
* @author unascribed
* @since 1.0
*/
public
class AbstractMethodError extends IncompatibleClassChangeError {
private static final long serialVersionUID = -1654391082989018462L;
/**
* Constructs an <code>AbstractMethodError</code> with no detail message.
*/
public AbstractMethodError() {
super();
}
/**
* Constructs an <code>AbstractMethodError</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public AbstractMethodError(String s) {
super(s);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 2003, 2004, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.io.IOException;
/**
* An object to which {@code char} sequences and values can be appended. The
* {@code Appendable} interface must be implemented by any class whose
* instances are intended to receive formatted output from a {@link
* java.util.Formatter}.
*
* <p> The characters to be appended should be valid Unicode characters as
* described in <a href="Character.html#unicode">Unicode Character
* Representation</a>. Note that supplementary characters may be composed of
* multiple 16-bit {@code char} values.
*
* <p> Appendables are not necessarily safe for multithreaded access. Thread
* safety is the responsibility of classes that extend and implement this
* interface.
*
* <p> Since this interface may be implemented by existing classes
* with different styles of error handling there is no guarantee that
* errors will be propagated to the invoker.
*
* @since 1.5
*/
public interface Appendable {
/**
* Appends the specified character sequence to this {@code Appendable}.
*
* <p> Depending on which class implements the character sequence
* {@code csq}, the entire sequence may not be appended. For
* instance, if {@code csq} is a {@link java.nio.CharBuffer} then
* the subsequence to append is defined by the buffer's position and limit.
*
* @param csq
* The character sequence to append. If {@code csq} is
* {@code null}, then the four characters {@code "null"} are
* appended to this Appendable.
*
* @return A reference to this {@code Appendable}
*
* @throws IOException
* If an I/O error occurs
*/
Appendable append(CharSequence csq) throws IOException;
/**
* Appends a subsequence of the specified character sequence to this
* {@code Appendable}.
*
* <p> An invocation of this method of the form {@code out.append(csq, start, end)}
* when {@code csq} is not {@code null}, behaves in
* exactly the same way as the invocation
*
* <pre>
* out.append(csq.subSequence(start, end)) </pre>
*
* @param csq
* The character sequence from which a subsequence will be
* appended. If {@code csq} is {@code null}, then characters
* will be appended as if {@code csq} contained the four
* characters {@code "null"}.
*
* @param start
* The index of the first character in the subsequence
*
* @param end
* The index of the character following the last character in the
* subsequence
*
* @return A reference to this {@code Appendable}
*
* @throws IndexOutOfBoundsException
* If {@code start} or {@code end} are negative, {@code start}
* is greater than {@code end}, or {@code end} is greater than
* {@code csq.length()}
*
* @throws IOException
* If an I/O error occurs
*/
Appendable append(CharSequence csq, int start, int end) throws IOException;
/**
* Appends the specified character to this {@code Appendable}.
*
* @param c
* The character to append
*
* @return A reference to this {@code Appendable}
*
* @throws IOException
* If an I/O error occurs
*/
Appendable append(char c) throws IOException;
}

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2005, 2010, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.util.*;
/*
* Class to track and run user level shutdown hooks registered through
* {@link Runtime#addShutdownHook Runtime.addShutdownHook}.
*
* @see java.lang.Runtime#addShutdownHook
* @see java.lang.Runtime#removeShutdownHook
*/
class ApplicationShutdownHooks {
/* The set of registered hooks */
private static IdentityHashMap<Thread, Thread> hooks;
static {
try {
Shutdown.add(1 /* shutdown hook invocation order */,
false /* not registered if shutdown in progress */,
new Runnable() {
public void run() {
runHooks();
}
}
);
hooks = new IdentityHashMap<>();
} catch (IllegalStateException e) {
// application shutdown hooks cannot be added if
// shutdown is in progress.
hooks = null;
}
}
private ApplicationShutdownHooks() {}
/* Add a new shutdown hook. Checks the shutdown state and the hook itself,
* but does not do any security checks.
*/
static synchronized void add(Thread hook) {
if(hooks == null)
throw new IllegalStateException("Shutdown in progress");
if (hook.isAlive())
throw new IllegalArgumentException("Hook already running");
if (hooks.containsKey(hook))
throw new IllegalArgumentException("Hook previously registered");
hooks.put(hook, hook);
}
/* Remove a previously-registered hook. Like the add method, this method
* does not do any security checks.
*/
static synchronized boolean remove(Thread hook) {
if(hooks == null)
throw new IllegalStateException("Shutdown in progress");
if (hook == null)
throw new NullPointerException();
return hooks.remove(hook) != null;
}
/* Iterates over all application hooks creating a new thread for each
* to run in. Hooks are run concurrently and this method waits for
* them to finish.
*/
static void runHooks() {
Collection<Thread> threads;
synchronized(ApplicationShutdownHooks.class) {
threads = hooks.keySet();
hooks = null;
}
for (Thread hook : threads) {
hook.start();
}
for (Thread hook : threads) {
while (true) {
try {
hook.join();
break;
} catch (InterruptedException ignored) {
}
}
}
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 1994, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when an exceptional arithmetic condition has occurred. For
* example, an integer "divide by zero" throws an
* instance of this class.
*
* {@code ArithmeticException} objects may be constructed by the
* virtual machine as if {@linkplain Throwable#Throwable(String,
* Throwable, boolean, boolean) suppression were disabled and/or the
* stack trace was not writable}.
*
* @author unascribed
* @since 1.0
*/
public class ArithmeticException extends RuntimeException {
private static final long serialVersionUID = 2256477558314496007L;
/**
* Constructs an {@code ArithmeticException} with no detail
* message.
*/
public ArithmeticException() {
super();
}
/**
* Constructs an {@code ArithmeticException} with the specified
* detail message.
*
* @param s the detail message.
*/
public ArithmeticException(String s) {
super(s);
}
}

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 1994, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that an array has been accessed with an illegal index. The
* index is either negative or greater than or equal to the size of the array.
*
* @since 1.0
*/
public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
private static final long serialVersionUID = -5116101128118950844L;
/**
* Constructs an {@code ArrayIndexOutOfBoundsException} with no detail
* message.
*/
public ArrayIndexOutOfBoundsException() {
super();
}
/**
* Constructs an {@code ArrayIndexOutOfBoundsException} class with the
* specified detail message.
*
* @param s the detail message.
*/
public ArrayIndexOutOfBoundsException(String s) {
super(s);
}
/**
* Constructs a new {@code ArrayIndexOutOfBoundsException} class with an
* argument indicating the illegal index.
*
* <p>The index is included in this exception's detail message. The
* exact presentation format of the detail message is unspecified.
*
* @param index the illegal index.
*/
public ArrayIndexOutOfBoundsException(int index) {
super("Array index out of range: " + index);
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 1995, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that an attempt has been made to store the
* wrong type of object into an array of objects. For example, the
* following code generates an <code>ArrayStoreException</code>:
* <blockquote><pre>
* Object x[] = new String[3];
* x[0] = new Integer(0);
* </pre></blockquote>
*
* @author unascribed
* @since 1.0
*/
public
class ArrayStoreException extends RuntimeException {
private static final long serialVersionUID = -4522193890499838241L;
/**
* Constructs an <code>ArrayStoreException</code> with no detail message.
*/
public ArrayStoreException() {
super();
}
/**
* Constructs an <code>ArrayStoreException</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public ArrayStoreException(String s) {
super(s);
}
}

View file

@ -0,0 +1,167 @@
/*
* Copyright (c) 2000, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that an assertion has failed.
*
* <p>The seven one-argument public constructors provided by this
* class ensure that the assertion error returned by the invocation:
* <pre>
* new AssertionError(<i>expression</i>)
* </pre>
* has as its detail message the <i>string conversion</i> of
* <i>expression</i> (as defined in section 15.18.1.1 of
* <cite>The Java&trade; Language Specification</cite>),
* regardless of the type of <i>expression</i>.
*
* @since 1.4
*/
public class AssertionError extends Error {
private static final long serialVersionUID = -5013299493970297370L;
/**
* Constructs an AssertionError with no detail message.
*/
public AssertionError() {
}
/**
* This internal constructor does no processing on its string argument,
* even if it is a null reference. The public constructors will
* never call this constructor with a null argument.
*/
private AssertionError(String detailMessage) {
super(detailMessage);
}
/**
* Constructs an AssertionError with its detail message derived
* from the specified object, which is converted to a string as
* defined in section 15.18.1.1 of
* <cite>The Java&trade; Language Specification</cite>.
*<p>
* If the specified object is an instance of {@code Throwable}, it
* becomes the <i>cause</i> of the newly constructed assertion error.
*
* @param detailMessage value to be used in constructing detail message
* @see Throwable#getCause()
*/
public AssertionError(Object detailMessage) {
this(String.valueOf(detailMessage));
if (detailMessage instanceof Throwable)
initCause((Throwable) detailMessage);
}
/**
* Constructs an AssertionError with its detail message derived
* from the specified <code>boolean</code>, which is converted to
* a string as defined in section 15.18.1.1 of
* <cite>The Java&trade; Language Specification</cite>.
*
* @param detailMessage value to be used in constructing detail message
*/
public AssertionError(boolean detailMessage) {
this(String.valueOf(detailMessage));
}
/**
* Constructs an AssertionError with its detail message derived
* from the specified <code>char</code>, which is converted to a
* string as defined in section 15.18.1.1 of
* <cite>The Java&trade; Language Specification</cite>.
*
* @param detailMessage value to be used in constructing detail message
*/
public AssertionError(char detailMessage) {
this(String.valueOf(detailMessage));
}
/**
* Constructs an AssertionError with its detail message derived
* from the specified <code>int</code>, which is converted to a
* string as defined in section 15.18.1.1 of
* <cite>The Java&trade; Language Specification</cite>.
*
* @param detailMessage value to be used in constructing detail message
*/
public AssertionError(int detailMessage) {
this(String.valueOf(detailMessage));
}
/**
* Constructs an AssertionError with its detail message derived
* from the specified <code>long</code>, which is converted to a
* string as defined in section 15.18.1.1 of
* <cite>The Java&trade; Language Specification</cite>.
*
* @param detailMessage value to be used in constructing detail message
*/
public AssertionError(long detailMessage) {
this(String.valueOf(detailMessage));
}
/**
* Constructs an AssertionError with its detail message derived
* from the specified <code>float</code>, which is converted to a
* string as defined in section 15.18.1.1 of
* <cite>The Java&trade; Language Specification</cite>.
*
* @param detailMessage value to be used in constructing detail message
*/
public AssertionError(float detailMessage) {
this(String.valueOf(detailMessage));
}
/**
* Constructs an AssertionError with its detail message derived
* from the specified <code>double</code>, which is converted to a
* string as defined in section 15.18.1.1 of
* <cite>The Java&trade; Language Specification</cite>.
*
* @param detailMessage value to be used in constructing detail message
*/
public AssertionError(double detailMessage) {
this(String.valueOf(detailMessage));
}
/**
* Constructs a new {@code AssertionError} with the specified
* detail message and cause.
*
* <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this error's detail message.
*
* @param message the detail message, may be {@code null}
* @param cause the cause, may be {@code null}
*
* @since 1.7
*/
public AssertionError(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2000, 2006, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* A collection of assertion status directives (such as "enable assertions
* in package p" or "disable assertions in class c"). This class is used by
* the JVM to communicate the assertion status directives implied by
* the {@code java} command line flags {@code -enableassertions}
* ({@code -ea}) and {@code -disableassertions} ({@code -da}).
*
* @since 1.4
* @author Josh Bloch
*/
class AssertionStatusDirectives {
/**
* The classes for which assertions are to be enabled or disabled.
* The strings in this array are fully qualified class names (for
* example,"com.xyz.foo.Bar").
*/
String[] classes;
/**
* A parallel array to {@code classes}, indicating whether each class
* is to have assertions enabled or disabled. A value of {@code true}
* for {@code classEnabled[i]} indicates that the class named by
* {@code classes[i]} should have assertions enabled; a value of
* {@code false} indicates that it should have classes disabled.
* This array must have the same number of elements as {@code classes}.
*
* <p>In the case of conflicting directives for the same class, the
* last directive for a given class wins. In other words, if a string
* {@code s} appears multiple times in the {@code classes} array
* and {@code i} is the highest integer for which
* {@code classes[i].equals(s)}, then {@code classEnabled[i]}
* indicates whether assertions are to be enabled in class {@code s}.
*/
boolean[] classEnabled;
/**
* The package-trees for which assertions are to be enabled or disabled.
* The strings in this array are compete or partial package names
* (for example, "com.xyz" or "com.xyz.foo").
*/
String[] packages;
/**
* A parallel array to {@code packages}, indicating whether each
* package-tree is to have assertions enabled or disabled. A value of
* {@code true} for {@code packageEnabled[i]} indicates that the
* package-tree named by {@code packages[i]} should have assertions
* enabled; a value of {@code false} indicates that it should have
* assertions disabled. This array must have the same number of
* elements as {@code packages}.
*
* In the case of conflicting directives for the same package-tree, the
* last directive for a given package-tree wins. In other words, if a
* string {@code s} appears multiple times in the {@code packages} array
* and {@code i} is the highest integer for which
* {@code packages[i].equals(s)}, then {@code packageEnabled[i]}
* indicates whether assertions are to be enabled in package-tree
* {@code s}.
*/
boolean[] packageEnabled;
/**
* Whether or not assertions in non-system classes are to be enabled
* by default.
*/
boolean deflt;
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2009, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* An object that may hold resources (such as file or socket handles)
* until it is closed. The {@link #close()} method of an {@code AutoCloseable}
* object is called automatically when exiting a {@code
* try}-with-resources block for which the object has been declared in
* the resource specification header. This construction ensures prompt
* release, avoiding resource exhaustion exceptions and errors that
* may otherwise occur.
*
* @apiNote
* <p>It is possible, and in fact common, for a base class to
* implement AutoCloseable even though not all of its subclasses or
* instances will hold releasable resources. For code that must operate
* in complete generality, or when it is known that the {@code AutoCloseable}
* instance requires resource release, it is recommended to use {@code
* try}-with-resources constructions. However, when using facilities such as
* {@link java.util.stream.Stream} that support both I/O-based and
* non-I/O-based forms, {@code try}-with-resources blocks are in
* general unnecessary when using non-I/O-based forms.
*
* @author Josh Bloch
* @since 1.7
*/
public interface AutoCloseable {
/**
* Closes this resource, relinquishing any underlying resources.
* This method is invoked automatically on objects managed by the
* {@code try}-with-resources statement.
*
* <p>While this interface method is declared to throw {@code
* Exception}, implementers are <em>strongly</em> encouraged to
* declare concrete implementations of the {@code close} method to
* throw more specific exceptions, or to throw no exception at all
* if the close operation cannot fail.
*
* <p> Cases where the close operation may fail require careful
* attention by implementers. It is strongly advised to relinquish
* the underlying resources and to internally <em>mark</em> the
* resource as closed, prior to throwing the exception. The {@code
* close} method is unlikely to be invoked more than once and so
* this ensures that the resources are released in a timely manner.
* Furthermore it reduces problems that could arise when the resource
* wraps, or is wrapped, by another resource.
*
* <p><em>Implementers of this interface are also strongly advised
* to not have the {@code close} method throw {@link
* InterruptedException}.</em>
*
* This exception interacts with a thread's interrupted status,
* and runtime misbehavior is likely to occur if an {@code
* InterruptedException} is {@linkplain Throwable#addSuppressed
* suppressed}.
*
* More generally, if it would cause problems for an
* exception to be suppressed, the {@code AutoCloseable.close}
* method should not throw it.
*
* <p>Note that unlike the {@link java.io.Closeable#close close}
* method of {@link java.io.Closeable}, this {@code close} method
* is <em>not</em> required to be idempotent. In other words,
* calling this {@code close} method more than once may have some
* visible side effect, unlike {@code Closeable.close} which is
* required to have no effect if called more than once.
*
* However, implementers of this interface are strongly encouraged
* to make their {@code close} methods idempotent.
*
* @throws Exception if this resource cannot be closed
*/
void close() throws Exception;
}

View file

@ -0,0 +1,346 @@
/*
* Copyright (c) 1994, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The Boolean class wraps a value of the primitive type
* {@code boolean} in an object. An object of type
* {@code Boolean} contains a single field whose type is
* {@code boolean}.
* <p>
* In addition, this class provides many methods for
* converting a {@code boolean} to a {@code String} and a
* {@code String} to a {@code boolean}, as well as other
* constants and methods useful when dealing with a
* {@code boolean}.
*
* @author Arthur van Hoff
* @since 1.0
*/
public final class Boolean implements java.io.Serializable,
Comparable<Boolean>
{
/**
* The {@code Boolean} object corresponding to the primitive
* value {@code true}.
*/
public static final Boolean TRUE = new Boolean(true);
/**
* The {@code Boolean} object corresponding to the primitive
* value {@code false}.
*/
public static final Boolean FALSE = new Boolean(false);
/**
* The Class object representing the primitive type boolean.
*
* @since 1.1
*/
@SuppressWarnings("unchecked")
public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");
/**
* The value of the Boolean.
*
* @serial
*/
private final boolean value;
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -3665804199014368530L;
/**
* Allocates a {@code Boolean} object representing the
* {@code value} argument.
*
* @param value the value of the {@code Boolean}.
*
* @deprecated
* It is rarely appropriate to use this constructor. The static factory
* {@link #valueOf(boolean)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
* Also consider using the final fields {@link #TRUE} and {@link #FALSE}
* if possible.
*/
@Deprecated(since="9")
public Boolean(boolean value) {
this.value = value;
}
/**
* Allocates a {@code Boolean} object representing the value
* {@code true} if the string argument is not {@code null}
* and is equal, ignoring case, to the string {@code "true"}.
* Otherwise, allocates a {@code Boolean} object representing the
* value {@code false}.
*
* @param s the string to be converted to a {@code Boolean}.
*
* @deprecated
* It is rarely appropriate to use this constructor.
* Use {@link #parseBoolean(String)} to convert a string to a
* {@code boolean} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Boolean} object.
*/
@Deprecated(since="9")
public Boolean(String s) {
this(parseBoolean(s));
}
/**
* Parses the string argument as a boolean. The {@code boolean}
* returned represents the value {@code true} if the string argument
* is not {@code null} and is equal, ignoring case, to the string
* {@code "true"}.
* Otherwise, a false value is returned, including for a null
* argument.<p>
* Example: {@code Boolean.parseBoolean("True")} returns {@code true}.<br>
* Example: {@code Boolean.parseBoolean("yes")} returns {@code false}.
*
* @param s the {@code String} containing the boolean
* representation to be parsed
* @return the boolean represented by the string argument
* @since 1.5
*/
public static boolean parseBoolean(String s) {
return ((s != null) && s.equalsIgnoreCase("true"));
}
/**
* Returns the value of this {@code Boolean} object as a boolean
* primitive.
*
* @return the primitive {@code boolean} value of this object.
*/
@HotSpotIntrinsicCandidate
public boolean booleanValue() {
return value;
}
/**
* Returns a {@code Boolean} instance representing the specified
* {@code boolean} value. If the specified {@code boolean} value
* is {@code true}, this method returns {@code Boolean.TRUE};
* if it is {@code false}, this method returns {@code Boolean.FALSE}.
* If a new {@code Boolean} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Boolean(boolean)}, as this method is likely to yield
* significantly better space and time performance.
*
* @param b a boolean value.
* @return a {@code Boolean} instance representing {@code b}.
* @since 1.4
*/
@HotSpotIntrinsicCandidate
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
/**
* Returns a {@code Boolean} with a value represented by the
* specified string. The {@code Boolean} returned represents a
* true value if the string argument is not {@code null}
* and is equal, ignoring case, to the string {@code "true"}.
* Otherwise, a false value is returned, including for a null
* argument.
*
* @param s a string.
* @return the {@code Boolean} value represented by the string.
*/
public static Boolean valueOf(String s) {
return parseBoolean(s) ? TRUE : FALSE;
}
/**
* Returns a {@code String} object representing the specified
* boolean. If the specified boolean is {@code true}, then
* the string {@code "true"} will be returned, otherwise the
* string {@code "false"} will be returned.
*
* @param b the boolean to be converted
* @return the string representation of the specified {@code boolean}
* @since 1.4
*/
public static String toString(boolean b) {
return b ? "true" : "false";
}
/**
* Returns a {@code String} object representing this Boolean's
* value. If this object represents the value {@code true},
* a string equal to {@code "true"} is returned. Otherwise, a
* string equal to {@code "false"} is returned.
*
* @return a string representation of this object.
*/
public String toString() {
return value ? "true" : "false";
}
/**
* Returns a hash code for this {@code Boolean} object.
*
* @return the integer {@code 1231} if this object represents
* {@code true}; returns the integer {@code 1237} if this
* object represents {@code false}.
*/
@Override
public int hashCode() {
return Boolean.hashCode(value);
}
/**
* Returns a hash code for a {@code boolean} value; compatible with
* {@code Boolean.hashCode()}.
*
* @param value the value to hash
* @return a hash code value for a {@code boolean} value.
* @since 1.8
*/
public static int hashCode(boolean value) {
return value ? 1231 : 1237;
}
/**
* Returns {@code true} if and only if the argument is not
* {@code null} and is a {@code Boolean} object that
* represents the same {@code boolean} value as this object.
*
* @param obj the object to compare with.
* @return {@code true} if the Boolean objects represent the
* same value; {@code false} otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
/**
* Returns {@code true} if and only if the system property named
* by the argument exists and is equal to, ignoring case, the
* string {@code "true"}.
* A system property is accessible through {@code getProperty}, a
* method defined by the {@code System} class. <p> If there is no
* property with the specified name, or if the specified name is
* empty or null, then {@code false} is returned.
*
* @param name the system property name.
* @return the {@code boolean} value of the system property.
* @throws SecurityException for the same reasons as
* {@link System#getProperty(String) System.getProperty}
* @see java.lang.System#getProperty(java.lang.String)
* @see java.lang.System#getProperty(java.lang.String, java.lang.String)
*/
public static boolean getBoolean(String name) {
boolean result = false;
try {
result = parseBoolean(System.getProperty(name));
} catch (IllegalArgumentException | NullPointerException e) {
}
return result;
}
/**
* Compares this {@code Boolean} instance with another.
*
* @param b the {@code Boolean} instance to be compared
* @return zero if this object represents the same boolean value as the
* argument; a positive value if this object represents true
* and the argument represents false; and a negative value if
* this object represents false and the argument represents true
* @throws NullPointerException if the argument is {@code null}
* @see Comparable
* @since 1.5
*/
public int compareTo(Boolean b) {
return compare(this.value, b.value);
}
/**
* Compares two {@code boolean} values.
* The value returned is identical to what would be returned by:
* <pre>
* Boolean.valueOf(x).compareTo(Boolean.valueOf(y))
* </pre>
*
* @param x the first {@code boolean} to compare
* @param y the second {@code boolean} to compare
* @return the value {@code 0} if {@code x == y};
* a value less than {@code 0} if {@code !x && y}; and
* a value greater than {@code 0} if {@code x && !y}
* @since 1.7
*/
public static int compare(boolean x, boolean y) {
return (x == y) ? 0 : (x ? 1 : -1);
}
/**
* Returns the result of applying the logical AND operator to the
* specified {@code boolean} operands.
*
* @param a the first operand
* @param b the second operand
* @return the logical AND of {@code a} and {@code b}
* @see java.util.function.BinaryOperator
* @since 1.8
*/
public static boolean logicalAnd(boolean a, boolean b) {
return a && b;
}
/**
* Returns the result of applying the logical OR operator to the
* specified {@code boolean} operands.
*
* @param a the first operand
* @param b the second operand
* @return the logical OR of {@code a} and {@code b}
* @see java.util.function.BinaryOperator
* @since 1.8
*/
public static boolean logicalOr(boolean a, boolean b) {
return a || b;
}
/**
* Returns the result of applying the logical XOR operator to the
* specified {@code boolean} operands.
*
* @param a the first operand
* @param b the second operand
* @return the logical XOR of {@code a} and {@code b}
* @see java.util.function.BinaryOperator
* @since 1.8
*/
public static boolean logicalXor(boolean a, boolean b) {
return a ^ b;
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that an {@code invokedynamic} instruction has
* failed to find its bootstrap method,
* or the bootstrap method has failed to provide a
* {@linkplain java.lang.invoke.CallSite call site} with a {@linkplain java.lang.invoke.CallSite#getTarget target}
* of the correct {@linkplain java.lang.invoke.MethodHandle#type() method type}.
*
* @author John Rose, JSR 292 EG
* @since 1.7
*/
public class BootstrapMethodError extends LinkageError {
private static final long serialVersionUID = 292L;
/**
* Constructs a {@code BootstrapMethodError} with no detail message.
*/
public BootstrapMethodError() {
super();
}
/**
* Constructs a {@code BootstrapMethodError} with the specified
* detail message.
*
* @param s the detail message.
*/
public BootstrapMethodError(String s) {
super(s);
}
/**
* Constructs a {@code BootstrapMethodError} with the specified
* detail message and cause.
*
* @param s the detail message.
* @param cause the cause, may be {@code null}.
*/
public BootstrapMethodError(String s, Throwable cause) {
super(s, cause);
}
/**
* Constructs a {@code BootstrapMethodError} with the specified
* cause.
*
* @param cause the cause, may be {@code null}.
*/
public BootstrapMethodError(Throwable cause) {
// cf. Throwable(Throwable cause) constructor.
super(cause == null ? null : cause.toString());
initCause(cause);
}
}

View file

@ -0,0 +1,552 @@
/*
* Copyright (c) 1996, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
*
* The {@code Byte} class wraps a value of primitive type {@code byte}
* in an object. An object of type {@code Byte} contains a single
* field whose type is {@code byte}.
*
* <p>In addition, this class provides several methods for converting
* a {@code byte} to a {@code String} and a {@code String} to a {@code
* byte}, as well as other constants and methods useful when dealing
* with a {@code byte}.
*
* @author Nakul Saraiya
* @author Joseph D. Darcy
* @see java.lang.Number
* @since 1.1
*/
public final class Byte extends Number implements Comparable<Byte> {
/**
* A constant holding the minimum value a {@code byte} can
* have, -2<sup>7</sup>.
*/
public static final byte MIN_VALUE = -128;
/**
* A constant holding the maximum value a {@code byte} can
* have, 2<sup>7</sup>-1.
*/
public static final byte MAX_VALUE = 127;
/**
* The {@code Class} instance representing the primitive type
* {@code byte}.
*/
@SuppressWarnings("unchecked")
public static final Class<Byte> TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
/**
* Returns a new {@code String} object representing the
* specified {@code byte}. The radix is assumed to be 10.
*
* @param b the {@code byte} to be converted
* @return the string representation of the specified {@code byte}
* @see java.lang.Integer#toString(int)
*/
public static String toString(byte b) {
return Integer.toString((int)b, 10);
}
private static class ByteCache {
private ByteCache(){}
static final Byte cache[] = new Byte[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Byte((byte)(i - 128));
}
}
/**
* Returns a {@code Byte} instance representing the specified
* {@code byte} value.
* If a new {@code Byte} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Byte(byte)}, as this method is likely to yield
* significantly better space and time performance since
* all byte values are cached.
*
* @param b a byte value.
* @return a {@code Byte} instance representing {@code b}.
* @since 1.5
*/
@HotSpotIntrinsicCandidate
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}
/**
* Parses the string argument as a signed {@code byte} in the
* radix specified by the second argument. The characters in the
* string must all be digits, of the specified radix (as
* determined by whether {@link java.lang.Character#digit(char,
* int)} returns a nonnegative value) except that the first
* character may be an ASCII minus sign {@code '-'}
* ({@code '\u005Cu002D'}) to indicate a negative value or an
* ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
* indicate a positive value. The resulting {@code byte} value is
* returned.
*
* <p>An exception of type {@code NumberFormatException} is
* thrown if any of the following situations occurs:
* <ul>
* <li> The first argument is {@code null} or is a string of
* length zero.
*
* <li> The radix is either smaller than {@link
* java.lang.Character#MIN_RADIX} or larger than {@link
* java.lang.Character#MAX_RADIX}.
*
* <li> Any character of the string is not a digit of the
* specified radix, except that the first character may be a minus
* sign {@code '-'} ({@code '\u005Cu002D'}) or plus sign
* {@code '+'} ({@code '\u005Cu002B'}) provided that the
* string is longer than length 1.
*
* <li> The value represented by the string is not a value of type
* {@code byte}.
* </ul>
*
* @param s the {@code String} containing the
* {@code byte}
* representation to be parsed
* @param radix the radix to be used while parsing {@code s}
* @return the {@code byte} value represented by the string
* argument in the specified radix
* @throws NumberFormatException If the string does
* not contain a parsable {@code byte}.
*/
public static byte parseByte(String s, int radix)
throws NumberFormatException {
int i = Integer.parseInt(s, radix);
if (i < MIN_VALUE || i > MAX_VALUE)
throw new NumberFormatException(
"Value out of range. Value:\"" + s + "\" Radix:" + radix);
return (byte)i;
}
/**
* Parses the string argument as a signed decimal {@code
* byte}. The characters in the string must all be decimal digits,
* except that the first character may be an ASCII minus sign
* {@code '-'} ({@code '\u005Cu002D'}) to indicate a negative
* value or an ASCII plus sign {@code '+'}
* ({@code '\u005Cu002B'}) to indicate a positive value. The
* resulting {@code byte} value is returned, exactly as if the
* argument and the radix 10 were given as arguments to the {@link
* #parseByte(java.lang.String, int)} method.
*
* @param s a {@code String} containing the
* {@code byte} representation to be parsed
* @return the {@code byte} value represented by the
* argument in decimal
* @throws NumberFormatException if the string does not
* contain a parsable {@code byte}.
*/
public static byte parseByte(String s) throws NumberFormatException {
return parseByte(s, 10);
}
/**
* Returns a {@code Byte} object holding the value
* extracted from the specified {@code String} when parsed
* with the radix given by the second argument. The first argument
* is interpreted as representing a signed {@code byte} in
* the radix specified by the second argument, exactly as if the
* argument were given to the {@link #parseByte(java.lang.String,
* int)} method. The result is a {@code Byte} object that
* represents the {@code byte} value specified by the string.
*
* <p> In other words, this method returns a {@code Byte} object
* equal to the value of:
*
* <blockquote>
* {@code new Byte(Byte.parseByte(s, radix))}
* </blockquote>
*
* @param s the string to be parsed
* @param radix the radix to be used in interpreting {@code s}
* @return a {@code Byte} object holding the value
* represented by the string argument in the
* specified radix.
* @throws NumberFormatException If the {@code String} does
* not contain a parsable {@code byte}.
*/
public static Byte valueOf(String s, int radix)
throws NumberFormatException {
return valueOf(parseByte(s, radix));
}
/**
* Returns a {@code Byte} object holding the value
* given by the specified {@code String}. The argument is
* interpreted as representing a signed decimal {@code byte},
* exactly as if the argument were given to the {@link
* #parseByte(java.lang.String)} method. The result is a
* {@code Byte} object that represents the {@code byte}
* value specified by the string.
*
* <p> In other words, this method returns a {@code Byte} object
* equal to the value of:
*
* <blockquote>
* {@code new Byte(Byte.parseByte(s))}
* </blockquote>
*
* @param s the string to be parsed
* @return a {@code Byte} object holding the value
* represented by the string argument
* @throws NumberFormatException If the {@code String} does
* not contain a parsable {@code byte}.
*/
public static Byte valueOf(String s) throws NumberFormatException {
return valueOf(s, 10);
}
/**
* Decodes a {@code String} into a {@code Byte}.
* Accepts decimal, hexadecimal, and octal numbers given by
* the following grammar:
*
* <blockquote>
* <dl>
* <dt><i>DecodableString:</i>
* <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
* <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
* <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
* <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
* <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
*
* <dt><i>Sign:</i>
* <dd>{@code -}
* <dd>{@code +}
* </dl>
* </blockquote>
*
* <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
* are as defined in section 3.10.1 of
* <cite>The Java&trade; Language Specification</cite>,
* except that underscores are not accepted between digits.
*
* <p>The sequence of characters following an optional
* sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
* "{@code #}", or leading zero) is parsed as by the {@code
* Byte.parseByte} method with the indicated radix (10, 16, or 8).
* This sequence of characters must represent a positive value or
* a {@link NumberFormatException} will be thrown. The result is
* negated if first character of the specified {@code String} is
* the minus sign. No whitespace characters are permitted in the
* {@code String}.
*
* @param nm the {@code String} to decode.
* @return a {@code Byte} object holding the {@code byte}
* value represented by {@code nm}
* @throws NumberFormatException if the {@code String} does not
* contain a parsable {@code byte}.
* @see java.lang.Byte#parseByte(java.lang.String, int)
*/
public static Byte decode(String nm) throws NumberFormatException {
int i = Integer.decode(nm);
if (i < MIN_VALUE || i > MAX_VALUE)
throw new NumberFormatException(
"Value " + i + " out of range from input " + nm);
return valueOf((byte)i);
}
/**
* The value of the {@code Byte}.
*
* @serial
*/
private final byte value;
/**
* Constructs a newly allocated {@code Byte} object that
* represents the specified {@code byte} value.
*
* @param value the value to be represented by the
* {@code Byte}.
*
* @deprecated
* It is rarely appropriate to use this constructor. The static factory
* {@link #valueOf(byte)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
public Byte(byte value) {
this.value = value;
}
/**
* Constructs a newly allocated {@code Byte} object that
* represents the {@code byte} value indicated by the
* {@code String} parameter. The string is converted to a
* {@code byte} value in exactly the manner used by the
* {@code parseByte} method for radix 10.
*
* @param s the {@code String} to be converted to a
* {@code Byte}
* @throws NumberFormatException if the {@code String}
* does not contain a parsable {@code byte}.
*
* @deprecated
* It is rarely appropriate to use this constructor.
* Use {@link #parseByte(String)} to convert a string to a
* {@code byte} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Byte} object.
*/
@Deprecated(since="9")
public Byte(String s) throws NumberFormatException {
this.value = parseByte(s, 10);
}
/**
* Returns the value of this {@code Byte} as a
* {@code byte}.
*/
@HotSpotIntrinsicCandidate
public byte byteValue() {
return value;
}
/**
* Returns the value of this {@code Byte} as a {@code short} after
* a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public short shortValue() {
return (short)value;
}
/**
* Returns the value of this {@code Byte} as an {@code int} after
* a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public int intValue() {
return (int)value;
}
/**
* Returns the value of this {@code Byte} as a {@code long} after
* a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public long longValue() {
return (long)value;
}
/**
* Returns the value of this {@code Byte} as a {@code float} after
* a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public float floatValue() {
return (float)value;
}
/**
* Returns the value of this {@code Byte} as a {@code double}
* after a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public double doubleValue() {
return (double)value;
}
/**
* Returns a {@code String} object representing this
* {@code Byte}'s value. The value is converted to signed
* decimal representation and returned as a string, exactly as if
* the {@code byte} value were given as an argument to the
* {@link java.lang.Byte#toString(byte)} method.
*
* @return a string representation of the value of this object in
* base&nbsp;10.
*/
public String toString() {
return Integer.toString((int)value);
}
/**
* Returns a hash code for this {@code Byte}; equal to the result
* of invoking {@code intValue()}.
*
* @return a hash code value for this {@code Byte}
*/
@Override
public int hashCode() {
return Byte.hashCode(value);
}
/**
* Returns a hash code for a {@code byte} value; compatible with
* {@code Byte.hashCode()}.
*
* @param value the value to hash
* @return a hash code value for a {@code byte} value.
* @since 1.8
*/
public static int hashCode(byte value) {
return (int)value;
}
/**
* Compares this object to the specified object. The result is
* {@code true} if and only if the argument is not
* {@code null} and is a {@code Byte} object that
* contains the same {@code byte} value as this object.
*
* @param obj the object to compare with
* @return {@code true} if the objects are the same;
* {@code false} otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof Byte) {
return value == ((Byte)obj).byteValue();
}
return false;
}
/**
* Compares two {@code Byte} objects numerically.
*
* @param anotherByte the {@code Byte} to be compared.
* @return the value {@code 0} if this {@code Byte} is
* equal to the argument {@code Byte}; a value less than
* {@code 0} if this {@code Byte} is numerically less
* than the argument {@code Byte}; and a value greater than
* {@code 0} if this {@code Byte} is numerically
* greater than the argument {@code Byte} (signed
* comparison).
* @since 1.2
*/
public int compareTo(Byte anotherByte) {
return compare(this.value, anotherByte.value);
}
/**
* Compares two {@code byte} values numerically.
* The value returned is identical to what would be returned by:
* <pre>
* Byte.valueOf(x).compareTo(Byte.valueOf(y))
* </pre>
*
* @param x the first {@code byte} to compare
* @param y the second {@code byte} to compare
* @return the value {@code 0} if {@code x == y};
* a value less than {@code 0} if {@code x < y}; and
* a value greater than {@code 0} if {@code x > y}
* @since 1.7
*/
public static int compare(byte x, byte y) {
return x - y;
}
/**
* Compares two {@code byte} values numerically treating the values
* as unsigned.
*
* @param x the first {@code byte} to compare
* @param y the second {@code byte} to compare
* @return the value {@code 0} if {@code x == y}; a value less
* than {@code 0} if {@code x < y} as unsigned values; and
* a value greater than {@code 0} if {@code x > y} as
* unsigned values
* @since 9
*/
public static int compareUnsigned(byte x, byte y) {
return Byte.toUnsignedInt(x) - Byte.toUnsignedInt(y);
}
/**
* Converts the argument to an {@code int} by an unsigned
* conversion. In an unsigned conversion to an {@code int}, the
* high-order 24 bits of the {@code int} are zero and the
* low-order 8 bits are equal to the bits of the {@code byte} argument.
*
* Consequently, zero and positive {@code byte} values are mapped
* to a numerically equal {@code int} value and negative {@code
* byte} values are mapped to an {@code int} value equal to the
* input plus 2<sup>8</sup>.
*
* @param x the value to convert to an unsigned {@code int}
* @return the argument converted to {@code int} by an unsigned
* conversion
* @since 1.8
*/
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
/**
* Converts the argument to a {@code long} by an unsigned
* conversion. In an unsigned conversion to a {@code long}, the
* high-order 56 bits of the {@code long} are zero and the
* low-order 8 bits are equal to the bits of the {@code byte} argument.
*
* Consequently, zero and positive {@code byte} values are mapped
* to a numerically equal {@code long} value and negative {@code
* byte} values are mapped to a {@code long} value equal to the
* input plus 2<sup>8</sup>.
*
* @param x the value to convert to an unsigned {@code long}
* @return the argument converted to {@code long} by an unsigned
* conversion
* @since 1.8
*/
public static long toUnsignedLong(byte x) {
return ((long) x) & 0xffL;
}
/**
* The number of bits used to represent a {@code byte} value in two's
* complement binary form.
*
* @since 1.5
*/
public static final int SIZE = 8;
/**
* The number of bytes used to represent a {@code byte} value in two's
* complement binary form.
*
* @since 1.8
*/
public static final int BYTES = SIZE / Byte.SIZE;
/** use serialVersionUID from JDK 1.1. for interoperability */
private static final long serialVersionUID = -7183698231559129828L;
}

View file

@ -0,0 +1,240 @@
/*
* Copyright (c) 2000, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.util.NoSuchElementException;
import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.IntConsumer;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
/**
* A {@code CharSequence} is a readable sequence of {@code char} values. This
* interface provides uniform, read-only access to many different kinds of
* {@code char} sequences.
* A {@code char} value represents a character in the <i>Basic
* Multilingual Plane (BMP)</i> or a surrogate. Refer to <a
* href="Character.html#unicode">Unicode Character Representation</a> for details.
*
* <p> This interface does not refine the general contracts of the {@link
* java.lang.Object#equals(java.lang.Object) equals} and {@link
* java.lang.Object#hashCode() hashCode} methods. The result of comparing two
* objects that implement {@code CharSequence} is therefore, in general,
* undefined. Each object may be implemented by a different class, and there
* is no guarantee that each class will be capable of testing its instances
* for equality with those of the other. It is therefore inappropriate to use
* arbitrary {@code CharSequence} instances as elements in a set or as keys in
* a map. </p>
*
* @author Mike McCloskey
* @since 1.4
* @spec JSR-51
*/
public interface CharSequence {
/**
* Returns the length of this character sequence. The length is the number
* of 16-bit {@code char}s in the sequence.
*
* @return the number of {@code char}s in this sequence
*/
int length();
/**
* Returns the {@code char} value at the specified index. An index ranges from zero
* to {@code length() - 1}. The first {@code char} value of the sequence is at
* index zero, the next at index one, and so on, as for array
* indexing.
*
* <p>If the {@code char} value specified by the index is a
* <a href="{@docRoot}/java/lang/Character.html#unicode">surrogate</a>, the surrogate
* value is returned.
*
* @param index the index of the {@code char} value to be returned
*
* @return the specified {@code char} value
*
* @throws IndexOutOfBoundsException
* if the {@code index} argument is negative or not less than
* {@code length()}
*/
char charAt(int index);
/**
* Returns a {@code CharSequence} that is a subsequence of this sequence.
* The subsequence starts with the {@code char} value at the specified index and
* ends with the {@code char} value at index {@code end - 1}. The length
* (in {@code char}s) of the
* returned sequence is {@code end - start}, so if {@code start == end}
* then an empty sequence is returned.
*
* @param start the start index, inclusive
* @param end the end index, exclusive
*
* @return the specified subsequence
*
* @throws IndexOutOfBoundsException
* if {@code start} or {@code end} are negative,
* if {@code end} is greater than {@code length()},
* or if {@code start} is greater than {@code end}
*/
CharSequence subSequence(int start, int end);
/**
* Returns a string containing the characters in this sequence in the same
* order as this sequence. The length of the string will be the length of
* this sequence.
*
* @return a string consisting of exactly this sequence of characters
*/
public String toString();
/**
* Returns a stream of {@code int} zero-extending the {@code char} values
* from this sequence. Any char which maps to a <a
* href="{@docRoot}/java/lang/Character.html#unicode">surrogate code
* point</a> is passed through uninterpreted.
*
* <p>The stream binds to this sequence when the terminal stream operation
* commences (specifically, for mutable sequences the spliterator for the
* stream is <a href="../util/Spliterator.html#binding"><em>late-binding</em></a>).
* If the sequence is modified during that operation then the result is
* undefined.
*
* @return an IntStream of char values from this sequence
* @since 1.8
*/
public default IntStream chars() {
class CharIterator implements PrimitiveIterator.OfInt {
int cur = 0;
public boolean hasNext() {
return cur < length();
}
public int nextInt() {
if (hasNext()) {
return charAt(cur++);
} else {
throw new NoSuchElementException();
}
}
@Override
public void forEachRemaining(IntConsumer block) {
for (; cur < length(); cur++) {
block.accept(charAt(cur));
}
}
}
return StreamSupport.intStream(() ->
Spliterators.spliterator(
new CharIterator(),
length(),
Spliterator.ORDERED),
Spliterator.SUBSIZED | Spliterator.SIZED | Spliterator.ORDERED,
false);
}
/**
* Returns a stream of code point values from this sequence. Any surrogate
* pairs encountered in the sequence are combined as if by {@linkplain
* Character#toCodePoint Character.toCodePoint} and the result is passed
* to the stream. Any other code units, including ordinary BMP characters,
* unpaired surrogates, and undefined code units, are zero-extended to
* {@code int} values which are then passed to the stream.
*
* <p>The stream binds to this sequence when the terminal stream operation
* commences (specifically, for mutable sequences the spliterator for the
* stream is <a href="../util/Spliterator.html#binding"><em>late-binding</em></a>).
* If the sequence is modified during that operation then the result is
* undefined.
*
* @return an IntStream of Unicode code points from this sequence
* @since 1.8
*/
public default IntStream codePoints() {
class CodePointIterator implements PrimitiveIterator.OfInt {
int cur = 0;
@Override
public void forEachRemaining(IntConsumer block) {
final int length = length();
int i = cur;
try {
while (i < length) {
char c1 = charAt(i++);
if (!Character.isHighSurrogate(c1) || i >= length) {
block.accept(c1);
} else {
char c2 = charAt(i);
if (Character.isLowSurrogate(c2)) {
i++;
block.accept(Character.toCodePoint(c1, c2));
} else {
block.accept(c1);
}
}
}
} finally {
cur = i;
}
}
public boolean hasNext() {
return cur < length();
}
public int nextInt() {
final int length = length();
if (cur >= length) {
throw new NoSuchElementException();
}
char c1 = charAt(cur++);
if (Character.isHighSurrogate(c1) && cur < length) {
char c2 = charAt(cur);
if (Character.isLowSurrogate(c2)) {
cur++;
return Character.toCodePoint(c1, c2);
}
}
return c1;
}
}
return StreamSupport.intStream(() ->
Spliterators.spliteratorUnknownSize(
new CodePointIterator(),
Spliterator.ORDERED),
Spliterator.ORDERED,
false);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2006, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
abstract class CharacterData {
abstract int getProperties(int ch);
abstract int getType(int ch);
abstract boolean isWhitespace(int ch);
abstract boolean isMirrored(int ch);
abstract boolean isJavaIdentifierStart(int ch);
abstract boolean isJavaIdentifierPart(int ch);
abstract boolean isUnicodeIdentifierStart(int ch);
abstract boolean isUnicodeIdentifierPart(int ch);
abstract boolean isIdentifierIgnorable(int ch);
abstract int toLowerCase(int ch);
abstract int toUpperCase(int ch);
abstract int toTitleCase(int ch);
abstract int digit(int ch, int radix);
abstract int getNumericValue(int ch);
abstract byte getDirectionality(int ch);
//need to implement for JSR204
int toUpperCaseEx(int ch) {
return toUpperCase(ch);
}
char[] toUpperCaseCharArray(int ch) {
return null;
}
boolean isOtherLowercase(int ch) {
return false;
}
boolean isOtherUppercase(int ch) {
return false;
}
boolean isOtherAlphabetic(int ch) {
return false;
}
boolean isIdeographic(int ch) {
return false;
}
// Character <= 0xff (basic latin) is handled by internal fast-path
// to avoid initializing large tables.
// Note: performance of this "fast-path" code may be sub-optimal
// in negative cases for some accessors due to complicated ranges.
// Should revisit after optimization of table initialization.
static final CharacterData of(int ch) {
if (ch >>> 8 == 0) { // fast-path
return CharacterDataLatin1.instance;
} else {
switch(ch >>> 16) { //plane 00-16
case(0):
return CharacterData00.instance;
case(1):
return CharacterData01.instance;
case(2):
return CharacterData02.instance;
case(14):
return CharacterData0E.instance;
case(15): // Private Use
case(16): // Private Use
return CharacterDataPrivateUse.instance;
default:
return CharacterDataUndefined.instance;
}
}
}
}

View file

@ -0,0 +1,180 @@
/*
* Copyright (c) 2010, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.io.DataInputStream;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.Arrays;
import java.util.Locale;
import java.util.zip.InflaterInputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
class CharacterName {
private static SoftReference<CharacterName> refCharName;
// codepoint -> bkIndex -> lookup -> offset/len
private final byte[] strPool;
private final int[] lookup; // code point -> offset/len in strPool
private final int[] bkIndices; // code point -> lookup index
// name -> hash -> hsIndices -> cpEntries -> code point
private final int[] cpEntries; // code points that have name in strPool
private final int[] hsIndices; // chain heads, hash indices into "cps"
private CharacterName() {
try (DataInputStream dis = new DataInputStream(new InflaterInputStream(
AccessController.doPrivileged(new PrivilegedAction<>() {
public InputStream run() {
return getClass().getResourceAsStream("uniName.dat");
}
})))) {
int total = dis.readInt();
int bkNum = dis.readInt();
int cpNum = dis.readInt();
int cpEnd = dis.readInt();
byte ba[] = new byte[cpEnd];
lookup = new int[bkNum * 256];
bkIndices = new int[(Character.MAX_CODE_POINT + 1) >> 8];
strPool = new byte[total - cpEnd];
cpEntries = new int[cpNum * 3];
hsIndices = new int[(cpNum / 2) | 1];
Arrays.fill(bkIndices, -1);
Arrays.fill(hsIndices, -1);
dis.readFully(ba);
dis.readFully(strPool);
int nameOff = 0;
int cpOff = 0;
int cp = 0;
int bk = -1;
int prevBk = -1; // prev bkNo;
int idx = 0;
int next = -1;
int hash = 0;
int hsh = 0;
do {
int len = ba[cpOff++] & 0xff;
if (len == 0) {
len = ba[cpOff++] & 0xff;
// always big-endian
cp = ((ba[cpOff++] & 0xff) << 16) |
((ba[cpOff++] & 0xff) << 8) |
((ba[cpOff++] & 0xff));
} else {
cp++;
}
// cp -> name
int hi = cp >> 8;
if (prevBk != hi) {
bk++;
bkIndices[hi] = bk;
prevBk = hi;
}
lookup[(bk << 8) + (cp & 0xff)] = (nameOff << 8) | len;
// name -> cp
hash = hashN(strPool, nameOff, len);
hsh = (hash & 0x7fffffff) % hsIndices.length;
next = hsIndices[hsh];
hsIndices[hsh] = idx;
idx = addCp(idx, hash, next, cp);
nameOff += len;
} while (cpOff < cpEnd);
} catch (Exception x) {
throw new InternalError(x.getMessage(), x);
}
}
private static final int hashN(byte[] a, int off, int len) {
int h = 1;
while (len-- > 0) {
h = 31 * h + a[off++];
}
return h;
}
private int addCp(int idx, int hash, int next, int cp) {
cpEntries[idx++] = hash;
cpEntries[idx++] = next;
cpEntries[idx++] = cp;
return idx;
}
private int getCpHash(int idx) { return cpEntries[idx]; }
private int getCpNext(int idx) { return cpEntries[idx + 1]; }
private int getCp(int idx) { return cpEntries[idx + 2]; }
public static CharacterName getInstance() {
SoftReference<CharacterName> ref = refCharName;
CharacterName cname = null;
if (ref == null || (cname = ref.get()) == null) {
cname = new CharacterName();
refCharName = new SoftReference<>(cname);
}
return cname;
}
public String getName(int cp) {
int off = 0;
int bk = bkIndices[cp >> 8];
if (bk == -1 || (off = lookup[(bk << 8) + (cp & 0xff)]) == 0)
return null;
@SuppressWarnings("deprecation")
String result = new String(strPool, 0, off >>> 8, off & 0xff); // ASCII
return result;
}
public int getCodePoint(String name) {
byte[] bname = name.getBytes(java.nio.charset.StandardCharsets.ISO_8859_1);
int hsh = hashN(bname, 0, bname.length);
int idx = hsIndices[(hsh & 0x7fffffff) % hsIndices.length];
while (idx != -1) {
if (getCpHash(idx) == hsh) {
int cp = getCp(idx);
int off = -1;
int bk = bkIndices[cp >> 8];
if (bk != -1 && (off = lookup[(bk << 8) + (cp & 0xff)]) != 0) {
int len = off & 0xff;
off = off >>> 8;
if (bname.length == len) {
int i = 0;
while (i < len && bname[i] == strPool[off++]) {
i++;
}
if (i == len) {
return cp;
}
}
}
}
idx = getCpNext(idx);
}
return -1;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 1994, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that the code has attempted to cast an object
* to a subclass of which it is not an instance. For example, the
* following code generates a <code>ClassCastException</code>:
* <blockquote><pre>
* Object x = new Integer(0);
* System.out.println((String)x);
* </pre></blockquote>
*
* @author unascribed
* @since 1.0
*/
public
class ClassCastException extends RuntimeException {
private static final long serialVersionUID = -9223365651070458532L;
/**
* Constructs a <code>ClassCastException</code> with no detail message.
*/
public ClassCastException() {
super();
}
/**
* Constructs a <code>ClassCastException</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public ClassCastException(String s) {
super(s);
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when the Java Virtual Machine detects a circularity in the
* superclass hierarchy of a class being loaded.
*
* @author unascribed
* @since 1.0
*/
public class ClassCircularityError extends LinkageError {
private static final long serialVersionUID = 1054362542914539689L;
/**
* Constructs a {@code ClassCircularityError} with no detail message.
*/
public ClassCircularityError() {
super();
}
/**
* Constructs a {@code ClassCircularityError} with the specified detail
* message.
*
* @param s
* The detail message
*/
public ClassCircularityError(String s) {
super(s);
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 1994, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when the Java Virtual Machine attempts to read a class
* file and determines that the file is malformed or otherwise cannot
* be interpreted as a class file.
*
* @author unascribed
* @since 1.0
*/
public
class ClassFormatError extends LinkageError {
private static final long serialVersionUID = -8420114879011949195L;
/**
* Constructs a <code>ClassFormatError</code> with no detail message.
*/
public ClassFormatError() {
super();
}
/**
* Constructs a <code>ClassFormatError</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public ClassFormatError(String s) {
super(s);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 1995, 2004, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when an application tries to load in a class through its
* string name using:
* <ul>
* <li>The <code>forName</code> method in class <code>Class</code>.
* <li>The <code>findSystemClass</code> method in class
* <code>ClassLoader</code> .
* <li>The <code>loadClass</code> method in class <code>ClassLoader</code>.
* </ul>
* <p>
* but no definition for the class with the specified name could be found.
*
* <p>As of release 1.4, this exception has been retrofitted to conform to
* the general purpose exception-chaining mechanism. The "optional exception
* that was raised while loading the class" that may be provided at
* construction time and accessed via the {@link #getException()} method is
* now known as the <i>cause</i>, and may be accessed via the {@link
* Throwable#getCause()} method, as well as the aforementioned "legacy method."
*
* @author unascribed
* @see java.lang.Class#forName(java.lang.String)
* @see java.lang.ClassLoader#findSystemClass(java.lang.String)
* @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
* @since 1.0
*/
public class ClassNotFoundException extends ReflectiveOperationException {
/**
* use serialVersionUID from JDK 1.1.X for interoperability
*/
private static final long serialVersionUID = 9176873029745254542L;
/**
* This field holds the exception ex if the
* ClassNotFoundException(String s, Throwable ex) constructor was
* used to instantiate the object
* @serial
* @since 1.2
*/
private Throwable ex;
/**
* Constructs a <code>ClassNotFoundException</code> with no detail message.
*/
public ClassNotFoundException() {
super((Throwable)null); // Disallow initCause
}
/**
* Constructs a <code>ClassNotFoundException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public ClassNotFoundException(String s) {
super(s, null); // Disallow initCause
}
/**
* Constructs a <code>ClassNotFoundException</code> with the
* specified detail message and optional exception that was
* raised while loading the class.
*
* @param s the detail message
* @param ex the exception that was raised while loading the class
* @since 1.2
*/
public ClassNotFoundException(String s, Throwable ex) {
super(s, null); // Disallow initCause
this.ex = ex;
}
/**
* Returns the exception that was raised if an error occurred while
* attempting to load the class. Otherwise, returns {@code null}.
*
* <p>This method predates the general-purpose exception chaining facility.
* The {@link Throwable#getCause()} method is now the preferred means of
* obtaining this information.
*
* @return the <code>Exception</code> that was raised while loading a class
* @since 1.2
*/
public Throwable getException() {
return ex;
}
/**
* Returns the cause of this exception (the exception that was raised
* if an error occurred while attempting to load the class; otherwise
* {@code null}).
*
* @return the cause of this exception.
* @since 1.4
*/
public Throwable getCause() {
return ex;
}
}

View file

@ -0,0 +1,757 @@
/*
* Copyright (c) 2010, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.util.WeakHashMap;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
import static java.lang.ClassValue.ClassValueMap.probeHomeLocation;
import static java.lang.ClassValue.ClassValueMap.probeBackupLocations;
/**
* Lazily associate a computed value with (potentially) every type.
* For example, if a dynamic language needs to construct a message dispatch
* table for each class encountered at a message send call site,
* it can use a {@code ClassValue} to cache information needed to
* perform the message send quickly, for each class encountered.
* @author John Rose, JSR 292 EG
* @since 1.7
*/
public abstract class ClassValue<T> {
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
protected ClassValue() {
}
/**
* Computes the given class's derived value for this {@code ClassValue}.
* <p>
* This method will be invoked within the first thread that accesses
* the value with the {@link #get get} method.
* <p>
* Normally, this method is invoked at most once per class,
* but it may be invoked again if there has been a call to
* {@link #remove remove}.
* <p>
* If this method throws an exception, the corresponding call to {@code get}
* will terminate abnormally with that exception, and no class value will be recorded.
*
* @param type the type whose class value must be computed
* @return the newly computed value associated with this {@code ClassValue}, for the given class or interface
* @see #get
* @see #remove
*/
protected abstract T computeValue(Class<?> type);
/**
* Returns the value for the given class.
* If no value has yet been computed, it is obtained by
* an invocation of the {@link #computeValue computeValue} method.
* <p>
* The actual installation of the value on the class
* is performed atomically.
* At that point, if several racing threads have
* computed values, one is chosen, and returned to
* all the racing threads.
* <p>
* The {@code type} parameter is typically a class, but it may be any type,
* such as an interface, a primitive type (like {@code int.class}), or {@code void.class}.
* <p>
* In the absence of {@code remove} calls, a class value has a simple
* state diagram: uninitialized and initialized.
* When {@code remove} calls are made,
* the rules for value observation are more complex.
* See the documentation for {@link #remove remove} for more information.
*
* @param type the type whose class value must be computed or retrieved
* @return the current value associated with this {@code ClassValue}, for the given class or interface
* @throws NullPointerException if the argument is null
* @see #remove
* @see #computeValue
*/
public T get(Class<?> type) {
// non-racing this.hashCodeForCache : final int
Entry<?>[] cache;
Entry<T> e = probeHomeLocation(cache = getCacheCarefully(type), this);
// racing e : current value <=> stale value from current cache or from stale cache
// invariant: e is null or an Entry with readable Entry.version and Entry.value
if (match(e))
// invariant: No false positive matches. False negatives are OK if rare.
// The key fact that makes this work: if this.version == e.version,
// then this thread has a right to observe (final) e.value.
return e.value();
// The fast path can fail for any of these reasons:
// 1. no entry has been computed yet
// 2. hash code collision (before or after reduction mod cache.length)
// 3. an entry has been removed (either on this type or another)
// 4. the GC has somehow managed to delete e.version and clear the reference
return getFromBackup(cache, type);
}
/**
* Removes the associated value for the given class.
* If this value is subsequently {@linkplain #get read} for the same class,
* its value will be reinitialized by invoking its {@link #computeValue computeValue} method.
* This may result in an additional invocation of the
* {@code computeValue} method for the given class.
* <p>
* In order to explain the interaction between {@code get} and {@code remove} calls,
* we must model the state transitions of a class value to take into account
* the alternation between uninitialized and initialized states.
* To do this, number these states sequentially from zero, and note that
* uninitialized (or removed) states are numbered with even numbers,
* while initialized (or re-initialized) states have odd numbers.
* <p>
* When a thread {@code T} removes a class value in state {@code 2N},
* nothing happens, since the class value is already uninitialized.
* Otherwise, the state is advanced atomically to {@code 2N+1}.
* <p>
* When a thread {@code T} queries a class value in state {@code 2N},
* the thread first attempts to initialize the class value to state {@code 2N+1}
* by invoking {@code computeValue} and installing the resulting value.
* <p>
* When {@code T} attempts to install the newly computed value,
* if the state is still at {@code 2N}, the class value will be initialized
* with the computed value, advancing it to state {@code 2N+1}.
* <p>
* Otherwise, whether the new state is even or odd,
* {@code T} will discard the newly computed value
* and retry the {@code get} operation.
* <p>
* Discarding and retrying is an important proviso,
* since otherwise {@code T} could potentially install
* a disastrously stale value. For example:
* <ul>
* <li>{@code T} calls {@code CV.get(C)} and sees state {@code 2N}
* <li>{@code T} quickly computes a time-dependent value {@code V0} and gets ready to install it
* <li>{@code T} is hit by an unlucky paging or scheduling event, and goes to sleep for a long time
* <li>...meanwhile, {@code T2} also calls {@code CV.get(C)} and sees state {@code 2N}
* <li>{@code T2} quickly computes a similar time-dependent value {@code V1} and installs it on {@code CV.get(C)}
* <li>{@code T2} (or a third thread) then calls {@code CV.remove(C)}, undoing {@code T2}'s work
* <li> the previous actions of {@code T2} are repeated several times
* <li> also, the relevant computed values change over time: {@code V1}, {@code V2}, ...
* <li>...meanwhile, {@code T} wakes up and attempts to install {@code V0}; <em>this must fail</em>
* </ul>
* We can assume in the above scenario that {@code CV.computeValue} uses locks to properly
* observe the time-dependent states as it computes {@code V1}, etc.
* This does not remove the threat of a stale value, since there is a window of time
* between the return of {@code computeValue} in {@code T} and the installation
* of the new value. No user synchronization is possible during this time.
*
* @param type the type whose class value must be removed
* @throws NullPointerException if the argument is null
*/
public void remove(Class<?> type) {
ClassValueMap map = getMap(type);
map.removeEntry(this);
}
// Possible functionality for JSR 292 MR 1
/*public*/ void put(Class<?> type, T value) {
ClassValueMap map = getMap(type);
map.changeEntry(this, value);
}
/// --------
/// Implementation...
/// --------
/** Return the cache, if it exists, else a dummy empty cache. */
private static Entry<?>[] getCacheCarefully(Class<?> type) {
// racing type.classValueMap{.cacheArray} : null => new Entry[X] <=> new Entry[Y]
ClassValueMap map = type.classValueMap;
if (map == null) return EMPTY_CACHE;
Entry<?>[] cache = map.getCache();
return cache;
// invariant: returned value is safe to dereference and check for an Entry
}
/** Initial, one-element, empty cache used by all Class instances. Must never be filled. */
private static final Entry<?>[] EMPTY_CACHE = { null };
/**
* Slow tail of ClassValue.get to retry at nearby locations in the cache,
* or take a slow lock and check the hash table.
* Called only if the first probe was empty or a collision.
* This is a separate method, so compilers can process it independently.
*/
private T getFromBackup(Entry<?>[] cache, Class<?> type) {
Entry<T> e = probeBackupLocations(cache, this);
if (e != null)
return e.value();
return getFromHashMap(type);
}
// Hack to suppress warnings on the (T) cast, which is a no-op.
@SuppressWarnings("unchecked")
Entry<T> castEntry(Entry<?> e) { return (Entry<T>) e; }
/** Called when the fast path of get fails, and cache reprobe also fails.
*/
private T getFromHashMap(Class<?> type) {
// The fail-safe recovery is to fall back to the underlying classValueMap.
ClassValueMap map = getMap(type);
for (;;) {
Entry<T> e = map.startEntry(this);
if (!e.isPromise())
return e.value();
try {
// Try to make a real entry for the promised version.
e = makeEntry(e.version(), computeValue(type));
} finally {
// Whether computeValue throws or returns normally,
// be sure to remove the empty entry.
e = map.finishEntry(this, e);
}
if (e != null)
return e.value();
// else try again, in case a racing thread called remove (so e == null)
}
}
/** Check that e is non-null, matches this ClassValue, and is live. */
boolean match(Entry<?> e) {
// racing e.version : null (blank) => unique Version token => null (GC-ed version)
// non-racing this.version : v1 => v2 => ... (updates are read faithfully from volatile)
return (e != null && e.get() == this.version);
// invariant: No false positives on version match. Null is OK for false negative.
// invariant: If version matches, then e.value is readable (final set in Entry.<init>)
}
/** Internal hash code for accessing Class.classValueMap.cacheArray. */
final int hashCodeForCache = nextHashCode.getAndAdd(HASH_INCREMENT) & HASH_MASK;
/** Value stream for hashCodeForCache. See similar structure in ThreadLocal. */
private static final AtomicInteger nextHashCode = new AtomicInteger();
/** Good for power-of-two tables. See similar structure in ThreadLocal. */
private static final int HASH_INCREMENT = 0x61c88647;
/** Mask a hash code to be positive but not too large, to prevent wraparound. */
static final int HASH_MASK = (-1 >>> 2);
/**
* Private key for retrieval of this object from ClassValueMap.
*/
static class Identity {
}
/**
* This ClassValue's identity, expressed as an opaque object.
* The main object {@code ClassValue.this} is incorrect since
* subclasses may override {@code ClassValue.equals}, which
* could confuse keys in the ClassValueMap.
*/
final Identity identity = new Identity();
/**
* Current version for retrieving this class value from the cache.
* Any number of computeValue calls can be cached in association with one version.
* But the version changes when a remove (on any type) is executed.
* A version change invalidates all cache entries for the affected ClassValue,
* by marking them as stale. Stale cache entries do not force another call
* to computeValue, but they do require a synchronized visit to a backing map.
* <p>
* All user-visible state changes on the ClassValue take place under
* a lock inside the synchronized methods of ClassValueMap.
* Readers (of ClassValue.get) are notified of such state changes
* when this.version is bumped to a new token.
* This variable must be volatile so that an unsynchronized reader
* will receive the notification without delay.
* <p>
* If version were not volatile, one thread T1 could persistently hold onto
* a stale value this.value == V1, while another thread T2 advances
* (under a lock) to this.value == V2. This will typically be harmless,
* but if T1 and T2 interact causally via some other channel, such that
* T1's further actions are constrained (in the JMM) to happen after
* the V2 event, then T1's observation of V1 will be an error.
* <p>
* The practical effect of making this.version be volatile is that it cannot
* be hoisted out of a loop (by an optimizing JIT) or otherwise cached.
* Some machines may also require a barrier instruction to execute
* before this.version.
*/
private volatile Version<T> version = new Version<>(this);
Version<T> version() { return version; }
void bumpVersion() { version = new Version<>(this); }
static class Version<T> {
private final ClassValue<T> classValue;
private final Entry<T> promise = new Entry<>(this);
Version(ClassValue<T> classValue) { this.classValue = classValue; }
ClassValue<T> classValue() { return classValue; }
Entry<T> promise() { return promise; }
boolean isLive() { return classValue.version() == this; }
}
/** One binding of a value to a class via a ClassValue.
* States are:<ul>
* <li> promise if value == Entry.this
* <li> else dead if version == null
* <li> else stale if version != classValue.version
* <li> else live </ul>
* Promises are never put into the cache; they only live in the
* backing map while a computeValue call is in flight.
* Once an entry goes stale, it can be reset at any time
* into the dead state.
*/
static class Entry<T> extends WeakReference<Version<T>> {
final Object value; // usually of type T, but sometimes (Entry)this
Entry(Version<T> version, T value) {
super(version);
this.value = value; // for a regular entry, value is of type T
}
private void assertNotPromise() { assert(!isPromise()); }
/** For creating a promise. */
Entry(Version<T> version) {
super(version);
this.value = this; // for a promise, value is not of type T, but Entry!
}
/** Fetch the value. This entry must not be a promise. */
@SuppressWarnings("unchecked") // if !isPromise, type is T
T value() { assertNotPromise(); return (T) value; }
boolean isPromise() { return value == this; }
Version<T> version() { return get(); }
ClassValue<T> classValueOrNull() {
Version<T> v = version();
return (v == null) ? null : v.classValue();
}
boolean isLive() {
Version<T> v = version();
if (v == null) return false;
if (v.isLive()) return true;
clear();
return false;
}
Entry<T> refreshVersion(Version<T> v2) {
assertNotPromise();
@SuppressWarnings("unchecked") // if !isPromise, type is T
Entry<T> e2 = new Entry<>(v2, (T) value);
clear();
// value = null -- caller must drop
return e2;
}
static final Entry<?> DEAD_ENTRY = new Entry<>(null, null);
}
/** Return the backing map associated with this type. */
private static ClassValueMap getMap(Class<?> type) {
// racing type.classValueMap : null (blank) => unique ClassValueMap
// if a null is observed, a map is created (lazily, synchronously, uniquely)
// all further access to that map is synchronized
ClassValueMap map = type.classValueMap;
if (map != null) return map;
return initializeMap(type);
}
private static final Object CRITICAL_SECTION = new Object();
private static ClassValueMap initializeMap(Class<?> type) {
ClassValueMap map;
synchronized (CRITICAL_SECTION) { // private object to avoid deadlocks
// happens about once per type
if ((map = type.classValueMap) == null)
type.classValueMap = map = new ClassValueMap();
}
return map;
}
static <T> Entry<T> makeEntry(Version<T> explicitVersion, T value) {
// Note that explicitVersion might be different from this.version.
return new Entry<>(explicitVersion, value);
// As soon as the Entry is put into the cache, the value will be
// reachable via a data race (as defined by the Java Memory Model).
// This race is benign, assuming the value object itself can be
// read safely by multiple threads. This is up to the user.
//
// The entry and version fields themselves can be safely read via
// a race because they are either final or have controlled states.
// If the pointer from the entry to the version is still null,
// or if the version goes immediately dead and is nulled out,
// the reader will take the slow path and retry under a lock.
}
// The following class could also be top level and non-public:
/** A backing map for all ClassValues.
* Gives a fully serialized "true state" for each pair (ClassValue cv, Class type).
* Also manages an unserialized fast-path cache.
*/
static class ClassValueMap extends WeakHashMap<ClassValue.Identity, Entry<?>> {
private Entry<?>[] cacheArray;
private int cacheLoad, cacheLoadLimit;
/** Number of entries initially allocated to each type when first used with any ClassValue.
* It would be pointless to make this much smaller than the Class and ClassValueMap objects themselves.
* Must be a power of 2.
*/
private static final int INITIAL_ENTRIES = 32;
/** Build a backing map for ClassValues.
* Also, create an empty cache array and install it on the class.
*/
ClassValueMap() {
sizeCache(INITIAL_ENTRIES);
}
Entry<?>[] getCache() { return cacheArray; }
/** Initiate a query. Store a promise (placeholder) if there is no value yet. */
synchronized
<T> Entry<T> startEntry(ClassValue<T> classValue) {
@SuppressWarnings("unchecked") // one map has entries for all value types <T>
Entry<T> e = (Entry<T>) get(classValue.identity);
Version<T> v = classValue.version();
if (e == null) {
e = v.promise();
// The presence of a promise means that a value is pending for v.
// Eventually, finishEntry will overwrite the promise.
put(classValue.identity, e);
// Note that the promise is never entered into the cache!
return e;
} else if (e.isPromise()) {
// Somebody else has asked the same question.
// Let the races begin!
if (e.version() != v) {
e = v.promise();
put(classValue.identity, e);
}
return e;
} else {
// there is already a completed entry here; report it
if (e.version() != v) {
// There is a stale but valid entry here; make it fresh again.
// Once an entry is in the hash table, we don't care what its version is.
e = e.refreshVersion(v);
put(classValue.identity, e);
}
// Add to the cache, to enable the fast path, next time.
checkCacheLoad();
addToCache(classValue, e);
return e;
}
}
/** Finish a query. Overwrite a matching placeholder. Drop stale incoming values. */
synchronized
<T> Entry<T> finishEntry(ClassValue<T> classValue, Entry<T> e) {
@SuppressWarnings("unchecked") // one map has entries for all value types <T>
Entry<T> e0 = (Entry<T>) get(classValue.identity);
if (e == e0) {
// We can get here during exception processing, unwinding from computeValue.
assert(e.isPromise());
remove(classValue.identity);
return null;
} else if (e0 != null && e0.isPromise() && e0.version() == e.version()) {
// If e0 matches the intended entry, there has not been a remove call
// between the previous startEntry and now. So now overwrite e0.
Version<T> v = classValue.version();
if (e.version() != v)
e = e.refreshVersion(v);
put(classValue.identity, e);
// Add to the cache, to enable the fast path, next time.
checkCacheLoad();
addToCache(classValue, e);
return e;
} else {
// Some sort of mismatch; caller must try again.
return null;
}
}
/** Remove an entry. */
synchronized
void removeEntry(ClassValue<?> classValue) {
Entry<?> e = remove(classValue.identity);
if (e == null) {
// Uninitialized, and no pending calls to computeValue. No change.
} else if (e.isPromise()) {
// State is uninitialized, with a pending call to finishEntry.
// Since remove is a no-op in such a state, keep the promise
// by putting it back into the map.
put(classValue.identity, e);
} else {
// In an initialized state. Bump forward, and de-initialize.
classValue.bumpVersion();
// Make all cache elements for this guy go stale.
removeStaleEntries(classValue);
}
}
/** Change the value for an entry. */
synchronized
<T> void changeEntry(ClassValue<T> classValue, T value) {
@SuppressWarnings("unchecked") // one map has entries for all value types <T>
Entry<T> e0 = (Entry<T>) get(classValue.identity);
Version<T> version = classValue.version();
if (e0 != null) {
if (e0.version() == version && e0.value() == value)
// no value change => no version change needed
return;
classValue.bumpVersion();
removeStaleEntries(classValue);
}
Entry<T> e = makeEntry(version, value);
put(classValue.identity, e);
// Add to the cache, to enable the fast path, next time.
checkCacheLoad();
addToCache(classValue, e);
}
/// --------
/// Cache management.
/// --------
// Statics do not need synchronization.
/** Load the cache entry at the given (hashed) location. */
static Entry<?> loadFromCache(Entry<?>[] cache, int i) {
// non-racing cache.length : constant
// racing cache[i & (mask)] : null <=> Entry
return cache[i & (cache.length-1)];
// invariant: returned value is null or well-constructed (ready to match)
}
/** Look in the cache, at the home location for the given ClassValue. */
static <T> Entry<T> probeHomeLocation(Entry<?>[] cache, ClassValue<T> classValue) {
return classValue.castEntry(loadFromCache(cache, classValue.hashCodeForCache));
}
/** Given that first probe was a collision, retry at nearby locations. */
static <T> Entry<T> probeBackupLocations(Entry<?>[] cache, ClassValue<T> classValue) {
if (PROBE_LIMIT <= 0) return null;
// Probe the cache carefully, in a range of slots.
int mask = (cache.length-1);
int home = (classValue.hashCodeForCache & mask);
Entry<?> e2 = cache[home]; // victim, if we find the real guy
if (e2 == null) {
return null; // if nobody is at home, no need to search nearby
}
// assume !classValue.match(e2), but do not assert, because of races
int pos2 = -1;
for (int i = home + 1; i < home + PROBE_LIMIT; i++) {
Entry<?> e = cache[i & mask];
if (e == null) {
break; // only search within non-null runs
}
if (classValue.match(e)) {
// relocate colliding entry e2 (from cache[home]) to first empty slot
cache[home] = e;
if (pos2 >= 0) {
cache[i & mask] = Entry.DEAD_ENTRY;
} else {
pos2 = i;
}
cache[pos2 & mask] = ((entryDislocation(cache, pos2, e2) < PROBE_LIMIT)
? e2 // put e2 here if it fits
: Entry.DEAD_ENTRY);
return classValue.castEntry(e);
}
// Remember first empty slot, if any:
if (!e.isLive() && pos2 < 0) pos2 = i;
}
return null;
}
/** How far out of place is e? */
private static int entryDislocation(Entry<?>[] cache, int pos, Entry<?> e) {
ClassValue<?> cv = e.classValueOrNull();
if (cv == null) return 0; // entry is not live!
int mask = (cache.length-1);
return (pos - cv.hashCodeForCache) & mask;
}
/// --------
/// Below this line all functions are private, and assume synchronized access.
/// --------
private void sizeCache(int length) {
assert((length & (length-1)) == 0); // must be power of 2
cacheLoad = 0;
cacheLoadLimit = (int) ((double) length * CACHE_LOAD_LIMIT / 100);
cacheArray = new Entry<?>[length];
}
/** Make sure the cache load stays below its limit, if possible. */
private void checkCacheLoad() {
if (cacheLoad >= cacheLoadLimit) {
reduceCacheLoad();
}
}
private void reduceCacheLoad() {
removeStaleEntries();
if (cacheLoad < cacheLoadLimit)
return; // win
Entry<?>[] oldCache = getCache();
if (oldCache.length > HASH_MASK)
return; // lose
sizeCache(oldCache.length * 2);
for (Entry<?> e : oldCache) {
if (e != null && e.isLive()) {
addToCache(e);
}
}
}
/** Remove stale entries in the given range.
* Should be executed under a Map lock.
*/
private void removeStaleEntries(Entry<?>[] cache, int begin, int count) {
if (PROBE_LIMIT <= 0) return;
int mask = (cache.length-1);
int removed = 0;
for (int i = begin; i < begin + count; i++) {
Entry<?> e = cache[i & mask];
if (e == null || e.isLive())
continue; // skip null and live entries
Entry<?> replacement = null;
if (PROBE_LIMIT > 1) {
// avoid breaking up a non-null run
replacement = findReplacement(cache, i);
}
cache[i & mask] = replacement;
if (replacement == null) removed += 1;
}
cacheLoad = Math.max(0, cacheLoad - removed);
}
/** Clearing a cache slot risks disconnecting following entries
* from the head of a non-null run, which would allow them
* to be found via reprobes. Find an entry after cache[begin]
* to plug into the hole, or return null if none is needed.
*/
private Entry<?> findReplacement(Entry<?>[] cache, int home1) {
Entry<?> replacement = null;
int haveReplacement = -1, replacementPos = 0;
int mask = (cache.length-1);
for (int i2 = home1 + 1; i2 < home1 + PROBE_LIMIT; i2++) {
Entry<?> e2 = cache[i2 & mask];
if (e2 == null) break; // End of non-null run.
if (!e2.isLive()) continue; // Doomed anyway.
int dis2 = entryDislocation(cache, i2, e2);
if (dis2 == 0) continue; // e2 already optimally placed
int home2 = i2 - dis2;
if (home2 <= home1) {
// e2 can replace entry at cache[home1]
if (home2 == home1) {
// Put e2 exactly where he belongs.
haveReplacement = 1;
replacementPos = i2;
replacement = e2;
} else if (haveReplacement <= 0) {
haveReplacement = 0;
replacementPos = i2;
replacement = e2;
}
// And keep going, so we can favor larger dislocations.
}
}
if (haveReplacement >= 0) {
if (cache[(replacementPos+1) & mask] != null) {
// Be conservative, to avoid breaking up a non-null run.
cache[replacementPos & mask] = (Entry<?>) Entry.DEAD_ENTRY;
} else {
cache[replacementPos & mask] = null;
cacheLoad -= 1;
}
}
return replacement;
}
/** Remove stale entries in the range near classValue. */
private void removeStaleEntries(ClassValue<?> classValue) {
removeStaleEntries(getCache(), classValue.hashCodeForCache, PROBE_LIMIT);
}
/** Remove all stale entries, everywhere. */
private void removeStaleEntries() {
Entry<?>[] cache = getCache();
removeStaleEntries(cache, 0, cache.length + PROBE_LIMIT - 1);
}
/** Add the given entry to the cache, in its home location, unless it is out of date. */
private <T> void addToCache(Entry<T> e) {
ClassValue<T> classValue = e.classValueOrNull();
if (classValue != null)
addToCache(classValue, e);
}
/** Add the given entry to the cache, in its home location. */
private <T> void addToCache(ClassValue<T> classValue, Entry<T> e) {
if (PROBE_LIMIT <= 0) return; // do not fill cache
// Add e to the cache.
Entry<?>[] cache = getCache();
int mask = (cache.length-1);
int home = classValue.hashCodeForCache & mask;
Entry<?> e2 = placeInCache(cache, home, e, false);
if (e2 == null) return; // done
if (PROBE_LIMIT > 1) {
// try to move e2 somewhere else in his probe range
int dis2 = entryDislocation(cache, home, e2);
int home2 = home - dis2;
for (int i2 = home2; i2 < home2 + PROBE_LIMIT; i2++) {
if (placeInCache(cache, i2 & mask, e2, true) == null) {
return;
}
}
}
// Note: At this point, e2 is just dropped from the cache.
}
/** Store the given entry. Update cacheLoad, and return any live victim.
* 'Gently' means return self rather than dislocating a live victim.
*/
private Entry<?> placeInCache(Entry<?>[] cache, int pos, Entry<?> e, boolean gently) {
Entry<?> e2 = overwrittenEntry(cache[pos]);
if (gently && e2 != null) {
// do not overwrite a live entry
return e;
} else {
cache[pos] = e;
return e2;
}
}
/** Note an entry that is about to be overwritten.
* If it is not live, quietly replace it by null.
* If it is an actual null, increment cacheLoad,
* because the caller is going to store something
* in its place.
*/
private <T> Entry<T> overwrittenEntry(Entry<T> e2) {
if (e2 == null) cacheLoad += 1;
else if (e2.isLive()) return e2;
return null;
}
/** Percent loading of cache before resize. */
private static final int CACHE_LOAD_LIMIT = 67; // 0..100
/** Maximum number of probes to attempt. */
private static final int PROBE_LIMIT = 6; // 1..
// N.B. Set PROBE_LIMIT=0 to disable all fast paths.
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that the <code>clone</code> method in class
* <code>Object</code> has been called to clone an object, but that
* the object's class does not implement the <code>Cloneable</code>
* interface.
* <p>
* Applications that override the <code>clone</code> method can also
* throw this exception to indicate that an object could not or
* should not be cloned.
*
* @author unascribed
* @see java.lang.Cloneable
* @see java.lang.Object#clone()
* @since 1.0
*/
public
class CloneNotSupportedException extends Exception {
private static final long serialVersionUID = 5195511250079656443L;
/**
* Constructs a <code>CloneNotSupportedException</code> with no
* detail message.
*/
public CloneNotSupportedException() {
super();
}
/**
* Constructs a <code>CloneNotSupportedException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public CloneNotSupportedException(String s) {
super(s);
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 1995, 2004, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* A class implements the <code>Cloneable</code> interface to
* indicate to the {@link java.lang.Object#clone()} method that it
* is legal for that method to make a
* field-for-field copy of instances of that class.
* <p>
* Invoking Object's clone method on an instance that does not implement the
* <code>Cloneable</code> interface results in the exception
* <code>CloneNotSupportedException</code> being thrown.
* <p>
* By convention, classes that implement this interface should override
* {@code Object.clone} (which is protected) with a public method.
* See {@link java.lang.Object#clone()} for details on overriding this
* method.
* <p>
* Note that this interface does <i>not</i> contain the {@code clone} method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface. Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.
*
* @author unascribed
* @see java.lang.CloneNotSupportedException
* @see java.lang.Object#clone()
* @since 1.0
*/
public interface Cloneable {
}

View file

@ -0,0 +1,138 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.util.*;
/**
* This interface imposes a total ordering on the objects of each class that
* implements it. This ordering is referred to as the class's <i>natural
* ordering</i>, and the class's {@code compareTo} method is referred to as
* its <i>natural comparison method</i>.<p>
*
* Lists (and arrays) of objects that implement this interface can be sorted
* automatically by {@link Collections#sort(List) Collections.sort} (and
* {@link Arrays#sort(Object[]) Arrays.sort}). Objects that implement this
* interface can be used as keys in a {@linkplain SortedMap sorted map} or as
* elements in a {@linkplain SortedSet sorted set}, without the need to
* specify a {@linkplain Comparator comparator}.<p>
*
* The natural ordering for a class {@code C} is said to be <i>consistent
* with equals</i> if and only if {@code e1.compareTo(e2) == 0} has
* the same boolean value as {@code e1.equals(e2)} for every
* {@code e1} and {@code e2} of class {@code C}. Note that {@code null}
* is not an instance of any class, and {@code e.compareTo(null)} should
* throw a {@code NullPointerException} even though {@code e.equals(null)}
* returns {@code false}.<p>
*
* It is strongly recommended (though not required) that natural orderings be
* consistent with equals. This is so because sorted sets (and sorted maps)
* without explicit comparators behave "strangely" when they are used with
* elements (or keys) whose natural ordering is inconsistent with equals. In
* particular, such a sorted set (or sorted map) violates the general contract
* for set (or map), which is defined in terms of the {@code equals}
* method.<p>
*
* For example, if one adds two keys {@code a} and {@code b} such that
* {@code (!a.equals(b) && a.compareTo(b) == 0)} to a sorted
* set that does not use an explicit comparator, the second {@code add}
* operation returns false (and the size of the sorted set does not increase)
* because {@code a} and {@code b} are equivalent from the sorted set's
* perspective.<p>
*
* Virtually all Java core classes that implement {@code Comparable} have natural
* orderings that are consistent with equals. One exception is
* {@code java.math.BigDecimal}, whose natural ordering equates
* {@code BigDecimal} objects with equal values and different precisions
* (such as 4.0 and 4.00).<p>
*
* For the mathematically inclined, the <i>relation</i> that defines
* the natural ordering on a given class C is:<pre>{@code
* {(x, y) such that x.compareTo(y) <= 0}.
* }</pre> The <i>quotient</i> for this total order is: <pre>{@code
* {(x, y) such that x.compareTo(y) == 0}.
* }</pre>
*
* It follows immediately from the contract for {@code compareTo} that the
* quotient is an <i>equivalence relation</i> on {@code C}, and that the
* natural ordering is a <i>total order</i> on {@code C}. When we say that a
* class's natural ordering is <i>consistent with equals</i>, we mean that the
* quotient for the natural ordering is the equivalence relation defined by
* the class's {@link Object#equals(Object) equals(Object)} method:<pre>
* {(x, y) such that x.equals(y)}. </pre><p>
*
* This interface is a member of the
* <a href="{@docRoot}/java/util/package-summary.html#CollectionsFramework">
* Java Collections Framework</a>.
*
* @param <T> the type of objects that this object may be compared to
*
* @author Josh Bloch
* @see java.util.Comparator
* @since 1.2
*/
public interface Comparable<T> {
/**
* Compares this object with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
*
* <p>The implementor must ensure
* {@code sgn(x.compareTo(y)) == -sgn(y.compareTo(x))}
* for all {@code x} and {@code y}. (This
* implies that {@code x.compareTo(y)} must throw an exception iff
* {@code y.compareTo(x)} throws an exception.)
*
* <p>The implementor must also ensure that the relation is transitive:
* {@code (x.compareTo(y) > 0 && y.compareTo(z) > 0)} implies
* {@code x.compareTo(z) > 0}.
*
* <p>Finally, the implementor must ensure that {@code x.compareTo(y)==0}
* implies that {@code sgn(x.compareTo(z)) == sgn(y.compareTo(z))}, for
* all {@code z}.
*
* <p>It is strongly recommended, but <i>not</i> strictly required that
* {@code (x.compareTo(y)==0) == (x.equals(y))}. Generally speaking, any
* class that implements the {@code Comparable} interface and violates
* this condition should clearly indicate this fact. The recommended
* language is "Note: this class has a natural ordering that is
* inconsistent with equals."
*
* <p>In the foregoing description, the notation
* {@code sgn(}<i>expression</i>{@code )} designates the mathematical
* <i>signum</i> function, which is defined to return one of {@code -1},
* {@code 0}, or {@code 1} according to whether the value of
* <i>expression</i> is negative, zero, or positive, respectively.
*
* @param o the object to be compared.
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
*
* @throws NullPointerException if the specified object is null
* @throws ClassCastException if the specified object's type prevents it
* from being compared to this object.
*/
public int compareTo(T o);
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 1995, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* The {@code Compiler} class is provided to support Java-to-native-code
* compilers and related services. By design, the {@code Compiler} class does
* nothing; it serves as a placeholder for a JIT compiler implementation.
* If no compiler is available, these methods do nothing.
*
* @deprecated JIT compilers and their technologies vary too widely to
* be controlled effectively by a standardized interface. As such, many
* JIT compiler implementations ignore this interface, and are instead
* controllable by implementation-specific mechanisms such as command-line
* options. This class is subject to removal in a future version of Java SE.
*
* @author Frank Yellin
* @since 1.0
*/
@Deprecated(since="9", forRemoval=true)
public final class Compiler {
private Compiler() {} // don't make instances
/**
* Compiles the specified class.
*
* @param clazz
* A class
*
* @return {@code true} if the compilation succeeded; {@code false} if the
* compilation failed or no compiler is available
*
* @throws NullPointerException
* If {@code clazz} is {@code null}
*/
public static boolean compileClass(Class<?> clazz) {
return false;
}
/**
* Compiles all classes whose name matches the specified string.
*
* @param string
* The name of the classes to compile
*
* @return {@code true} if the compilation succeeded; {@code false} if the
* compilation failed or no compiler is available
*
* @throws NullPointerException
* If {@code string} is {@code null}
*/
public static boolean compileClasses(String string) {
return false;
}
/**
* Examines the argument type and its fields and perform some documented
* operation. No specific operations are required.
*
* @param any
* An argument
*
* @return A compiler-specific value, or {@code null} if no compiler is
* available
*
* @throws NullPointerException
* If {@code any} is {@code null}
*/
public static Object command(Object any) {
return null;
}
/**
* Cause the Compiler to resume operation.
*/
public static void enable() { }
/**
* Cause the Compiler to cease operation.
*/
public static void disable() { }
}

View file

@ -0,0 +1,471 @@
/*
* Copyright (c) 2003, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.text.BreakIterator;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import sun.text.Normalizer;
/**
* This is a utility class for <code>String.toLowerCase()</code> and
* <code>String.toUpperCase()</code>, that handles special casing with
* conditions. In other words, it handles the mappings with conditions
* that are defined in
* <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">Special
* Casing Properties</a> file.
* <p>
* Note that the unconditional case mappings (including 1:M mappings)
* are handled in <code>Character.toLower/UpperCase()</code>.
*/
final class ConditionalSpecialCasing {
// context conditions.
static final int FINAL_CASED = 1;
static final int AFTER_SOFT_DOTTED = 2;
static final int MORE_ABOVE = 3;
static final int AFTER_I = 4;
static final int NOT_BEFORE_DOT = 5;
// combining class definitions
static final int COMBINING_CLASS_ABOVE = 230;
// Special case mapping entries
static Entry[] entry = {
//# ================================================================================
//# Conditional mappings
//# ================================================================================
new Entry(0x03A3, new char[]{0x03C2}, new char[]{0x03A3}, null, FINAL_CASED), // # GREEK CAPITAL LETTER SIGMA
new Entry(0x0130, new char[]{0x0069, 0x0307}, new char[]{0x0130}, null, 0), // # LATIN CAPITAL LETTER I WITH DOT ABOVE
//# ================================================================================
//# Locale-sensitive mappings
//# ================================================================================
//# Lithuanian
new Entry(0x0307, new char[]{0x0307}, new char[]{}, "lt", AFTER_SOFT_DOTTED), // # COMBINING DOT ABOVE
new Entry(0x0049, new char[]{0x0069, 0x0307}, new char[]{0x0049}, "lt", MORE_ABOVE), // # LATIN CAPITAL LETTER I
new Entry(0x004A, new char[]{0x006A, 0x0307}, new char[]{0x004A}, "lt", MORE_ABOVE), // # LATIN CAPITAL LETTER J
new Entry(0x012E, new char[]{0x012F, 0x0307}, new char[]{0x012E}, "lt", MORE_ABOVE), // # LATIN CAPITAL LETTER I WITH OGONEK
new Entry(0x00CC, new char[]{0x0069, 0x0307, 0x0300}, new char[]{0x00CC}, "lt", 0), // # LATIN CAPITAL LETTER I WITH GRAVE
new Entry(0x00CD, new char[]{0x0069, 0x0307, 0x0301}, new char[]{0x00CD}, "lt", 0), // # LATIN CAPITAL LETTER I WITH ACUTE
new Entry(0x0128, new char[]{0x0069, 0x0307, 0x0303}, new char[]{0x0128}, "lt", 0), // # LATIN CAPITAL LETTER I WITH TILDE
//# ================================================================================
//# Turkish and Azeri
new Entry(0x0130, new char[]{0x0069}, new char[]{0x0130}, "tr", 0), // # LATIN CAPITAL LETTER I WITH DOT ABOVE
new Entry(0x0130, new char[]{0x0069}, new char[]{0x0130}, "az", 0), // # LATIN CAPITAL LETTER I WITH DOT ABOVE
new Entry(0x0307, new char[]{}, new char[]{0x0307}, "tr", AFTER_I), // # COMBINING DOT ABOVE
new Entry(0x0307, new char[]{}, new char[]{0x0307}, "az", AFTER_I), // # COMBINING DOT ABOVE
new Entry(0x0049, new char[]{0x0131}, new char[]{0x0049}, "tr", NOT_BEFORE_DOT), // # LATIN CAPITAL LETTER I
new Entry(0x0049, new char[]{0x0131}, new char[]{0x0049}, "az", NOT_BEFORE_DOT), // # LATIN CAPITAL LETTER I
new Entry(0x0069, new char[]{0x0069}, new char[]{0x0130}, "tr", 0), // # LATIN SMALL LETTER I
new Entry(0x0069, new char[]{0x0069}, new char[]{0x0130}, "az", 0) // # LATIN SMALL LETTER I
};
// A hash table that contains the above entries
static Hashtable<Integer, HashSet<Entry>> entryTable = new Hashtable<>();
static {
// create hashtable from the entry
for (Entry cur : entry) {
Integer cp = cur.getCodePoint();
HashSet<Entry> set = entryTable.get(cp);
if (set == null) {
set = new HashSet<>();
entryTable.put(cp, set);
}
set.add(cur);
}
}
static int toLowerCaseEx(String src, int index, Locale locale) {
char[] result = lookUpTable(src, index, locale, true);
if (result != null) {
if (result.length == 1) {
return result[0];
} else {
return Character.ERROR;
}
} else {
// default to Character class' one
return Character.toLowerCase(src.codePointAt(index));
}
}
static int toUpperCaseEx(String src, int index, Locale locale) {
char[] result = lookUpTable(src, index, locale, false);
if (result != null) {
if (result.length == 1) {
return result[0];
} else {
return Character.ERROR;
}
} else {
// default to Character class' one
return Character.toUpperCaseEx(src.codePointAt(index));
}
}
static char[] toLowerCaseCharArray(String src, int index, Locale locale) {
return lookUpTable(src, index, locale, true);
}
static char[] toUpperCaseCharArray(String src, int index, Locale locale) {
char[] result = lookUpTable(src, index, locale, false);
if (result != null) {
return result;
} else {
return Character.toUpperCaseCharArray(src.codePointAt(index));
}
}
private static char[] lookUpTable(String src, int index, Locale locale, boolean bLowerCasing) {
HashSet<Entry> set = entryTable.get(src.codePointAt(index));
char[] ret = null;
if (set != null) {
Iterator<Entry> iter = set.iterator();
String currentLang = locale.getLanguage();
while (iter.hasNext()) {
Entry entry = iter.next();
String conditionLang = entry.getLanguage();
if (((conditionLang == null) || (conditionLang.equals(currentLang))) &&
isConditionMet(src, index, locale, entry.getCondition())) {
ret = bLowerCasing ? entry.getLowerCase() : entry.getUpperCase();
if (conditionLang != null) {
break;
}
}
}
}
return ret;
}
private static boolean isConditionMet(String src, int index, Locale locale, int condition) {
switch (condition) {
case FINAL_CASED:
return isFinalCased(src, index, locale);
case AFTER_SOFT_DOTTED:
return isAfterSoftDotted(src, index);
case MORE_ABOVE:
return isMoreAbove(src, index);
case AFTER_I:
return isAfterI(src, index);
case NOT_BEFORE_DOT:
return !isBeforeDot(src, index);
default:
return true;
}
}
/**
* Implements the "Final_Cased" condition
*
* Specification: Within the closest word boundaries containing C, there is a cased
* letter before C, and there is no cased letter after C.
*
* Regular Expression:
* Before C: [{cased==true}][{wordBoundary!=true}]*
* After C: !([{wordBoundary!=true}]*[{cased}])
*/
private static boolean isFinalCased(String src, int index, Locale locale) {
BreakIterator wordBoundary = BreakIterator.getWordInstance(locale);
wordBoundary.setText(src);
int ch;
// Look for a preceding 'cased' letter
for (int i = index; (i >= 0) && !wordBoundary.isBoundary(i);
i -= Character.charCount(ch)) {
ch = src.codePointBefore(i);
if (isCased(ch)) {
int len = src.length();
// Check that there is no 'cased' letter after the index
for (i = index + Character.charCount(src.codePointAt(index));
(i < len) && !wordBoundary.isBoundary(i);
i += Character.charCount(ch)) {
ch = src.codePointAt(i);
if (isCased(ch)) {
return false;
}
}
return true;
}
}
return false;
}
/**
* Implements the "After_I" condition
*
* Specification: The last preceding base character was an uppercase I,
* and there is no intervening combining character class 230 (ABOVE).
*
* Regular Expression:
* Before C: [I]([{cc!=230}&{cc!=0}])*
*/
private static boolean isAfterI(String src, int index) {
int ch;
int cc;
// Look for the last preceding base character
for (int i = index; i > 0; i -= Character.charCount(ch)) {
ch = src.codePointBefore(i);
if (ch == 'I') {
return true;
} else {
cc = Normalizer.getCombiningClass(ch);
if ((cc == 0) || (cc == COMBINING_CLASS_ABOVE)) {
return false;
}
}
}
return false;
}
/**
* Implements the "After_Soft_Dotted" condition
*
* Specification: The last preceding character with combining class
* of zero before C was Soft_Dotted, and there is no intervening
* combining character class 230 (ABOVE).
*
* Regular Expression:
* Before C: [{Soft_Dotted==true}]([{cc!=230}&{cc!=0}])*
*/
private static boolean isAfterSoftDotted(String src, int index) {
int ch;
int cc;
// Look for the last preceding character
for (int i = index; i > 0; i -= Character.charCount(ch)) {
ch = src.codePointBefore(i);
if (isSoftDotted(ch)) {
return true;
} else {
cc = Normalizer.getCombiningClass(ch);
if ((cc == 0) || (cc == COMBINING_CLASS_ABOVE)) {
return false;
}
}
}
return false;
}
/**
* Implements the "More_Above" condition
*
* Specification: C is followed by one or more characters of combining
* class 230 (ABOVE) in the combining character sequence.
*
* Regular Expression:
* After C: [{cc!=0}]*[{cc==230}]
*/
private static boolean isMoreAbove(String src, int index) {
int ch;
int cc;
int len = src.length();
// Look for a following ABOVE combining class character
for (int i = index + Character.charCount(src.codePointAt(index));
i < len; i += Character.charCount(ch)) {
ch = src.codePointAt(i);
cc = Normalizer.getCombiningClass(ch);
if (cc == COMBINING_CLASS_ABOVE) {
return true;
} else if (cc == 0) {
return false;
}
}
return false;
}
/**
* Implements the "Before_Dot" condition
*
* Specification: C is followed by <code>U+0307 COMBINING DOT ABOVE</code>.
* Any sequence of characters with a combining class that is
* neither 0 nor 230 may intervene between the current character
* and the combining dot above.
*
* Regular Expression:
* After C: ([{cc!=230}&{cc!=0}])*[\u0307]
*/
private static boolean isBeforeDot(String src, int index) {
int ch;
int cc;
int len = src.length();
// Look for a following COMBINING DOT ABOVE
for (int i = index + Character.charCount(src.codePointAt(index));
i < len; i += Character.charCount(ch)) {
ch = src.codePointAt(i);
if (ch == '\u0307') {
return true;
} else {
cc = Normalizer.getCombiningClass(ch);
if ((cc == 0) || (cc == COMBINING_CLASS_ABOVE)) {
return false;
}
}
}
return false;
}
/**
* Examines whether a character is 'cased'.
*
* A character C is defined to be 'cased' if and only if at least one of
* following are true for C: uppercase==true, or lowercase==true, or
* general_category==titlecase_letter.
*
* The uppercase and lowercase property values are specified in the data
* file DerivedCoreProperties.txt in the Unicode Character Database.
*/
private static boolean isCased(int ch) {
int type = Character.getType(ch);
if (type == Character.LOWERCASE_LETTER ||
type == Character.UPPERCASE_LETTER ||
type == Character.TITLECASE_LETTER) {
return true;
} else {
// Check for Other_Lowercase and Other_Uppercase
//
if ((ch >= 0x02B0) && (ch <= 0x02B8)) {
// MODIFIER LETTER SMALL H..MODIFIER LETTER SMALL Y
return true;
} else if ((ch >= 0x02C0) && (ch <= 0x02C1)) {
// MODIFIER LETTER GLOTTAL STOP..MODIFIER LETTER REVERSED GLOTTAL STOP
return true;
} else if ((ch >= 0x02E0) && (ch <= 0x02E4)) {
// MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
return true;
} else if (ch == 0x0345) {
// COMBINING GREEK YPOGEGRAMMENI
return true;
} else if (ch == 0x037A) {
// GREEK YPOGEGRAMMENI
return true;
} else if ((ch >= 0x1D2C) && (ch <= 0x1D61)) {
// MODIFIER LETTER CAPITAL A..MODIFIER LETTER SMALL CHI
return true;
} else if ((ch >= 0x2160) && (ch <= 0x217F)) {
// ROMAN NUMERAL ONE..ROMAN NUMERAL ONE THOUSAND
// SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND
return true;
} else if ((ch >= 0x24B6) && (ch <= 0x24E9)) {
// CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN CAPITAL LETTER Z
// CIRCLED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z
return true;
} else {
return false;
}
}
}
private static boolean isSoftDotted(int ch) {
switch (ch) {
case 0x0069: // Soft_Dotted # L& LATIN SMALL LETTER I
case 0x006A: // Soft_Dotted # L& LATIN SMALL LETTER J
case 0x012F: // Soft_Dotted # L& LATIN SMALL LETTER I WITH OGONEK
case 0x0268: // Soft_Dotted # L& LATIN SMALL LETTER I WITH STROKE
case 0x0456: // Soft_Dotted # L& CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
case 0x0458: // Soft_Dotted # L& CYRILLIC SMALL LETTER JE
case 0x1D62: // Soft_Dotted # L& LATIN SUBSCRIPT SMALL LETTER I
case 0x1E2D: // Soft_Dotted # L& LATIN SMALL LETTER I WITH TILDE BELOW
case 0x1ECB: // Soft_Dotted # L& LATIN SMALL LETTER I WITH DOT BELOW
case 0x2071: // Soft_Dotted # L& SUPERSCRIPT LATIN SMALL LETTER I
return true;
default:
return false;
}
}
/**
* An internal class that represents an entry in the Special Casing Properties.
*/
static class Entry {
int ch;
char [] lower;
char [] upper;
String lang;
int condition;
Entry(int ch, char[] lower, char[] upper, String lang, int condition) {
this.ch = ch;
this.lower = lower;
this.upper = upper;
this.lang = lang;
this.condition = condition;
}
int getCodePoint() {
return ch;
}
char[] getLowerCase() {
return lower;
}
char[] getUpperCase() {
return upper;
}
String getLanguage() {
return lang;
}
int getCondition() {
return condition;
}
}
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2003, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
/**
* A program element annotated {@code @Deprecated} is one that programmers
* are discouraged from using. An element may be deprecated for any of several
* reasons, for example, its usage is likely to lead to errors; it may
* be changed incompatibly or removed in a future version; it has been
* superseded by a newer, usually preferable alternative; or it is obsolete.
*
* <p>Compilers issue warnings when a deprecated program element is used or
* overridden in non-deprecated code. Use of the {@code @Deprecated}
* annotation on a local variable declaration or on a parameter declaration
* or a package declaration has no effect on the warnings issued by a compiler.
*
* <p>When a module is deprecated, the use of that module in {@code
* requires}, but not in {@code exports} or {@code opens} clauses causes
* a warning to be issued. A module being deprecated does <em>not</em> cause
* warnings to be issued for uses of types within the module.
*
* <p>This annotation type has a string-valued element {@code since}. The value
* of this element indicates the version in which the annotated program element
* was first deprecated.
*
* <p>This annotation type has a boolean-valued element {@code forRemoval}.
* A value of {@code true} indicates intent to remove the annotated program
* element in a future version. A value of {@code false} indicates that use of
* the annotated program element is discouraged, but at the time the program
* element was annotated, there was no specific intent to remove it.
*
* @apiNote
* It is strongly recommended that the reason for deprecating a program element
* be explained in the documentation, using the {@code @deprecated}
* javadoc tag. The documentation should also suggest and link to a
* recommended replacement API, if applicable. A replacement API often
* has subtly different semantics, so such issues should be discussed as
* well.
*
* <p>It is recommended that a {@code since} value be provided with all newly
* annotated program elements. Note that {@code since} cannot be mandatory,
* as there are many existing annotations that lack this element value.
*
* <p>There is no defined order among annotation elements. As a matter of
* style, the {@code since} element should be placed first.
*
* <p>The {@code @Deprecated} annotation should always be present if
* the {@code @deprecated} javadoc tag is present, and vice-versa.
*
* @author Neal Gafter
* @since 1.5
* @jls 9.6.4.6 @Deprecated
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface Deprecated {
/**
* Returns the version in which the annotated element became deprecated.
* The version string is in the same format and namespace as the value of
* the {@code @since} javadoc tag. The default value is the empty
* string.
*
* @return the version string
* @since 9
*/
String since() default "";
/**
* Indicates whether the annotated element is subject to removal in a
* future version. The default value is {@code false}.
*
* @return whether the element is subject to removal
* @since 9
*/
boolean forRemoval() default false;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,260 @@
/*
* Copyright (c) 2003, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.io.Serializable;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
/**
* This is the common base class of all Java language enumeration types.
*
* More information about enums, including descriptions of the
* implicitly declared methods synthesized by the compiler, can be
* found in section 8.9 of
* <cite>The Java&trade; Language Specification</cite>.
*
* <p> Note that when using an enumeration type as the type of a set
* or as the type of the keys in a map, specialized and efficient
* {@linkplain java.util.EnumSet set} and {@linkplain
* java.util.EnumMap map} implementations are available.
*
* @param <E> The enum type subclass
* @author Josh Bloch
* @author Neal Gafter
* @see Class#getEnumConstants()
* @see java.util.EnumSet
* @see java.util.EnumMap
* @since 1.5
*/
@SuppressWarnings("serial") // No serialVersionUID needed due to
// special-casing of enum types.
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
/**
* The name of this enum constant, as declared in the enum declaration.
* Most programmers should use the {@link #toString} method rather than
* accessing this field.
*/
private final String name;
/**
* Returns the name of this enum constant, exactly as declared in its
* enum declaration.
*
* <b>Most programmers should use the {@link #toString} method in
* preference to this one, as the toString method may return
* a more user-friendly name.</b> This method is designed primarily for
* use in specialized situations where correctness depends on getting the
* exact name, which will not vary from release to release.
*
* @return the name of this enum constant
*/
public final String name() {
return name;
}
/**
* The ordinal of this enumeration constant (its position
* in the enum declaration, where the initial constant is assigned
* an ordinal of zero).
*
* Most programmers will have no use for this field. It is designed
* for use by sophisticated enum-based data structures, such as
* {@link java.util.EnumSet} and {@link java.util.EnumMap}.
*/
private final int ordinal;
/**
* Returns the ordinal of this enumeration constant (its position
* in its enum declaration, where the initial constant is assigned
* an ordinal of zero).
*
* Most programmers will have no use for this method. It is
* designed for use by sophisticated enum-based data structures, such
* as {@link java.util.EnumSet} and {@link java.util.EnumMap}.
*
* @return the ordinal of this enumeration constant
*/
public final int ordinal() {
return ordinal;
}
/**
* Sole constructor. Programmers cannot invoke this constructor.
* It is for use by code emitted by the compiler in response to
* enum type declarations.
*
* @param name - The name of this enum constant, which is the identifier
* used to declare it.
* @param ordinal - The ordinal of this enumeration constant (its position
* in the enum declaration, where the initial constant is assigned
* an ordinal of zero).
*/
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
/**
* Returns the name of this enum constant, as contained in the
* declaration. This method may be overridden, though it typically
* isn't necessary or desirable. An enum type should override this
* method when a more "programmer-friendly" string form exists.
*
* @return the name of this enum constant
*/
public String toString() {
return name;
}
/**
* Returns true if the specified object is equal to this
* enum constant.
*
* @param other the object to be compared for equality with this object.
* @return true if the specified object is equal to this
* enum constant.
*/
public final boolean equals(Object other) {
return this==other;
}
/**
* Returns a hash code for this enum constant.
*
* @return a hash code for this enum constant.
*/
public final int hashCode() {
return super.hashCode();
}
/**
* Throws CloneNotSupportedException. This guarantees that enums
* are never cloned, which is necessary to preserve their "singleton"
* status.
*
* @return (never returns)
*/
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
/**
* Compares this enum with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
*
* Enum constants are only comparable to other enum constants of the
* same enum type. The natural order implemented by this
* method is the order in which the constants are declared.
*/
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
}
/**
* Returns the Class object corresponding to this enum constant's
* enum type. Two enum constants e1 and e2 are of the
* same enum type if and only if
* e1.getDeclaringClass() == e2.getDeclaringClass().
* (The value returned by this method may differ from the one returned
* by the {@link Object#getClass} method for enum constants with
* constant-specific class bodies.)
*
* @return the Class object corresponding to this enum constant's
* enum type
*/
@SuppressWarnings("unchecked")
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}
/**
* Returns the enum constant of the specified enum type with the
* specified name. The name must match exactly an identifier used
* to declare an enum constant in this type. (Extraneous whitespace
* characters are not permitted.)
*
* <p>Note that for a particular enum type {@code T}, the
* implicitly declared {@code public static T valueOf(String)}
* method on that enum may be used instead of this method to map
* from a name to the corresponding enum constant. All the
* constants of an enum type can be obtained by calling the
* implicit {@code public static T[] values()} method of that
* type.
*
* @param <T> The enum type whose constant is to be returned
* @param enumType the {@code Class} object of the enum type from which
* to return a constant
* @param name the name of the constant to return
* @return the enum constant of the specified enum type with the
* specified name
* @throws IllegalArgumentException if the specified enum type has
* no constant with the specified name, or the specified
* class object does not represent an enum type
* @throws NullPointerException if {@code enumType} or {@code name}
* is null
* @since 1.5
*/
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
/**
* enum classes cannot have finalize methods.
*/
@SuppressWarnings("deprecation")
protected final void finalize() { }
/**
* prevent default deserialization
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2004, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when an application tries to access an enum constant by name
* and the enum type contains no constant with the specified name.
* This exception can be thrown by the {@linkplain
* java.lang.reflect.AnnotatedElement API used to read annotations
* reflectively}.
*
* @author Josh Bloch
* @see java.lang.reflect.AnnotatedElement
* @since 1.5
*/
@SuppressWarnings("rawtypes") /* rawtypes are part of the public api */
public class EnumConstantNotPresentException extends RuntimeException {
private static final long serialVersionUID = -6046998521960521108L;
/**
* The type of the missing enum constant.
*/
private Class<? extends Enum> enumType;
/**
* The name of the missing enum constant.
*/
private String constantName;
/**
* Constructs an {@code EnumConstantNotPresentException} for the
* specified constant.
*
* @param enumType the type of the missing enum constant
* @param constantName the name of the missing enum constant
*/
public EnumConstantNotPresentException(Class<? extends Enum> enumType,
String constantName) {
super(enumType.getName() + "." + constantName);
this.enumType = enumType;
this.constantName = constantName;
}
/**
* Returns the type of the missing enum constant.
*
* @return the type of the missing enum constant
*/
public Class<? extends Enum> enumType() { return enumType; }
/**
* Returns the name of the missing enum constant.
*
* @return the name of the missing enum constant
*/
public String constantName() { return constantName; }
}

View file

@ -0,0 +1,128 @@
/*
* Copyright (c) 1995, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* An {@code Error} is a subclass of {@code Throwable}
* that indicates serious problems that a reasonable application
* should not try to catch. Most such errors are abnormal conditions.
* The {@code ThreadDeath} error, though a "normal" condition,
* is also a subclass of {@code Error} because most applications
* should not try to catch it.
* <p>
* A method is not required to declare in its {@code throws}
* clause any subclasses of {@code Error} that might be thrown
* during the execution of the method but not caught, since these
* errors are abnormal conditions that should never occur.
*
* That is, {@code Error} and its subclasses are regarded as unchecked
* exceptions for the purposes of compile-time checking of exceptions.
*
* @author Frank Yellin
* @see java.lang.ThreadDeath
* @jls 11.2 Compile-Time Checking of Exceptions
* @since 1.0
*/
public class Error extends Throwable {
static final long serialVersionUID = 4980196508277280342L;
/**
* Constructs a new error with {@code null} as its detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*/
public Error() {
super();
}
/**
* Constructs a new error with the specified detail message. The
* cause is not initialized, and may subsequently be initialized by
* a call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public Error(String message) {
super(message);
}
/**
* Constructs a new error with the specified detail message and
* cause. <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this error's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public Error(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new error with the specified cause and a detail
* message of {@code (cause==null ? null : cause.toString())} (which
* typically contains the class and detail message of {@code cause}).
* This constructor is useful for errors that are little more than
* wrappers for other throwables.
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public Error(Throwable cause) {
super(cause);
}
/**
* Constructs a new error with the specified detail message,
* cause, suppression enabled or disabled, and writable stack
* trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
*
* @since 1.7
*/
protected Error(String message, Throwable cause,
boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 1994, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* The class {@code Exception} and its subclasses are a form of
* {@code Throwable} that indicates conditions that a reasonable
* application might want to catch.
*
* <p>The class {@code Exception} and any subclasses that are not also
* subclasses of {@link RuntimeException} are <em>checked
* exceptions</em>. Checked exceptions need to be declared in a
* method or constructor's {@code throws} clause if they can be thrown
* by the execution of the method or constructor and propagate outside
* the method or constructor boundary.
*
* @author Frank Yellin
* @see java.lang.Error
* @jls 11.2 Compile-Time Checking of Exceptions
* @since 1.0
*/
public class Exception extends Throwable {
static final long serialVersionUID = -3387516993124229948L;
/**
* Constructs a new exception with {@code null} as its detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*/
public Exception() {
super();
}
/**
* Constructs a new exception with the specified detail message. The
* cause is not initialized, and may subsequently be initialized by
* a call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public Exception(String message) {
super(message);
}
/**
* Constructs a new exception with the specified detail message and
* cause. <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this exception's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public Exception(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new exception with the specified cause and a detail
* message of {@code (cause==null ? null : cause.toString())} (which
* typically contains the class and detail message of {@code cause}).
* This constructor is useful for exceptions that are little more than
* wrappers for other throwables (for example, {@link
* java.security.PrivilegedActionException}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public Exception(Throwable cause) {
super(cause);
}
/**
* Constructs a new exception with the specified detail message,
* cause, suppression enabled or disabled, and writable stack
* trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
* @since 1.7
*/
protected Exception(String message, Throwable cause,
boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 1996, 2000, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Signals that an unexpected exception has occurred in a static initializer.
* An <code>ExceptionInInitializerError</code> is thrown to indicate that an
* exception occurred during evaluation of a static initializer or the
* initializer for a static variable.
*
* <p>As of release 1.4, this exception has been retrofitted to conform to
* the general purpose exception-chaining mechanism. The "saved throwable
* object" that may be provided at construction time and accessed via
* the {@link #getException()} method is now known as the <i>cause</i>,
* and may be accessed via the {@link Throwable#getCause()} method, as well
* as the aforementioned "legacy method."
*
* @author Frank Yellin
* @since 1.1
*/
public class ExceptionInInitializerError extends LinkageError {
/**
* Use serialVersionUID from JDK 1.1.X for interoperability
*/
private static final long serialVersionUID = 1521711792217232256L;
/**
* This field holds the exception if the
* ExceptionInInitializerError(Throwable thrown) constructor was
* used to instantiate the object
*
* @serial
*
*/
private Throwable exception;
/**
* Constructs an <code>ExceptionInInitializerError</code> with
* <code>null</code> as its detail message string and with no saved
* throwable object.
* A detail message is a String that describes this particular exception.
*/
public ExceptionInInitializerError() {
initCause(null); // Disallow subsequent initCause
}
/**
* Constructs a new <code>ExceptionInInitializerError</code> class by
* saving a reference to the <code>Throwable</code> object thrown for
* later retrieval by the {@link #getException()} method. The detail
* message string is set to <code>null</code>.
*
* @param thrown The exception thrown
*/
public ExceptionInInitializerError(Throwable thrown) {
initCause(null); // Disallow subsequent initCause
this.exception = thrown;
}
/**
* Constructs an ExceptionInInitializerError with the specified detail
* message string. A detail message is a String that describes this
* particular exception. The detail message string is saved for later
* retrieval by the {@link Throwable#getMessage()} method. There is no
* saved throwable object.
*
*
* @param s the detail message
*/
public ExceptionInInitializerError(String s) {
super(s);
initCause(null); // Disallow subsequent initCause
}
/**
* Returns the exception that occurred during a static initialization that
* caused this error to be created.
*
* <p>This method predates the general-purpose exception chaining facility.
* The {@link Throwable#getCause()} method is now the preferred means of
* obtaining this information.
*
* @return the saved throwable object of this
* <code>ExceptionInInitializerError</code>, or <code>null</code>
* if this <code>ExceptionInInitializerError</code> has no saved
* throwable object.
*/
public Throwable getException() {
return exception;
}
/**
* Returns the cause of this error (the exception that occurred
* during a static initialization that caused this error to be created).
*
* @return the cause of this error or <code>null</code> if the
* cause is nonexistent or unknown.
* @since 1.4
*/
public Throwable getCause() {
return exception;
}
}

View file

@ -0,0 +1,749 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Port of the "Freely Distributable Math Library", version 5.3, from
* C to Java.
*
* <p>The C version of fdlibm relied on the idiom of pointer aliasing
* a 64-bit double floating-point value as a two-element array of
* 32-bit integers and reading and writing the two halves of the
* double independently. This coding pattern was problematic to C
* optimizers and not directly expressible in Java. Therefore, rather
* than a memory level overlay, if portions of a double need to be
* operated on as integer values, the standard library methods for
* bitwise floating-point to integer conversion,
* Double.longBitsToDouble and Double.doubleToRawLongBits, are directly
* or indirectly used.
*
* <p>The C version of fdlibm also took some pains to signal the
* correct IEEE 754 exceptional conditions divide by zero, invalid,
* overflow and underflow. For example, overflow would be signaled by
* {@code huge * huge} where {@code huge} was a large constant that
* would overflow when squared. Since IEEE floating-point exceptional
* handling is not supported natively in the JVM, such coding patterns
* have been omitted from this port. For example, rather than {@code
* return huge * huge}, this port will use {@code return INFINITY}.
*
* <p>Various comparison and arithmetic operations in fdlibm could be
* done either based on the integer view of a value or directly on the
* floating-point representation. Which idiom is faster may depend on
* platform specific factors. However, for code clarity if no other
* reason, this port will favor expressing the semantics of those
* operations in terms of floating-point operations when convenient to
* do so.
*/
class FdLibm {
// Constants used by multiple algorithms
private static final double INFINITY = Double.POSITIVE_INFINITY;
private FdLibm() {
throw new UnsupportedOperationException("No FdLibm instances for you.");
}
/**
* Return the low-order 32 bits of the double argument as an int.
*/
private static int __LO(double x) {
long transducer = Double.doubleToRawLongBits(x);
return (int)transducer;
}
/**
* Return a double with its low-order bits of the second argument
* and the high-order bits of the first argument..
*/
private static double __LO(double x, int low) {
long transX = Double.doubleToRawLongBits(x);
return Double.longBitsToDouble((transX & 0xFFFF_FFFF_0000_0000L) |
(low & 0x0000_0000_FFFF_FFFFL));
}
/**
* Return the high-order 32 bits of the double argument as an int.
*/
private static int __HI(double x) {
long transducer = Double.doubleToRawLongBits(x);
return (int)(transducer >> 32);
}
/**
* Return a double with its high-order bits of the second argument
* and the low-order bits of the first argument..
*/
private static double __HI(double x, int high) {
long transX = Double.doubleToRawLongBits(x);
return Double.longBitsToDouble((transX & 0x0000_0000_FFFF_FFFFL) |
( ((long)high)) << 32 );
}
/**
* cbrt(x)
* Return cube root of x
*/
public static class Cbrt {
// unsigned
private static final int B1 = 715094163; /* B1 = (682-0.03306235651)*2**20 */
private static final int B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
private static final double C = 0x1.15f15f15f15f1p-1; // 19/35 ~= 5.42857142857142815906e-01
private static final double D = -0x1.691de2532c834p-1; // -864/1225 ~= 7.05306122448979611050e-01
private static final double E = 0x1.6a0ea0ea0ea0fp0; // 99/70 ~= 1.41428571428571436819e+00
private static final double F = 0x1.9b6db6db6db6ep0; // 45/28 ~= 1.60714285714285720630e+00
private static final double G = 0x1.6db6db6db6db7p-2; // 5/14 ~= 3.57142857142857150787e-01
private Cbrt() {
throw new UnsupportedOperationException();
}
public static strictfp double compute(double x) {
double t = 0.0;
double sign;
if (x == 0.0 || !Double.isFinite(x))
return x; // Handles signed zeros properly
sign = (x < 0.0) ? -1.0: 1.0;
x = Math.abs(x); // x <- |x|
// Rough cbrt to 5 bits
if (x < 0x1.0p-1022) { // subnormal number
t = 0x1.0p54; // set t= 2**54
t *= x;
t = __HI(t, __HI(t)/3 + B2);
} else {
int hx = __HI(x); // high word of x
t = __HI(t, hx/3 + B1);
}
// New cbrt to 23 bits, may be implemented in single precision
double r, s, w;
r = t * t/x;
s = C + r*t;
t *= G + F/(s + E + D/s);
// Chopped to 20 bits and make it larger than cbrt(x)
t = __LO(t, 0);
t = __HI(t, __HI(t) + 0x00000001);
// One step newton iteration to 53 bits with error less than 0.667 ulps
s = t * t; // t*t is exact
r = x / s;
w = t + t;
r = (r - t)/(w + r); // r-s is exact
t = t + t*r;
// Restore the original sign bit
return sign * t;
}
}
/**
* hypot(x,y)
*
* Method :
* If (assume round-to-nearest) z = x*x + y*y
* has error less than sqrt(2)/2 ulp, than
* sqrt(z) has error less than 1 ulp (exercise).
*
* So, compute sqrt(x*x + y*y) with some care as
* follows to get the error below 1 ulp:
*
* Assume x > y > 0;
* (if possible, set rounding to round-to-nearest)
* 1. if x > 2y use
* x1*x1 + (y*y + (x2*(x + x1))) for x*x + y*y
* where x1 = x with lower 32 bits cleared, x2 = x - x1; else
* 2. if x <= 2y use
* t1*y1 + ((x-y) * (x-y) + (t1*y2 + t2*y))
* where t1 = 2x with lower 32 bits cleared, t2 = 2x - t1,
* y1= y with lower 32 bits chopped, y2 = y - y1.
*
* NOTE: scaling may be necessary if some argument is too
* large or too tiny
*
* Special cases:
* hypot(x,y) is INF if x or y is +INF or -INF; else
* hypot(x,y) is NAN if x or y is NAN.
*
* Accuracy:
* hypot(x,y) returns sqrt(x^2 + y^2) with error less
* than 1 ulp (unit in the last place)
*/
public static class Hypot {
public static final double TWO_MINUS_600 = 0x1.0p-600;
public static final double TWO_PLUS_600 = 0x1.0p+600;
private Hypot() {
throw new UnsupportedOperationException();
}
public static strictfp double compute(double x, double y) {
double a = Math.abs(x);
double b = Math.abs(y);
if (!Double.isFinite(a) || !Double.isFinite(b)) {
if (a == INFINITY || b == INFINITY)
return INFINITY;
else
return a + b; // Propagate NaN significand bits
}
if (b > a) {
double tmp = a;
a = b;
b = tmp;
}
assert a >= b;
// Doing bitwise conversion after screening for NaN allows
// the code to not worry about the possibility of
// "negative" NaN values.
// Note: the ha and hb variables are the high-order
// 32-bits of a and b stored as integer values. The ha and
// hb values are used first for a rough magnitude
// comparison of a and b and second for simulating higher
// precision by allowing a and b, respectively, to be
// decomposed into non-overlapping portions. Both of these
// uses could be eliminated. The magnitude comparison
// could be eliminated by extracting and comparing the
// exponents of a and b or just be performing a
// floating-point divide. Splitting a floating-point
// number into non-overlapping portions can be
// accomplished by judicious use of multiplies and
// additions. For details see T. J. Dekker, A Floating
// Point Technique for Extending the Available Precision ,
// Numerische Mathematik, vol. 18, 1971, pp.224-242 and
// subsequent work.
int ha = __HI(a); // high word of a
int hb = __HI(b); // high word of b
if ((ha - hb) > 0x3c00000) {
return a + b; // x / y > 2**60
}
int k = 0;
if (a > 0x1.00000_ffff_ffffp500) { // a > ~2**500
// scale a and b by 2**-600
ha -= 0x25800000;
hb -= 0x25800000;
a = a * TWO_MINUS_600;
b = b * TWO_MINUS_600;
k += 600;
}
double t1, t2;
if (b < 0x1.0p-500) { // b < 2**-500
if (b < Double.MIN_NORMAL) { // subnormal b or 0 */
if (b == 0.0)
return a;
t1 = 0x1.0p1022; // t1 = 2^1022
b *= t1;
a *= t1;
k -= 1022;
} else { // scale a and b by 2^600
ha += 0x25800000; // a *= 2^600
hb += 0x25800000; // b *= 2^600
a = a * TWO_PLUS_600;
b = b * TWO_PLUS_600;
k -= 600;
}
}
// medium size a and b
double w = a - b;
if (w > b) {
t1 = 0;
t1 = __HI(t1, ha);
t2 = a - t1;
w = Math.sqrt(t1*t1 - (b*(-b) - t2 * (a + t1)));
} else {
double y1, y2;
a = a + a;
y1 = 0;
y1 = __HI(y1, hb);
y2 = b - y1;
t1 = 0;
t1 = __HI(t1, ha + 0x00100000);
t2 = a - t1;
w = Math.sqrt(t1*y1 - (w*(-w) - (t1*y2 + t2*b)));
}
if (k != 0) {
return Math.powerOfTwoD(k) * w;
} else
return w;
}
}
/**
* Compute x**y
* n
* Method: Let x = 2 * (1+f)
* 1. Compute and return log2(x) in two pieces:
* log2(x) = w1 + w2,
* where w1 has 53 - 24 = 29 bit trailing zeros.
* 2. Perform y*log2(x) = n+y' by simulating multi-precision
* arithmetic, where |y'| <= 0.5.
* 3. Return x**y = 2**n*exp(y'*log2)
*
* Special cases:
* 1. (anything) ** 0 is 1
* 2. (anything) ** 1 is itself
* 3. (anything) ** NAN is NAN
* 4. NAN ** (anything except 0) is NAN
* 5. +-(|x| > 1) ** +INF is +INF
* 6. +-(|x| > 1) ** -INF is +0
* 7. +-(|x| < 1) ** +INF is +0
* 8. +-(|x| < 1) ** -INF is +INF
* 9. +-1 ** +-INF is NAN
* 10. +0 ** (+anything except 0, NAN) is +0
* 11. -0 ** (+anything except 0, NAN, odd integer) is +0
* 12. +0 ** (-anything except 0, NAN) is +INF
* 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
* 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
* 15. +INF ** (+anything except 0,NAN) is +INF
* 16. +INF ** (-anything except 0,NAN) is +0
* 17. -INF ** (anything) = -0 ** (-anything)
* 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
* 19. (-anything except 0 and inf) ** (non-integer) is NAN
*
* Accuracy:
* pow(x,y) returns x**y nearly rounded. In particular
* pow(integer,integer)
* always returns the correct integer provided it is
* representable.
*/
public static class Pow {
private Pow() {
throw new UnsupportedOperationException();
}
public static strictfp double compute(final double x, final double y) {
double z;
double r, s, t, u, v, w;
int i, j, k, n;
// y == zero: x**0 = 1
if (y == 0.0)
return 1.0;
// +/-NaN return x + y to propagate NaN significands
if (Double.isNaN(x) || Double.isNaN(y))
return x + y;
final double y_abs = Math.abs(y);
double x_abs = Math.abs(x);
// Special values of y
if (y == 2.0) {
return x * x;
} else if (y == 0.5) {
if (x >= -Double.MAX_VALUE) // Handle x == -infinity later
return Math.sqrt(x + 0.0); // Add 0.0 to properly handle x == -0.0
} else if (y_abs == 1.0) { // y is +/-1
return (y == 1.0) ? x : 1.0 / x;
} else if (y_abs == INFINITY) { // y is +/-infinity
if (x_abs == 1.0)
return y - y; // inf**+/-1 is NaN
else if (x_abs > 1.0) // (|x| > 1)**+/-inf = inf, 0
return (y >= 0) ? y : 0.0;
else // (|x| < 1)**-/+inf = inf, 0
return (y < 0) ? -y : 0.0;
}
final int hx = __HI(x);
int ix = hx & 0x7fffffff;
/*
* When x < 0, determine if y is an odd integer:
* y_is_int = 0 ... y is not an integer
* y_is_int = 1 ... y is an odd int
* y_is_int = 2 ... y is an even int
*/
int y_is_int = 0;
if (hx < 0) {
if (y_abs >= 0x1.0p53) // |y| >= 2^53 = 9.007199254740992E15
y_is_int = 2; // y is an even integer since ulp(2^53) = 2.0
else if (y_abs >= 1.0) { // |y| >= 1.0
long y_abs_as_long = (long) y_abs;
if ( ((double) y_abs_as_long) == y_abs) {
y_is_int = 2 - (int)(y_abs_as_long & 0x1L);
}
}
}
// Special value of x
if (x_abs == 0.0 ||
x_abs == INFINITY ||
x_abs == 1.0) {
z = x_abs; // x is +/-0, +/-inf, +/-1
if (y < 0.0)
z = 1.0/z; // z = (1/|x|)
if (hx < 0) {
if (((ix - 0x3ff00000) | y_is_int) == 0) {
z = (z-z)/(z-z); // (-1)**non-int is NaN
} else if (y_is_int == 1)
z = -1.0 * z; // (x < 0)**odd = -(|x|**odd)
}
return z;
}
n = (hx >> 31) + 1;
// (x < 0)**(non-int) is NaN
if ((n | y_is_int) == 0)
return (x-x)/(x-x);
s = 1.0; // s (sign of result -ve**odd) = -1 else = 1
if ( (n | (y_is_int - 1)) == 0)
s = -1.0; // (-ve)**(odd int)
double p_h, p_l, t1, t2;
// |y| is huge
if (y_abs > 0x1.00000_ffff_ffffp31) { // if |y| > ~2**31
final double INV_LN2 = 0x1.7154_7652_b82fep0; // 1.44269504088896338700e+00 = 1/ln2
final double INV_LN2_H = 0x1.715476p0; // 1.44269502162933349609e+00 = 24 bits of 1/ln2
final double INV_LN2_L = 0x1.4ae0_bf85_ddf44p-26; // 1.92596299112661746887e-08 = 1/ln2 tail
// Over/underflow if x is not close to one
if (x_abs < 0x1.fffff_0000_0000p-1) // |x| < ~0.9999995231628418
return (y < 0.0) ? s * INFINITY : s * 0.0;
if (x_abs > 0x1.00000_ffff_ffffp0) // |x| > ~1.0
return (y > 0.0) ? s * INFINITY : s * 0.0;
/*
* now |1-x| is tiny <= 2**-20, sufficient to compute
* log(x) by x - x^2/2 + x^3/3 - x^4/4
*/
t = x_abs - 1.0; // t has 20 trailing zeros
w = (t * t) * (0.5 - t * (0.3333333333333333333333 - t * 0.25));
u = INV_LN2_H * t; // INV_LN2_H has 21 sig. bits
v = t * INV_LN2_L - w * INV_LN2;
t1 = u + v;
t1 =__LO(t1, 0);
t2 = v - (t1 - u);
} else {
final double CP = 0x1.ec70_9dc3_a03fdp-1; // 9.61796693925975554329e-01 = 2/(3ln2)
final double CP_H = 0x1.ec709ep-1; // 9.61796700954437255859e-01 = (float)cp
final double CP_L = -0x1.e2fe_0145_b01f5p-28; // -7.02846165095275826516e-09 = tail of CP_H
double z_h, z_l, ss, s2, s_h, s_l, t_h, t_l;
n = 0;
// Take care of subnormal numbers
if (ix < 0x00100000) {
x_abs *= 0x1.0p53; // 2^53 = 9007199254740992.0
n -= 53;
ix = __HI(x_abs);
}
n += ((ix) >> 20) - 0x3ff;
j = ix & 0x000fffff;
// Determine interval
ix = j | 0x3ff00000; // Normalize ix
if (j <= 0x3988E)
k = 0; // |x| <sqrt(3/2)
else if (j < 0xBB67A)
k = 1; // |x| <sqrt(3)
else {
k = 0;
n += 1;
ix -= 0x00100000;
}
x_abs = __HI(x_abs, ix);
// Compute ss = s_h + s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5)
final double BP[] = {1.0,
1.5};
final double DP_H[] = {0.0,
0x1.2b80_34p-1}; // 5.84962487220764160156e-01
final double DP_L[] = {0.0,
0x1.cfde_b43c_fd006p-27};// 1.35003920212974897128e-08
// Poly coefs for (3/2)*(log(x)-2s-2/3*s**3
final double L1 = 0x1.3333_3333_33303p-1; // 5.99999999999994648725e-01
final double L2 = 0x1.b6db_6db6_fabffp-2; // 4.28571428578550184252e-01
final double L3 = 0x1.5555_5518_f264dp-2; // 3.33333329818377432918e-01
final double L4 = 0x1.1746_0a91_d4101p-2; // 2.72728123808534006489e-01
final double L5 = 0x1.d864_a93c_9db65p-3; // 2.30660745775561754067e-01
final double L6 = 0x1.a7e2_84a4_54eefp-3; // 2.06975017800338417784e-01
u = x_abs - BP[k]; // BP[0]=1.0, BP[1]=1.5
v = 1.0 / (x_abs + BP[k]);
ss = u * v;
s_h = ss;
s_h = __LO(s_h, 0);
// t_h=x_abs + BP[k] High
t_h = 0.0;
t_h = __HI(t_h, ((ix >> 1) | 0x20000000) + 0x00080000 + (k << 18) );
t_l = x_abs - (t_h - BP[k]);
s_l = v * ((u - s_h * t_h) - s_h * t_l);
// Compute log(x_abs)
s2 = ss * ss;
r = s2 * s2* (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6)))));
r += s_l * (s_h + ss);
s2 = s_h * s_h;
t_h = 3.0 + s2 + r;
t_h = __LO(t_h, 0);
t_l = r - ((t_h - 3.0) - s2);
// u+v = ss*(1+...)
u = s_h * t_h;
v = s_l * t_h + t_l * ss;
// 2/(3log2)*(ss + ...)
p_h = u + v;
p_h = __LO(p_h, 0);
p_l = v - (p_h - u);
z_h = CP_H * p_h; // CP_H + CP_L = 2/(3*log2)
z_l = CP_L * p_h + p_l * CP + DP_L[k];
// log2(x_abs) = (ss + ..)*2/(3*log2) = n + DP_H + z_h + z_l
t = (double)n;
t1 = (((z_h + z_l) + DP_H[k]) + t);
t1 = __LO(t1, 0);
t2 = z_l - (((t1 - t) - DP_H[k]) - z_h);
}
// Split up y into (y1 + y2) and compute (y1 + y2) * (t1 + t2)
double y1 = y;
y1 = __LO(y1, 0);
p_l = (y - y1) * t1 + y * t2;
p_h = y1 * t1;
z = p_l + p_h;
j = __HI(z);
i = __LO(z);
if (j >= 0x40900000) { // z >= 1024
if (((j - 0x40900000) | i)!=0) // if z > 1024
return s * INFINITY; // Overflow
else {
final double OVT = 8.0085662595372944372e-0017; // -(1024-log2(ovfl+.5ulp))
if (p_l + OVT > z - p_h)
return s * INFINITY; // Overflow
}
} else if ((j & 0x7fffffff) >= 0x4090cc00 ) { // z <= -1075
if (((j - 0xc090cc00) | i)!=0) // z < -1075
return s * 0.0; // Underflow
else {
if (p_l <= z - p_h)
return s * 0.0; // Underflow
}
}
/*
* Compute 2**(p_h+p_l)
*/
// Poly coefs for (3/2)*(log(x)-2s-2/3*s**3
final double P1 = 0x1.5555_5555_5553ep-3; // 1.66666666666666019037e-01
final double P2 = -0x1.6c16_c16b_ebd93p-9; // -2.77777777770155933842e-03
final double P3 = 0x1.1566_aaf2_5de2cp-14; // 6.61375632143793436117e-05
final double P4 = -0x1.bbd4_1c5d_26bf1p-20; // -1.65339022054652515390e-06
final double P5 = 0x1.6376_972b_ea4d0p-25; // 4.13813679705723846039e-08
final double LG2 = 0x1.62e4_2fef_a39efp-1; // 6.93147180559945286227e-01
final double LG2_H = 0x1.62e43p-1; // 6.93147182464599609375e-01
final double LG2_L = -0x1.05c6_10ca_86c39p-29; // -1.90465429995776804525e-09
i = j & 0x7fffffff;
k = (i >> 20) - 0x3ff;
n = 0;
if (i > 0x3fe00000) { // if |z| > 0.5, set n = [z + 0.5]
n = j + (0x00100000 >> (k + 1));
k = ((n & 0x7fffffff) >> 20) - 0x3ff; // new k for n
t = 0.0;
t = __HI(t, (n & ~(0x000fffff >> k)) );
n = ((n & 0x000fffff) | 0x00100000) >> (20 - k);
if (j < 0)
n = -n;
p_h -= t;
}
t = p_l + p_h;
t = __LO(t, 0);
u = t * LG2_H;
v = (p_l - (t - p_h)) * LG2 + t * LG2_L;
z = u + v;
w = v - (z - u);
t = z * z;
t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
r = (z * t1)/(t1 - 2.0) - (w + z * w);
z = 1.0 - (r - z);
j = __HI(z);
j += (n << 20);
if ((j >> 20) <= 0)
z = Math.scalb(z, n); // subnormal output
else {
int z_hi = __HI(z);
z_hi += (n << 20);
z = __HI(z, z_hi);
}
return s * z;
}
}
/**
* Returns the exponential of x.
*
* Method
* 1. Argument reduction:
* Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
* Given x, find r and integer k such that
*
* x = k*ln2 + r, |r| <= 0.5*ln2.
*
* Here r will be represented as r = hi-lo for better
* accuracy.
*
* 2. Approximation of exp(r) by a special rational function on
* the interval [0,0.34658]:
* Write
* R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
* We use a special Reme algorithm on [0,0.34658] to generate
* a polynomial of degree 5 to approximate R. The maximum error
* of this polynomial approximation is bounded by 2**-59. In
* other words,
* R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
* (where z=r*r, and the values of P1 to P5 are listed below)
* and
* | 5 | -59
* | 2.0+P1*z+...+P5*z - R(z) | <= 2
* | |
* The computation of exp(r) thus becomes
* 2*r
* exp(r) = 1 + -------
* R - r
* r*R1(r)
* = 1 + r + ----------- (for better accuracy)
* 2 - R1(r)
* where
* 2 4 10
* R1(r) = r - (P1*r + P2*r + ... + P5*r ).
*
* 3. Scale back to obtain exp(x):
* From step 1, we have
* exp(x) = 2^k * exp(r)
*
* Special cases:
* exp(INF) is INF, exp(NaN) is NaN;
* exp(-INF) is 0, and
* for finite argument, only exp(0)=1 is exact.
*
* Accuracy:
* according to an error analysis, the error is always less than
* 1 ulp (unit in the last place).
*
* Misc. info.
* For IEEE double
* if x > 7.09782712893383973096e+02 then exp(x) overflow
* if x < -7.45133219101941108420e+02 then exp(x) underflow
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
static class Exp {
private static final double one = 1.0;
private static final double[] half = {0.5, -0.5,};
private static final double huge = 1.0e+300;
private static final double twom1000= 0x1.0p-1000; // 9.33263618503218878990e-302 = 2^-1000
private static final double o_threshold= 0x1.62e42fefa39efp9; // 7.09782712893383973096e+02
private static final double u_threshold= -0x1.74910d52d3051p9; // -7.45133219101941108420e+02;
private static final double[] ln2HI ={ 0x1.62e42feep-1, // 6.93147180369123816490e-01
-0x1.62e42feep-1}; // -6.93147180369123816490e-01
private static final double[] ln2LO ={ 0x1.a39ef35793c76p-33, // 1.90821492927058770002e-10
-0x1.a39ef35793c76p-33}; // -1.90821492927058770002e-10
private static final double invln2 = 0x1.71547652b82fep0; // 1.44269504088896338700e+00
private static final double P1 = 0x1.555555555553ep-3; // 1.66666666666666019037e-01
private static final double P2 = -0x1.6c16c16bebd93p-9; // -2.77777777770155933842e-03
private static final double P3 = 0x1.1566aaf25de2cp-14; // 6.61375632143793436117e-05
private static final double P4 = -0x1.bbd41c5d26bf1p-20; // -1.65339022054652515390e-06
private static final double P5 = 0x1.6376972bea4d0p-25; // 4.13813679705723846039e-08
private Exp() {
throw new UnsupportedOperationException();
}
// should be able to forgo strictfp due to controlled over/underflow
public static strictfp double compute(double x) {
double y;
double hi = 0.0;
double lo = 0.0;
double c;
double t;
int k = 0;
int xsb;
/*unsigned*/ int hx;
hx = __HI(x); /* high word of x */
xsb = (hx >> 31) & 1; /* sign bit of x */
hx &= 0x7fffffff; /* high word of |x| */
/* filter out non-finite argument */
if (hx >= 0x40862E42) { /* if |x| >= 709.78... */
if (hx >= 0x7ff00000) {
if (((hx & 0xfffff) | __LO(x)) != 0)
return x + x; /* NaN */
else
return (xsb == 0) ? x : 0.0; /* exp(+-inf) = {inf, 0} */
}
if (x > o_threshold)
return huge * huge; /* overflow */
if (x < u_threshold) // unsigned compare needed here?
return twom1000 * twom1000; /* underflow */
}
/* argument reduction */
if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
hi = x - ln2HI[xsb];
lo=ln2LO[xsb];
k = 1 - xsb - xsb;
} else {
k = (int)(invln2 * x + half[xsb]);
t = k;
hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
lo = t*ln2LO[0];
}
x = hi - lo;
} else if (hx < 0x3e300000) { /* when |x|<2**-28 */
if (huge + x > one)
return one + x; /* trigger inexact */
} else {
k = 0;
}
/* x is now in primary range */
t = x * x;
c = x - t*(P1 + t*(P2 + t*(P3 + t*(P4 + t*P5))));
if (k == 0)
return one - ((x*c)/(c - 2.0) - x);
else
y = one - ((lo - (x*c)/(2.0 - c)) - hi);
if(k >= -1021) {
y = __HI(y, __HI(y) + (k << 20)); /* add k to y's exponent */
return y;
} else {
y = __HI(y, __HI(y) + ((k + 1000) << 20)); /* add k to y's exponent */
return y * twom1000;
}
}
}
}

View file

@ -0,0 +1,987 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import jdk.internal.math.FloatingDecimal;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The {@code Float} class wraps a value of primitive type
* {@code float} in an object. An object of type
* {@code Float} contains a single field whose type is
* {@code float}.
*
* <p>In addition, this class provides several methods for converting a
* {@code float} to a {@code String} and a
* {@code String} to a {@code float}, as well as other
* constants and methods useful when dealing with a
* {@code float}.
*
* @author Lee Boynton
* @author Arthur van Hoff
* @author Joseph D. Darcy
* @since 1.0
*/
public final class Float extends Number implements Comparable<Float> {
/**
* A constant holding the positive infinity of type
* {@code float}. It is equal to the value returned by
* {@code Float.intBitsToFloat(0x7f800000)}.
*/
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
/**
* A constant holding the negative infinity of type
* {@code float}. It is equal to the value returned by
* {@code Float.intBitsToFloat(0xff800000)}.
*/
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
/**
* A constant holding a Not-a-Number (NaN) value of type
* {@code float}. It is equivalent to the value returned by
* {@code Float.intBitsToFloat(0x7fc00000)}.
*/
public static final float NaN = 0.0f / 0.0f;
/**
* A constant holding the largest positive finite value of type
* {@code float}, (2-2<sup>-23</sup>)&middot;2<sup>127</sup>.
* It is equal to the hexadecimal floating-point literal
* {@code 0x1.fffffeP+127f} and also equal to
* {@code Float.intBitsToFloat(0x7f7fffff)}.
*/
public static final float MAX_VALUE = 0x1.fffffeP+127f; // 3.4028235e+38f
/**
* A constant holding the smallest positive normal value of type
* {@code float}, 2<sup>-126</sup>. It is equal to the
* hexadecimal floating-point literal {@code 0x1.0p-126f} and also
* equal to {@code Float.intBitsToFloat(0x00800000)}.
*
* @since 1.6
*/
public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f
/**
* A constant holding the smallest positive nonzero value of type
* {@code float}, 2<sup>-149</sup>. It is equal to the
* hexadecimal floating-point literal {@code 0x0.000002P-126f}
* and also equal to {@code Float.intBitsToFloat(0x1)}.
*/
public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f
/**
* Maximum exponent a finite {@code float} variable may have. It
* is equal to the value returned by {@code
* Math.getExponent(Float.MAX_VALUE)}.
*
* @since 1.6
*/
public static final int MAX_EXPONENT = 127;
/**
* Minimum exponent a normalized {@code float} variable may have.
* It is equal to the value returned by {@code
* Math.getExponent(Float.MIN_NORMAL)}.
*
* @since 1.6
*/
public static final int MIN_EXPONENT = -126;
/**
* The number of bits used to represent a {@code float} value.
*
* @since 1.5
*/
public static final int SIZE = 32;
/**
* The number of bytes used to represent a {@code float} value.
*
* @since 1.8
*/
public static final int BYTES = SIZE / Byte.SIZE;
/**
* The {@code Class} instance representing the primitive type
* {@code float}.
*
* @since 1.1
*/
@SuppressWarnings("unchecked")
public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");
/**
* Returns a string representation of the {@code float}
* argument. All characters mentioned below are ASCII characters.
* <ul>
* <li>If the argument is NaN, the result is the string
* "{@code NaN}".
* <li>Otherwise, the result is a string that represents the sign and
* magnitude (absolute value) of the argument. If the sign is
* negative, the first character of the result is
* '{@code -}' ({@code '\u005Cu002D'}); if the sign is
* positive, no sign character appears in the result. As for
* the magnitude <i>m</i>:
* <ul>
* <li>If <i>m</i> is infinity, it is represented by the characters
* {@code "Infinity"}; thus, positive infinity produces
* the result {@code "Infinity"} and negative infinity
* produces the result {@code "-Infinity"}.
* <li>If <i>m</i> is zero, it is represented by the characters
* {@code "0.0"}; thus, negative zero produces the result
* {@code "-0.0"} and positive zero produces the result
* {@code "0.0"}.
* <li> If <i>m</i> is greater than or equal to 10<sup>-3</sup> but
* less than 10<sup>7</sup>, then it is represented as the
* integer part of <i>m</i>, in decimal form with no leading
* zeroes, followed by '{@code .}'
* ({@code '\u005Cu002E'}), followed by one or more
* decimal digits representing the fractional part of
* <i>m</i>.
* <li> If <i>m</i> is less than 10<sup>-3</sup> or greater than or
* equal to 10<sup>7</sup>, then it is represented in
* so-called "computerized scientific notation." Let <i>n</i>
* be the unique integer such that 10<sup><i>n</i> </sup>&le;
* <i>m</i> {@literal <} 10<sup><i>n</i>+1</sup>; then let <i>a</i>
* be the mathematically exact quotient of <i>m</i> and
* 10<sup><i>n</i></sup> so that 1 &le; <i>a</i> {@literal <} 10.
* The magnitude is then represented as the integer part of
* <i>a</i>, as a single decimal digit, followed by
* '{@code .}' ({@code '\u005Cu002E'}), followed by
* decimal digits representing the fractional part of
* <i>a</i>, followed by the letter '{@code E}'
* ({@code '\u005Cu0045'}), followed by a representation
* of <i>n</i> as a decimal integer, as produced by the
* method {@link java.lang.Integer#toString(int)}.
*
* </ul>
* </ul>
* How many digits must be printed for the fractional part of
* <i>m</i> or <i>a</i>? There must be at least one digit
* to represent the fractional part, and beyond that as many, but
* only as many, more digits as are needed to uniquely distinguish
* the argument value from adjacent values of type
* {@code float}. That is, suppose that <i>x</i> is the
* exact mathematical value represented by the decimal
* representation produced by this method for a finite nonzero
* argument <i>f</i>. Then <i>f</i> must be the {@code float}
* value nearest to <i>x</i>; or, if two {@code float} values are
* equally close to <i>x</i>, then <i>f</i> must be one of
* them and the least significant bit of the significand of
* <i>f</i> must be {@code 0}.
*
* <p>To create localized string representations of a floating-point
* value, use subclasses of {@link java.text.NumberFormat}.
*
* @param f the float to be converted.
* @return a string representation of the argument.
*/
public static String toString(float f) {
return FloatingDecimal.toJavaFormatString(f);
}
/**
* Returns a hexadecimal string representation of the
* {@code float} argument. All characters mentioned below are
* ASCII characters.
*
* <ul>
* <li>If the argument is NaN, the result is the string
* "{@code NaN}".
* <li>Otherwise, the result is a string that represents the sign and
* magnitude (absolute value) of the argument. If the sign is negative,
* the first character of the result is '{@code -}'
* ({@code '\u005Cu002D'}); if the sign is positive, no sign character
* appears in the result. As for the magnitude <i>m</i>:
*
* <ul>
* <li>If <i>m</i> is infinity, it is represented by the string
* {@code "Infinity"}; thus, positive infinity produces the
* result {@code "Infinity"} and negative infinity produces
* the result {@code "-Infinity"}.
*
* <li>If <i>m</i> is zero, it is represented by the string
* {@code "0x0.0p0"}; thus, negative zero produces the result
* {@code "-0x0.0p0"} and positive zero produces the result
* {@code "0x0.0p0"}.
*
* <li>If <i>m</i> is a {@code float} value with a
* normalized representation, substrings are used to represent the
* significand and exponent fields. The significand is
* represented by the characters {@code "0x1."}
* followed by a lowercase hexadecimal representation of the rest
* of the significand as a fraction. Trailing zeros in the
* hexadecimal representation are removed unless all the digits
* are zero, in which case a single zero is used. Next, the
* exponent is represented by {@code "p"} followed
* by a decimal string of the unbiased exponent as if produced by
* a call to {@link Integer#toString(int) Integer.toString} on the
* exponent value.
*
* <li>If <i>m</i> is a {@code float} value with a subnormal
* representation, the significand is represented by the
* characters {@code "0x0."} followed by a
* hexadecimal representation of the rest of the significand as a
* fraction. Trailing zeros in the hexadecimal representation are
* removed. Next, the exponent is represented by
* {@code "p-126"}. Note that there must be at
* least one nonzero digit in a subnormal significand.
*
* </ul>
*
* </ul>
*
* <table class="striped">
* <caption>Examples</caption>
* <thead>
* <tr><th scope="col">Floating-point Value</th><th scope="col">Hexadecimal String</th>
* </thead>
* <tbody>
* <tr><th scope="row">{@code 1.0}</th> <td>{@code 0x1.0p0}</td>
* <tr><th scope="row">{@code -1.0}</th> <td>{@code -0x1.0p0}</td>
* <tr><th scope="row">{@code 2.0}</th> <td>{@code 0x1.0p1}</td>
* <tr><th scope="row">{@code 3.0}</th> <td>{@code 0x1.8p1}</td>
* <tr><th scope="row">{@code 0.5}</th> <td>{@code 0x1.0p-1}</td>
* <tr><th scope="row">{@code 0.25}</th> <td>{@code 0x1.0p-2}</td>
* <tr><th scope="row">{@code Float.MAX_VALUE}</th>
* <td>{@code 0x1.fffffep127}</td>
* <tr><th scope="row">{@code Minimum Normal Value}</th>
* <td>{@code 0x1.0p-126}</td>
* <tr><th scope="row">{@code Maximum Subnormal Value}</th>
* <td>{@code 0x0.fffffep-126}</td>
* <tr><th scope="row">{@code Float.MIN_VALUE}</th>
* <td>{@code 0x0.000002p-126}</td>
* </tbody>
* </table>
* @param f the {@code float} to be converted.
* @return a hex string representation of the argument.
* @since 1.5
* @author Joseph D. Darcy
*/
public static String toHexString(float f) {
if (Math.abs(f) < Float.MIN_NORMAL
&& f != 0.0f ) {// float subnormal
// Adjust exponent to create subnormal double, then
// replace subnormal double exponent with subnormal float
// exponent
String s = Double.toHexString(Math.scalb((double)f,
/* -1022+126 */
Double.MIN_EXPONENT-
Float.MIN_EXPONENT));
return s.replaceFirst("p-1022$", "p-126");
}
else // double string will be the same as float string
return Double.toHexString(f);
}
/**
* Returns a {@code Float} object holding the
* {@code float} value represented by the argument string
* {@code s}.
*
* <p>If {@code s} is {@code null}, then a
* {@code NullPointerException} is thrown.
*
* <p>Leading and trailing whitespace characters in {@code s}
* are ignored. Whitespace is removed as if by the {@link
* String#trim} method; that is, both ASCII space and control
* characters are removed. The rest of {@code s} should
* constitute a <i>FloatValue</i> as described by the lexical
* syntax rules:
*
* <blockquote>
* <dl>
* <dt><i>FloatValue:</i>
* <dd><i>Sign<sub>opt</sub></i> {@code NaN}
* <dd><i>Sign<sub>opt</sub></i> {@code Infinity}
* <dd><i>Sign<sub>opt</sub> FloatingPointLiteral</i>
* <dd><i>Sign<sub>opt</sub> HexFloatingPointLiteral</i>
* <dd><i>SignedInteger</i>
* </dl>
*
* <dl>
* <dt><i>HexFloatingPointLiteral</i>:
* <dd> <i>HexSignificand BinaryExponent FloatTypeSuffix<sub>opt</sub></i>
* </dl>
*
* <dl>
* <dt><i>HexSignificand:</i>
* <dd><i>HexNumeral</i>
* <dd><i>HexNumeral</i> {@code .}
* <dd>{@code 0x} <i>HexDigits<sub>opt</sub>
* </i>{@code .}<i> HexDigits</i>
* <dd>{@code 0X}<i> HexDigits<sub>opt</sub>
* </i>{@code .} <i>HexDigits</i>
* </dl>
*
* <dl>
* <dt><i>BinaryExponent:</i>
* <dd><i>BinaryExponentIndicator SignedInteger</i>
* </dl>
*
* <dl>
* <dt><i>BinaryExponentIndicator:</i>
* <dd>{@code p}
* <dd>{@code P}
* </dl>
*
* </blockquote>
*
* where <i>Sign</i>, <i>FloatingPointLiteral</i>,
* <i>HexNumeral</i>, <i>HexDigits</i>, <i>SignedInteger</i> and
* <i>FloatTypeSuffix</i> are as defined in the lexical structure
* sections of
* <cite>The Java&trade; Language Specification</cite>,
* except that underscores are not accepted between digits.
* If {@code s} does not have the form of
* a <i>FloatValue</i>, then a {@code NumberFormatException}
* is thrown. Otherwise, {@code s} is regarded as
* representing an exact decimal value in the usual
* "computerized scientific notation" or as an exact
* hexadecimal value; this exact numerical value is then
* conceptually converted to an "infinitely precise"
* binary value that is then rounded to type {@code float}
* by the usual round-to-nearest rule of IEEE 754 floating-point
* arithmetic, which includes preserving the sign of a zero
* value.
*
* Note that the round-to-nearest rule also implies overflow and
* underflow behaviour; if the exact value of {@code s} is large
* enough in magnitude (greater than or equal to ({@link
* #MAX_VALUE} + {@link Math#ulp(float) ulp(MAX_VALUE)}/2),
* rounding to {@code float} will result in an infinity and if the
* exact value of {@code s} is small enough in magnitude (less
* than or equal to {@link #MIN_VALUE}/2), rounding to float will
* result in a zero.
*
* Finally, after rounding a {@code Float} object representing
* this {@code float} value is returned.
*
* <p>To interpret localized string representations of a
* floating-point value, use subclasses of {@link
* java.text.NumberFormat}.
*
* <p>Note that trailing format specifiers, specifiers that
* determine the type of a floating-point literal
* ({@code 1.0f} is a {@code float} value;
* {@code 1.0d} is a {@code double} value), do
* <em>not</em> influence the results of this method. In other
* words, the numerical value of the input string is converted
* directly to the target floating-point type. In general, the
* two-step sequence of conversions, string to {@code double}
* followed by {@code double} to {@code float}, is
* <em>not</em> equivalent to converting a string directly to
* {@code float}. For example, if first converted to an
* intermediate {@code double} and then to
* {@code float}, the string<br>
* {@code "1.00000017881393421514957253748434595763683319091796875001d"}<br>
* results in the {@code float} value
* {@code 1.0000002f}; if the string is converted directly to
* {@code float}, <code>1.000000<b>1</b>f</code> results.
*
* <p>To avoid calling this method on an invalid string and having
* a {@code NumberFormatException} be thrown, the documentation
* for {@link Double#valueOf Double.valueOf} lists a regular
* expression which can be used to screen the input.
*
* @param s the string to be parsed.
* @return a {@code Float} object holding the value
* represented by the {@code String} argument.
* @throws NumberFormatException if the string does not contain a
* parsable number.
*/
public static Float valueOf(String s) throws NumberFormatException {
return new Float(parseFloat(s));
}
/**
* Returns a {@code Float} instance representing the specified
* {@code float} value.
* If a new {@code Float} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Float(float)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param f a float value.
* @return a {@code Float} instance representing {@code f}.
* @since 1.5
*/
@HotSpotIntrinsicCandidate
public static Float valueOf(float f) {
return new Float(f);
}
/**
* Returns a new {@code float} initialized to the value
* represented by the specified {@code String}, as performed
* by the {@code valueOf} method of class {@code Float}.
*
* @param s the string to be parsed.
* @return the {@code float} value represented by the string
* argument.
* @throws NullPointerException if the string is null
* @throws NumberFormatException if the string does not contain a
* parsable {@code float}.
* @see java.lang.Float#valueOf(String)
* @since 1.2
*/
public static float parseFloat(String s) throws NumberFormatException {
return FloatingDecimal.parseFloat(s);
}
/**
* Returns {@code true} if the specified number is a
* Not-a-Number (NaN) value, {@code false} otherwise.
*
* @param v the value to be tested.
* @return {@code true} if the argument is NaN;
* {@code false} otherwise.
*/
public static boolean isNaN(float v) {
return (v != v);
}
/**
* Returns {@code true} if the specified number is infinitely
* large in magnitude, {@code false} otherwise.
*
* @param v the value to be tested.
* @return {@code true} if the argument is positive infinity or
* negative infinity; {@code false} otherwise.
*/
public static boolean isInfinite(float v) {
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
/**
* Returns {@code true} if the argument is a finite floating-point
* value; returns {@code false} otherwise (for NaN and infinity
* arguments).
*
* @param f the {@code float} value to be tested
* @return {@code true} if the argument is a finite
* floating-point value, {@code false} otherwise.
* @since 1.8
*/
public static boolean isFinite(float f) {
return Math.abs(f) <= Float.MAX_VALUE;
}
/**
* The value of the Float.
*
* @serial
*/
private final float value;
/**
* Constructs a newly allocated {@code Float} object that
* represents the primitive {@code float} argument.
*
* @param value the value to be represented by the {@code Float}.
*
* @deprecated
* It is rarely appropriate to use this constructor. The static factory
* {@link #valueOf(float)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
public Float(float value) {
this.value = value;
}
/**
* Constructs a newly allocated {@code Float} object that
* represents the argument converted to type {@code float}.
*
* @param value the value to be represented by the {@code Float}.
*
* @deprecated
* It is rarely appropriate to use this constructor. Instead, use the
* static factory method {@link #valueOf(float)} method as follows:
* {@code Float.valueOf((float)value)}.
*/
@Deprecated(since="9")
public Float(double value) {
this.value = (float)value;
}
/**
* Constructs a newly allocated {@code Float} object that
* represents the floating-point value of type {@code float}
* represented by the string. The string is converted to a
* {@code float} value as if by the {@code valueOf} method.
*
* @param s a string to be converted to a {@code Float}.
* @throws NumberFormatException if the string does not contain a
* parsable number.
*
* @deprecated
* It is rarely appropriate to use this constructor.
* Use {@link #parseFloat(String)} to convert a string to a
* {@code float} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Float} object.
*/
@Deprecated(since="9")
public Float(String s) throws NumberFormatException {
value = parseFloat(s);
}
/**
* Returns {@code true} if this {@code Float} value is a
* Not-a-Number (NaN), {@code false} otherwise.
*
* @return {@code true} if the value represented by this object is
* NaN; {@code false} otherwise.
*/
public boolean isNaN() {
return isNaN(value);
}
/**
* Returns {@code true} if this {@code Float} value is
* infinitely large in magnitude, {@code false} otherwise.
*
* @return {@code true} if the value represented by this object is
* positive infinity or negative infinity;
* {@code false} otherwise.
*/
public boolean isInfinite() {
return isInfinite(value);
}
/**
* Returns a string representation of this {@code Float} object.
* The primitive {@code float} value represented by this object
* is converted to a {@code String} exactly as if by the method
* {@code toString} of one argument.
*
* @return a {@code String} representation of this object.
* @see java.lang.Float#toString(float)
*/
public String toString() {
return Float.toString(value);
}
/**
* Returns the value of this {@code Float} as a {@code byte} after
* a narrowing primitive conversion.
*
* @return the {@code float} value represented by this object
* converted to type {@code byte}
* @jls 5.1.3 Narrowing Primitive Conversions
*/
public byte byteValue() {
return (byte)value;
}
/**
* Returns the value of this {@code Float} as a {@code short}
* after a narrowing primitive conversion.
*
* @return the {@code float} value represented by this object
* converted to type {@code short}
* @jls 5.1.3 Narrowing Primitive Conversions
* @since 1.1
*/
public short shortValue() {
return (short)value;
}
/**
* Returns the value of this {@code Float} as an {@code int} after
* a narrowing primitive conversion.
*
* @return the {@code float} value represented by this object
* converted to type {@code int}
* @jls 5.1.3 Narrowing Primitive Conversions
*/
public int intValue() {
return (int)value;
}
/**
* Returns value of this {@code Float} as a {@code long} after a
* narrowing primitive conversion.
*
* @return the {@code float} value represented by this object
* converted to type {@code long}
* @jls 5.1.3 Narrowing Primitive Conversions
*/
public long longValue() {
return (long)value;
}
/**
* Returns the {@code float} value of this {@code Float} object.
*
* @return the {@code float} value represented by this object
*/
@HotSpotIntrinsicCandidate
public float floatValue() {
return value;
}
/**
* Returns the value of this {@code Float} as a {@code double}
* after a widening primitive conversion.
*
* @return the {@code float} value represented by this
* object converted to type {@code double}
* @jls 5.1.2 Widening Primitive Conversions
*/
public double doubleValue() {
return (double)value;
}
/**
* Returns a hash code for this {@code Float} object. The
* result is the integer bit representation, exactly as produced
* by the method {@link #floatToIntBits(float)}, of the primitive
* {@code float} value represented by this {@code Float}
* object.
*
* @return a hash code value for this object.
*/
@Override
public int hashCode() {
return Float.hashCode(value);
}
/**
* Returns a hash code for a {@code float} value; compatible with
* {@code Float.hashCode()}.
*
* @param value the value to hash
* @return a hash code value for a {@code float} value.
* @since 1.8
*/
public static int hashCode(float value) {
return floatToIntBits(value);
}
/**
* Compares this object against the specified object. The result
* is {@code true} if and only if the argument is not
* {@code null} and is a {@code Float} object that
* represents a {@code float} with the same value as the
* {@code float} represented by this object. For this
* purpose, two {@code float} values are considered to be the
* same if and only if the method {@link #floatToIntBits(float)}
* returns the identical {@code int} value when applied to
* each.
*
* <p>Note that in most cases, for two instances of class
* {@code Float}, {@code f1} and {@code f2}, the value
* of {@code f1.equals(f2)} is {@code true} if and only if
*
* <blockquote><pre>
* f1.floatValue() == f2.floatValue()
* </pre></blockquote>
*
* <p>also has the value {@code true}. However, there are two exceptions:
* <ul>
* <li>If {@code f1} and {@code f2} both represent
* {@code Float.NaN}, then the {@code equals} method returns
* {@code true}, even though {@code Float.NaN==Float.NaN}
* has the value {@code false}.
* <li>If {@code f1} represents {@code +0.0f} while
* {@code f2} represents {@code -0.0f}, or vice
* versa, the {@code equal} test has the value
* {@code false}, even though {@code 0.0f==-0.0f}
* has the value {@code true}.
* </ul>
*
* This definition allows hash tables to operate properly.
*
* @param obj the object to be compared
* @return {@code true} if the objects are the same;
* {@code false} otherwise.
* @see java.lang.Float#floatToIntBits(float)
*/
public boolean equals(Object obj) {
return (obj instanceof Float)
&& (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}
/**
* Returns a representation of the specified floating-point value
* according to the IEEE 754 floating-point "single format" bit
* layout.
*
* <p>Bit 31 (the bit that is selected by the mask
* {@code 0x80000000}) represents the sign of the floating-point
* number.
* Bits 30-23 (the bits that are selected by the mask
* {@code 0x7f800000}) represent the exponent.
* Bits 22-0 (the bits that are selected by the mask
* {@code 0x007fffff}) represent the significand (sometimes called
* the mantissa) of the floating-point number.
*
* <p>If the argument is positive infinity, the result is
* {@code 0x7f800000}.
*
* <p>If the argument is negative infinity, the result is
* {@code 0xff800000}.
*
* <p>If the argument is NaN, the result is {@code 0x7fc00000}.
*
* <p>In all cases, the result is an integer that, when given to the
* {@link #intBitsToFloat(int)} method, will produce a floating-point
* value the same as the argument to {@code floatToIntBits}
* (except all NaN values are collapsed to a single
* "canonical" NaN value).
*
* @param value a floating-point number.
* @return the bits that represent the floating-point number.
*/
@HotSpotIntrinsicCandidate
public static int floatToIntBits(float value) {
if (!isNaN(value)) {
return floatToRawIntBits(value);
}
return 0x7fc00000;
}
/**
* Returns a representation of the specified floating-point value
* according to the IEEE 754 floating-point "single format" bit
* layout, preserving Not-a-Number (NaN) values.
*
* <p>Bit 31 (the bit that is selected by the mask
* {@code 0x80000000}) represents the sign of the floating-point
* number.
* Bits 30-23 (the bits that are selected by the mask
* {@code 0x7f800000}) represent the exponent.
* Bits 22-0 (the bits that are selected by the mask
* {@code 0x007fffff}) represent the significand (sometimes called
* the mantissa) of the floating-point number.
*
* <p>If the argument is positive infinity, the result is
* {@code 0x7f800000}.
*
* <p>If the argument is negative infinity, the result is
* {@code 0xff800000}.
*
* <p>If the argument is NaN, the result is the integer representing
* the actual NaN value. Unlike the {@code floatToIntBits}
* method, {@code floatToRawIntBits} does not collapse all the
* bit patterns encoding a NaN to a single "canonical"
* NaN value.
*
* <p>In all cases, the result is an integer that, when given to the
* {@link #intBitsToFloat(int)} method, will produce a
* floating-point value the same as the argument to
* {@code floatToRawIntBits}.
*
* @param value a floating-point number.
* @return the bits that represent the floating-point number.
* @since 1.3
*/
@HotSpotIntrinsicCandidate
public static native int floatToRawIntBits(float value);
/**
* Returns the {@code float} value corresponding to a given
* bit representation.
* The argument is considered to be a representation of a
* floating-point value according to the IEEE 754 floating-point
* "single format" bit layout.
*
* <p>If the argument is {@code 0x7f800000}, the result is positive
* infinity.
*
* <p>If the argument is {@code 0xff800000}, the result is negative
* infinity.
*
* <p>If the argument is any value in the range
* {@code 0x7f800001} through {@code 0x7fffffff} or in
* the range {@code 0xff800001} through
* {@code 0xffffffff}, the result is a NaN. No IEEE 754
* floating-point operation provided by Java can distinguish
* between two NaN values of the same type with different bit
* patterns. Distinct values of NaN are only distinguishable by
* use of the {@code Float.floatToRawIntBits} method.
*
* <p>In all other cases, let <i>s</i>, <i>e</i>, and <i>m</i> be three
* values that can be computed from the argument:
*
* <blockquote><pre>{@code
* int s = ((bits >> 31) == 0) ? 1 : -1;
* int e = ((bits >> 23) & 0xff);
* int m = (e == 0) ?
* (bits & 0x7fffff) << 1 :
* (bits & 0x7fffff) | 0x800000;
* }</pre></blockquote>
*
* Then the floating-point result equals the value of the mathematical
* expression <i>s</i>&middot;<i>m</i>&middot;2<sup><i>e</i>-150</sup>.
*
* <p>Note that this method may not be able to return a
* {@code float} NaN with exactly same bit pattern as the
* {@code int} argument. IEEE 754 distinguishes between two
* kinds of NaNs, quiet NaNs and <i>signaling NaNs</i>. The
* differences between the two kinds of NaN are generally not
* visible in Java. Arithmetic operations on signaling NaNs turn
* them into quiet NaNs with a different, but often similar, bit
* pattern. However, on some processors merely copying a
* signaling NaN also performs that conversion. In particular,
* copying a signaling NaN to return it to the calling method may
* perform this conversion. So {@code intBitsToFloat} may
* not be able to return a {@code float} with a signaling NaN
* bit pattern. Consequently, for some {@code int} values,
* {@code floatToRawIntBits(intBitsToFloat(start))} may
* <i>not</i> equal {@code start}. Moreover, which
* particular bit patterns represent signaling NaNs is platform
* dependent; although all NaN bit patterns, quiet or signaling,
* must be in the NaN range identified above.
*
* @param bits an integer.
* @return the {@code float} floating-point value with the same bit
* pattern.
*/
@HotSpotIntrinsicCandidate
public static native float intBitsToFloat(int bits);
/**
* Compares two {@code Float} objects numerically. There are
* two ways in which comparisons performed by this method differ
* from those performed by the Java language numerical comparison
* operators ({@code <, <=, ==, >=, >}) when
* applied to primitive {@code float} values:
*
* <ul><li>
* {@code Float.NaN} is considered by this method to
* be equal to itself and greater than all other
* {@code float} values
* (including {@code Float.POSITIVE_INFINITY}).
* <li>
* {@code 0.0f} is considered by this method to be greater
* than {@code -0.0f}.
* </ul>
*
* This ensures that the <i>natural ordering</i> of {@code Float}
* objects imposed by this method is <i>consistent with equals</i>.
*
* @param anotherFloat the {@code Float} to be compared.
* @return the value {@code 0} if {@code anotherFloat} is
* numerically equal to this {@code Float}; a value
* less than {@code 0} if this {@code Float}
* is numerically less than {@code anotherFloat};
* and a value greater than {@code 0} if this
* {@code Float} is numerically greater than
* {@code anotherFloat}.
*
* @since 1.2
* @see Comparable#compareTo(Object)
*/
public int compareTo(Float anotherFloat) {
return Float.compare(value, anotherFloat.value);
}
/**
* Compares the two specified {@code float} values. The sign
* of the integer value returned is the same as that of the
* integer that would be returned by the call:
* <pre>
* new Float(f1).compareTo(new Float(f2))
* </pre>
*
* @param f1 the first {@code float} to compare.
* @param f2 the second {@code float} to compare.
* @return the value {@code 0} if {@code f1} is
* numerically equal to {@code f2}; a value less than
* {@code 0} if {@code f1} is numerically less than
* {@code f2}; and a value greater than {@code 0}
* if {@code f1} is numerically greater than
* {@code f2}.
* @since 1.4
*/
public static int compare(float f1, float f2) {
if (f1 < f2)
return -1; // Neither val is NaN, thisVal is smaller
if (f1 > f2)
return 1; // Neither val is NaN, thisVal is larger
// Cannot use floatToRawIntBits because of possibility of NaNs.
int thisBits = Float.floatToIntBits(f1);
int anotherBits = Float.floatToIntBits(f2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
/**
* Adds two {@code float} values together as per the + operator.
*
* @param a the first operand
* @param b the second operand
* @return the sum of {@code a} and {@code b}
* @jls 4.2.4 Floating-Point Operations
* @see java.util.function.BinaryOperator
* @since 1.8
*/
public static float sum(float a, float b) {
return a + b;
}
/**
* Returns the greater of two {@code float} values
* as if by calling {@link Math#max(float, float) Math.max}.
*
* @param a the first operand
* @param b the second operand
* @return the greater of {@code a} and {@code b}
* @see java.util.function.BinaryOperator
* @since 1.8
*/
public static float max(float a, float b) {
return Math.max(a, b);
}
/**
* Returns the smaller of two {@code float} values
* as if by calling {@link Math#min(float, float) Math.min}.
*
* @param a the first operand
* @param b the second operand
* @return the smaller of {@code a} and {@code b}
* @see java.util.function.BinaryOperator
* @since 1.8
*/
public static float min(float a, float b) {
return Math.min(a, b);
}
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -2671257302660747028L;
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.annotation.*;
/**
* An informative annotation type used to indicate that an interface
* type declaration is intended to be a <i>functional interface</i> as
* defined by the Java Language Specification.
*
* Conceptually, a functional interface has exactly one abstract
* method. Since {@linkplain java.lang.reflect.Method#isDefault()
* default methods} have an implementation, they are not abstract. If
* an interface declares an abstract method overriding one of the
* public methods of {@code java.lang.Object}, that also does
* <em>not</em> count toward the interface's abstract method count
* since any implementation of the interface will have an
* implementation from {@code java.lang.Object} or elsewhere.
*
* <p>Note that instances of functional interfaces can be created with
* lambda expressions, method references, or constructor references.
*
* <p>If a type is annotated with this annotation type, compilers are
* required to generate an error message unless:
*
* <ul>
* <li> The type is an interface type and not an annotation type, enum, or class.
* <li> The annotated type satisfies the requirements of a functional interface.
* </ul>
*
* <p>However, the compiler will treat any interface meeting the
* definition of a functional interface as a functional interface
* regardless of whether or not a {@code FunctionalInterface}
* annotation is present on the interface declaration.
*
* @jls 4.3.2. The Class Object
* @jls 9.8 Functional Interfaces
* @jls 9.4.3 Interface Method Body
* @jls 9.6.4.9 @FunctionalInterface
* @since 1.8
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown if an application attempts to access or modify a field, or
* to call a method that it does not have access to.
* <p>
* Normally, this error is caught by the compiler; this error can
* only occur at run time if the definition of a class has
* incompatibly changed.
*
* @author unascribed
* @since 1.0
*/
public class IllegalAccessError extends IncompatibleClassChangeError {
private static final long serialVersionUID = -8988904074992417891L;
/**
* Constructs an <code>IllegalAccessError</code> with no detail message.
*/
public IllegalAccessError() {
super();
}
/**
* Constructs an <code>IllegalAccessError</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public IllegalAccessError(String s) {
super(s);
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* An IllegalAccessException is thrown when an application tries
* to reflectively create an instance (other than an array),
* set or get a field, or invoke a method, but the currently
* executing method does not have access to the definition of
* the specified class, field, method or constructor.
*
* @author unascribed
* @see Class#newInstance()
* @see java.lang.reflect.Field#set(Object, Object)
* @see java.lang.reflect.Field#setBoolean(Object, boolean)
* @see java.lang.reflect.Field#setByte(Object, byte)
* @see java.lang.reflect.Field#setShort(Object, short)
* @see java.lang.reflect.Field#setChar(Object, char)
* @see java.lang.reflect.Field#setInt(Object, int)
* @see java.lang.reflect.Field#setLong(Object, long)
* @see java.lang.reflect.Field#setFloat(Object, float)
* @see java.lang.reflect.Field#setDouble(Object, double)
* @see java.lang.reflect.Field#get(Object)
* @see java.lang.reflect.Field#getBoolean(Object)
* @see java.lang.reflect.Field#getByte(Object)
* @see java.lang.reflect.Field#getShort(Object)
* @see java.lang.reflect.Field#getChar(Object)
* @see java.lang.reflect.Field#getInt(Object)
* @see java.lang.reflect.Field#getLong(Object)
* @see java.lang.reflect.Field#getFloat(Object)
* @see java.lang.reflect.Field#getDouble(Object)
* @see java.lang.reflect.Method#invoke(Object, Object[])
* @see java.lang.reflect.Constructor#newInstance(Object[])
* @since 1.0
*/
public class IllegalAccessException extends ReflectiveOperationException {
private static final long serialVersionUID = 6616958222490762034L;
/**
* Constructs an <code>IllegalAccessException</code> without a
* detail message.
*/
public IllegalAccessException() {
super();
}
/**
* Constructs an <code>IllegalAccessException</code> with a detail message.
*
* @param s the detail message.
*/
public IllegalAccessException(String s) {
super(s);
}
}

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 1994, 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that a method has been passed an illegal or
* inappropriate argument.
*
* @author unascribed
* @since 1.0
*/
public
class IllegalArgumentException extends RuntimeException {
/**
* Constructs an <code>IllegalArgumentException</code> with no
* detail message.
*/
public IllegalArgumentException() {
super();
}
/**
* Constructs an <code>IllegalArgumentException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public IllegalArgumentException(String s) {
super(s);
}
/**
* Constructs a new exception with the specified detail message and
* cause.
*
* <p>Note that the detail message associated with <code>cause</code> is
* <i>not</i> automatically incorporated in this exception's detail
* message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link Throwable#getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link Throwable#getCause()} method). (A {@code null} value
* is permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.5
*/
public IllegalArgumentException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new exception with the specified cause and a detail
* message of {@code (cause==null ? null : cause.toString())} (which
* typically contains the class and detail message of {@code cause}).
* This constructor is useful for exceptions that are little more than
* wrappers for other throwables (for example, {@link
* java.security.PrivilegedActionException}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link Throwable#getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.5
*/
public IllegalArgumentException(Throwable cause) {
super(cause);
}
private static final long serialVersionUID = -5365630128856068164L;
}

View file

@ -0,0 +1,76 @@
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that a method has been called by an inappropriate caller.
*
* @since 9
* @spec JPMS
* @see StackWalker#getCallerClass
*/
public class IllegalCallerException extends RuntimeException {
/**
* Constructs an IllegalCallerException with no detail message.
*/
public IllegalCallerException() {
super();
}
/**
* Constructs an IllegalCallerException with the specified detail
* message.
*
* @param s the String that contains a detailed message (can be null)
*/
public IllegalCallerException(String s) {
super(s);
}
/**
* Constructs a new exception with the specified detail message and
* cause.
*
* @param message the detail message (can be null)
* @param cause the cause (can be null)
*/
public IllegalCallerException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new exception with the specified cause and a detail
* message of {@code (cause==null ? null : cause.toString())} (which
* typically contains the class and detail message of {@code cause}).
*
* @param cause the cause (can be null)
*/
public IllegalCallerException(Throwable cause) {
super(cause);
}
static final long serialVersionUID = -2349421918363102232L;
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that a thread has attempted to wait on an
* object's monitor or to notify other threads waiting on an object's
* monitor without owning the specified monitor.
*
* @author unascribed
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
* @see java.lang.Object#wait()
* @see java.lang.Object#wait(long)
* @see java.lang.Object#wait(long, int)
* @since 1.0
*/
public
class IllegalMonitorStateException extends RuntimeException {
private static final long serialVersionUID = 3713306369498869069L;
/**
* Constructs an <code>IllegalMonitorStateException</code> with no
* detail message.
*/
public IllegalMonitorStateException() {
super();
}
/**
* Constructs an <code>IllegalMonitorStateException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public IllegalMonitorStateException(String s) {
super(s);
}
}

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 1996, 2003, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Signals that a method has been invoked at an illegal or
* inappropriate time. In other words, the Java environment or
* Java application is not in an appropriate state for the requested
* operation.
*
* @author Jonni Kanerva
* @since 1.1
*/
public
class IllegalStateException extends RuntimeException {
/**
* Constructs an IllegalStateException with no detail message.
* A detail message is a String that describes this particular exception.
*/
public IllegalStateException() {
super();
}
/**
* Constructs an IllegalStateException with the specified detail
* message. A detail message is a String that describes this particular
* exception.
*
* @param s the String that contains a detailed message
*/
public IllegalStateException(String s) {
super(s);
}
/**
* Constructs a new exception with the specified detail message and
* cause.
*
* <p>Note that the detail message associated with <code>cause</code> is
* <i>not</i> automatically incorporated in this exception's detail
* message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link Throwable#getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link Throwable#getCause()} method). (A {@code null} value
* is permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.5
*/
public IllegalStateException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new exception with the specified cause and a detail
* message of {@code (cause==null ? null : cause.toString())} (which
* typically contains the class and detail message of {@code cause}).
* This constructor is useful for exceptions that are little more than
* wrappers for other throwables (for example, {@link
* java.security.PrivilegedActionException}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link Throwable#getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.5
*/
public IllegalStateException(Throwable cause) {
super(cause);
}
static final long serialVersionUID = -1848914673093119416L;
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 1994, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that a thread is not in an appropriate state
* for the requested operation. See, for example, the
* <code>suspend</code> and <code>resume</code> methods in class
* <code>Thread</code>.
*
* @author unascribed
* @see java.lang.Thread#resume()
* @see java.lang.Thread#suspend()
* @since 1.0
*/
public class IllegalThreadStateException extends IllegalArgumentException {
private static final long serialVersionUID = -7626246362397460174L;
/**
* Constructs an <code>IllegalThreadStateException</code> with no
* detail message.
*/
public IllegalThreadStateException() {
super();
}
/**
* Constructs an <code>IllegalThreadStateException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public IllegalThreadStateException(String s) {
super(s);
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 1994, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when an incompatible class change has occurred to some class
* definition. The definition of some class, on which the currently
* executing method depends, has since changed.
*
* @author unascribed
* @since 1.0
*/
public
class IncompatibleClassChangeError extends LinkageError {
private static final long serialVersionUID = -4914975503642802119L;
/**
* Constructs an <code>IncompatibleClassChangeError</code> with no
* detail message.
*/
public IncompatibleClassChangeError () {
super();
}
/**
* Constructs an <code>IncompatibleClassChangeError</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public IncompatibleClassChangeError(String s) {
super(s);
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 1995, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that an index of some sort (such as to an array, to a
* string, or to a vector) is out of range.
* <p>
* Applications can subclass this class to indicate similar exceptions.
*
* @author Frank Yellin
* @since 1.0
*/
public class IndexOutOfBoundsException extends RuntimeException {
private static final long serialVersionUID = 234122996006267687L;
/**
* Constructs an {@code IndexOutOfBoundsException} with no detail message.
*/
public IndexOutOfBoundsException() {
super();
}
/**
* Constructs an {@code IndexOutOfBoundsException} with the specified detail
* message.
*
* @param s the detail message
*/
public IndexOutOfBoundsException(String s) {
super(s);
}
/**
* Constructs a new {@code IndexOutOfBoundsException} class with an
* argument indicating the illegal index.
*
* <p>The index is included in this exception's detail message. The
* exact presentation format of the detail message is unspecified.
*
* @param index the illegal index.
* @since 9
*/
public IndexOutOfBoundsException(int index) {
super("Index out of range: " + index);
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 1998, 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.ref.*;
/**
* This class extends {@code ThreadLocal} to provide inheritance of values
* from parent thread to child thread: when a child thread is created, the
* child receives initial values for all inheritable thread-local variables
* for which the parent has values. Normally the child's values will be
* identical to the parent's; however, the child's value can be made an
* arbitrary function of the parent's by overriding the {@code childValue}
* method in this class.
*
* <p>Inheritable thread-local variables are used in preference to
* ordinary thread-local variables when the per-thread-attribute being
* maintained in the variable (e.g., User ID, Transaction ID) must be
* automatically transmitted to any child threads that are created.
*
* <p>Note: During the creation of a new {@link
* Thread#Thread(ThreadGroup,Runnable,String,long,boolean) thread}, it is
* possible to <i>opt out</i> of receiving initial values for inheritable
* thread-local variables.
*
* @author Josh Bloch and Doug Lea
* @see ThreadLocal
* @since 1.2
*/
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
/**
* Computes the child's initial value for this inheritable thread-local
* variable as a function of the parent's value at the time the child
* thread is created. This method is called from within the parent
* thread before the child is started.
* <p>
* This method merely returns its input argument, and should be overridden
* if a different behavior is desired.
*
* @param parentValue the parent thread's value
* @return the child thread's initial value
*/
protected T childValue(T parentValue) {
return parentValue;
}
/**
* Get the map associated with a ThreadLocal.
*
* @param t the current thread
*/
ThreadLocalMap getMap(Thread t) {
return t.inheritableThreadLocals;
}
/**
* Create the map associated with a ThreadLocal.
*
* @param t the current thread
* @param firstValue value for the initial entry of the table.
*/
void createMap(Thread t, T firstValue) {
t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when an application tries to use the Java <code>new</code>
* construct to instantiate an abstract class or an interface.
* <p>
* Normally, this error is caught by the compiler; this error can
* only occur at run time if the definition of a class has
* incompatibly changed.
*
* @author unascribed
* @since 1.0
*/
public
class InstantiationError extends IncompatibleClassChangeError {
private static final long serialVersionUID = -4885810657349421204L;
/**
* Constructs an <code>InstantiationError</code> with no detail message.
*/
public InstantiationError() {
super();
}
/**
* Constructs an <code>InstantiationError</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public InstantiationError(String s) {
super(s);
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when an application tries to create an instance of a class
* using the {@code newInstance} method in class
* {@code Class}, but the specified class object cannot be
* instantiated. The instantiation can fail for a variety of
* reasons including but not limited to:
*
* <ul>
* <li> the class object represents an abstract class, an interface,
* an array class, a primitive type, or {@code void}
* <li> the class has no nullary constructor
*</ul>
*
* @author unascribed
* @see java.lang.Class#newInstance()
* @since 1.0
*/
public
class InstantiationException extends ReflectiveOperationException {
private static final long serialVersionUID = -8441929162975509110L;
/**
* Constructs an {@code InstantiationException} with no detail message.
*/
public InstantiationException() {
super();
}
/**
* Constructs an {@code InstantiationException} with the
* specified detail message.
*
* @param s the detail message.
*/
public InstantiationException(String s) {
super(s);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 1994, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate some unexpected internal error has occurred in
* the Java Virtual Machine.
*
* @author unascribed
* @since 1.0
*/
public class InternalError extends VirtualMachineError {
private static final long serialVersionUID = -9062593416125562365L;
/**
* Constructs an <code>InternalError</code> with no detail message.
*/
public InternalError() {
super();
}
/**
* Constructs an <code>InternalError</code> with the specified
* detail message.
*
* @param message the detail message.
*/
public InternalError(String message) {
super(message);
}
/**
* Constructs an {@code InternalError} with the specified detail
* message and cause. <p>Note that the detail message associated
* with {@code cause} is <i>not</i> automatically incorporated in
* this error's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.8
*/
public InternalError(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs an {@code InternalError} with the specified cause
* and a detail message of {@code (cause==null ? null :
* cause.toString())} (which typically contains the class and
* detail message of {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.8
*/
public InternalError(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when a thread is waiting, sleeping, or otherwise occupied,
* and the thread is interrupted, either before or during the activity.
* Occasionally a method may wish to test whether the current
* thread has been interrupted, and if so, to immediately throw
* this exception. The following code can be used to achieve
* this effect:
* <pre>
* if (Thread.interrupted()) // Clears interrupted status!
* throw new InterruptedException();
* </pre>
*
* @author Frank Yellin
* @see java.lang.Object#wait()
* @see java.lang.Object#wait(long)
* @see java.lang.Object#wait(long, int)
* @see java.lang.Thread#sleep(long)
* @see java.lang.Thread#interrupt()
* @see java.lang.Thread#interrupted()
* @since 1.0
*/
public
class InterruptedException extends Exception {
private static final long serialVersionUID = 6700697376100628473L;
/**
* Constructs an <code>InterruptedException</code> with no detail message.
*/
public InterruptedException() {
super();
}
/**
* Constructs an <code>InterruptedException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public InterruptedException(String s) {
super(s);
}
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2003, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
/**
* Implementing this interface allows an object to be the target of the enhanced
* {@code for} statement (sometimes called the "for-each loop" statement).
*
* @param <T> the type of elements returned by the iterator
*
* @since 1.5
* @jls 14.14.2 The enhanced {@code for} statement
*/
public interface Iterable<T> {
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator<T> iterator();
/**
* Performs the given action for each element of the {@code Iterable}
* until all elements have been processed or the action throws an
* exception. Actions are performed in the order of iteration, if that
* order is specified. Exceptions thrown by the action are relayed to the
* caller.
* <p>
* The behavior of this method is unspecified if the action performs
* side-effects that modify the underlying source of elements, unless an
* overriding class has specified a concurrent modification policy.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* for (T t : this)
* action.accept(t);
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
/**
* Creates a {@link Spliterator} over the elements described by this
* {@code Iterable}.
*
* @implSpec
* The default implementation creates an
* <em><a href="../util/Spliterator.html#binding">early-binding</a></em>
* spliterator from the iterable's {@code Iterator}. The spliterator
* inherits the <em>fail-fast</em> properties of the iterable's iterator.
*
* @implNote
* The default implementation should usually be overridden. The
* spliterator returned by the default implementation has poor splitting
* capabilities, is unsized, and does not report any spliterator
* characteristics. Implementing classes can nearly always provide a
* better implementation.
*
* @return a {@code Spliterator} over the elements described by this
* {@code Iterable}.
* @since 1.8
*/
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}

View file

@ -0,0 +1,78 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when creating a {@linkplain ModuleLayer module layer} fails.
*
* @see ModuleLayer
* @since 9
* @spec JPMS
*/
public class LayerInstantiationException extends RuntimeException {
private static final long serialVersionUID = -906239691613568347L;
/**
* Constructs a {@code LayerInstantiationException} with no detail message.
*/
public LayerInstantiationException() {
}
/**
* Constructs a {@code LayerInstantiationException} with the given detail
* message.
*
* @param msg
* The detail message; can be {@code null}
*/
public LayerInstantiationException(String msg) {
super(msg);
}
/**
* Constructs a {@code LayerInstantiationException} with the given cause.
*
* @param cause
* The cause; can be {@code null}
*/
public LayerInstantiationException(Throwable cause) {
super(cause);
}
/**
* Constructs a {@code LayerInstantiationException} with the given detail
* message and cause.
*
* @param msg
* The detail message; can be {@code null}
* @param cause
* The cause; can be {@code null}
*/
public LayerInstantiationException(String msg, Throwable cause) {
super(msg, cause);
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 1995, 2010, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Subclasses of {@code LinkageError} indicate that a class has
* some dependency on another class; however, the latter class has
* incompatibly changed after the compilation of the former class.
*
*
* @author Frank Yellin
* @since 1.0
*/
public
class LinkageError extends Error {
private static final long serialVersionUID = 3579600108157160122L;
/**
* Constructs a {@code LinkageError} with no detail message.
*/
public LinkageError() {
super();
}
/**
* Constructs a {@code LinkageError} with the specified detail
* message.
*
* @param s the detail message.
*/
public LinkageError(String s) {
super(s);
}
/**
* Constructs a {@code LinkageError} with the specified detail
* message and cause.
*
* @param s the detail message.
* @param cause the cause, may be {@code null}
* @since 1.7
*/
public LinkageError(String s, Throwable cause) {
super(s, cause);
}
}

View file

@ -0,0 +1,181 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.StackWalker.StackFrame;
import java.util.EnumSet;
import java.util.Set;
import static java.lang.StackWalker.ExtendedOption.LOCALS_AND_OPERANDS;
/**
* <em>UNSUPPORTED</em> This interface is intended to be package-private
* or move to an internal package.<p>
*
* {@code LiveStackFrame} represents a frame storing data and partial results.
* Each frame has its own array of local variables (JVMS section 2.6.1),
* its own operand stack (JVMS section 2.6.2) for a method invocation.
*
* @jvms 2.6 Frames
*/
/* package-private */
interface LiveStackFrame extends StackFrame {
/**
* Return the monitors held by this stack frame. This method returns
* an empty array if no monitor is held by this stack frame.
*
* @return the monitors held by this stack frames
*/
public Object[] getMonitors();
/**
* Gets the local variable array of this stack frame.
*
* <p>A single local variable can hold a value of type boolean, byte, char,
* short, int, float, reference or returnAddress. A pair of local variables
* can hold a value of type long or double (JVMS section 2.6.1). Primitive
* locals are represented in the returned array as {@code PrimitiveSlot}s,
* with longs and doubles occupying a pair of consecutive
* {@code PrimitiveSlot}s.
*
* <p>The current VM implementation does not provide specific type
* information for primitive locals. This method simply returns the raw
* contents of the VM's primitive locals on a best-effort basis, without
* indicating a specific type.
*
* <p>The returned array may contain null entries for local variables that
* are not live.
*
* @implNote
* <p> The specific subclass of {@code PrimitiveSlot} will reflect the
* underlying architecture, and will be either {@code PrimitiveSlot32} or
* {@code PrimitiveSlot64}.
*
* <p>How a long or double value is stored in the pair of
* {@code PrimitiveSlot}s can vary based on the underlying architecture and
* VM implementation. On 32-bit architectures, long/double values are split
* between the two {@code PrimitiveSlot32}s.
* On 64-bit architectures, the entire value may be stored in one of the
* {@code PrimitiveSlot64}s, with the other {@code PrimitiveSlot64} being
* unused.
*
* <p>The contents of the unused, high-order portion of a
* {@code PrimitiveSlot64} (when storing a primitive other than a long or
* double) is unspecified. In particular, the unused bits are not
* necessarily zeroed out.
*
* @return the local variable array of this stack frame.
*/
public Object[] getLocals();
/**
* Gets the operand stack of this stack frame.
*
* <p>
* The 0-th element of the returned array represents the top of the operand stack.
* This method returns an empty array if the operand stack is empty.
*
* <p>Each entry on the operand stack can hold a value of any Java Virtual
* Machine Type.
* For a value of primitive type, the element in the returned array is
* a {@link PrimitiveSlot} object; otherwise, the element is the {@code Object}
* on the operand stack.
*
* @return the operand stack of this stack frame.
*/
public Object[] getStack();
/**
* <em>UNSUPPORTED</em> This interface is intended to be package-private
* or moved to an internal package.<p>
*
* Represents a local variable or an entry on the operand stack whose value is
* of primitive type.
*/
public abstract class PrimitiveSlot {
/**
* Returns the size, in bytes, of the slot.
*/
public abstract int size();
/**
* Returns the int value if this primitive value is of size 4
* @return the int value if this primitive value is of size 4
*
* @throws UnsupportedOperationException if this primitive value is not
* of size 4.
*/
public int intValue() {
throw new UnsupportedOperationException("this " + size() + "-byte primitive");
}
/**
* Returns the long value if this primitive value is of size 8
* @return the long value if this primitive value is of size 8
*
* @throws UnsupportedOperationException if this primitive value is not
* of size 8.
*/
public long longValue() {
throw new UnsupportedOperationException("this " + size() + "-byte primitive");
}
}
/**
* Gets {@code StackWalker} that can get locals and operands.
*
* @throws SecurityException if the security manager is present and
* denies access to {@code RuntimePermission("liveStackFrames")}
*/
public static StackWalker getStackWalker() {
return getStackWalker(EnumSet.noneOf(StackWalker.Option.class));
}
/**
* Gets a {@code StackWalker} instance with the given options specifying
* the stack frame information it can access, and which will traverse at most
* the given {@code maxDepth} number of stack frames. If no option is
* specified, this {@code StackWalker} obtains the method name and
* the class name with all
* {@linkplain StackWalker.Option#SHOW_HIDDEN_FRAMES hidden frames} skipped.
* The returned {@code StackWalker} can get locals and operands.
*
* @param options stack walk {@link StackWalker.Option options}
*
* @throws SecurityException if the security manager is present and
* it denies access to {@code RuntimePermission("liveStackFrames")}; or
* or if the given {@code options} contains
* {@link StackWalker.Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE}
* and it denies access to {@code RuntimePermission("getStackWalkerWithClassReference")}.
*/
public static StackWalker getStackWalker(Set<StackWalker.Option> options) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("liveStackFrames"));
}
return StackWalker.newInstance(options, LOCALS_AND_OPERANDS);
}
}

View file

@ -0,0 +1,131 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
final class LiveStackFrameInfo extends StackFrameInfo implements LiveStackFrame {
private static Object[] EMPTY_ARRAY = new Object[0];
// These flags must match the values maintained in the VM
private static final int MODE_INTERPRETED = 0x01;
private static final int MODE_COMPILED = 0x02;
LiveStackFrameInfo(StackWalker walker) {
super(walker);
}
// These fields are initialized by the VM if ExtendedOption.LOCALS_AND_OPERANDS is set
private Object[] monitors = EMPTY_ARRAY;
private Object[] locals = EMPTY_ARRAY;
private Object[] operands = EMPTY_ARRAY;
private int mode = 0;
@Override
public Object[] getMonitors() {
return monitors;
}
@Override
public Object[] getLocals() {
return locals;
}
@Override
public Object[] getStack() {
return operands;
}
@Override
public String toString() {
StringBuilder retVal = new StringBuilder(super.toString());
if (mode != 0) {
retVal.append("(");
if ((mode & MODE_INTERPRETED) == MODE_INTERPRETED) {
retVal.append(" interpreted ");
}
if ((mode & MODE_COMPILED) == MODE_COMPILED) {
retVal.append(" compiled ");
}
retVal.append(")");
}
return retVal.toString();
}
/*
* Convert primitive value to {@code PrimitiveSlot} object to represent
* a local variable or an element on the operand stack of primitive type.
*/
static PrimitiveSlot asPrimitive(int value) {
return new PrimitiveSlot32(value);
}
static PrimitiveSlot asPrimitive(long value) {
return new PrimitiveSlot64(value);
}
private static class PrimitiveSlot32 extends PrimitiveSlot {
final int value;
PrimitiveSlot32(int value) {
this.value = value;
}
@Override
public int size() {
return 4;
}
@Override
public int intValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}
private static class PrimitiveSlot64 extends PrimitiveSlot {
final long value;
PrimitiveSlot64(long value) {
this.value = value;
}
@Override
public int size() {
return 8;
}
@Override
public long longValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,981 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ResolvedModule;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.loader.ClassLoaderValue;
import jdk.internal.loader.Loader;
import jdk.internal.loader.LoaderPool;
import jdk.internal.module.ServicesCatalog;
import sun.security.util.SecurityConstants;
/**
* A layer of modules in the Java virtual machine.
*
* <p> A layer is created from a graph of modules in a {@link Configuration}
* and a function that maps each module to a {@link ClassLoader}.
* Creating a layer informs the Java virtual machine about the classes that
* may be loaded from the modules so that the Java virtual machine knows which
* module that each class is a member of. </p>
*
* <p> Creating a layer creates a {@link Module} object for each {@link
* ResolvedModule} in the configuration. For each resolved module that is
* {@link ResolvedModule#reads() read}, the {@code Module} {@link
* Module#canRead reads} the corresponding run-time {@code Module}, which may
* be in the same layer or a {@link #parents() parent} layer. </p>
*
* <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
* {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
* provide convenient ways to create a module layer where all modules are
* mapped to a single class loader or where each module is mapped to its own
* class loader. The {@link #defineModules defineModules} method is for more
* advanced cases where modules are mapped to custom class loaders by means of
* a function specified to the method. Each of these methods has an instance
* and static variant. The instance methods create a layer with the receiver
* as the parent layer. The static methods are for more advanced cases where
* there can be more than one parent layer or where a {@link
* ModuleLayer.Controller Controller} is needed to control modules in the layer
* </p>
*
* <p> A Java virtual machine has at least one non-empty layer, the {@link
* #boot() boot} layer, that is created when the Java virtual machine is
* started. The boot layer contains module {@code java.base} and is the only
* layer in the Java virtual machine with a module named "{@code java.base}".
* The modules in the boot layer are mapped to the bootstrap class loader and
* other class loaders that are <a href="ClassLoader.html#builtinLoaders">
* built-in</a> into the Java virtual machine. The boot layer will often be
* the {@link #parents() parent} when creating additional layers. </p>
*
* <p> Each {@code Module} in a layer is created so that it {@link
* Module#isExported(String) exports} and {@link Module#isOpen(String) opens}
* the packages described by its {@link ModuleDescriptor}. Qualified exports
* (where a package is exported to a set of target modules rather than all
* modules) are reified when creating the layer as follows: </p>
* <ul>
* <li> If module {@code X} exports a package to {@code Y}, and if the
* runtime {@code Module} {@code X} reads {@code Module} {@code Y}, then
* the package is exported to {@code Module} {@code Y} (which may be in
* the same layer as {@code X} or a parent layer). </li>
*
* <li> If module {@code X} exports a package to {@code Y}, and if the
* runtime {@code Module} {@code X} does not read {@code Y} then target
* {@code Y} is located as if by invoking {@link #findModule(String)
* findModule} to find the module in the layer or its parent layers. If
* {@code Y} is found then the package is exported to the instance of
* {@code Y} that was found. If {@code Y} is not found then the qualified
* export is ignored. </li>
* </ul>
*
* <p> Qualified opens are handled in same way as qualified exports. </p>
*
* <p> As when creating a {@code Configuration},
* {@link ModuleDescriptor#isAutomatic() automatic} modules receive special
* treatment when creating a layer. An automatic module is created in the
* Java virtual machine as a {@code Module} that reads every unnamed {@code
* Module} in the Java virtual machine. </p>
*
* <p> Unless otherwise specified, passing a {@code null} argument to a method
* in this class causes a {@link NullPointerException NullPointerException} to
* be thrown. </p>
*
* <h3> Example usage: </h3>
*
* <p> This example creates a configuration by resolving a module named
* "{@code myapp}" with the configuration for the boot layer as the parent. It
* then creates a new layer with the modules in this configuration. All modules
* are defined to the same class loader. </p>
*
* <pre>{@code
* ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
*
* ModuleLayer parent = ModuleLayer.boot();
*
* Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
*
* ClassLoader scl = ClassLoader.getSystemClassLoader();
*
* ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
*
* Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
* }</pre>
*
* @since 9
* @spec JPMS
* @see Module#getLayer()
*/
public final class ModuleLayer {
// the empty layer
private static final ModuleLayer EMPTY_LAYER
= new ModuleLayer(Configuration.empty(), List.of(), null);
// the configuration from which this ;ayer was created
private final Configuration cf;
// parent layers, empty in the case of the empty layer
private final List<ModuleLayer> parents;
// maps module name to jlr.Module
private final Map<String, Module> nameToModule;
/**
* Creates a new module layer from the modules in the given configuration.
*/
private ModuleLayer(Configuration cf,
List<ModuleLayer> parents,
Function<String, ClassLoader> clf)
{
this.cf = cf;
this.parents = parents; // no need to do defensive copy
Map<String, Module> map;
if (parents.isEmpty()) {
map = Collections.emptyMap();
} else {
map = Module.defineModules(cf, clf, this);
}
this.nameToModule = map; // no need to do defensive copy
}
/**
* Controls a module layer. The static methods defined by {@link ModuleLayer}
* to create module layers return a {@code Controller} that can be used to
* control modules in the layer.
*
* <p> Unless otherwise specified, passing a {@code null} argument to a
* method in this class causes a {@link NullPointerException
* NullPointerException} to be thrown. </p>
*
* @apiNote Care should be taken with {@code Controller} objects, they
* should never be shared with untrusted code.
*
* @since 9
* @spec JPMS
*/
public static final class Controller {
private final ModuleLayer layer;
Controller(ModuleLayer layer) {
this.layer = layer;
}
/**
* Returns the layer that this object controls.
*
* @return the module layer
*/
public ModuleLayer layer() {
return layer;
}
private void ensureInLayer(Module source) {
if (source.getLayer() != layer)
throw new IllegalArgumentException(source + " not in layer");
}
/**
* Updates module {@code source} in the layer to read module
* {@code target}. This method is a no-op if {@code source} already
* reads {@code target}.
*
* @implNote <em>Read edges</em> added by this method are <em>weak</em>
* and do not prevent {@code target} from being GC'ed when {@code source}
* is strongly reachable.
*
* @param source
* The source module
* @param target
* The target module to read
*
* @return This controller
*
* @throws IllegalArgumentException
* If {@code source} is not in the module layer
*
* @see Module#addReads
*/
public Controller addReads(Module source, Module target) {
ensureInLayer(source);
source.implAddReads(target);
return this;
}
/**
* Updates module {@code source} in the layer to export a package to
* module {@code target}. This method is a no-op if {@code source}
* already exports the package to at least {@code target}.
*
* @param source
* The source module
* @param pn
* The package name
* @param target
* The target module
*
* @return This controller
*
* @throws IllegalArgumentException
* If {@code source} is not in the module layer or the package
* is not in the source module
*
* @see Module#addExports
*/
public Controller addExports(Module source, String pn, Module target) {
ensureInLayer(source);
source.implAddExports(pn, target);
return this;
}
/**
* Updates module {@code source} in the layer to open a package to
* module {@code target}. This method is a no-op if {@code source}
* already opens the package to at least {@code target}.
*
* @param source
* The source module
* @param pn
* The package name
* @param target
* The target module
*
* @return This controller
*
* @throws IllegalArgumentException
* If {@code source} is not in the module layer or the package
* is not in the source module
*
* @see Module#addOpens
*/
public Controller addOpens(Module source, String pn, Module target) {
ensureInLayer(source);
source.implAddOpens(pn, target);
return this;
}
}
/**
* Creates a new module layer, with this layer as its parent, by defining the
* modules in the given {@code Configuration} to the Java virtual machine.
* This method creates one class loader and defines all modules to that
* class loader. The {@link ClassLoader#getParent() parent} of each class
* loader is the given parent class loader. This method works exactly as
* specified by the static {@link
* #defineModulesWithOneLoader(Configuration,List,ClassLoader)
* defineModulesWithOneLoader} method when invoked with this layer as the
* parent. In other words, if this layer is {@code thisLayer} then this
* method is equivalent to invoking:
* <pre> {@code
* ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
* }</pre>
*
* @param cf
* The configuration for the layer
* @param parentLoader
* The parent class loader for the class loader created by this
* method; may be {@code null} for the bootstrap class loader
*
* @return The newly created layer
*
* @throws IllegalArgumentException
* If the parent of the given configuration is not the configuration
* for this layer
* @throws LayerInstantiationException
* If the layer cannot be created for any of the reasons specified
* by the static {@code defineModulesWithOneLoader} method
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
* the security manager
*
* @see #findLoader
*/
public ModuleLayer defineModulesWithOneLoader(Configuration cf,
ClassLoader parentLoader) {
return defineModulesWithOneLoader(cf, List.of(this), parentLoader).layer();
}
/**
* Creates a new module layer, with this layer as its parent, by defining the
* modules in the given {@code Configuration} to the Java virtual machine.
* Each module is defined to its own {@link ClassLoader} created by this
* method. The {@link ClassLoader#getParent() parent} of each class loader
* is the given parent class loader. This method works exactly as specified
* by the static {@link
* #defineModulesWithManyLoaders(Configuration,List,ClassLoader)
* defineModulesWithManyLoaders} method when invoked with this layer as the
* parent. In other words, if this layer is {@code thisLayer} then this
* method is equivalent to invoking:
* <pre> {@code
* ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
* }</pre>
*
* @param cf
* The configuration for the layer
* @param parentLoader
* The parent class loader for each of the class loaders created by
* this method; may be {@code null} for the bootstrap class loader
*
* @return The newly created layer
*
* @throws IllegalArgumentException
* If the parent of the given configuration is not the configuration
* for this layer
* @throws LayerInstantiationException
* If the layer cannot be created for any of the reasons specified
* by the static {@code defineModulesWithManyLoaders} method
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
* the security manager
*
* @see #findLoader
*/
public ModuleLayer defineModulesWithManyLoaders(Configuration cf,
ClassLoader parentLoader) {
return defineModulesWithManyLoaders(cf, List.of(this), parentLoader).layer();
}
/**
* Creates a new module layer, with this layer as its parent, by defining the
* modules in the given {@code Configuration} to the Java virtual machine.
* Each module is mapped, by name, to its class loader by means of the
* given function. This method works exactly as specified by the static
* {@link #defineModules(Configuration,List,Function) defineModules}
* method when invoked with this layer as the parent. In other words, if
* this layer is {@code thisLayer} then this method is equivalent to
* invoking:
* <pre> {@code
* ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
* }</pre>
*
* @param cf
* The configuration for the layer
* @param clf
* The function to map a module name to a class loader
*
* @return The newly created layer
*
* @throws IllegalArgumentException
* If the parent of the given configuration is not the configuration
* for this layer
* @throws LayerInstantiationException
* If the layer cannot be created for any of the reasons specified
* by the static {@code defineModules} method
* @throws SecurityException
* If {@code RuntimePermission("getClassLoader")} is denied by
* the security manager
*/
public ModuleLayer defineModules(Configuration cf,
Function<String, ClassLoader> clf) {
return defineModules(cf, List.of(this), clf).layer();
}
/**
* Creates a new module layer by defining the modules in the given {@code
* Configuration} to the Java virtual machine. This method creates one
* class loader and defines all modules to that class loader.
*
* <p> The class loader created by this method implements <em>direct
* delegation</em> when loading classes from modules. If the {@link
* ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
* load a class then it uses the package name of the class to map it to a
* module. This may be a module in this layer and hence defined to the same
* class loader. It may be a package in a module in a parent layer that is
* exported to one or more of the modules in this layer. The class
* loader delegates to the class loader of the module, throwing {@code
* ClassNotFoundException} if not found by that class loader.
* When {@code loadClass} is invoked to load classes that do not map to a
* module then it delegates to the parent class loader. </p>
*
* <p> The class loader created by this method locates resources
* ({@link ClassLoader#getResource(String) getResource}, {@link
* ClassLoader#getResources(String) getResources}, and other resource
* methods) in all modules in the layer before searching the parent class
* loader. </p>
*
* <p> Attempting to create a layer with all modules defined to the same
* class loader can fail for the following reasons:
*
* <ul>
*
* <li><p> <em>Overlapping packages</em>: Two or more modules in the
* configuration have the same package. </p></li>
*
* <li><p> <em>Split delegation</em>: The resulting class loader would
* need to delegate to more than one class loader in order to load
* classes in a specific package. </p></li>
*
* </ul>
*
* <p> In addition, a layer cannot be created if the configuration contains
* a module named "{@code java.base}", or a module contains a package named
* "{@code java}" or a package with a name starting with "{@code java.}". </p>
*
* <p> If there is a security manager then the class loader created by
* this method will load classes and resources with privileges that are
* restricted by the calling context of this method. </p>
*
* @param cf
* The configuration for the layer
* @param parentLayers
* The list of parent layers in search order
* @param parentLoader
* The parent class loader for the class loader created by this
* method; may be {@code null} for the bootstrap class loader
*
* @return A controller that controls the newly created layer
*
* @throws IllegalArgumentException
* If the parent configurations do not match the configuration of
* the parent layers, including order
* @throws LayerInstantiationException
* If all modules cannot be defined to the same class loader for any
* of the reasons listed above
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
* the security manager
*
* @see #findLoader
*/
public static Controller defineModulesWithOneLoader(Configuration cf,
List<ModuleLayer> parentLayers,
ClassLoader parentLoader)
{
List<ModuleLayer> parents = new ArrayList<>(parentLayers);
checkConfiguration(cf, parents);
checkCreateClassLoaderPermission();
checkGetClassLoaderPermission();
try {
Loader loader = new Loader(cf.modules(), parentLoader);
loader.initRemotePackageMap(cf, parents);
ModuleLayer layer = new ModuleLayer(cf, parents, mn -> loader);
return new Controller(layer);
} catch (IllegalArgumentException | IllegalStateException e) {
throw new LayerInstantiationException(e.getMessage());
}
}
/**
* Creates a new module layer by defining the modules in the given {@code
* Configuration} to the Java virtual machine. Each module is defined to
* its own {@link ClassLoader} created by this method. The {@link
* ClassLoader#getParent() parent} of each class loader is the given parent
* class loader.
*
* <p> The class loaders created by this method implement <em>direct
* delegation</em> when loading classes from modules. If the {@link
* ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
* load a class then it uses the package name of the class to map it to a
* module. The package may be in the module defined to the class loader.
* The package may be exported by another module in this layer to the
* module defined to the class loader. It may be in a package exported by a
* module in a parent layer. The class loader delegates to the class loader
* of the module, throwing {@code ClassNotFoundException} if not found by
* that class loader. When {@code loadClass} is invoked to load a class
* that does not map to a module then it delegates to the parent class
* loader. </p>
*
* <p> The class loaders created by this method locate resources
* ({@link ClassLoader#getResource(String) getResource}, {@link
* ClassLoader#getResources(String) getResources}, and other resource
* methods) in the module defined to the class loader before searching
* the parent class loader. </p>
*
* <p> If there is a security manager then the class loaders created by
* this method will load classes and resources with privileges that are
* restricted by the calling context of this method. </p>
*
* @param cf
* The configuration for the layer
* @param parentLayers
* The list of parent layers in search order
* @param parentLoader
* The parent class loader for each of the class loaders created by
* this method; may be {@code null} for the bootstrap class loader
*
* @return A controller that controls the newly created layer
*
* @throws IllegalArgumentException
* If the parent configurations do not match the configuration of
* the parent layers, including order
* @throws LayerInstantiationException
* If the layer cannot be created because the configuration contains
* a module named "{@code java.base}" or a module contains a package
* named "{@code java}" or a package with a name starting with
* "{@code java.}"
*
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
* the security manager
*
* @see #findLoader
*/
public static Controller defineModulesWithManyLoaders(Configuration cf,
List<ModuleLayer> parentLayers,
ClassLoader parentLoader)
{
List<ModuleLayer> parents = new ArrayList<>(parentLayers);
checkConfiguration(cf, parents);
checkCreateClassLoaderPermission();
checkGetClassLoaderPermission();
LoaderPool pool = new LoaderPool(cf, parents, parentLoader);
try {
ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor);
return new Controller(layer);
} catch (IllegalArgumentException | IllegalStateException e) {
throw new LayerInstantiationException(e.getMessage());
}
}
/**
* Creates a new module layer by defining the modules in the given {@code
* Configuration} to the Java virtual machine. The given function maps each
* module in the configuration, by name, to a class loader. Creating the
* layer informs the Java virtual machine about the classes that may be
* loaded so that the Java virtual machine knows which module that each
* class is a member of.
*
* <p> The class loader delegation implemented by the class loaders must
* respect module readability. The class loaders should be
* {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to
* avoid deadlocks during class loading. In addition, the entity creating
* a new layer with this method should arrange that the class loaders be
* ready to load from these modules before there are any attempts to load
* classes or resources. </p>
*
* <p> Creating a layer can fail for the following reasons: </p>
*
* <ul>
*
* <li><p> Two or more modules with the same package are mapped to the
* same class loader. </p></li>
*
* <li><p> A module is mapped to a class loader that already has a
* module of the same name defined to it. </p></li>
*
* <li><p> A module is mapped to a class loader that has already
* defined types in any of the packages in the module. </p></li>
*
* </ul>
*
* <p> In addition, a layer cannot be created if the configuration contains
* a module named "{@code java.base}", a configuration contains a module
* with a package named "{@code java}" or a package name starting with
* "{@code java.}", or the function to map a module name to a class loader
* returns {@code null} or the {@linkplain ClassLoader#getPlatformClassLoader()
* platform class loader}. </p>
*
* <p> If the function to map a module name to class loader throws an error
* or runtime exception then it is propagated to the caller of this method.
* </p>
*
* @apiNote It is implementation specific as to whether creating a layer
* with this method is an atomic operation or not. Consequentially it is
* possible for this method to fail with some modules, but not all, defined
* to the Java virtual machine.
*
* @param cf
* The configuration for the layer
* @param parentLayers
* The list of parent layers in search order
* @param clf
* The function to map a module name to a class loader
*
* @return A controller that controls the newly created layer
*
* @throws IllegalArgumentException
* If the parent configurations do not match the configuration of
* the parent layers, including order
* @throws LayerInstantiationException
* If creating the layer fails for any of the reasons listed above
* @throws SecurityException
* If {@code RuntimePermission("getClassLoader")} is denied by
* the security manager
*/
public static Controller defineModules(Configuration cf,
List<ModuleLayer> parentLayers,
Function<String, ClassLoader> clf)
{
List<ModuleLayer> parents = new ArrayList<>(parentLayers);
checkConfiguration(cf, parents);
Objects.requireNonNull(clf);
checkGetClassLoaderPermission();
// The boot layer is checked during module system initialization
if (boot() != null) {
checkForDuplicatePkgs(cf, clf);
}
try {
ModuleLayer layer = new ModuleLayer(cf, parents, clf);
return new Controller(layer);
} catch (IllegalArgumentException | IllegalStateException e) {
throw new LayerInstantiationException(e.getMessage());
}
}
/**
* Checks that the parent configurations match the configuration of
* the parent layers.
*/
private static void checkConfiguration(Configuration cf,
List<ModuleLayer> parentLayers)
{
Objects.requireNonNull(cf);
List<Configuration> parentConfigurations = cf.parents();
if (parentLayers.size() != parentConfigurations.size())
throw new IllegalArgumentException("wrong number of parents");
int index = 0;
for (ModuleLayer parent : parentLayers) {
if (parent.configuration() != parentConfigurations.get(index)) {
throw new IllegalArgumentException(
"Parent of configuration != configuration of this Layer");
}
index++;
}
}
private static void checkCreateClassLoaderPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
}
private static void checkGetClassLoaderPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
/**
* Checks a configuration and the module-to-loader mapping to ensure that
* no two modules mapped to the same class loader have the same package.
* It also checks that no two automatic modules have the same package.
*
* @throws LayerInstantiationException
*/
private static void checkForDuplicatePkgs(Configuration cf,
Function<String, ClassLoader> clf)
{
// HashMap allows null keys
Map<ClassLoader, Set<String>> loaderToPackages = new HashMap<>();
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
ClassLoader loader = clf.apply(descriptor.name());
Set<String> loaderPackages
= loaderToPackages.computeIfAbsent(loader, k -> new HashSet<>());
for (String pkg : descriptor.packages()) {
boolean added = loaderPackages.add(pkg);
if (!added) {
throw fail("More than one module with package %s mapped" +
" to the same class loader", pkg);
}
}
}
}
/**
* Creates a LayerInstantiationException with the a message formatted from
* the given format string and arguments.
*/
private static LayerInstantiationException fail(String fmt, Object ... args) {
String msg = String.format(fmt, args);
return new LayerInstantiationException(msg);
}
/**
* Returns the configuration for this layer.
*
* @return The configuration for this layer
*/
public Configuration configuration() {
return cf;
}
/**
* Returns the list of this layer's parents unless this is the
* {@linkplain #empty empty layer}, which has no parents and so an
* empty list is returned.
*
* @return The list of this layer's parents
*/
public List<ModuleLayer> parents() {
return parents;
}
/**
* Returns an ordered stream of layers. The first element is is this layer,
* the remaining elements are the parent layers in DFS order.
*
* @implNote For now, the assumption is that the number of elements will
* be very low and so this method does not use a specialized spliterator.
*/
Stream<ModuleLayer> layers() {
List<ModuleLayer> allLayers = this.allLayers;
if (allLayers != null)
return allLayers.stream();
allLayers = new ArrayList<>();
Set<ModuleLayer> visited = new HashSet<>();
Deque<ModuleLayer> stack = new ArrayDeque<>();
visited.add(this);
stack.push(this);
while (!stack.isEmpty()) {
ModuleLayer layer = stack.pop();
allLayers.add(layer);
// push in reverse order
for (int i = layer.parents.size() - 1; i >= 0; i--) {
ModuleLayer parent = layer.parents.get(i);
if (!visited.contains(parent)) {
visited.add(parent);
stack.push(parent);
}
}
}
this.allLayers = allLayers = Collections.unmodifiableList(allLayers);
return allLayers.stream();
}
private volatile List<ModuleLayer> allLayers;
/**
* Returns the set of the modules in this layer.
*
* @return A possibly-empty unmodifiable set of the modules in this layer
*/
public Set<Module> modules() {
Set<Module> modules = this.modules;
if (modules == null) {
this.modules = modules =
Collections.unmodifiableSet(new HashSet<>(nameToModule.values()));
}
return modules;
}
private volatile Set<Module> modules;
/**
* Returns the module with the given name in this layer, or if not in this
* layer, the {@linkplain #parents() parent} layers. Finding a module in
* parent layers is equivalent to invoking {@code findModule} on each
* parent, in search order, until the module is found or all parents have
* been searched. In a <em>tree of layers</em> then this is equivalent to
* a depth-first search.
*
* @param name
* The name of the module to find
*
* @return The module with the given name or an empty {@code Optional}
* if there isn't a module with this name in this layer or any
* parent layer
*/
public Optional<Module> findModule(String name) {
Objects.requireNonNull(name);
if (this == EMPTY_LAYER)
return Optional.empty();
Module m = nameToModule.get(name);
if (m != null)
return Optional.of(m);
return layers()
.skip(1) // skip this layer
.map(l -> l.nameToModule)
.filter(map -> map.containsKey(name))
.map(map -> map.get(name))
.findAny();
}
/**
* Returns the {@code ClassLoader} for the module with the given name. If
* a module of the given name is not in this layer then the {@link #parents()
* parent} layers are searched in the manner specified by {@link
* #findModule(String) findModule}.
*
* <p> If there is a security manager then its {@code checkPermission}
* method is called with a {@code RuntimePermission("getClassLoader")}
* permission to check that the caller is allowed to get access to the
* class loader. </p>
*
* @apiNote This method does not return an {@code Optional<ClassLoader>}
* because `null` must be used to represent the bootstrap class loader.
*
* @param name
* The name of the module to find
*
* @return The ClassLoader that the module is defined to
*
* @throws IllegalArgumentException if a module of the given name is not
* defined in this layer or any parent of this layer
*
* @throws SecurityException if denied by the security manager
*/
public ClassLoader findLoader(String name) {
Optional<Module> om = findModule(name);
// can't use map(Module::getClassLoader) as class loader can be null
if (om.isPresent()) {
return om.get().getClassLoader();
} else {
throw new IllegalArgumentException("Module " + name
+ " not known to this layer");
}
}
/**
* Returns a string describing this module layer.
*
* @return A possibly empty string describing this module layer
*/
@Override
public String toString() {
return modules().stream()
.map(Module::getName)
.collect(Collectors.joining(", "));
}
/**
* Returns the <em>empty</em> layer. There are no modules in the empty
* layer. It has no parents.
*
* @return The empty layer
*/
public static ModuleLayer empty() {
return EMPTY_LAYER;
}
/**
* Returns the boot layer. The boot layer contains at least one module,
* {@code java.base}. Its parent is the {@link #empty() empty} layer.
*
* @apiNote This method returns {@code null} during startup and before
* the boot layer is fully initialized.
*
* @return The boot layer
*/
public static ModuleLayer boot() {
return System.bootLayer;
}
/**
* Returns the ServicesCatalog for this Layer, creating it if not
* already created.
*/
ServicesCatalog getServicesCatalog() {
ServicesCatalog servicesCatalog = this.servicesCatalog;
if (servicesCatalog != null)
return servicesCatalog;
synchronized (this) {
servicesCatalog = this.servicesCatalog;
if (servicesCatalog == null) {
servicesCatalog = ServicesCatalog.create();
nameToModule.values().forEach(servicesCatalog::register);
this.servicesCatalog = servicesCatalog;
}
}
return servicesCatalog;
}
private volatile ServicesCatalog servicesCatalog;
/**
* Record that this layer has at least one module defined to the given
* class loader.
*/
void bindToLoader(ClassLoader loader) {
// CLV.computeIfAbsent(loader, (cl, clv) -> new CopyOnWriteArrayList<>())
List<ModuleLayer> list = CLV.get(loader);
if (list == null) {
list = new CopyOnWriteArrayList<>();
List<ModuleLayer> previous = CLV.putIfAbsent(loader, list);
if (previous != null) list = previous;
}
list.add(this);
}
/**
* Returns a stream of the layers that have at least one module defined to
* the given class loader.
*/
static Stream<ModuleLayer> layers(ClassLoader loader) {
List<ModuleLayer> list = CLV.get(loader);
if (list != null) {
return list.stream();
} else {
return Stream.empty();
}
}
// the list of layers with modules defined to a class loader
private static final ClassLoaderValue<List<ModuleLayer>> CLV = new ClassLoaderValue<>();
}

View file

@ -0,0 +1,89 @@
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.module.Configuration;
import java.lang.module.ModuleReference;
import java.net.URI;
/**
* A NamedPackage represents a package by name in a specific module.
*
* A class loader will automatically create NamedPackage for each
* package when a class is defined. Package object is lazily
* defined until Class::getPackage, Package::getPackage(s), or
* ClassLoader::getDefinedPackage(s) method is called.
*
* NamedPackage allows ClassLoader to keep track of the runtime
* packages with minimal footprint and avoid constructing Package
* object.
*/
class NamedPackage {
private final String name;
private final Module module;
NamedPackage(String pn, Module module) {
if (pn.isEmpty() && module.isNamed()) {
throw new InternalError("unnamed package in " + module);
}
this.name = pn.intern();
this.module = module;
}
/**
* Returns the name of this package.
*/
String packageName() {
return name;
}
/**
* Returns the module of this named package.
*/
Module module() {
return module;
}
/**
* Returns the location of the module if this named package is in
* a named module; otherwise, returns null.
*/
URI location() {
if (module.isNamed() && module.getLayer() != null) {
Configuration cf = module.getLayer().configuration();
ModuleReference mref
= cf.findModule(module.getName()).get().reference();
return mref.location().orElse(null);
}
return null;
}
/**
* Creates a Package object of the given name and module.
*/
static Package toPackage(String name, Module module) {
return new Package(name, module);
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 1994, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown if an application tries to create an array with negative size.
*
* @author unascribed
* @since 1.0
*/
public
class NegativeArraySizeException extends RuntimeException {
private static final long serialVersionUID = -8960118058596991861L;
/**
* Constructs a <code>NegativeArraySizeException</code> with no
* detail message.
*/
public NegativeArraySizeException() {
super();
}
/**
* Constructs a <code>NegativeArraySizeException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public NegativeArraySizeException(String s) {
super(s);
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 1994, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown if the Java Virtual Machine or a <code>ClassLoader</code> instance
* tries to load in the definition of a class (as part of a normal method call
* or as part of creating a new instance using the <code>new</code> expression)
* and no definition of the class could be found.
* <p>
* The searched-for class definition existed when the currently
* executing class was compiled, but the definition can no longer be
* found.
*
* @author unascribed
* @since 1.0
*/
public
class NoClassDefFoundError extends LinkageError {
private static final long serialVersionUID = 9095859863287012458L;
/**
* Constructs a <code>NoClassDefFoundError</code> with no detail message.
*/
public NoClassDefFoundError() {
super();
}
/**
* Constructs a <code>NoClassDefFoundError</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public NoClassDefFoundError(String s) {
super(s);
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown if an application tries to access or modify a specified
* field of an object, and that object no longer has that field.
* <p>
* Normally, this error is caught by the compiler; this error can
* only occur at run time if the definition of a class has
* incompatibly changed.
*
* @author unascribed
* @since 1.0
*/
public
class NoSuchFieldError extends IncompatibleClassChangeError {
private static final long serialVersionUID = -3456430195886129035L;
/**
* Constructs a <code>NoSuchFieldError</code> with no detail message.
*/
public NoSuchFieldError() {
super();
}
/**
* Constructs a <code>NoSuchFieldError</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public NoSuchFieldError(String s) {
super(s);
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 1996, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Signals that the class doesn't have a field of a specified name.
*
* @author unascribed
* @since 1.1
*/
public class NoSuchFieldException extends ReflectiveOperationException {
private static final long serialVersionUID = -6143714805279938260L;
/**
* Constructor.
*/
public NoSuchFieldException() {
super();
}
/**
* Constructor with a detail message.
*
* @param s the detail message
*/
public NoSuchFieldException(String s) {
super(s);
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 1994, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown if an application tries to call a specified method of a
* class (either static or instance), and that class no longer has a
* definition of that method.
* <p>
* Normally, this error is caught by the compiler; this error can
* only occur at run time if the definition of a class has
* incompatibly changed.
*
* @author unascribed
* @since 1.0
*/
public
class NoSuchMethodError extends IncompatibleClassChangeError {
private static final long serialVersionUID = -3765521442372831335L;
/**
* Constructs a <code>NoSuchMethodError</code> with no detail message.
*/
public NoSuchMethodError() {
super();
}
/**
* Constructs a <code>NoSuchMethodError</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public NoSuchMethodError(String s) {
super(s);
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 1995, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when a particular method cannot be found.
*
* @author unascribed
* @since 1.0
*/
public
class NoSuchMethodException extends ReflectiveOperationException {
private static final long serialVersionUID = 5034388446362600923L;
/**
* Constructs a <code>NoSuchMethodException</code> without a detail message.
*/
public NoSuchMethodException() {
super();
}
/**
* Constructs a <code>NoSuchMethodException</code> with a detail message.
*
* @param s the detail message.
*/
public NoSuchMethodException(String s) {
super(s);
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 1994, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when an application attempts to use {@code null} in a
* case where an object is required. These include:
* <ul>
* <li>Calling the instance method of a {@code null} object.
* <li>Accessing or modifying the field of a {@code null} object.
* <li>Taking the length of {@code null} as if it were an array.
* <li>Accessing or modifying the slots of {@code null} as if it
* were an array.
* <li>Throwing {@code null} as if it were a {@code Throwable}
* value.
* </ul>
* <p>
* Applications should throw instances of this class to indicate
* other illegal uses of the {@code null} object.
*
* {@code NullPointerException} objects may be constructed by the
* virtual machine as if {@linkplain Throwable#Throwable(String,
* Throwable, boolean, boolean) suppression were disabled and/or the
* stack trace was not writable}.
*
* @author unascribed
* @since 1.0
*/
public
class NullPointerException extends RuntimeException {
private static final long serialVersionUID = 5162710183389028792L;
/**
* Constructs a {@code NullPointerException} with no detail message.
*/
public NullPointerException() {
super();
}
/**
* Constructs a {@code NullPointerException} with the specified
* detail message.
*
* @param s the detail message.
*/
public NullPointerException(String s) {
super(s);
}
}

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 1994, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* The abstract class {@code Number} is the superclass of platform
* classes representing numeric values that are convertible to the
* primitive types {@code byte}, {@code double}, {@code float}, {@code
* int}, {@code long}, and {@code short}.
*
* The specific semantics of the conversion from the numeric value of
* a particular {@code Number} implementation to a given primitive
* type is defined by the {@code Number} implementation in question.
*
* For platform classes, the conversion is often analogous to a
* narrowing primitive conversion or a widening primitive conversion
* as defined in <cite>The Java&trade; Language Specification</cite>
* for converting between primitive types. Therefore, conversions may
* lose information about the overall magnitude of a numeric value, may
* lose precision, and may even return a result of a different sign
* than the input.
*
* See the documentation of a given {@code Number} implementation for
* conversion details.
*
* @author Lee Boynton
* @author Arthur van Hoff
* @jls 5.1.2 Widening Primitive Conversions
* @jls 5.1.3 Narrowing Primitive Conversions
* @since 1.0
*/
public abstract class Number implements java.io.Serializable {
/**
* Returns the value of the specified number as an {@code int}.
*
* @return the numeric value represented by this object after conversion
* to type {@code int}.
*/
public abstract int intValue();
/**
* Returns the value of the specified number as a {@code long}.
*
* @return the numeric value represented by this object after conversion
* to type {@code long}.
*/
public abstract long longValue();
/**
* Returns the value of the specified number as a {@code float}.
*
* @return the numeric value represented by this object after conversion
* to type {@code float}.
*/
public abstract float floatValue();
/**
* Returns the value of the specified number as a {@code double}.
*
* @return the numeric value represented by this object after conversion
* to type {@code double}.
*/
public abstract double doubleValue();
/**
* Returns the value of the specified number as a {@code byte}.
*
* <p>This implementation returns the result of {@link #intValue} cast
* to a {@code byte}.
*
* @return the numeric value represented by this object after conversion
* to type {@code byte}.
* @since 1.1
*/
public byte byteValue() {
return (byte)intValue();
}
/**
* Returns the value of the specified number as a {@code short}.
*
* <p>This implementation returns the result of {@link #intValue} cast
* to a {@code short}.
*
* @return the numeric value represented by this object after conversion
* to type {@code short}.
* @since 1.1
*/
public short shortValue() {
return (short)intValue();
}
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -8742448824652078965L;
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 1994, 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown to indicate that the application has attempted to convert
* a string to one of the numeric types, but that the string does not
* have the appropriate format.
*
* @author unascribed
* @see java.lang.Integer#parseInt(String)
* @since 1.0
*/
public
class NumberFormatException extends IllegalArgumentException {
static final long serialVersionUID = -2848938806368998894L;
/**
* Constructs a <code>NumberFormatException</code> with no detail message.
*/
public NumberFormatException () {
super();
}
/**
* Constructs a <code>NumberFormatException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public NumberFormatException (String s) {
super (s);
}
/**
* Factory method for making a {@code NumberFormatException}
* given the specified input which caused the error.
*
* @param s the input causing the error
*/
static NumberFormatException forInputString(String s) {
return new NumberFormatException("For input string: \"" + s + "\"");
}
/**
* Factory method for making a {@code NumberFormatException}
* given the specified input which caused the error.
*
* @param s the input causing the error
* @param beginIndex the beginning index, inclusive.
* @param endIndex the ending index, exclusive.
* @param errorIndex the index of the first error in s
*/
static NumberFormatException forCharSequence(CharSequence s,
int beginIndex, int endIndex, int errorIndex) {
return new NumberFormatException("Error at index "
+ (errorIndex - beginIndex) + " in: \""
+ s.subSequence(beginIndex, endIndex) + "\"");
}
}

View file

@ -0,0 +1,613 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
* Class {@code Object} is the root of the class hierarchy.
* Every class has {@code Object} as a superclass. All objects,
* including arrays, implement the methods of this class.
*
* @author unascribed
* @see java.lang.Class
* @since 1.0
*/
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
/**
* Constructs a new object.
*/
@HotSpotIntrinsicCandidate
public Object() {}
/**
* Returns the runtime class of this {@code Object}. The returned
* {@code Class} object is the object that is locked by {@code
* static synchronized} methods of the represented class.
*
* <p><b>The actual result type is {@code Class<? extends |X|>}
* where {@code |X|} is the erasure of the static type of the
* expression on which {@code getClass} is called.</b> For
* example, no cast is required in this code fragment:</p>
*
* <p>
* {@code Number n = 0; }<br>
* {@code Class<? extends Number> c = n.getClass(); }
* </p>
*
* @return The {@code Class} object that represents the runtime
* class of this object.
* @jls 15.8.2 Class Literals
*/
@HotSpotIntrinsicCandidate
public final native Class<?> getClass();
/**
* Returns a hash code value for the object. This method is
* supported for the benefit of hash tables such as those provided by
* {@link java.util.HashMap}.
* <p>
* The general contract of {@code hashCode} is:
* <ul>
* <li>Whenever it is invoked on the same object more than once during
* an execution of a Java application, the {@code hashCode} method
* must consistently return the same integer, provided no information
* used in {@code equals} comparisons on the object is modified.
* This integer need not remain consistent from one execution of an
* application to another execution of the same application.
* <li>If two objects are equal according to the {@code equals(Object)}
* method, then calling the {@code hashCode} method on each of
* the two objects must produce the same integer result.
* <li>It is <em>not</em> required that if two objects are unequal
* according to the {@link java.lang.Object#equals(java.lang.Object)}
* method, then calling the {@code hashCode} method on each of the
* two objects must produce distinct integer results. However, the
* programmer should be aware that producing distinct integer results
* for unequal objects may improve the performance of hash tables.
* </ul>
* <p>
* As much as is reasonably practical, the hashCode method defined
* by class {@code Object} does return distinct integers for
* distinct objects. (The hashCode may or may not be implemented
* as some function of an object's memory address at some point
* in time.)
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)
* @see java.lang.System#identityHashCode
*/
@HotSpotIntrinsicCandidate
public native int hashCode();
/**
* Indicates whether some other object is "equal to" this one.
* <p>
* The {@code equals} method implements an equivalence relation
* on non-null object references:
* <ul>
* <li>It is <i>reflexive</i>: for any non-null reference value
* {@code x}, {@code x.equals(x)} should return
* {@code true}.
* <li>It is <i>symmetric</i>: for any non-null reference values
* {@code x} and {@code y}, {@code x.equals(y)}
* should return {@code true} if and only if
* {@code y.equals(x)} returns {@code true}.
* <li>It is <i>transitive</i>: for any non-null reference values
* {@code x}, {@code y}, and {@code z}, if
* {@code x.equals(y)} returns {@code true} and
* {@code y.equals(z)} returns {@code true}, then
* {@code x.equals(z)} should return {@code true}.
* <li>It is <i>consistent</i>: for any non-null reference values
* {@code x} and {@code y}, multiple invocations of
* {@code x.equals(y)} consistently return {@code true}
* or consistently return {@code false}, provided no
* information used in {@code equals} comparisons on the
* objects is modified.
* <li>For any non-null reference value {@code x},
* {@code x.equals(null)} should return {@code false}.
* </ul>
* <p>
* The {@code equals} method for class {@code Object} implements
* the most discriminating possible equivalence relation on objects;
* that is, for any non-null reference values {@code x} and
* {@code y}, this method returns {@code true} if and only
* if {@code x} and {@code y} refer to the same object
* ({@code x == y} has the value {@code true}).
* <p>
* Note that it is generally necessary to override the {@code hashCode}
* method whenever this method is overridden, so as to maintain the
* general contract for the {@code hashCode} method, which states
* that equal objects must have equal hash codes.
*
* @param obj the reference object with which to compare.
* @return {@code true} if this object is the same as the obj
* argument; {@code false} otherwise.
* @see #hashCode()
* @see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}
/**
* Creates and returns a copy of this object. The precise meaning
* of "copy" may depend on the class of the object. The general
* intent is that, for any object {@code x}, the expression:
* <blockquote>
* <pre>
* x.clone() != x</pre></blockquote>
* will be true, and that the expression:
* <blockquote>
* <pre>
* x.clone().getClass() == x.getClass()</pre></blockquote>
* will be {@code true}, but these are not absolute requirements.
* While it is typically the case that:
* <blockquote>
* <pre>
* x.clone().equals(x)</pre></blockquote>
* will be {@code true}, this is not an absolute requirement.
* <p>
* By convention, the returned object should be obtained by calling
* {@code super.clone}. If a class and all of its superclasses (except
* {@code Object}) obey this convention, it will be the case that
* {@code x.clone().getClass() == x.getClass()}.
* <p>
* By convention, the object returned by this method should be independent
* of this object (which is being cloned). To achieve this independence,
* it may be necessary to modify one or more fields of the object returned
* by {@code super.clone} before returning it. Typically, this means
* copying any mutable objects that comprise the internal "deep structure"
* of the object being cloned and replacing the references to these
* objects with references to the copies. If a class contains only
* primitive fields or references to immutable objects, then it is usually
* the case that no fields in the object returned by {@code super.clone}
* need to be modified.
* <p>
* The method {@code clone} for class {@code Object} performs a
* specific cloning operation. First, if the class of this object does
* not implement the interface {@code Cloneable}, then a
* {@code CloneNotSupportedException} is thrown. Note that all arrays
* are considered to implement the interface {@code Cloneable} and that
* the return type of the {@code clone} method of an array type {@code T[]}
* is {@code T[]} where T is any reference or primitive type.
* Otherwise, this method creates a new instance of the class of this
* object and initializes all its fields with exactly the contents of
* the corresponding fields of this object, as if by assignment; the
* contents of the fields are not themselves cloned. Thus, this method
* performs a "shallow copy" of this object, not a "deep copy" operation.
* <p>
* The class {@code Object} does not itself implement the interface
* {@code Cloneable}, so calling the {@code clone} method on an object
* whose class is {@code Object} will result in throwing an
* exception at run time.
*
* @return a clone of this instance.
* @throws CloneNotSupportedException if the object's class does not
* support the {@code Cloneable} interface. Subclasses
* that override the {@code clone} method can also
* throw this exception to indicate that an instance cannot
* be cloned.
* @see java.lang.Cloneable
*/
@HotSpotIntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;
/**
* Returns a string representation of the object. In general, the
* {@code toString} method returns a string that
* "textually represents" this object. The result should
* be a concise but informative representation that is easy for a
* person to read.
* It is recommended that all subclasses override this method.
* <p>
* The {@code toString} method for class {@code Object}
* returns a string consisting of the name of the class of which the
* object is an instance, the at-sign character `{@code @}', and
* the unsigned hexadecimal representation of the hash code of the
* object. In other words, this method returns a string equal to the
* value of:
* <blockquote>
* <pre>
* getClass().getName() + '@' + Integer.toHexString(hashCode())
* </pre></blockquote>
*
* @return a string representation of the object.
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/**
* Wakes up a single thread that is waiting on this object's
* monitor. If any threads are waiting on this object, one of them
* is chosen to be awakened. The choice is arbitrary and occurs at
* the discretion of the implementation. A thread waits on an object's
* monitor by calling one of the {@code wait} methods.
* <p>
* The awakened thread will not be able to proceed until the current
* thread relinquishes the lock on this object. The awakened thread will
* compete in the usual manner with any other threads that might be
* actively competing to synchronize on this object; for example, the
* awakened thread enjoys no reliable privilege or disadvantage in being
* the next thread to lock this object.
* <p>
* This method should only be called by a thread that is the owner
* of this object's monitor. A thread becomes the owner of the
* object's monitor in one of three ways:
* <ul>
* <li>By executing a synchronized instance method of that object.
* <li>By executing the body of a {@code synchronized} statement
* that synchronizes on the object.
* <li>For objects of type {@code Class,} by executing a
* synchronized static method of that class.
* </ul>
* <p>
* Only one thread at a time can own an object's monitor.
*
* @throws IllegalMonitorStateException if the current thread is not
* the owner of this object's monitor.
* @see java.lang.Object#notifyAll()
* @see java.lang.Object#wait()
*/
@HotSpotIntrinsicCandidate
public final native void notify();
/**
* Wakes up all threads that are waiting on this object's monitor. A
* thread waits on an object's monitor by calling one of the
* {@code wait} methods.
* <p>
* The awakened threads will not be able to proceed until the current
* thread relinquishes the lock on this object. The awakened threads
* will compete in the usual manner with any other threads that might
* be actively competing to synchronize on this object; for example,
* the awakened threads enjoy no reliable privilege or disadvantage in
* being the next thread to lock this object.
* <p>
* This method should only be called by a thread that is the owner
* of this object's monitor. See the {@code notify} method for a
* description of the ways in which a thread can become the owner of
* a monitor.
*
* @throws IllegalMonitorStateException if the current thread is not
* the owner of this object's monitor.
* @see java.lang.Object#notify()
* @see java.lang.Object#wait()
*/
@HotSpotIntrinsicCandidate
public final native void notifyAll();
/**
* Causes the current thread to wait until either another thread invokes the
* {@link java.lang.Object#notify()} method or the
* {@link java.lang.Object#notifyAll()} method for this object, or a
* specified amount of time has elapsed.
* <p>
* The current thread must own this object's monitor.
* <p>
* This method causes the current thread (call it <var>T</var>) to
* place itself in the wait set for this object and then to relinquish
* any and all synchronization claims on this object. Thread <var>T</var>
* becomes disabled for thread scheduling purposes and lies dormant
* until one of four things happens:
* <ul>
* <li>Some other thread invokes the {@code notify} method for this
* object and thread <var>T</var> happens to be arbitrarily chosen as
* the thread to be awakened.
* <li>Some other thread invokes the {@code notifyAll} method for this
* object.
* <li>Some other thread {@linkplain Thread#interrupt() interrupts}
* thread <var>T</var>.
* <li>The specified amount of real time has elapsed, more or less. If
* {@code timeout} is zero, however, then real time is not taken into
* consideration and the thread simply waits until notified.
* </ul>
* The thread <var>T</var> is then removed from the wait set for this
* object and re-enabled for thread scheduling. It then competes in the
* usual manner with other threads for the right to synchronize on the
* object; once it has gained control of the object, all its
* synchronization claims on the object are restored to the status quo
* ante - that is, to the situation as of the time that the {@code wait}
* method was invoked. Thread <var>T</var> then returns from the
* invocation of the {@code wait} method. Thus, on return from the
* {@code wait} method, the synchronization state of the object and of
* thread {@code T} is exactly as it was when the {@code wait} method
* was invoked.
* <p>
* A thread can also wake up without being notified, interrupted, or
* timing out, a so-called <i>spurious wakeup</i>. While this will rarely
* occur in practice, applications must guard against it by testing for
* the condition that should have caused the thread to be awakened, and
* continuing to wait if the condition is not satisfied. In other words,
* waits should always occur in loops, like this one:
* <pre>
* synchronized (obj) {
* while (&lt;condition does not hold&gt;)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
*
* (For more information on this topic, see section 14.2,
* Condition Queues, in Brian Goetz and others' "Java Concurrency
* in Practice" (Addison-Wesley, 2006) or Item 69 in Joshua
* Bloch's "Effective Java (Second Edition)" (Addison-Wesley,
* 2008).
*
* <p>If the current thread is {@linkplain java.lang.Thread#interrupt()
* interrupted} by any thread before or while it is waiting, then an
* {@code InterruptedException} is thrown. This exception is not
* thrown until the lock status of this object has been restored as
* described above.
*
* <p>
* Note that the {@code wait} method, as it places the current thread
* into the wait set for this object, unlocks only this object; any
* other objects on which the current thread may be synchronized remain
* locked while the thread waits.
* <p>
* This method should only be called by a thread that is the owner
* of this object's monitor. See the {@code notify} method for a
* description of the ways in which a thread can become the owner of
* a monitor.
*
* @param timeout the maximum time to wait in milliseconds.
* @throws IllegalArgumentException if the value of timeout is
* negative.
* @throws IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor.
* @throws InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
* this exception is thrown.
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
public final native void wait(long timeout) throws InterruptedException;
/**
* Causes the current thread to wait until another thread invokes the
* {@link java.lang.Object#notify()} method or the
* {@link java.lang.Object#notifyAll()} method for this object, or
* some other thread interrupts the current thread, or a certain
* amount of real time has elapsed.
* <p>
* This method is similar to the {@code wait} method of one
* argument, but it allows finer control over the amount of time to
* wait for a notification before giving up. The amount of real time,
* measured in nanoseconds, is given by:
* <blockquote>
* <pre>
* 1000000*timeout+nanos</pre></blockquote>
* <p>
* In all other respects, this method does the same thing as the
* method {@link #wait(long)} of one argument. In particular,
* {@code wait(0, 0)} means the same thing as {@code wait(0)}.
* <p>
* The current thread must own this object's monitor. The thread
* releases ownership of this monitor and waits until either of the
* following two conditions has occurred:
* <ul>
* <li>Another thread notifies threads waiting on this object's monitor
* to wake up either through a call to the {@code notify} method
* or the {@code notifyAll} method.
* <li>The timeout period, specified by {@code timeout}
* milliseconds plus {@code nanos} nanoseconds arguments, has
* elapsed.
* </ul>
* <p>
* The thread then waits until it can re-obtain ownership of the
* monitor and resumes execution.
* <p>
* As in the one argument version, interrupts and spurious wakeups are
* possible, and this method should always be used in a loop:
* <pre>
* synchronized (obj) {
* while (&lt;condition does not hold&gt;)
* obj.wait(timeout, nanos);
* ... // Perform action appropriate to condition
* }
* </pre>
* This method should only be called by a thread that is the owner
* of this object's monitor. See the {@code notify} method for a
* description of the ways in which a thread can become the owner of
* a monitor.
*
* @param timeout the maximum time to wait in milliseconds.
* @param nanos additional time, in nanoseconds range
* 0-999999.
* @throws IllegalArgumentException if the value of timeout is
* negative or the value of nanos is
* not in the range 0-999999.
* @throws IllegalMonitorStateException if the current thread is not
* the owner of this object's monitor.
* @throws InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
* this exception is thrown.
*/
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
/**
* Causes the current thread to wait until another thread invokes the
* {@link java.lang.Object#notify()} method or the
* {@link java.lang.Object#notifyAll()} method for this object.
* In other words, this method behaves exactly as if it simply
* performs the call {@code wait(0)}.
* <p>
* The current thread must own this object's monitor. The thread
* releases ownership of this monitor and waits until another thread
* notifies threads waiting on this object's monitor to wake up
* either through a call to the {@code notify} method or the
* {@code notifyAll} method. The thread then waits until it can
* re-obtain ownership of the monitor and resumes execution.
* <p>
* As in the one argument version, interrupts and spurious wakeups are
* possible, and this method should always be used in a loop:
* <pre>
* synchronized (obj) {
* while (&lt;condition does not hold&gt;)
* obj.wait();
* ... // Perform action appropriate to condition
* }
* </pre>
* This method should only be called by a thread that is the owner
* of this object's monitor. See the {@code notify} method for a
* description of the ways in which a thread can become the owner of
* a monitor.
*
* @throws IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor.
* @throws InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
* this exception is thrown.
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
public final void wait() throws InterruptedException {
wait(0);
}
/**
* Called by the garbage collector on an object when garbage collection
* determines that there are no more references to the object.
* A subclass overrides the {@code finalize} method to dispose of
* system resources or to perform other cleanup.
* <p>
* The general contract of {@code finalize} is that it is invoked
* if and when the Java&trade; virtual
* machine has determined that there is no longer any
* means by which this object can be accessed by any thread that has
* not yet died, except as a result of an action taken by the
* finalization of some other object or class which is ready to be
* finalized. The {@code finalize} method may take any action, including
* making this object available again to other threads; the usual purpose
* of {@code finalize}, however, is to perform cleanup actions before
* the object is irrevocably discarded. For example, the finalize method
* for an object that represents an input/output connection might perform
* explicit I/O transactions to break the connection before the object is
* permanently discarded.
* <p>
* The {@code finalize} method of class {@code Object} performs no
* special action; it simply returns normally. Subclasses of
* {@code Object} may override this definition.
* <p>
* The Java programming language does not guarantee which thread will
* invoke the {@code finalize} method for any given object. It is
* guaranteed, however, that the thread that invokes finalize will not
* be holding any user-visible synchronization locks when finalize is
* invoked. If an uncaught exception is thrown by the finalize method,
* the exception is ignored and finalization of that object terminates.
* <p>
* After the {@code finalize} method has been invoked for an object, no
* further action is taken until the Java virtual machine has again
* determined that there is no longer any means by which this object can
* be accessed by any thread that has not yet died, including possible
* actions by other objects or classes which are ready to be finalized,
* at which point the object may be discarded.
* <p>
* The {@code finalize} method is never invoked more than once by a Java
* virtual machine for any given object.
* <p>
* Any exception thrown by the {@code finalize} method causes
* the finalization of this object to be halted, but is otherwise
* ignored.
*
* @apiNote
* Classes that embed non-heap resources have many options
* for cleanup of those resources. The class must ensure that the
* lifetime of each instance is longer than that of any resource it embeds.
* {@link java.lang.ref.Reference#reachabilityFence} can be used to ensure that
* objects remain reachable while resources embedded in the object are in use.
* <p>
* A subclass should avoid overriding the {@code finalize} method
* unless the subclass embeds non-heap resources that must be cleaned up
* before the instance is collected.
* Finalizer invocations are not automatically chained, unlike constructors.
* If a subclass overrides {@code finalize} it must invoke the superclass
* finalizer explicitly.
* To guard against exceptions prematurely terminating the finalize chain,
* the subclass should use a {@code try-finally} block to ensure
* {@code super.finalize()} is always invoked. For example,
* <pre>{@code @Override
* protected void finalize() throws Throwable {
* try {
* ... // cleanup subclass state
* } finally {
* super.finalize();
* }
* }
* }</pre>
*
* @deprecated The finalization mechanism is inherently problematic.
* Finalization can lead to performance issues, deadlocks, and hangs.
* Errors in finalizers can lead to resource leaks; there is no way to cancel
* finalization if it is no longer necessary; and no ordering is specified
* among calls to {@code finalize} methods of different objects.
* Furthermore, there are no guarantees regarding the timing of finalization.
* The {@code finalize} method might be called on a finalizable object
* only after an indefinite delay, if at all.
*
* Classes whose instances hold non-heap resources should provide a method
* to enable explicit release of those resources, and they should also
* implement {@link AutoCloseable} if appropriate.
* The {@link java.lang.ref.Cleaner} and {@link java.lang.ref.PhantomReference}
* provide more flexible and efficient ways to release resources when an object
* becomes unreachable.
*
* @throws Throwable the {@code Exception} raised by this method
* @see java.lang.ref.WeakReference
* @see java.lang.ref.PhantomReference
* @jls 12.6 Finalization of Class Instances
*/
@Deprecated(since="9")
protected void finalize() throws Throwable { }
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 1994, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when the Java Virtual Machine cannot allocate an object
* because it is out of memory, and no more memory could be made
* available by the garbage collector.
*
* {@code OutOfMemoryError} objects may be constructed by the virtual
* machine as if {@linkplain Throwable#Throwable(String, Throwable,
* boolean, boolean) suppression were disabled and/or the stack trace was not
* writable}.
*
* @author unascribed
* @since 1.0
*/
public class OutOfMemoryError extends VirtualMachineError {
private static final long serialVersionUID = 8228564086184010517L;
/**
* Constructs an {@code OutOfMemoryError} with no detail message.
*/
public OutOfMemoryError() {
super();
}
/**
* Constructs an {@code OutOfMemoryError} with the specified
* detail message.
*
* @param s the detail message.
*/
public OutOfMemoryError(String s) {
super(s);
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2003, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.annotation.*;
/**
* Indicates that a method declaration is intended to override a
* method declaration in a supertype. If a method is annotated with
* this annotation type compilers are required to generate an error
* message unless at least one of the following conditions hold:
*
* <ul><li>
* The method does override or implement a method declared in a
* supertype.
* </li><li>
* The method has a signature that is override-equivalent to that of
* any public method declared in {@linkplain Object}.
* </li></ul>
*
* @author Peter von der Ah&eacute;
* @author Joshua Bloch
* @jls 8.4.8 Inheritance, Overriding, and Hiding
* @jls 9.4.1 Inheritance and Overriding
* @jls 9.6.4.4 @Override
* @since 1.5
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

View file

@ -0,0 +1,578 @@
/*
* Copyright (c) 1997, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;
import jdk.internal.loader.BootLoader;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
/**
* Represents metadata about a run-time package associated with a class loader.
* Metadata includes annotations, versioning, and sealing.
* <p>
* Annotations for the run-time package are read from {@code package-info.class}
* at the same code source as classes in the run-time package.
* <p>
* The set of classes that make up the run-time package may implement a
* particular specification. The specification title, version, and vendor
* (indicating the owner/maintainer of the specification) can be provided
* when the {@code Package} is defined. An application can ask if the
* {@code Package} is compatible with a particular specification version
* by using the {@link #isCompatibleWith Package.isCompatibleWith(String)}
* method. In addition, information about the actual classes that make up the
* run-time package can be provided when the Package is defined.
* This information consists of an implementation title, version, and vendor
* (indicating the supplier of the classes).
* <p>
* A {@code Package} may be explicitly defined with
* the {@link ClassLoader#definePackage(String, String, String, String,
* String, String, String, URL)} method.
* The caller supplies the specification and implementation titles, versions, and
* vendors. The caller also indicates whether the package is
* {@linkplain java.util.jar.Attributes.Name#SEALED sealed}.
* If a {@code Package} is not explicitly defined for a run-time package when
* a class in that run-time package is defined, then a {@code Package} is
* automatically defined by the class's defining class loader, as follows.
* <p>
* A {@code Package} automatically defined for classes in a named module has
* the following properties:
* <ul>
* <li>The name of the package is derived from the {@linkplain Class#getName() binary names}
* of the classes. Since classes in a named module must be in a named package,
* the derived name is never empty.</li>
* <li>The package is sealed with the {@linkplain java.lang.module.ModuleReference#location()
* module location} as the code source, if known.</li>
* <li>The specification and implementation titles, versions, and vendors
* are unspecified.</li>
* <li>Any annotations on the package are read from {@code package-info.class}
* as specified above.</li>
* </ul>
* <p>
* A {@code Package} automatically defined for classes in an unnamed module
* has the following properties:
* <ul>
* <li>The name of the package is either {@code ""} (for classes in an unnamed package)
* or derived from the {@linkplain Class#getName() binary names} of the classes
* (for classes in a named package).</li>
* <li>The package is not sealed.</li>
* <li>The specification and implementation titles, versions, and vendors
* are unspecified.</li>
* <li>Any annotations on the package are read from {@code package-info.class}
* as specified above.</li>
* </ul>
*
* <p>
* A {@code Package} can be obtained with the {@link Package#getPackage
* Package.getPackage(String)} and {@link ClassLoader#getDefinedPackage
* ClassLoader.getDefinedPackage(String)} methods.
* Every {@code Package} defined by a class loader can be obtained
* with the {@link Package#getPackages Package.getPackages()} and
* {@link ClassLoader#getDefinedPackages} methods.
*
* @implNote
* The <a href="ClassLoader.html#builtinLoaders">builtin class loaders</a>
* do not explicitly define {@code Package} objects for packages in
* <em>named modules</em>. Instead those packages are automatically defined
* and have no specification and implementation versioning information.
*
* @jvms 5.3 Run-time package
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
* The JAR File Specification: Package Sealing</a>
* @see ClassLoader#definePackage(String, String, String, String, String, String, String, URL)
*
* @since 1.2
* @revised 9
* @spec JPMS
*/
public class Package extends NamedPackage implements java.lang.reflect.AnnotatedElement {
/**
* Return the name of this package.
*
* @return The fully-qualified name of this package as defined in section 6.5.3 of
* <cite>The Java&trade; Language Specification</cite>,
* for example, {@code java.lang}
*/
public String getName() {
return packageName();
}
/**
* Return the title of the specification that this package implements.
* @return the specification title, {@code null} is returned if it is not known.
*/
public String getSpecificationTitle() {
return versionInfo.specTitle;
}
/**
* Returns the version number of the specification
* that this package implements.
* This version string must be a sequence of non-negative decimal
* integers separated by "."'s and may have leading zeros.
* When version strings are compared the most significant
* numbers are compared.
*
*
* <p>Specification version numbers use a syntax that consists of non-negative
* decimal integers separated by periods ".", for example "2.0" or
* "1.2.3.4.5.6.7". This allows an extensible number to be used to represent
* major, minor, micro, etc. versions. The version specification is described
* by the following formal grammar:
* <blockquote>
* <dl>
* <dt><i>SpecificationVersion:</i>
* <dd><i>Digits RefinedVersion<sub>opt</sub></i>
* <dt><i>RefinedVersion:</i>
* <dd>{@code .} <i>Digits</i>
* <dd>{@code .} <i>Digits RefinedVersion</i>
*
* <dt><i>Digits:</i>
* <dd><i>Digit</i>
* <dd><i>Digits</i>
*
* <dt><i>Digit:</i>
* <dd>any character for which {@link Character#isDigit} returns {@code true},
* e.g. 0, 1, 2, ...
* </dl>
* </blockquote>
*
* @return the specification version, {@code null} is returned if it is not known.
*/
public String getSpecificationVersion() {
return versionInfo.specVersion;
}
/**
* Return the name of the organization, vendor,
* or company that owns and maintains the specification
* of the classes that implement this package.
* @return the specification vendor, {@code null} is returned if it is not known.
*/
public String getSpecificationVendor() {
return versionInfo.specVendor;
}
/**
* Return the title of this package.
* @return the title of the implementation, {@code null} is returned if it is not known.
*/
public String getImplementationTitle() {
return versionInfo.implTitle;
}
/**
* Return the version of this implementation. It consists of any string
* assigned by the vendor of this implementation and does
* not have any particular syntax specified or expected by the Java
* runtime. It may be compared for equality with other
* package version strings used for this implementation
* by this vendor for this package.
* @return the version of the implementation, {@code null} is returned if it is not known.
*/
public String getImplementationVersion() {
return versionInfo.implVersion;
}
/**
* Returns the vendor that implemented this package, {@code null}
* is returned if it is not known.
* @return the vendor that implemented this package, {@code null}
* is returned if it is not known.
*
* @revised 9
* @spec JPMS
*/
public String getImplementationVendor() {
return versionInfo.implVendor;
}
/**
* Returns true if this package is sealed.
*
* @return true if the package is sealed, false otherwise
*/
public boolean isSealed() {
return module().isNamed() || versionInfo.sealBase != null;
}
/**
* Returns true if this package is sealed with respect to the specified
* code source {@code url}.
*
* @param url the code source URL
* @return true if this package is sealed with respect to the given {@code url}
*/
public boolean isSealed(URL url) {
Objects.requireNonNull(url);
URL sealBase = null;
if (versionInfo != VersionInfo.NULL_VERSION_INFO) {
sealBase = versionInfo.sealBase;
} else {
try {
URI uri = location();
sealBase = uri != null ? uri.toURL() : null;
} catch (MalformedURLException e) {
}
}
return url.equals(sealBase);
}
/**
* Compare this package's specification version with a
* desired version. It returns true if
* this packages specification version number is greater than or equal
* to the desired version number. <p>
*
* Version numbers are compared by sequentially comparing corresponding
* components of the desired and specification strings.
* Each component is converted as a decimal integer and the values
* compared.
* If the specification value is greater than the desired
* value true is returned. If the value is less false is returned.
* If the values are equal the period is skipped and the next pair of
* components is compared.
*
* @param desired the version string of the desired version.
* @return true if this package's version number is greater
* than or equal to the desired version number
*
* @exception NumberFormatException if the current version is not known or
* the desired or current version is not of the correct dotted form.
*/
public boolean isCompatibleWith(String desired)
throws NumberFormatException
{
if (versionInfo.specVersion == null || versionInfo.specVersion.length() < 1) {
throw new NumberFormatException("Empty version string");
}
String [] sa = versionInfo.specVersion.split("\\.", -1);
int [] si = new int[sa.length];
for (int i = 0; i < sa.length; i++) {
si[i] = Integer.parseInt(sa[i]);
if (si[i] < 0)
throw NumberFormatException.forInputString("" + si[i]);
}
String [] da = desired.split("\\.", -1);
int [] di = new int[da.length];
for (int i = 0; i < da.length; i++) {
di[i] = Integer.parseInt(da[i]);
if (di[i] < 0)
throw NumberFormatException.forInputString("" + di[i]);
}
int len = Math.max(di.length, si.length);
for (int i = 0; i < len; i++) {
int d = (i < di.length ? di[i] : 0);
int s = (i < si.length ? si[i] : 0);
if (s < d)
return false;
if (s > d)
return true;
}
return true;
}
/**
* Finds a package by name in the caller's class loader and its
* ancestors.
* <p>
* If the caller's class loader defines a {@code Package} of the given name,
* the {@code Package} is returned. Otherwise, the ancestors of the
* caller's class loader are searched recursively (parent by parent)
* for a {@code Package} of the given name.
* <p>
* Calling this method is equivalent to calling {@link ClassLoader#getPackage}
* on a {@code ClassLoader} instance which is the caller's class loader.
*
* @param name A package name, such as "{@code java.lang}".
* @return The {@code Package} of the given name defined by the caller's
* class loader or its ancestors, or {@code null} if not found.
*
* @throws NullPointerException
* if {@code name} is {@code null}.
*
* @deprecated
* If multiple class loaders delegate to each other and define classes
* with the same package name, and one such loader relies on the lookup
* behavior of {@code getPackage} to return a {@code Package} from
* a parent loader, then the properties exposed by the {@code Package}
* may not be as expected in the rest of the program.
* For example, the {@code Package} will only expose annotations from the
* {@code package-info.class} file defined by the parent loader, even if
* annotations exist in a {@code package-info.class} file defined by
* a child loader. A more robust approach is to use the
* {@link ClassLoader#getDefinedPackage} method which returns
* a {@code Package} for the specified class loader.
*
* @see ClassLoader#getDefinedPackage
*
* @revised 9
* @spec JPMS
*/
@CallerSensitive
@Deprecated(since="9")
@SuppressWarnings("deprecation")
public static Package getPackage(String name) {
ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
return l != null ? l.getPackage(name) : BootLoader.getDefinedPackage(name);
}
/**
* Returns all of the {@code Package}s defined by the caller's class loader
* and its ancestors. The returned array may contain more than one
* {@code Package} object of the same package name, each defined by
* a different class loader in the class loader hierarchy.
* <p>
* Calling this method is equivalent to calling {@link ClassLoader#getPackages}
* on a {@code ClassLoader} instance which is the caller's class loader.
*
* @return The array of {@code Package} objects defined by this
* class loader and its ancestors
*
* @see ClassLoader#getDefinedPackages
*
* @revised 9
* @spec JPMS
*/
@CallerSensitive
public static Package[] getPackages() {
ClassLoader cl = ClassLoader.getClassLoader(Reflection.getCallerClass());
return cl != null ? cl.getPackages() : BootLoader.packages().toArray(Package[]::new);
}
/**
* Return the hash code computed from the package name.
* @return the hash code computed from the package name.
*/
@Override
public int hashCode(){
return packageName().hashCode();
}
/**
* Returns the string representation of this Package.
* Its value is the string "package " and the package name.
* If the package title is defined it is appended.
* If the package version is defined it is appended.
* @return the string representation of the package.
*/
@Override
public String toString() {
String spec = versionInfo.specTitle;
String ver = versionInfo.specVersion;
if (spec != null && spec.length() > 0)
spec = ", " + spec;
else
spec = "";
if (ver != null && ver.length() > 0)
ver = ", version " + ver;
else
ver = "";
return "package " + packageName() + spec + ver;
}
private Class<?> getPackageInfo() {
if (packageInfo == null) {
// find package-info.class defined by loader
String cn = packageName() + ".package-info";
Module module = module();
PrivilegedAction<ClassLoader> pa = module::getClassLoader;
ClassLoader loader = AccessController.doPrivileged(pa);
Class<?> c;
if (loader != null) {
c = loader.loadClass(module, cn);
} else {
c = BootLoader.loadClass(module, cn);
}
if (c != null) {
packageInfo = c;
} else {
// store a proxy for the package info that has no annotations
class PackageInfoProxy {}
packageInfo = PackageInfoProxy.class;
}
}
return packageInfo;
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.5
*/
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
return getPackageInfo().getAnnotation(annotationClass);
}
/**
* {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @since 1.5
*/
@Override
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
return AnnotatedElement.super.isAnnotationPresent(annotationClass);
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
@Override
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
return getPackageInfo().getAnnotationsByType(annotationClass);
}
/**
* @since 1.5
*/
public Annotation[] getAnnotations() {
return getPackageInfo().getAnnotations();
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
@Override
public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
return getPackageInfo().getDeclaredAnnotation(annotationClass);
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
@Override
public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
return getPackageInfo().getDeclaredAnnotationsByType(annotationClass);
}
/**
* @since 1.5
*/
public Annotation[] getDeclaredAnnotations() {
return getPackageInfo().getDeclaredAnnotations();
}
/**
* Construct a package instance for an unnamed module
* with the specified version information.
*
* @apiNote
* This method should not be called to define a Package for named module.
*
* @param name the name of the package
* @param spectitle the title of the specification
* @param specversion the version of the specification
* @param specvendor the organization that maintains the specification
* @param impltitle the title of the implementation
* @param implversion the version of the implementation
* @param implvendor the organization that maintains the implementation
* @param sealbase code source where this Package comes from
* @param loader defining class loader
*/
Package(String name,
String spectitle, String specversion, String specvendor,
String impltitle, String implversion, String implvendor,
URL sealbase, ClassLoader loader)
{
super(Objects.requireNonNull(name),
loader != null ? loader.getUnnamedModule()
: BootLoader.getUnnamedModule());
this.versionInfo = VersionInfo.getInstance(spectitle, specversion,
specvendor, impltitle,
implversion, implvendor,
sealbase);
}
Package(String name, Module module) {
super(name, module);
this.versionInfo = VersionInfo.NULL_VERSION_INFO;
}
/*
* Versioning information. Only for packages in unnamed modules.
*/
static class VersionInfo {
static final VersionInfo NULL_VERSION_INFO
= new VersionInfo(null, null, null, null, null, null, null);
private final String specTitle;
private final String specVersion;
private final String specVendor;
private final String implTitle;
private final String implVersion;
private final String implVendor;
private final URL sealBase;
static VersionInfo getInstance(String spectitle, String specversion,
String specvendor, String impltitle,
String implversion, String implvendor,
URL sealbase) {
if (spectitle == null && specversion == null &&
specvendor == null && impltitle == null &&
implvendor == null && sealbase == null) {
return NULL_VERSION_INFO;
}
return new VersionInfo(spectitle, specversion, specvendor,
impltitle, implversion, implvendor,
sealbase);
}
private VersionInfo(String spectitle, String specversion,
String specvendor, String impltitle,
String implversion, String implvendor,
URL sealbase)
{
this.implTitle = impltitle;
this.implVersion = implversion;
this.implVendor = implvendor;
this.specTitle = spectitle;
this.specVersion = specversion;
this.specVendor = specvendor;
this.sealBase = sealbase;
}
}
private final VersionInfo versionInfo;
private Class<?> packageInfo;
}

View file

@ -0,0 +1,583 @@
/*
* Copyright (c) 1995, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.io.*;
import java.lang.ProcessBuilder.Redirect;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
/**
* {@code Process} provides control of native processes started by
* ProcessBuilder.start and Runtime.exec.
* The class provides methods for performing input from the process, performing
* output to the process, waiting for the process to complete,
* checking the exit status of the process, and destroying (killing)
* the process.
* The {@link ProcessBuilder#start()} and
* {@link Runtime#exec(String[],String[],File) Runtime.exec}
* methods create a native process and return an instance of a
* subclass of {@code Process} that can be used to control the process
* and obtain information about it.
*
* <p>The methods that create processes may not work well for special
* processes on certain native platforms, such as native windowing
* processes, daemon processes, Win16/DOS processes on Microsoft
* Windows, or shell scripts.
*
* <p>By default, the created process does not have its own terminal
* or console. All its standard I/O (i.e. stdin, stdout, stderr)
* operations will be redirected to the parent process, where they can
* be accessed via the streams obtained using the methods
* {@link #getOutputStream()},
* {@link #getInputStream()}, and
* {@link #getErrorStream()}.
* The parent process uses these streams to feed input to and get output
* from the process. Because some native platforms only provide
* limited buffer size for standard input and output streams, failure
* to promptly write the input stream or read the output stream of
* the process may cause the process to block, or even deadlock.
*
* <p>Where desired, <a href="ProcessBuilder.html#redirect-input">
* process I/O can also be redirected</a>
* using methods of the {@link ProcessBuilder} class.
*
* <p>The process is not killed when there are no more references to
* the {@code Process} object, but rather the process
* continues executing asynchronously.
*
* <p>There is no requirement that the process represented by a {@code
* Process} object execute asynchronously or concurrently with respect
* to the Java process that owns the {@code Process} object.
*
* <p>As of 1.5, {@link ProcessBuilder#start()} is the preferred way
* to create a {@code Process}.
*
* <p>Subclasses of Process should override the {@link #onExit()} and
* {@link #toHandle()} methods to provide a fully functional Process including the
* {@linkplain #pid() process id},
* {@linkplain #info() information about the process},
* {@linkplain #children() direct children}, and
* {@linkplain #descendants() direct children plus descendants of those children} of the process.
* Delegating to the underlying Process or ProcessHandle is typically
* easiest and most efficient.
*
* @since 1.0
*/
public abstract class Process {
/**
* Default constructor for Process.
*/
public Process() {}
/**
* Returns the output stream connected to the normal input of the
* process. Output to the stream is piped into the standard
* input of the process represented by this {@code Process} object.
*
* <p>If the standard input of the process has been redirected using
* {@link ProcessBuilder#redirectInput(Redirect)
* ProcessBuilder.redirectInput}
* then this method will return a
* <a href="ProcessBuilder.html#redirect-input">null output stream</a>.
*
* <p>Implementation note: It is a good idea for the returned
* output stream to be buffered.
*
* @return the output stream connected to the normal input of the
* process
*/
public abstract OutputStream getOutputStream();
/**
* Returns the input stream connected to the normal output of the
* process. The stream obtains data piped from the standard
* output of the process represented by this {@code Process} object.
*
* <p>If the standard output of the process has been redirected using
* {@link ProcessBuilder#redirectOutput(Redirect)
* ProcessBuilder.redirectOutput}
* then this method will return a
* <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
*
* <p>Otherwise, if the standard error of the process has been
* redirected using
* {@link ProcessBuilder#redirectErrorStream(boolean)
* ProcessBuilder.redirectErrorStream}
* then the input stream returned by this method will receive the
* merged standard output and the standard error of the process.
*
* <p>Implementation note: It is a good idea for the returned
* input stream to be buffered.
*
* @return the input stream connected to the normal output of the
* process
*/
public abstract InputStream getInputStream();
/**
* Returns the input stream connected to the error output of the
* process. The stream obtains data piped from the error output
* of the process represented by this {@code Process} object.
*
* <p>If the standard error of the process has been redirected using
* {@link ProcessBuilder#redirectError(Redirect)
* ProcessBuilder.redirectError} or
* {@link ProcessBuilder#redirectErrorStream(boolean)
* ProcessBuilder.redirectErrorStream}
* then this method will return a
* <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
*
* <p>Implementation note: It is a good idea for the returned
* input stream to be buffered.
*
* @return the input stream connected to the error output of
* the process
*/
public abstract InputStream getErrorStream();
/**
* Causes the current thread to wait, if necessary, until the
* process represented by this {@code Process} object has
* terminated. This method returns immediately if the process
* has already terminated. If the process has not yet
* terminated, the calling thread will be blocked until the
* process exits.
*
* @return the exit value of the process represented by this
* {@code Process} object. By convention, the value
* {@code 0} indicates normal termination.
* @throws InterruptedException if the current thread is
* {@linkplain Thread#interrupt() interrupted} by another
* thread while it is waiting, then the wait is ended and
* an {@link InterruptedException} is thrown.
*/
public abstract int waitFor() throws InterruptedException;
/**
* Causes the current thread to wait, if necessary, until the
* process represented by this {@code Process} object has
* terminated, or the specified waiting time elapses.
*
* <p>If the process has already terminated then this method returns
* immediately with the value {@code true}. If the process has not
* terminated and the timeout value is less than, or equal to, zero, then
* this method returns immediately with the value {@code false}.
*
* <p>The default implementation of this methods polls the {@code exitValue}
* to check if the process has terminated. Concrete implementations of this
* class are strongly encouraged to override this method with a more
* efficient implementation.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the {@code timeout} argument
* @return {@code true} if the process has exited and {@code false} if
* the waiting time elapsed before the process has exited.
* @throws InterruptedException if the current thread is interrupted
* while waiting.
* @throws NullPointerException if unit is null
* @since 1.8
*/
public boolean waitFor(long timeout, TimeUnit unit)
throws InterruptedException
{
long startTime = System.nanoTime();
long rem = unit.toNanos(timeout);
do {
try {
exitValue();
return true;
} catch(IllegalThreadStateException ex) {
if (rem > 0)
Thread.sleep(
Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
}
rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
} while (rem > 0);
return false;
}
/**
* Returns the exit value for the process.
*
* @return the exit value of the process represented by this
* {@code Process} object. By convention, the value
* {@code 0} indicates normal termination.
* @throws IllegalThreadStateException if the process represented
* by this {@code Process} object has not yet terminated
*/
public abstract int exitValue();
/**
* Kills the process.
* Whether the process represented by this {@code Process} object is
* {@linkplain #supportsNormalTermination normally terminated} or not is
* implementation dependent.
* Forcible process destruction is defined as the immediate termination of a
* process, whereas normal termination allows the process to shut down cleanly.
* If the process is not alive, no action is taken.
* <p>
* The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
* {@linkplain java.util.concurrent.CompletableFuture#complete completed}
* when the process has terminated.
*/
public abstract void destroy();
/**
* Kills the process forcibly. The process represented by this
* {@code Process} object is forcibly terminated.
* Forcible process destruction is defined as the immediate termination of a
* process, whereas normal termination allows the process to shut down cleanly.
* If the process is not alive, no action is taken.
* <p>
* The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
* {@linkplain java.util.concurrent.CompletableFuture#complete completed}
* when the process has terminated.
* <p>
* Invoking this method on {@code Process} objects returned by
* {@link ProcessBuilder#start} and {@link Runtime#exec} forcibly terminate
* the process.
*
* @implSpec
* The default implementation of this method invokes {@link #destroy}
* and so may not forcibly terminate the process.
* @implNote
* Concrete implementations of this class are strongly encouraged to override
* this method with a compliant implementation.
* @apiNote
* The process may not terminate immediately.
* i.e. {@code isAlive()} may return true for a brief period
* after {@code destroyForcibly()} is called. This method
* may be chained to {@code waitFor()} if needed.
*
* @return the {@code Process} object representing the
* process forcibly destroyed
* @since 1.8
*/
public Process destroyForcibly() {
destroy();
return this;
}
/**
* Returns {@code true} if the implementation of {@link #destroy} is to
* normally terminate the process,
* Returns {@code false} if the implementation of {@code destroy}
* forcibly and immediately terminates the process.
* <p>
* Invoking this method on {@code Process} objects returned by
* {@link ProcessBuilder#start} and {@link Runtime#exec} return
* {@code true} or {@code false} depending on the platform implementation.
*
* @implSpec
* This implementation throws an instance of
* {@link java.lang.UnsupportedOperationException} and performs no other action.
*
* @return {@code true} if the implementation of {@link #destroy} is to
* normally terminate the process;
* otherwise, {@link #destroy} forcibly terminates the process
* @throws UnsupportedOperationException if the Process implementation
* does not support this operation
* @since 9
*/
public boolean supportsNormalTermination() {
throw new UnsupportedOperationException(this.getClass()
+ ".supportsNormalTermination() not supported" );
}
/**
* Tests whether the process represented by this {@code Process} is
* alive.
*
* @return {@code true} if the process represented by this
* {@code Process} object has not yet terminated.
* @since 1.8
*/
public boolean isAlive() {
try {
exitValue();
return false;
} catch(IllegalThreadStateException e) {
return true;
}
}
/**
* Returns the native process ID of the process.
* The native process ID is an identification number that the operating
* system assigns to the process.
*
* @implSpec
* The implementation of this method returns the process id as:
* {@link #toHandle toHandle().pid()}.
*
* @return the native process id of the process
* @throws UnsupportedOperationException if the Process implementation
* does not support this operation
* @since 9
*/
public long pid() {
return toHandle().pid();
}
/**
* Returns a {@code CompletableFuture<Process>} for the termination of the Process.
* The {@link java.util.concurrent.CompletableFuture} provides the ability
* to trigger dependent functions or actions that may be run synchronously
* or asynchronously upon process termination.
* When the process has terminated the CompletableFuture is
* {@link java.util.concurrent.CompletableFuture#complete completed} regardless
* of the exit status of the process.
* <p>
* Calling {@code onExit().get()} waits for the process to terminate and returns
* the Process. The future can be used to check if the process is
* {@linkplain java.util.concurrent.CompletableFuture#isDone done} or to
* {@linkplain java.util.concurrent.CompletableFuture#get() wait} for it to terminate.
* {@linkplain java.util.concurrent.CompletableFuture#cancel(boolean) Cancelling}
* the CompletableFuture does not affect the Process.
* <p>
* Processes returned from {@link ProcessBuilder#start} override the
* default implementation to provide an efficient mechanism to wait
* for process exit.
*
* @apiNote
* Using {@link #onExit() onExit} is an alternative to
* {@link #waitFor() waitFor} that enables both additional concurrency
* and convenient access to the result of the Process.
* Lambda expressions can be used to evaluate the result of the Process
* execution.
* If there is other processing to be done before the value is used
* then {@linkplain #onExit onExit} is a convenient mechanism to
* free the current thread and block only if and when the value is needed.
* <br>
* For example, launching a process to compare two files and get a boolean if they are identical:
* <pre> {@code Process p = new ProcessBuilder("cmp", "f1", "f2").start();
* Future<Boolean> identical = p.onExit().thenApply(p1 -> p1.exitValue() == 0);
* ...
* if (identical.get()) { ... }
* }</pre>
*
* @implSpec
* This implementation executes {@link #waitFor()} in a separate thread
* repeatedly until it returns successfully. If the execution of
* {@code waitFor} is interrupted, the thread's interrupt status is preserved.
* <p>
* When {@link #waitFor()} returns successfully the CompletableFuture is
* {@linkplain java.util.concurrent.CompletableFuture#complete completed} regardless
* of the exit status of the process.
*
* This implementation may consume a lot of memory for thread stacks if a
* large number of processes are waited for concurrently.
* <p>
* External implementations should override this method and provide
* a more efficient implementation. For example, to delegate to the underlying
* process, it can do the following:
* <pre>{@code
* public CompletableFuture<Process> onExit() {
* return delegate.onExit().thenApply(p -> this);
* }
* }</pre>
* @apiNote
* The process may be observed to have terminated with {@link #isAlive}
* before the ComputableFuture is completed and dependent actions are invoked.
*
* @return a new {@code CompletableFuture<Process>} for the Process
*
* @since 9
*/
public CompletableFuture<Process> onExit() {
return CompletableFuture.supplyAsync(this::waitForInternal);
}
/**
* Wait for the process to exit by calling {@code waitFor}.
* If the thread is interrupted, remember the interrupted state to
* be restored before returning. Use ForkJoinPool.ManagedBlocker
* so that the number of workers in case ForkJoinPool is used is
* compensated when the thread blocks in waitFor().
*
* @return the Process
*/
private Process waitForInternal() {
boolean interrupted = false;
while (true) {
try {
ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker() {
@Override
public boolean block() throws InterruptedException {
waitFor();
return true;
}
@Override
public boolean isReleasable() {
return !isAlive();
}
});
break;
} catch (InterruptedException x) {
interrupted = true;
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
return this;
}
/**
* Returns a ProcessHandle for the Process.
*
* {@code Process} objects returned by {@link ProcessBuilder#start} and
* {@link Runtime#exec} implement {@code toHandle} as the equivalent of
* {@link ProcessHandle#of(long) ProcessHandle.of(pid)} including the
* check for a SecurityManager and {@code RuntimePermission("manageProcess")}.
*
* @implSpec
* This implementation throws an instance of
* {@link java.lang.UnsupportedOperationException} and performs no other action.
* Subclasses should override this method to provide a ProcessHandle for the
* process. The methods {@link #pid}, {@link #info}, {@link #children},
* and {@link #descendants}, unless overridden, operate on the ProcessHandle.
*
* @return Returns a ProcessHandle for the Process
* @throws UnsupportedOperationException if the Process implementation
* does not support this operation
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @since 9
*/
public ProcessHandle toHandle() {
throw new UnsupportedOperationException(this.getClass()
+ ".toHandle() not supported");
}
/**
* Returns a snapshot of information about the process.
*
* <p> A {@link ProcessHandle.Info} instance has accessor methods
* that return information about the process if it is available.
*
* @implSpec
* This implementation returns information about the process as:
* {@link #toHandle toHandle().info()}.
*
* @return a snapshot of information about the process, always non-null
* @throws UnsupportedOperationException if the Process implementation
* does not support this operation
* @since 9
*/
public ProcessHandle.Info info() {
return toHandle().info();
}
/**
* Returns a snapshot of the direct children of the process.
* The parent of a direct child process is the process.
* Typically, a process that is {@linkplain #isAlive not alive} has no children.
* <p>
* <em>Note that processes are created and terminate asynchronously.
* There is no guarantee that a process is {@linkplain #isAlive alive}.
* </em>
*
* @implSpec
* This implementation returns the direct children as:
* {@link #toHandle toHandle().children()}.
*
* @return a sequential Stream of ProcessHandles for processes that are
* direct children of the process
* @throws UnsupportedOperationException if the Process implementation
* does not support this operation
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @since 9
*/
public Stream<ProcessHandle> children() {
return toHandle().children();
}
/**
* Returns a snapshot of the descendants of the process.
* The descendants of a process are the children of the process
* plus the descendants of those children, recursively.
* Typically, a process that is {@linkplain #isAlive not alive} has no children.
* <p>
* <em>Note that processes are created and terminate asynchronously.
* There is no guarantee that a process is {@linkplain #isAlive alive}.
* </em>
*
* @implSpec
* This implementation returns all children as:
* {@link #toHandle toHandle().descendants()}.
*
* @return a sequential Stream of ProcessHandles for processes that
* are descendants of the process
* @throws UnsupportedOperationException if the Process implementation
* does not support this operation
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @since 9
*/
public Stream<ProcessHandle> descendants() {
return toHandle().descendants();
}
/**
* An input stream for a subprocess pipe that skips by reading bytes
* instead of seeking, the underlying pipe does not support seek.
*/
static class PipeInputStream extends FileInputStream {
PipeInputStream(FileDescriptor fd) {
super(fd);
}
@Override
public long skip(long n) throws IOException {
long remaining = n;
int nr;
if (n <= 0) {
return 0;
}
int size = (int)Math.min(2048, remaining);
byte[] skipBuffer = new byte[size];
while (remaining > 0) {
nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
if (nr < 0) {
break;
}
remaining -= nr;
}
return n - remaining;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,438 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
/**
* ProcessHandle identifies and provides control of native processes. Each
* individual process can be monitored for liveness, list its children,
* get information about the process or destroy it.
* By comparison, {@link java.lang.Process Process} instances were started
* by the current process and additionally provide access to the process
* input, output, and error streams.
* <p>
* The native process ID is an identification number that the
* operating system assigns to the process.
* The range for process id values is dependent on the operating system.
* For example, an embedded system might use a 16-bit value.
* Status information about a process is retrieved from the native system
* and may change asynchronously; processes may be created or terminate
* spontaneously.
* The time between when a process terminates and the process id
* is reused for a new process is unpredictable.
* Race conditions can exist between checking the status of a process and
* acting upon it. When using ProcessHandles avoid assumptions
* about the liveness or identity of the underlying process.
* <p>
* Each ProcessHandle identifies and allows control of a process in the native
* system. ProcessHandles are returned from the factory methods {@link #current()},
* {@link #of(long)},
* {@link #children}, {@link #descendants}, {@link #parent()} and
* {@link #allProcesses()}.
* <p>
* The {@link Process} instances created by {@link ProcessBuilder} can be queried
* for a ProcessHandle that provides information about the Process.
* ProcessHandle references should not be freely distributed.
*
* <p>
* A {@link java.util.concurrent.CompletableFuture} available from {@link #onExit}
* can be used to wait for process termination, and possibly trigger dependent
* actions.
* <p>
* The factory methods limit access to ProcessHandles using the
* SecurityManager checking the {@link RuntimePermission RuntimePermission("manageProcess")}.
* The ability to control processes is also restricted by the native system,
* ProcessHandle provides no more access to, or control over, the native process
* than would be allowed by a native application.
*
* @implSpec
* In the case where ProcessHandles cannot be supported then the factory
* methods must consistently throw {@link java.lang.UnsupportedOperationException}.
* The methods of this class throw {@link java.lang.UnsupportedOperationException}
* if the operating system does not allow access to query or kill a process.
*
* <p>
* The {@code ProcessHandle} static factory methods return instances that are
* <a href="{@docRoot}/java/lang/doc-files/ValueBased.html">value-based</a>,
* immutable and thread-safe.
* Use of identity-sensitive operations (including reference equality
* ({@code ==}), identity hash code, or synchronization) on these instances of
* {@code ProcessHandle} may have unpredictable results and should be avoided.
* Use {@link #equals(Object) equals} or
* {@link #compareTo(ProcessHandle) compareTo} methods to compare ProcessHandles.
*
* @see Process
* @since 9
*/
public interface ProcessHandle extends Comparable<ProcessHandle> {
/**
* Returns the native process ID of the process. The native process ID is an
* identification number that the operating system assigns to the process.
* The operating system may reuse the process ID after a process terminates.
* Use {@link #equals(Object) equals} or
* {@link #compareTo(ProcessHandle) compareTo} to compare ProcessHandles.
*
* @return the native process ID of the process
* @throws UnsupportedOperationException if the implementation
* does not support this operation
*/
long pid();
/**
* Returns an {@code Optional<ProcessHandle>} for an existing native process.
*
* @param pid a native process ID
* @return an {@code Optional<ProcessHandle>} of the PID for the process;
* the {@code Optional} is empty if the process does not exist
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @throws UnsupportedOperationException if the implementation
* does not support this operation
*/
public static Optional<ProcessHandle> of(long pid) {
return ProcessHandleImpl.get(pid);
}
/**
* Returns a ProcessHandle for the current process. The ProcessHandle cannot be
* used to destroy the current process, use {@link System#exit System.exit} instead.
*
* @return a ProcessHandle for the current process
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @throws UnsupportedOperationException if the implementation
* does not support this operation
*/
public static ProcessHandle current() {
return ProcessHandleImpl.current();
}
/**
* Returns an {@code Optional<ProcessHandle>} for the parent process.
* Note that Processes in a zombie state usually don't have a parent.
*
* @return an {@code Optional<ProcessHandle>} of the parent process;
* the {@code Optional} is empty if the child process does not have a parent
* or if the parent is not available, possibly due to operating system limitations
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
*/
Optional<ProcessHandle> parent();
/**
* Returns a snapshot of the current direct children of the process.
* The {@link #parent} of a direct child process is the process.
* Typically, a process that is {@link #isAlive not alive} has no children.
* <p>
* <em>Note that processes are created and terminate asynchronously.
* There is no guarantee that a process is {@link #isAlive alive}.
* </em>
*
* @return a sequential Stream of ProcessHandles for processes that are
* direct children of the process
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
*/
Stream<ProcessHandle> children();
/**
* Returns a snapshot of the descendants of the process.
* The descendants of a process are the children of the process
* plus the descendants of those children, recursively.
* Typically, a process that is {@link #isAlive not alive} has no children.
* <p>
* <em>Note that processes are created and terminate asynchronously.
* There is no guarantee that a process is {@link #isAlive alive}.
* </em>
*
* @return a sequential Stream of ProcessHandles for processes that
* are descendants of the process
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
*/
Stream<ProcessHandle> descendants();
/**
* Returns a snapshot of all processes visible to the current process.
* <p>
* <em>Note that processes are created and terminate asynchronously. There
* is no guarantee that a process in the stream is alive or that no other
* processes may have been created since the inception of the snapshot.
* </em>
*
* @return a Stream of ProcessHandles for all processes
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @throws UnsupportedOperationException if the implementation
* does not support this operation
*/
static Stream<ProcessHandle> allProcesses() {
return ProcessHandleImpl.children(0);
}
/**
* Returns a snapshot of information about the process.
*
* <p> A {@link ProcessHandle.Info} instance has accessor methods that return
* information about the process if it is available.
*
* @return a snapshot of information about the process, always non-null
*/
Info info();
/**
* Information snapshot about the process.
* The attributes of a process vary by operating system and are not available
* in all implementations. Information about processes is limited
* by the operating system privileges of the process making the request.
* The return types are {@code Optional<T>} allowing explicit tests
* and actions if the value is available.
* @since 9
*/
public interface Info {
/**
* Returns the executable pathname of the process.
*
* @return an {@code Optional<String>} of the executable pathname
* of the process
*/
public Optional<String> command();
/**
* Returns the command line of the process.
* <p>
* If {@link #command command()} and {@link #arguments arguments()} return
* non-empty optionals, this is simply a convenience method which concatenates
* the values of the two functions separated by spaces. Otherwise it will return a
* best-effort, platform dependent representation of the command line.
*
* @apiNote Note that the returned executable pathname and the
* arguments may be truncated on some platforms due to system
* limitations.
* <p>
* The executable pathname may contain only the
* name of the executable without the full path information.
* It is undecideable whether white space separates different
* arguments or is part of a single argument.
*
* @return an {@code Optional<String>} of the command line
* of the process
*/
public Optional<String> commandLine();
/**
* Returns an array of Strings of the arguments of the process.
*
* @apiNote On some platforms, native applications are free to change
* the arguments array after startup and this method may only
* show the changed values.
*
* @return an {@code Optional<String[]>} of the arguments of the process
*/
public Optional<String[]> arguments();
/**
* Returns the start time of the process.
*
* @return an {@code Optional<Instant>} of the start time of the process
*/
public Optional<Instant> startInstant();
/**
* Returns the total cputime accumulated of the process.
*
* @return an {@code Optional<Duration>} for the accumulated total cputime
*/
public Optional<Duration> totalCpuDuration();
/**
* Return the user of the process.
*
* @return an {@code Optional<String>} for the user of the process
*/
public Optional<String> user();
}
/**
* Returns a {@code CompletableFuture<ProcessHandle>} for the termination
* of the process.
* The {@link java.util.concurrent.CompletableFuture} provides the ability
* to trigger dependent functions or actions that may be run synchronously
* or asynchronously upon process termination.
* When the process has terminated the CompletableFuture is
* {@link java.util.concurrent.CompletableFuture#complete completed} regardless
* of the exit status of the process.
* The {@code onExit} method can be called multiple times to invoke
* independent actions when the process exits.
* <p>
* Calling {@code onExit().get()} waits for the process to terminate and returns
* the ProcessHandle. The future can be used to check if the process is
* {@link java.util.concurrent.CompletableFuture#isDone done} or to
* {@link java.util.concurrent.Future#get() wait} for it to terminate.
* {@link java.util.concurrent.Future#cancel(boolean) Cancelling}
* the CompleteableFuture does not affect the Process.
* @apiNote
* The process may be observed to have terminated with {@link #isAlive}
* before the ComputableFuture is completed and dependent actions are invoked.
*
* @return a new {@code CompletableFuture<ProcessHandle>} for the ProcessHandle
*
* @throws IllegalStateException if the process is the current process
*/
CompletableFuture<ProcessHandle> onExit();
/**
* Returns {@code true} if the implementation of {@link #destroy}
* normally terminates the process.
* Returns {@code false} if the implementation of {@code destroy}
* forcibly and immediately terminates the process.
*
* @return {@code true} if the implementation of {@link #destroy}
* normally terminates the process;
* otherwise, {@link #destroy} forcibly terminates the process
*/
boolean supportsNormalTermination();
/**
* Requests the process to be killed.
* Whether the process represented by this {@code ProcessHandle} object is
* {@link #supportsNormalTermination normally terminated} or not is
* implementation dependent.
* Forcible process destruction is defined as the immediate termination of the
* process, whereas normal termination allows the process to shut down cleanly.
* If the process is not alive, no action is taken.
* The operating system access controls may prevent the process
* from being killed.
* <p>
* The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
* {@link java.util.concurrent.CompletableFuture#complete completed}
* when the process has terminated.
* <p>
* Note: The process may not terminate immediately.
* For example, {@code isAlive()} may return true for a brief period
* after {@code destroy()} is called.
*
* @return {@code true} if termination was successfully requested,
* otherwise {@code false}
* @throws IllegalStateException if the process is the current process
*/
boolean destroy();
/**
* Requests the process to be killed forcibly.
* The process represented by this {@code ProcessHandle} object is
* forcibly terminated.
* Forcible process destruction is defined as the immediate termination of the
* process, whereas normal termination allows the process to shut down cleanly.
* If the process is not alive, no action is taken.
* The operating system access controls may prevent the process
* from being killed.
* <p>
* The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
* {@link java.util.concurrent.CompletableFuture#complete completed}
* when the process has terminated.
* <p>
* Note: The process may not terminate immediately.
* For example, {@code isAlive()} may return true for a brief period
* after {@code destroyForcibly()} is called.
*
* @return {@code true} if termination was successfully requested,
* otherwise {@code false}
* @throws IllegalStateException if the process is the current process
*/
boolean destroyForcibly();
/**
* Tests whether the process represented by this {@code ProcessHandle} is alive.
* Process termination is implementation and operating system specific.
* The process is considered alive as long as the PID is valid.
*
* @return {@code true} if the process represented by this
* {@code ProcessHandle} object has not yet terminated
*/
boolean isAlive();
/**
* Returns a hash code value for this ProcessHandle.
* The hashcode value follows the general contract for {@link Object#hashCode()}.
* The value is a function of the {@link #pid pid()} value and
* may be a function of additional information to uniquely identify the process.
* If two ProcessHandles are equal according to the {@link #equals(Object) equals}
* method, then calling the hashCode method on each of the two objects
* must produce the same integer result.
*
* @return a hash code value for this object
*/
@Override
int hashCode();
/**
* Returns {@code true} if {@code other} object is non-null, is of the
* same implementation, and represents the same system process;
* otherwise it returns {@code false}.
* @implNote
* It is implementation specific whether ProcessHandles with the same PID
* represent the same system process. ProcessHandle implementations
* should contain additional information to uniquely identify the process.
* For example, the start time of the process could be used
* to determine if the PID has been re-used.
* The implementation of {@code equals} should return {@code true} for two
* ProcessHandles with the same PID unless there is information to
* distinguish them.
*
* @param other another object
* @return {@code true} if the {@code other} object is non-null,
* is of the same implementation class and represents
* the same system process; otherwise returns {@code false}
*/
@Override
boolean equals(Object other);
/**
* Compares this ProcessHandle with the specified ProcessHandle for order.
* The order is not specified, but is consistent with {@link Object#equals},
* which returns {@code true} if and only if two instances of ProcessHandle
* are of the same implementation and represent the same system process.
* Comparison is only supported among objects of same implementation.
* If attempt is made to mutually compare two different implementations
* of {@link ProcessHandle}s, {@link ClassCastException} is thrown.
*
* @param other the ProcessHandle to be compared
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
* @throws NullPointerException if the specified object is null
* @throws ClassCastException if the specified object is not of same class
* as this object
*/
@Override
int compareTo(ProcessHandle other);
}

View file

@ -0,0 +1,664 @@
/*
* Copyright (c) 2014, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.annotation.Native;
import java.security.PrivilegedAction;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.security.AccessController.doPrivileged;
/**
* ProcessHandleImpl is the implementation of ProcessHandle.
*
* @see Process
* @since 9
*/
final class ProcessHandleImpl implements ProcessHandle {
/**
* Default size of stack for reaper processes.
*/
private static long REAPER_DEFAULT_STACKSIZE = 128 * 1024;
/**
* Return value from waitForProcessExit0 indicating the process is not a child.
*/
@Native
private static final int NOT_A_CHILD = -2;
/**
* Cache the ProcessHandle of this process.
*/
private static final ProcessHandleImpl current;
/**
* Map of pids to ExitCompletions.
*/
private static final ConcurrentMap<Long, ExitCompletion>
completions = new ConcurrentHashMap<>();
static {
initNative();
long pid = getCurrentPid0();
current = new ProcessHandleImpl(pid, isAlive0(pid));
}
private static native void initNative();
/**
* The thread pool of "process reaper" daemon threads.
*/
private static final Executor processReaperExecutor =
doPrivileged((PrivilegedAction<Executor>) () -> {
ThreadGroup tg = Thread.currentThread().getThreadGroup();
while (tg.getParent() != null) tg = tg.getParent();
ThreadGroup systemThreadGroup = tg;
final long stackSize = Boolean.getBoolean("jdk.lang.processReaperUseDefaultStackSize")
? 0 : REAPER_DEFAULT_STACKSIZE;
ThreadFactory threadFactory = grimReaper -> {
Thread t = new Thread(systemThreadGroup, grimReaper,
"process reaper", stackSize, false);
t.setDaemon(true);
// A small attempt (probably futile) to avoid priority inversion
t.setPriority(Thread.MAX_PRIORITY);
return t;
};
return Executors.newCachedThreadPool(threadFactory);
});
private static class ExitCompletion extends CompletableFuture<Integer> {
final boolean isReaping;
ExitCompletion(boolean isReaping) {
this.isReaping = isReaping;
}
}
/**
* Returns a CompletableFuture that completes with process exit status when
* the process completes.
*
* @param shouldReap true if the exit value should be reaped
*/
static CompletableFuture<Integer> completion(long pid, boolean shouldReap) {
// check canonicalizing cache 1st
ExitCompletion completion = completions.get(pid);
// re-try until we get a completion that shouldReap => isReaping
while (completion == null || (shouldReap && !completion.isReaping)) {
ExitCompletion newCompletion = new ExitCompletion(shouldReap);
if (completion == null) {
completion = completions.putIfAbsent(pid, newCompletion);
} else {
completion = completions.replace(pid, completion, newCompletion)
? null : completions.get(pid);
}
if (completion == null) {
// newCompletion has just been installed successfully
completion = newCompletion;
// spawn a thread to wait for and deliver the exit value
processReaperExecutor.execute(new Runnable() {
// Use inner class to avoid lambda stack overhead
public void run() {
int exitValue = waitForProcessExit0(pid, shouldReap);
if (exitValue == NOT_A_CHILD) {
// pid not alive or not a child of this process
// If it is alive wait for it to terminate
long sleep = 300; // initial milliseconds to sleep
int incr = 30; // increment to the sleep time
long startTime = isAlive0(pid);
long origStart = startTime;
while (startTime >= 0) {
try {
Thread.sleep(Math.min(sleep, 5000L)); // no more than 5 sec
sleep += incr;
} catch (InterruptedException ie) {
// ignore and retry
}
startTime = isAlive0(pid); // recheck if is alive
if (origStart > 0 && startTime != origStart) {
// start time changed, pid is not the same process
break;
}
}
exitValue = 0;
}
newCompletion.complete(exitValue);
// remove from cache afterwards
completions.remove(pid, newCompletion);
}
});
}
}
return completion;
}
@Override
public CompletableFuture<ProcessHandle> onExit() {
if (this.equals(current)) {
throw new IllegalStateException("onExit for current process not allowed");
}
return ProcessHandleImpl.completion(pid(), false)
.handleAsync((exitStatus, unusedThrowable) -> this);
}
/**
* Wait for the process to exit, return the value.
* Conditionally reap the value if requested
* @param pid the processId
* @param reapvalue if true, the value is retrieved,
* else return the value and leave the process waitable
*
* @return the value or -1 if an error occurs
*/
private static native int waitForProcessExit0(long pid, boolean reapvalue);
/**
* The pid of this ProcessHandle.
*/
private final long pid;
/**
* The start time of this process.
* If STARTTIME_ANY, the start time of the process is not available from the os.
* If greater than zero, the start time of the process.
*/
private final long startTime;
/* The start time should match any value.
* Typically, this is because the OS can not supply it.
* The process is known to exist but not the exact start time.
*/
private final long STARTTIME_ANY = 0L;
/* The start time of a Process that does not exist. */
private final long STARTTIME_PROCESS_UNKNOWN = -1;
/**
* Private constructor. Instances are created by the {@code get(long)} factory.
* @param pid the pid for this instance
*/
private ProcessHandleImpl(long pid, long startTime) {
this.pid = pid;
this.startTime = startTime;
}
/**
* Returns a ProcessHandle for an existing native process.
*
* @param pid the native process identifier
* @return The ProcessHandle for the pid if the process is alive;
* or {@code null} if the process ID does not exist in the native system.
* @throws SecurityException if RuntimePermission("manageProcess") is not granted
*/
static Optional<ProcessHandle> get(long pid) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("manageProcess"));
}
long start = isAlive0(pid);
return (start >= 0)
? Optional.of(new ProcessHandleImpl(pid, start))
: Optional.empty();
}
/**
* Returns a ProcessHandle for an existing native process known to be alive.
* The startTime of the process is retrieved and stored in the ProcessHandle.
* It does not perform a security check since it is called from ProcessImpl.
* @param pid of the known to exist process
* @return a ProcessHandle corresponding to an existing Process instance
*/
static ProcessHandleImpl getInternal(long pid) {
return new ProcessHandleImpl(pid, isAlive0(pid));
}
/**
* Returns the native process ID.
* A {@code long} is used to be able to fit the system specific binary values
* for the process.
*
* @return the native process ID
*/
@Override
public long pid() {
return pid;
}
/**
* Returns the ProcessHandle for the current native process.
*
* @return The ProcessHandle for the OS process.
* @throws SecurityException if RuntimePermission("manageProcess") is not granted
*/
public static ProcessHandleImpl current() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("manageProcess"));
}
return current;
}
/**
* Return the pid of the current process.
*
* @return the pid of the current process
*/
private static native long getCurrentPid0();
/**
* Returns a ProcessHandle for the parent process.
*
* @return a ProcessHandle of the parent process; {@code null} is returned
* if the child process does not have a parent
* @throws SecurityException if permission is not granted by the
* security policy
*/
public Optional<ProcessHandle> parent() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("manageProcess"));
}
long ppid = parent0(pid, startTime);
if (ppid <= 0) {
return Optional.empty();
}
return get(ppid);
}
/**
* Returns the parent of the native pid argument.
*
* @param pid the process id
* @param startTime the startTime of the process
* @return the parent of the native pid; if any, otherwise -1
*/
private static native long parent0(long pid, long startTime);
/**
* Returns the number of pids filled in to the array.
* @param pid if {@code pid} equals zero, then all known processes are returned;
* otherwise only direct child process pids are returned
* @param pids an allocated long array to receive the pids
* @param ppids an allocated long array to receive the parent pids; may be null
* @param starttimes an allocated long array to receive the child start times; may be null
* @return if greater than or equals to zero is the number of pids in the array;
* if greater than the length of the arrays, the arrays are too small
*/
private static native int getProcessPids0(long pid, long[] pids,
long[] ppids, long[] starttimes);
/**
* Destroy the process for this ProcessHandle.
* The native code checks the start time before sending the termination request.
*
* @param force {@code true} if the process should be terminated forcibly;
* else {@code false} for a normal termination
*/
boolean destroyProcess(boolean force) {
if (this.equals(current)) {
throw new IllegalStateException("destroy of current process not allowed");
}
return destroy0(pid, startTime, force);
}
/**
* Signal the process to terminate.
* The process is signaled only if its start time matches the known start time.
*
* @param pid process id to kill
* @param startTime the start time of the process
* @param forcibly true to forcibly terminate (SIGKILL vs SIGTERM)
* @return true if the process was signaled without error; false otherwise
*/
private static native boolean destroy0(long pid, long startTime, boolean forcibly);
@Override
public boolean destroy() {
return destroyProcess(false);
}
@Override
public boolean destroyForcibly() {
return destroyProcess(true);
}
@Override
public boolean supportsNormalTermination() {
return ProcessImpl.SUPPORTS_NORMAL_TERMINATION;
}
/**
* Tests whether the process represented by this {@code ProcessHandle} is alive.
*
* @return {@code true} if the process represented by this
* {@code ProcessHandle} object has not yet terminated.
* @since 9
*/
@Override
public boolean isAlive() {
long start = isAlive0(pid);
return (start >= 0 && (start == startTime || start == 0 || startTime == 0));
}
/**
* Returns the process start time depending on whether the pid is alive.
* This must not reap the exitValue.
*
* @param pid the pid to check
* @return the start time in milliseconds since 1970,
* 0 if the start time cannot be determined,
* -1 if the pid does not exist.
*/
private static native long isAlive0(long pid);
@Override
public Stream<ProcessHandle> children() {
// The native OS code selects based on matching the requested parent pid.
// If the original parent exits, the pid may have been re-used for
// this newer process.
// Processes started by the original parent (now dead) will all have
// start times less than the start of this newer parent.
// Processes started by this newer parent will have start times equal
// or after this parent.
return children(pid).filter(ph -> startTime <= ((ProcessHandleImpl)ph).startTime);
}
/**
* Returns a Stream of the children of a process or all processes.
*
* @param pid the pid of the process for which to find the children;
* 0 for all processes
* @return a stream of ProcessHandles
*/
static Stream<ProcessHandle> children(long pid) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("manageProcess"));
}
int size = 100;
long[] childpids = null;
long[] starttimes = null;
while (childpids == null || size > childpids.length) {
childpids = new long[size];
starttimes = new long[size];
size = getProcessPids0(pid, childpids, null, starttimes);
}
final long[] cpids = childpids;
final long[] stimes = starttimes;
return IntStream.range(0, size).mapToObj(i -> new ProcessHandleImpl(cpids[i], stimes[i]));
}
@Override
public Stream<ProcessHandle> descendants() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("manageProcess"));
}
int size = 100;
long[] pids = null;
long[] ppids = null;
long[] starttimes = null;
while (pids == null || size > pids.length) {
pids = new long[size];
ppids = new long[size];
starttimes = new long[size];
size = getProcessPids0(0, pids, ppids, starttimes);
}
int next = 0; // index of next process to check
int count = -1; // count of subprocesses scanned
long ppid = pid; // start looking for this parent
long ppStart = 0;
// Find the start time of the parent
for (int i = 0; i < size; i++) {
if (pids[i] == ppid) {
ppStart = starttimes[i];
break;
}
}
do {
// Scan from next to size looking for ppid with child start time
// the same or later than the parent.
// If found, exchange it with index next
for (int i = next; i < size; i++) {
if (ppids[i] == ppid &&
ppStart <= starttimes[i]) {
swap(pids, i, next);
swap(ppids, i, next);
swap(starttimes, i, next);
next++;
}
}
ppid = pids[++count]; // pick up the next pid to scan for
ppStart = starttimes[count]; // and its start time
} while (count < next);
final long[] cpids = pids;
final long[] stimes = starttimes;
return IntStream.range(0, count).mapToObj(i -> new ProcessHandleImpl(cpids[i], stimes[i]));
}
// Swap two elements in an array
private static void swap(long[] array, int x, int y) {
long v = array[x];
array[x] = array[y];
array[y] = v;
}
@Override
public ProcessHandle.Info info() {
return ProcessHandleImpl.Info.info(pid, startTime);
}
@Override
public int compareTo(ProcessHandle other) {
return Long.compare(pid, ((ProcessHandleImpl) other).pid);
}
@Override
public String toString() {
return Long.toString(pid);
}
@Override
public int hashCode() {
return Long.hashCode(pid);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ProcessHandleImpl) {
ProcessHandleImpl other = (ProcessHandleImpl) obj;
return (pid == other.pid) &&
(startTime == other.startTime
|| startTime == 0
|| other.startTime == 0);
}
return false;
}
/**
* Implementation of ProcessHandle.Info.
* Information snapshot about a process.
* The attributes of a process vary by operating system and are not available
* in all implementations. Additionally, information about other processes
* is limited by the operating system privileges of the process making the request.
* If a value is not available, either a {@code null} or {@code -1} is stored.
* The accessor methods return {@code null} if the value is not available.
*/
static class Info implements ProcessHandle.Info {
static {
initIDs();
}
/**
* Initialization of JNI fieldIDs.
*/
private static native void initIDs();
/**
* Fill in this Info instance with information about the native process.
* If values are not available the native code does not modify the field.
* @param pid of the native process
*/
private native void info0(long pid);
String command;
String commandLine;
String[] arguments;
long startTime;
long totalTime;
String user;
Info() {
command = null;
commandLine = null;
arguments = null;
startTime = -1L;
totalTime = -1L;
user = null;
}
/**
* Returns the Info object with the fields from the process.
* Whatever fields are provided by native are returned.
* If the startTime of the process does not match the provided
* startTime then an empty Info is returned.
*
* @param pid the native process identifier
* @param startTime the startTime of the process being queried
* @return ProcessHandle.Info non-null; individual fields may be null
* or -1 if not available.
*/
public static ProcessHandle.Info info(long pid, long startTime) {
Info info = new Info();
info.info0(pid);
if (startTime != info.startTime) {
info.command = null;
info.arguments = null;
info.startTime = -1L;
info.totalTime = -1L;
info.user = null;
}
return info;
}
@Override
public Optional<String> command() {
return Optional.ofNullable(command);
}
@Override
public Optional<String> commandLine() {
if (command != null && arguments != null) {
return Optional.of(command + " " + String.join(" ", arguments));
} else {
return Optional.ofNullable(commandLine);
}
}
@Override
public Optional<String[]> arguments() {
return Optional.ofNullable(arguments);
}
@Override
public Optional<Instant> startInstant() {
return (startTime > 0)
? Optional.of(Instant.ofEpochMilli(startTime))
: Optional.empty();
}
@Override
public Optional<Duration> totalCpuDuration() {
return (totalTime != -1)
? Optional.of(Duration.ofNanos(totalTime))
: Optional.empty();
}
@Override
public Optional<String> user() {
return Optional.ofNullable(user);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(60);
sb.append('[');
if (user != null) {
sb.append("user: ");
sb.append(user());
}
if (command != null) {
if (sb.length() != 0) sb.append(", ");
sb.append("cmd: ");
sb.append(command);
}
if (arguments != null && arguments.length > 0) {
if (sb.length() != 0) sb.append(", ");
sb.append("args: ");
sb.append(Arrays.toString(arguments));
}
if (commandLine != null) {
if (sb.length() != 0) sb.append(", ");
sb.append("cmdLine: ");
sb.append(commandLine);
}
if (startTime > 0) {
if (sb.length() != 0) sb.append(", ");
sb.append("startTime: ");
sb.append(startInstant());
}
if (totalTime != -1) {
if (sb.length() != 0) sb.append(", ");
sb.append("totalTime: ");
sb.append(totalCpuDuration().toString());
}
sb.append(']');
return sb.toString();
}
}
}

View file

@ -0,0 +1,272 @@
/*
* 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 java.lang;
import jdk.internal.reflect.ReflectionFactory;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* A collection of most specific public methods. Methods are added to it using
* {@link #merge(Method)} method. Only the most specific methods for a
* particular signature are kept.
*/
final class PublicMethods {
/**
* a map of (method name, parameter types) -> linked list of Method(s)
*/
private final Map<Key, MethodList> map = new LinkedHashMap<>();
/**
* keeps track of the number of collected methods
*/
private int methodCount;
/**
* Merges new method with existing methods. New method is either
* ignored (if a more specific method with same signature exists) or added
* to the collection. When it is added to the collection, it may replace one
* or more existing methods with same signature if they are less specific
* than added method.
* See comments in code...
*/
void merge(Method method) {
Key key = new Key(method);
MethodList existing = map.get(key);
int xLen = existing == null ? 0 : existing.length();
MethodList merged = MethodList.merge(existing, method);
methodCount += merged.length() - xLen;
// replace if head of list changed
if (merged != existing) {
map.put(key, merged);
}
}
/**
* Dumps methods to array.
*/
Method[] toArray() {
Method[] array = new Method[methodCount];
int i = 0;
for (MethodList ml : map.values()) {
for (; ml != null; ml = ml.next) {
array[i++] = ml.method;
}
}
return array;
}
/**
* Method (name, parameter types) tuple.
*/
private static final class Key {
private static final ReflectionFactory reflectionFactory =
AccessController.doPrivileged(
new ReflectionFactory.GetReflectionFactoryAction());
private final String name; // must be interned (as from Method.getName())
private final Class<?>[] ptypes;
Key(Method method) {
name = method.getName();
ptypes = reflectionFactory.getExecutableSharedParameterTypes(method);
}
static boolean matches(Method method,
String name, // may not be interned
Class<?>[] ptypes) {
return method.getName().equals(name) &&
Arrays.equals(
reflectionFactory.getExecutableSharedParameterTypes(method),
ptypes
);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Key)) return false;
Key that = (Key) o;
//noinspection StringEquality (guaranteed interned String(s))
return name == that.name &&
Arrays.equals(ptypes, that.ptypes);
}
@Override
public int hashCode() {
return System.identityHashCode(name) + // guaranteed interned String
31 * Arrays.hashCode(ptypes);
}
}
/**
* Node of a inked list containing Method(s) sharing the same
* (name, parameter types) tuple.
*/
static final class MethodList {
Method method;
MethodList next;
private MethodList(Method method) {
this.method = method;
}
/**
* @return the head of a linked list containing given {@code methods}
* filtered by given method {@code name}, parameter types
* {@code ptypes} and including or excluding static methods as
* requested by {@code includeStatic} flag.
*/
static MethodList filter(Method[] methods, String name,
Class<?>[] ptypes, boolean includeStatic) {
MethodList head = null, tail = null;
for (Method method : methods) {
if ((includeStatic || !Modifier.isStatic(method.getModifiers())) &&
Key.matches(method, name, ptypes)) {
if (tail == null) {
head = tail = new MethodList(method);
} else {
tail = tail.next = new MethodList(method);
}
}
}
return head;
}
/**
* This method should only be called with the {@code head} (possibly null)
* of a list of Method(s) that share the same (method name, parameter types)
* and another {@code methodList} that also contains Method(s) with the
* same and equal (method name, parameter types) as the 1st list.
* It modifies the 1st list and returns the head of merged list
* containing only the most specific methods for each signature
* (i.e. return type). The returned head of the merged list may or
* may not be the same as the {@code head} of the given list.
* The given {@code methodList} is not modified.
*/
static MethodList merge(MethodList head, MethodList methodList) {
for (MethodList ml = methodList; ml != null; ml = ml.next) {
head = merge(head, ml.method);
}
return head;
}
private static MethodList merge(MethodList head, Method method) {
Class<?> dclass = method.getDeclaringClass();
Class<?> rtype = method.getReturnType();
MethodList prev = null;
for (MethodList l = head; l != null; l = l.next) {
// eXisting method
Method xmethod = l.method;
// only merge methods with same signature:
// (return type, name, parameter types) tuple
// as we only keep methods with same (name, parameter types)
// tuple together in one list, we only need to check return type
if (rtype == xmethod.getReturnType()) {
Class<?> xdclass = xmethod.getDeclaringClass();
if (dclass.isInterface() == xdclass.isInterface()) {
// both methods are declared by interfaces
// or both by classes
if (dclass.isAssignableFrom(xdclass)) {
// existing method is the same or overrides
// new method - ignore new method
return head;
}
if (xdclass.isAssignableFrom(dclass)) {
// new method overrides existing
// method - knock out existing method
if (prev != null) {
prev.next = l.next;
} else {
head = l.next;
}
// keep iterating
} else {
// unrelated (should only happen for interfaces)
prev = l;
// keep iterating
}
} else if (dclass.isInterface()) {
// new method is declared by interface while
// existing method is declared by class -
// ignore new method
return head;
} else /* xdclass.isInterface() */ {
// new method is declared by class while
// existing method is declared by interface -
// knock out existing method
if (prev != null) {
prev.next = l.next;
} else {
head = l.next;
}
// keep iterating
}
} else {
// distinct signatures
prev = l;
// keep iterating
}
}
// append new method to the list
if (prev == null) {
head = new MethodList(method);
} else {
prev.next = new MethodList(method);
}
return head;
}
private int length() {
int len = 1;
for (MethodList ml = next; ml != null; ml = ml.next) {
len++;
}
return len;
}
/**
* @return 1st method in list with most specific return type
*/
Method getMostSpecific() {
Method m = method;
Class<?> rt = m.getReturnType();
for (MethodList ml = next; ml != null; ml = ml.next) {
Method m2 = ml.method;
Class<?> rt2 = m2.getReturnType();
if (rt2 != rt && rt.isAssignableFrom(rt2)) {
// found more specific return type
m = m2;
rt = rt2;
}
}
return m;
}
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2003, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.io.IOException;
/**
* A {@code Readable} is a source of characters. Characters from
* a {@code Readable} are made available to callers of the read
* method via a {@link java.nio.CharBuffer CharBuffer}.
*
* @since 1.5
*/
public interface Readable {
/**
* Attempts to read characters into the specified character buffer.
* The buffer is used as a repository of characters as-is: the only
* changes made are the results of a put operation. No flipping or
* rewinding of the buffer is performed.
*
* @param cb the buffer to read characters into
* @return The number of {@code char} values added to the buffer,
* or -1 if this source of characters is at its end
* @throws IOException if an I/O error occurs
* @throws NullPointerException if cb is null
* @throws java.nio.ReadOnlyBufferException if cb is a read only buffer
*/
public int read(java.nio.CharBuffer cb) throws IOException;
}

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2009, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Common superclass of exceptions thrown by reflective operations in
* core reflection.
*
* @see LinkageError
* @since 1.7
*/
public class ReflectiveOperationException extends Exception {
static final long serialVersionUID = 123456789L;
/**
* Constructs a new exception with {@code null} as its detail
* message. The cause is not initialized, and may subsequently be
* initialized by a call to {@link #initCause}.
*/
public ReflectiveOperationException() {
super();
}
/**
* Constructs a new exception with the specified detail message.
* The cause is not initialized, and may subsequently be
* initialized by a call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public ReflectiveOperationException(String message) {
super(message);
}
/**
* Constructs a new exception with the specified detail message
* and cause.
*
* <p>Note that the detail message associated with
* {@code cause} is <em>not</em> automatically incorporated in
* this exception's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public ReflectiveOperationException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new exception with the specified cause and a detail
* message of {@code (cause==null ? null : cause.toString())} (which
* typically contains the class and detail message of {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public ReflectiveOperationException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 1994, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* The <code>Runnable</code> interface should be implemented by any
* class whose instances are intended to be executed by a thread. The
* class must define a method of no arguments called <code>run</code>.
* <p>
* This interface is designed to provide a common protocol for objects that
* wish to execute code while they are active. For example,
* <code>Runnable</code> is implemented by class <code>Thread</code>.
* Being active simply means that a thread has been started and has not
* yet been stopped.
* <p>
* In addition, <code>Runnable</code> provides the means for a class to be
* active while not subclassing <code>Thread</code>. A class that implements
* <code>Runnable</code> can run without subclassing <code>Thread</code>
* by instantiating a <code>Thread</code> instance and passing itself in
* as the target. In most cases, the <code>Runnable</code> interface should
* be used if you are only planning to override the <code>run()</code>
* method and no other <code>Thread</code> methods.
* This is important because classes should not be subclassed
* unless the programmer intends on modifying or enhancing the fundamental
* behavior of the class.
*
* @author Arthur van Hoff
* @see java.lang.Thread
* @see java.util.concurrent.Callable
* @since 1.0
*/
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 1995, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* {@code RuntimeException} is the superclass of those
* exceptions that can be thrown during the normal operation of the
* Java Virtual Machine.
*
* <p>{@code RuntimeException} and its subclasses are <em>unchecked
* exceptions</em>. Unchecked exceptions do <em>not</em> need to be
* declared in a method or constructor's {@code throws} clause if they
* can be thrown by the execution of the method or constructor and
* propagate outside the method or constructor boundary.
*
* @author Frank Yellin
* @jls 11.2 Compile-Time Checking of Exceptions
* @since 1.0
*/
public class RuntimeException extends Exception {
static final long serialVersionUID = -7034897190745766939L;
/** Constructs a new runtime exception with {@code null} as its
* detail message. The cause is not initialized, and may subsequently be
* initialized by a call to {@link #initCause}.
*/
public RuntimeException() {
super();
}
/** Constructs a new runtime exception with the specified detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public RuntimeException(String message) {
super(message);
}
/**
* Constructs a new runtime exception with the specified detail message and
* cause. <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this runtime exception's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public RuntimeException(String message, Throwable cause) {
super(message, cause);
}
/** Constructs a new runtime exception with the specified cause and a
* detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}). This constructor is useful for runtime exceptions
* that are little more than wrappers for other throwables.
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public RuntimeException(Throwable cause) {
super(cause);
}
/**
* Constructs a new runtime exception with the specified detail
* message, cause, suppression enabled or disabled, and writable
* stack trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
*
* @since 1.7
*/
protected RuntimeException(String message, Throwable cause,
boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View file

@ -0,0 +1,439 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.security.*;
import java.lang.module.ModuleFinder;
/**
* This class is for runtime permissions. A {@code RuntimePermission}
* contains a name (also referred to as a "target name") but no actions
* list; you either have the named permission or you don't.
* <p>
* The target name is the name of the runtime permission (see below). The
* naming convention follows the hierarchical property naming convention.
* Also, an asterisk may appear at the end of the name, following a ".",
* or by itself, to signify a wildcard match. For example: "loadLibrary.*"
* and "*" signify a wildcard match, while "*loadLibrary" and "a*b" do not.
* <p>
* The following table lists the standard {@code RuntimePermission}
* target names, and for each provides a description of what the permission
* allows and a discussion of the risks of granting code the permission.
*
* <table class="striped">
* <caption style="display:none">permission target name,
* what the target allows, and associated risks</caption>
* <thead>
* <tr>
* <th scope="col">Permission Target Name</th>
* <th scope="col">What the Permission Allows</th>
* <th scope="col">Risks of Allowing this Permission</th>
* </tr>
* </thead>
* <tbody>
*
* <tr>
* <th scope="row">createClassLoader</th>
* <td>Creation of a class loader</td>
* <td>This is an extremely dangerous permission to grant.
* Malicious applications that can instantiate their own class
* loaders could then load their own rogue classes into the system.
* These newly loaded classes could be placed into any protection
* domain by the class loader, thereby automatically granting the
* classes the permissions for that domain.</td>
* </tr>
*
* <tr>
* <th scope="row">getClassLoader</th>
* <td>Retrieval of a class loader (e.g., the class loader for the calling
* class)</td>
* <td>This would grant an attacker permission to get the
* class loader for a particular class. This is dangerous because
* having access to a class's class loader allows the attacker to
* load other classes available to that class loader. The attacker
* would typically otherwise not have access to those classes.</td>
* </tr>
*
* <tr>
* <th scope="row">setContextClassLoader</th>
* <td>Setting of the context class loader used by a thread</td>
* <td>The context class loader is used by system code and extensions
* when they need to lookup resources that might not exist in the system
* class loader. Granting setContextClassLoader permission would allow
* code to change which context class loader is used
* for a particular thread, including system threads.</td>
* </tr>
*
* <tr>
* <th scope="row">enableContextClassLoaderOverride</th>
* <td>Subclass implementation of the thread context class loader methods</td>
* <td>The context class loader is used by system code and extensions
* when they need to lookup resources that might not exist in the system
* class loader. Granting enableContextClassLoaderOverride permission would allow
* a subclass of Thread to override the methods that are used
* to get or set the context class loader for a particular thread.</td>
* </tr>
*
* <tr>
* <th scope="row">closeClassLoader</th>
* <td>Closing of a ClassLoader</td>
* <td>Granting this permission allows code to close any URLClassLoader
* that it has a reference to.</td>
* </tr>
*
* <tr>
* <th scope="row">setSecurityManager</th>
* <td>Setting of the security manager (possibly replacing an existing one)
* </td>
* <td>The security manager is a class that allows
* applications to implement a security policy. Granting the setSecurityManager
* permission would allow code to change which security manager is used by
* installing a different, possibly less restrictive security manager,
* thereby bypassing checks that would have been enforced by the original
* security manager.</td>
* </tr>
*
* <tr>
* <th scope="row">createSecurityManager</th>
* <td>Creation of a new security manager</td>
* <td>This gives code access to protected, sensitive methods that may
* disclose information about other classes or the execution stack.</td>
* </tr>
*
* <tr>
* <th scope="row">getenv.{variable name}</th>
* <td>Reading of the value of the specified environment variable</td>
* <td>This would allow code to read the value, or determine the
* existence, of a particular environment variable. This is
* dangerous if the variable contains confidential data.</td>
* </tr>
*
* <tr>
* <th scope="row">exitVM.{exit status}</th>
* <td>Halting of the Java Virtual Machine with the specified exit status</td>
* <td>This allows an attacker to mount a denial-of-service attack
* by automatically forcing the virtual machine to halt.
* Note: The "exitVM.*" permission is automatically granted to all code
* loaded from the application class path, thus enabling applications
* to terminate themselves. Also, the "exitVM" permission is equivalent to
* "exitVM.*".</td>
* </tr>
*
* <tr>
* <th scope="row">shutdownHooks</th>
* <td>Registration and cancellation of virtual-machine shutdown hooks</td>
* <td>This allows an attacker to register a malicious shutdown
* hook that interferes with the clean shutdown of the virtual machine.</td>
* </tr>
*
* <tr>
* <th scope="row">setFactory</th>
* <td>Setting of the socket factory used by ServerSocket or Socket,
* or of the stream handler factory used by URL</td>
* <td>This allows code to set the actual implementation
* for the socket, server socket, stream handler, or RMI socket factory.
* An attacker may set a faulty implementation which mangles the data
* stream.</td>
* </tr>
*
* <tr>
* <th scope="row">setIO</th>
* <td>Setting of System.out, System.in, and System.err</td>
* <td>This allows changing the value of the standard system streams.
* An attacker may change System.in to monitor and
* steal user input, or may set System.err to a "null" OutputStream,
* which would hide any error messages sent to System.err. </td>
* </tr>
*
* <tr>
* <th scope="row">modifyThread</th>
* <td>Modification of threads, e.g., via calls to Thread
* {@code interrupt, stop, suspend, resume, setDaemon, setPriority,
* setName} and {@code setUncaughtExceptionHandler}
* methods</td>
* <td>This allows an attacker to modify the behaviour of
* any thread in the system.</td>
* </tr>
*
* <tr>
* <th scope="row">stopThread</th>
* <td>Stopping of threads via calls to the Thread <code>stop</code>
* method</td>
* <td>This allows code to stop any thread in the system provided that it is
* already granted permission to access that thread.
* This poses as a threat, because that code may corrupt the system by
* killing existing threads.</td>
* </tr>
*
* <tr>
* <th scope="row">modifyThreadGroup</th>
* <td>modification of thread groups, e.g., via calls to ThreadGroup
* <code>destroy</code>, <code>getParent</code>, <code>resume</code>,
* <code>setDaemon</code>, <code>setMaxPriority</code>, <code>stop</code>,
* and <code>suspend</code> methods</td>
* <td>This allows an attacker to create thread groups and
* set their run priority.</td>
* </tr>
*
* <tr>
* <th scope="row">getProtectionDomain</th>
* <td>Retrieval of the ProtectionDomain for a class</td>
* <td>This allows code to obtain policy information
* for a particular code source. While obtaining policy information
* does not compromise the security of the system, it does give
* attackers additional information, such as local file names for
* example, to better aim an attack.</td>
* </tr>
*
* <tr>
* <th scope="row">getFileSystemAttributes</th>
* <td>Retrieval of file system attributes</td>
* <td>This allows code to obtain file system information such as disk usage
* or disk space available to the caller. This is potentially dangerous
* because it discloses information about the system hardware
* configuration and some information about the caller's privilege to
* write files.</td>
* </tr>
*
* <tr>
* <th scope="row">readFileDescriptor</th>
* <td>Reading of file descriptors</td>
* <td>This would allow code to read the particular file associated
* with the file descriptor read. This is dangerous if the file
* contains confidential data.</td>
* </tr>
*
* <tr>
* <th scope="row">writeFileDescriptor</th>
* <td>Writing to file descriptors</td>
* <td>This allows code to write to a particular file associated
* with the descriptor. This is dangerous because it may allow
* malicious code to plant viruses or at the very least, fill up
* your entire disk.</td>
* </tr>
*
* <tr>
* <th scope="row">loadLibrary.{library name}</th>
* <td>Dynamic linking of the specified library</td>
* <td>It is dangerous to allow an applet permission to load native code
* libraries, because the Java security architecture is not designed to and
* does not prevent malicious behavior at the level of native code.</td>
* </tr>
*
* <tr>
* <th scope="row">accessClassInPackage.{package name}</th>
* <td>Access to the specified package via a class loader's
* <code>loadClass</code> method when that class loader calls
* the SecurityManager <code>checkPackageAccess</code> method</td>
* <td>This gives code access to classes in packages
* to which it normally does not have access. Malicious code
* may use these classes to help in its attempt to compromise
* security in the system.</td>
* </tr>
*
* <tr>
* <th scope="row">defineClassInPackage.{package name}</th>
* <td>Definition of classes in the specified package, via a class
* loader's <code>defineClass</code> method when that class loader calls
* the SecurityManager <code>checkPackageDefinition</code> method.</td>
* <td>This grants code permission to define a class
* in a particular package. This is dangerous because malicious
* code with this permission may define rogue classes in
* trusted packages like <code>java.security</code> or <code>java.lang</code>,
* for example.</td>
* </tr>
*
* <tr>
* <th scope="row">defineClass</th>
* <td>Define a class with
* {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[])
* Lookup.defineClass}.</td>
* <td>This grants code with a suitably privileged {@code Lookup} object
* permission to define classes in the same package as the {@code Lookup}'s
* lookup class. </td>
* </tr>
*
* <tr>
* <th scope="row">accessDeclaredMembers</th>
* <td>Access to the declared members of a class</td>
* <td>This grants code permission to query a class for its public,
* protected, default (package) access, and private fields and/or
* methods. Although the code would have
* access to the private and protected field and method names, it would not
* have access to the private/protected field data and would not be able
* to invoke any private methods. Nevertheless, malicious code
* may use this information to better aim an attack.
* Additionally, it may invoke any public methods and/or access public fields
* in the class. This could be dangerous if
* the code would normally not be able to invoke those methods and/or
* access the fields because
* it can't cast the object to the class/interface with those methods
* and fields.
</td>
* </tr>
* <tr>
* <th scope="row">queuePrintJob</th>
* <td>Initiation of a print job request</td>
* <td>This could print sensitive information to a printer,
* or simply waste paper.</td>
* </tr>
*
* <tr>
* <th scope="row">getStackTrace</th>
* <td>Retrieval of the stack trace information of another thread.</td>
* <td>This allows retrieval of the stack trace information of
* another thread. This might allow malicious code to monitor the
* execution of threads and discover vulnerabilities in applications.</td>
* </tr>
*
* <tr>
* <th scope="row">getStackWalkerWithClassReference</th>
* <td>Get a stack walker that can retrieve stack frames with class reference.</td>
* <td>This allows retrieval of Class objects from stack walking.
* This might allow malicious code to access Class objects on the stack
* outside its own context.</td>
* </tr>
*
* <tr>
* <th scope="row">setDefaultUncaughtExceptionHandler</th>
* <td>Setting the default handler to be used when a thread
* terminates abruptly due to an uncaught exception</td>
* <td>This allows an attacker to register a malicious
* uncaught exception handler that could interfere with termination
* of a thread</td>
* </tr>
*
* <tr>
* <th scope="row">preferences</th>
* <td>Represents the permission required to get access to the
* java.util.prefs.Preferences implementations user or system root
* which in turn allows retrieval or update operations within the
* Preferences persistent backing store.) </td>
* <td>This permission allows the user to read from or write to the
* preferences backing store if the user running the code has
* sufficient OS privileges to read/write to that backing store.
* The actual backing store may reside within a traditional filesystem
* directory or within a registry depending on the platform OS</td>
* </tr>
*
* <tr>
* <th scope="row">manageProcess</th>
* <td>Native process termination and information about processes
* {@link ProcessHandle}.</td>
* <td>Allows code to identify and terminate processes that it did not create.</td>
* </tr>
*
* <tr>
* <th scope="row">localeServiceProvider</th>
* <td>This {@code RuntimePermission} is required to be granted to
* classes which subclass and implement
* {@code java.util.spi.LocaleServiceProvider}. The permission is
* checked during invocation of the abstract base class constructor.
* This permission ensures trust in classes which implement this
* security-sensitive provider mechanism. </td>
* <td>See <a href= "../util/spi/LocaleServiceProvider.html">
* {@code java.util.spi.LocaleServiceProvider}</a> for more
* information.</td>
* </tr>
*
* <tr>
* <th scope="row">loggerFinder</th>
* <td>This {@code RuntimePermission} is required to be granted to
* classes which subclass or call methods on
* {@code java.lang.System.LoggerFinder}. The permission is
* checked during invocation of the abstract base class constructor, as
* well as on the invocation of its public methods.
* This permission ensures trust in classes which provide loggers
* to system classes.</td>
* <td>See {@link java.lang.System.LoggerFinder java.lang.System.LoggerFinder}
* for more information.</td>
* </tr>
*
* <tr>
* <th scope="row">accessSystemModules</th>
* <td>Access system modules in the runtime image.</td>
* <td>This grants the permission to access resources in the
* {@linkplain ModuleFinder#ofSystem system modules} in the runtime image.</td>
* </tr>
*
* </tbody>
* </table>
*
* @implNote
* Implementations may define additional target names, but should use naming
* conventions such as reverse domain name notation to avoid name clashes.
*
* @see java.security.BasicPermission
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
* @see java.lang.SecurityManager
*
*
* @author Marianne Mueller
* @author Roland Schemers
* @since 1.2
*/
public final class RuntimePermission extends BasicPermission {
private static final long serialVersionUID = 7399184964622342223L;
/**
* Creates a new RuntimePermission with the specified name.
* The name is the symbolic name of the RuntimePermission, such as
* "exit", "setFactory", etc. An asterisk
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match.
*
* @param name the name of the RuntimePermission.
*
* @throws NullPointerException if <code>name</code> is <code>null</code>.
* @throws IllegalArgumentException if <code>name</code> is empty.
*/
public RuntimePermission(String name)
{
super(name);
}
/**
* Creates a new RuntimePermission object with the specified name.
* The name is the symbolic name of the RuntimePermission, and the
* actions String is currently unused and should be null.
*
* @param name the name of the RuntimePermission.
* @param actions should be null.
*
* @throws NullPointerException if <code>name</code> is <code>null</code>.
* @throws IllegalArgumentException if <code>name</code> is empty.
*/
public RuntimePermission(String name, String actions)
{
super(name, actions);
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2010, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import java.lang.annotation.*;
/**
* A programmer assertion that the body of the annotated method or
* constructor does not perform potentially unsafe operations on its
* varargs parameter. Applying this annotation to a method or
* constructor suppresses unchecked warnings about a
* <i>non-reifiable</i> variable arity (vararg) type and suppresses
* unchecked warnings about parameterized array creation at call
* sites.
*
* <p> In addition to the usage restrictions imposed by its {@link
* Target @Target} meta-annotation, compilers are required to implement
* additional usage restrictions on this annotation type; it is a
* compile-time error if a method or constructor declaration is
* annotated with a {@code @SafeVarargs} annotation, and either:
* <ul>
* <li> the declaration is a fixed arity method or constructor
*
* <li> the declaration is a variable arity method that is neither
* {@code static} nor {@code final} nor {@code private}.
*
* </ul>
*
* <p> Compilers are encouraged to issue warnings when this annotation
* type is applied to a method or constructor declaration where:
*
* <ul>
*
* <li> The variable arity parameter has a reifiable element type,
* which includes primitive types, {@code Object}, and {@code String}.
* (The unchecked warnings this annotation type suppresses already do
* not occur for a reifiable element type.)
*
* <li> The body of the method or constructor declaration performs
* potentially unsafe operations, such as an assignment to an element
* of the variable arity parameter's array that generates an unchecked
* warning. Some unsafe operations do not trigger an unchecked
* warning. For example, the aliasing in
*
* <blockquote><pre>
* &#64;SafeVarargs // Not actually safe!
* static void m(List&lt;String&gt;... stringLists) {
* Object[] array = stringLists;
* List&lt;Integer&gt; tmpList = Arrays.asList(42);
* array[0] = tmpList; // Semantically invalid, but compiles without warnings
* String s = stringLists[0].get(0); // Oh no, ClassCastException at runtime!
* }
* </pre></blockquote>
*
* leads to a {@code ClassCastException} at runtime.
*
* <p>Future versions of the platform may mandate compiler errors for
* such unsafe operations.
*
* </ul>
*
* @since 1.7
* @jls 4.7 Reifiable Types
* @jls 8.4.1 Formal Parameters
* @jls 9.6.4.7 @SafeVarargs
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 1995, 2003, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown by the security manager to indicate a security violation.
*
* @author unascribed
* @see java.lang.SecurityManager
* @since 1.0
*/
public class SecurityException extends RuntimeException {
private static final long serialVersionUID = 6878364983674394167L;
/**
* Constructs a {@code SecurityException} with no detail message.
*/
public SecurityException() {
super();
}
/**
* Constructs a {@code SecurityException} with the specified
* detail message.
*
* @param s the detail message.
*/
public SecurityException(String s) {
super(s);
}
/**
* Creates a {@code SecurityException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public SecurityException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code SecurityException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public SecurityException(Throwable cause) {
super(cause);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,570 @@
/*
* Copyright (c) 1996, 2013, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The {@code Short} class wraps a value of primitive type {@code
* short} in an object. An object of type {@code Short} contains a
* single field whose type is {@code short}.
*
* <p>In addition, this class provides several methods for converting
* a {@code short} to a {@code String} and a {@code String} to a
* {@code short}, as well as other constants and methods useful when
* dealing with a {@code short}.
*
* @author Nakul Saraiya
* @author Joseph D. Darcy
* @see java.lang.Number
* @since 1.1
*/
public final class Short extends Number implements Comparable<Short> {
/**
* A constant holding the minimum value a {@code short} can
* have, -2<sup>15</sup>.
*/
public static final short MIN_VALUE = -32768;
/**
* A constant holding the maximum value a {@code short} can
* have, 2<sup>15</sup>-1.
*/
public static final short MAX_VALUE = 32767;
/**
* The {@code Class} instance representing the primitive type
* {@code short}.
*/
@SuppressWarnings("unchecked")
public static final Class<Short> TYPE = (Class<Short>) Class.getPrimitiveClass("short");
/**
* Returns a new {@code String} object representing the
* specified {@code short}. The radix is assumed to be 10.
*
* @param s the {@code short} to be converted
* @return the string representation of the specified {@code short}
* @see java.lang.Integer#toString(int)
*/
public static String toString(short s) {
return Integer.toString((int)s, 10);
}
/**
* Parses the string argument as a signed {@code short} in the
* radix specified by the second argument. The characters in the
* string must all be digits, of the specified radix (as
* determined by whether {@link java.lang.Character#digit(char,
* int)} returns a nonnegative value) except that the first
* character may be an ASCII minus sign {@code '-'}
* ({@code '\u005Cu002D'}) to indicate a negative value or an
* ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
* indicate a positive value. The resulting {@code short} value
* is returned.
*
* <p>An exception of type {@code NumberFormatException} is
* thrown if any of the following situations occurs:
* <ul>
* <li> The first argument is {@code null} or is a string of
* length zero.
*
* <li> The radix is either smaller than {@link
* java.lang.Character#MIN_RADIX} or larger than {@link
* java.lang.Character#MAX_RADIX}.
*
* <li> Any character of the string is not a digit of the
* specified radix, except that the first character may be a minus
* sign {@code '-'} ({@code '\u005Cu002D'}) or plus sign
* {@code '+'} ({@code '\u005Cu002B'}) provided that the
* string is longer than length 1.
*
* <li> The value represented by the string is not a value of type
* {@code short}.
* </ul>
*
* @param s the {@code String} containing the
* {@code short} representation to be parsed
* @param radix the radix to be used while parsing {@code s}
* @return the {@code short} represented by the string
* argument in the specified radix.
* @throws NumberFormatException If the {@code String}
* does not contain a parsable {@code short}.
*/
public static short parseShort(String s, int radix)
throws NumberFormatException {
int i = Integer.parseInt(s, radix);
if (i < MIN_VALUE || i > MAX_VALUE)
throw new NumberFormatException(
"Value out of range. Value:\"" + s + "\" Radix:" + radix);
return (short)i;
}
/**
* Parses the string argument as a signed decimal {@code
* short}. The characters in the string must all be decimal
* digits, except that the first character may be an ASCII minus
* sign {@code '-'} ({@code '\u005Cu002D'}) to indicate a
* negative value or an ASCII plus sign {@code '+'}
* ({@code '\u005Cu002B'}) to indicate a positive value. The
* resulting {@code short} value is returned, exactly as if the
* argument and the radix 10 were given as arguments to the {@link
* #parseShort(java.lang.String, int)} method.
*
* @param s a {@code String} containing the {@code short}
* representation to be parsed
* @return the {@code short} value represented by the
* argument in decimal.
* @throws NumberFormatException If the string does not
* contain a parsable {@code short}.
*/
public static short parseShort(String s) throws NumberFormatException {
return parseShort(s, 10);
}
/**
* Returns a {@code Short} object holding the value
* extracted from the specified {@code String} when parsed
* with the radix given by the second argument. The first argument
* is interpreted as representing a signed {@code short} in
* the radix specified by the second argument, exactly as if the
* argument were given to the {@link #parseShort(java.lang.String,
* int)} method. The result is a {@code Short} object that
* represents the {@code short} value specified by the string.
*
* <p>In other words, this method returns a {@code Short} object
* equal to the value of:
*
* <blockquote>
* {@code new Short(Short.parseShort(s, radix))}
* </blockquote>
*
* @param s the string to be parsed
* @param radix the radix to be used in interpreting {@code s}
* @return a {@code Short} object holding the value
* represented by the string argument in the
* specified radix.
* @throws NumberFormatException If the {@code String} does
* not contain a parsable {@code short}.
*/
public static Short valueOf(String s, int radix)
throws NumberFormatException {
return valueOf(parseShort(s, radix));
}
/**
* Returns a {@code Short} object holding the
* value given by the specified {@code String}. The argument
* is interpreted as representing a signed decimal
* {@code short}, exactly as if the argument were given to
* the {@link #parseShort(java.lang.String)} method. The result is
* a {@code Short} object that represents the
* {@code short} value specified by the string.
*
* <p>In other words, this method returns a {@code Short} object
* equal to the value of:
*
* <blockquote>
* {@code new Short(Short.parseShort(s))}
* </blockquote>
*
* @param s the string to be parsed
* @return a {@code Short} object holding the value
* represented by the string argument
* @throws NumberFormatException If the {@code String} does
* not contain a parsable {@code short}.
*/
public static Short valueOf(String s) throws NumberFormatException {
return valueOf(s, 10);
}
private static class ShortCache {
private ShortCache(){}
static final Short cache[] = new Short[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Short((short)(i - 128));
}
}
/**
* Returns a {@code Short} instance representing the specified
* {@code short} value.
* If a new {@code Short} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Short(short)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param s a short value.
* @return a {@code Short} instance representing {@code s}.
* @since 1.5
*/
@HotSpotIntrinsicCandidate
public static Short valueOf(short s) {
final int offset = 128;
int sAsInt = s;
if (sAsInt >= -128 && sAsInt <= 127) { // must cache
return ShortCache.cache[sAsInt + offset];
}
return new Short(s);
}
/**
* Decodes a {@code String} into a {@code Short}.
* Accepts decimal, hexadecimal, and octal numbers given by
* the following grammar:
*
* <blockquote>
* <dl>
* <dt><i>DecodableString:</i>
* <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
* <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
* <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
* <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
* <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
*
* <dt><i>Sign:</i>
* <dd>{@code -}
* <dd>{@code +}
* </dl>
* </blockquote>
*
* <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
* are as defined in section 3.10.1 of
* <cite>The Java&trade; Language Specification</cite>,
* except that underscores are not accepted between digits.
*
* <p>The sequence of characters following an optional
* sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
* "{@code #}", or leading zero) is parsed as by the {@code
* Short.parseShort} method with the indicated radix (10, 16, or
* 8). This sequence of characters must represent a positive
* value or a {@link NumberFormatException} will be thrown. The
* result is negated if first character of the specified {@code
* String} is the minus sign. No whitespace characters are
* permitted in the {@code String}.
*
* @param nm the {@code String} to decode.
* @return a {@code Short} object holding the {@code short}
* value represented by {@code nm}
* @throws NumberFormatException if the {@code String} does not
* contain a parsable {@code short}.
* @see java.lang.Short#parseShort(java.lang.String, int)
*/
public static Short decode(String nm) throws NumberFormatException {
int i = Integer.decode(nm);
if (i < MIN_VALUE || i > MAX_VALUE)
throw new NumberFormatException(
"Value " + i + " out of range from input " + nm);
return valueOf((short)i);
}
/**
* The value of the {@code Short}.
*
* @serial
*/
private final short value;
/**
* Constructs a newly allocated {@code Short} object that
* represents the specified {@code short} value.
*
* @param value the value to be represented by the
* {@code Short}.
*
* @deprecated
* It is rarely appropriate to use this constructor. The static factory
* {@link #valueOf(short)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
public Short(short value) {
this.value = value;
}
/**
* Constructs a newly allocated {@code Short} object that
* represents the {@code short} value indicated by the
* {@code String} parameter. The string is converted to a
* {@code short} value in exactly the manner used by the
* {@code parseShort} method for radix 10.
*
* @param s the {@code String} to be converted to a
* {@code Short}
* @throws NumberFormatException If the {@code String}
* does not contain a parsable {@code short}.
*
* @deprecated
* It is rarely appropriate to use this constructor.
* Use {@link #parseShort(String)} to convert a string to a
* {@code short} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Short} object.
*/
@Deprecated(since="9")
public Short(String s) throws NumberFormatException {
this.value = parseShort(s, 10);
}
/**
* Returns the value of this {@code Short} as a {@code byte} after
* a narrowing primitive conversion.
* @jls 5.1.3 Narrowing Primitive Conversions
*/
public byte byteValue() {
return (byte)value;
}
/**
* Returns the value of this {@code Short} as a
* {@code short}.
*/
@HotSpotIntrinsicCandidate
public short shortValue() {
return value;
}
/**
* Returns the value of this {@code Short} as an {@code int} after
* a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public int intValue() {
return (int)value;
}
/**
* Returns the value of this {@code Short} as a {@code long} after
* a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public long longValue() {
return (long)value;
}
/**
* Returns the value of this {@code Short} as a {@code float}
* after a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public float floatValue() {
return (float)value;
}
/**
* Returns the value of this {@code Short} as a {@code double}
* after a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public double doubleValue() {
return (double)value;
}
/**
* Returns a {@code String} object representing this
* {@code Short}'s value. The value is converted to signed
* decimal representation and returned as a string, exactly as if
* the {@code short} value were given as an argument to the
* {@link java.lang.Short#toString(short)} method.
*
* @return a string representation of the value of this object in
* base&nbsp;10.
*/
public String toString() {
return Integer.toString((int)value);
}
/**
* Returns a hash code for this {@code Short}; equal to the result
* of invoking {@code intValue()}.
*
* @return a hash code value for this {@code Short}
*/
@Override
public int hashCode() {
return Short.hashCode(value);
}
/**
* Returns a hash code for a {@code short} value; compatible with
* {@code Short.hashCode()}.
*
* @param value the value to hash
* @return a hash code value for a {@code short} value.
* @since 1.8
*/
public static int hashCode(short value) {
return (int)value;
}
/**
* Compares this object to the specified object. The result is
* {@code true} if and only if the argument is not
* {@code null} and is a {@code Short} object that
* contains the same {@code short} value as this object.
*
* @param obj the object to compare with
* @return {@code true} if the objects are the same;
* {@code false} otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof Short) {
return value == ((Short)obj).shortValue();
}
return false;
}
/**
* Compares two {@code Short} objects numerically.
*
* @param anotherShort the {@code Short} to be compared.
* @return the value {@code 0} if this {@code Short} is
* equal to the argument {@code Short}; a value less than
* {@code 0} if this {@code Short} is numerically less
* than the argument {@code Short}; and a value greater than
* {@code 0} if this {@code Short} is numerically
* greater than the argument {@code Short} (signed
* comparison).
* @since 1.2
*/
public int compareTo(Short anotherShort) {
return compare(this.value, anotherShort.value);
}
/**
* Compares two {@code short} values numerically.
* The value returned is identical to what would be returned by:
* <pre>
* Short.valueOf(x).compareTo(Short.valueOf(y))
* </pre>
*
* @param x the first {@code short} to compare
* @param y the second {@code short} to compare
* @return the value {@code 0} if {@code x == y};
* a value less than {@code 0} if {@code x < y}; and
* a value greater than {@code 0} if {@code x > y}
* @since 1.7
*/
public static int compare(short x, short y) {
return x - y;
}
/**
* Compares two {@code short} values numerically treating the values
* as unsigned.
*
* @param x the first {@code short} to compare
* @param y the second {@code short} to compare
* @return the value {@code 0} if {@code x == y}; a value less
* than {@code 0} if {@code x < y} as unsigned values; and
* a value greater than {@code 0} if {@code x > y} as
* unsigned values
* @since 9
*/
public static int compareUnsigned(short x, short y) {
return Short.toUnsignedInt(x) - Short.toUnsignedInt(y);
}
/**
* The number of bits used to represent a {@code short} value in two's
* complement binary form.
* @since 1.5
*/
public static final int SIZE = 16;
/**
* The number of bytes used to represent a {@code short} value in two's
* complement binary form.
*
* @since 1.8
*/
public static final int BYTES = SIZE / Byte.SIZE;
/**
* Returns the value obtained by reversing the order of the bytes in the
* two's complement representation of the specified {@code short} value.
*
* @param i the value whose bytes are to be reversed
* @return the value obtained by reversing (or, equivalently, swapping)
* the bytes in the specified {@code short} value.
* @since 1.5
*/
@HotSpotIntrinsicCandidate
public static short reverseBytes(short i) {
return (short) (((i & 0xFF00) >> 8) | (i << 8));
}
/**
* Converts the argument to an {@code int} by an unsigned
* conversion. In an unsigned conversion to an {@code int}, the
* high-order 16 bits of the {@code int} are zero and the
* low-order 16 bits are equal to the bits of the {@code short} argument.
*
* Consequently, zero and positive {@code short} values are mapped
* to a numerically equal {@code int} value and negative {@code
* short} values are mapped to an {@code int} value equal to the
* input plus 2<sup>16</sup>.
*
* @param x the value to convert to an unsigned {@code int}
* @return the argument converted to {@code int} by an unsigned
* conversion
* @since 1.8
*/
public static int toUnsignedInt(short x) {
return ((int) x) & 0xffff;
}
/**
* Converts the argument to a {@code long} by an unsigned
* conversion. In an unsigned conversion to a {@code long}, the
* high-order 48 bits of the {@code long} are zero and the
* low-order 16 bits are equal to the bits of the {@code short} argument.
*
* Consequently, zero and positive {@code short} values are mapped
* to a numerically equal {@code long} value and negative {@code
* short} values are mapped to a {@code long} value equal to the
* input plus 2<sup>16</sup>.
*
* @param x the value to convert to an unsigned {@code long}
* @return the argument converted to {@code long} by an unsigned
* conversion
* @since 1.8
*/
public static long toUnsignedLong(short x) {
return ((long) x) & 0xffffL;
}
/** use serialVersionUID from JDK 1.1. for interoperability */
private static final long serialVersionUID = 7515723908773894738L;
}

View file

@ -0,0 +1,238 @@
/*
* Copyright (c) 1999, 2005, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Package-private utility class containing data structures and logic
* governing the virtual-machine shutdown sequence.
*
* @author Mark Reinhold
* @since 1.3
*/
class Shutdown {
/* Shutdown state */
private static final int RUNNING = 0;
private static final int HOOKS = 1;
private static final int FINALIZERS = 2;
private static int state = RUNNING;
/* Should we run all finalizers upon exit? */
private static boolean runFinalizersOnExit = false;
// The system shutdown hooks are registered with a predefined slot.
// The list of shutdown hooks is as follows:
// (0) Console restore hook
// (1) Application hooks
// (2) DeleteOnExit hook
private static final int MAX_SYSTEM_HOOKS = 10;
private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
// the index of the currently running shutdown hook to the hooks array
private static int currentRunningHook = 0;
/* The preceding static fields are protected by this lock */
private static class Lock { };
private static Object lock = new Lock();
/* Lock object for the native halt method */
private static Object haltLock = new Lock();
/* Invoked by Runtime.runFinalizersOnExit */
static void setRunFinalizersOnExit(boolean run) {
synchronized (lock) {
runFinalizersOnExit = run;
}
}
/**
* Add a new shutdown hook. Checks the shutdown state and the hook itself,
* but does not do any security checks.
*
* The registerShutdownInProgress parameter should be false except
* registering the DeleteOnExitHook since the first file may
* be added to the delete on exit list by the application shutdown
* hooks.
*
* @params slot the slot in the shutdown hook array, whose element
* will be invoked in order during shutdown
* @params registerShutdownInProgress true to allow the hook
* to be registered even if the shutdown is in progress.
* @params hook the hook to be registered
*
* @throws IllegalStateException
* if registerShutdownInProgress is false and shutdown is in progress; or
* if registerShutdownInProgress is true and the shutdown process
* already passes the given slot
*/
static void add(int slot, boolean registerShutdownInProgress, Runnable hook) {
synchronized (lock) {
if (hooks[slot] != null)
throw new InternalError("Shutdown hook at slot " + slot + " already registered");
if (!registerShutdownInProgress) {
if (state > RUNNING)
throw new IllegalStateException("Shutdown in progress");
} else {
if (state > HOOKS || (state == HOOKS && slot <= currentRunningHook))
throw new IllegalStateException("Shutdown in progress");
}
hooks[slot] = hook;
}
}
/* Run all registered shutdown hooks
*/
private static void runHooks() {
for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
try {
Runnable hook;
synchronized (lock) {
// acquire the lock to make sure the hook registered during
// shutdown is visible here.
currentRunningHook = i;
hook = hooks[i];
}
if (hook != null) hook.run();
} catch(Throwable t) {
if (t instanceof ThreadDeath) {
ThreadDeath td = (ThreadDeath)t;
throw td;
}
}
}
}
/* The halt method is synchronized on the halt lock
* to avoid corruption of the delete-on-shutdown file list.
* It invokes the true native halt method.
*/
static void halt(int status) {
synchronized (haltLock) {
halt0(status);
}
}
static native void halt0(int status);
/* Wormhole for invoking java.lang.ref.Finalizer.runAllFinalizers */
private static native void runAllFinalizers();
/* The actual shutdown sequence is defined here.
*
* If it weren't for runFinalizersOnExit, this would be simple -- we'd just
* run the hooks and then halt. Instead we need to keep track of whether
* we're running hooks or finalizers. In the latter case a finalizer could
* invoke exit(1) to cause immediate termination, while in the former case
* any further invocations of exit(n), for any n, simply stall. Note that
* if on-exit finalizers are enabled they're run iff the shutdown is
* initiated by an exit(0); they're never run on exit(n) for n != 0 or in
* response to SIGINT, SIGTERM, etc.
*/
private static void sequence() {
synchronized (lock) {
/* Guard against the possibility of a daemon thread invoking exit
* after DestroyJavaVM initiates the shutdown sequence
*/
if (state != HOOKS) return;
}
runHooks();
boolean rfoe;
synchronized (lock) {
state = FINALIZERS;
rfoe = runFinalizersOnExit;
}
if (rfoe) runAllFinalizers();
}
/* Invoked by Runtime.exit, which does all the security checks.
* Also invoked by handlers for system-provided termination events,
* which should pass a nonzero status code.
*/
static void exit(int status) {
boolean runMoreFinalizers = false;
synchronized (lock) {
if (status != 0) runFinalizersOnExit = false;
switch (state) {
case RUNNING: /* Initiate shutdown */
state = HOOKS;
break;
case HOOKS: /* Stall and halt */
break;
case FINALIZERS:
if (status != 0) {
/* Halt immediately on nonzero status */
halt(status);
} else {
/* Compatibility with old behavior:
* Run more finalizers and then halt
*/
runMoreFinalizers = runFinalizersOnExit;
}
break;
}
}
if (runMoreFinalizers) {
runAllFinalizers();
halt(status);
}
synchronized (Shutdown.class) {
/* Synchronize on the class object, causing any other thread
* that attempts to initiate shutdown to stall indefinitely
*/
sequence();
halt(status);
}
}
/* Invoked by the JNI DestroyJavaVM procedure when the last non-daemon
* thread has finished. Unlike the exit method, this method does not
* actually halt the VM.
*/
static void shutdown() {
synchronized (lock) {
switch (state) {
case RUNNING: /* Initiate shutdown */
state = HOOKS;
break;
case HOOKS: /* Stall and then return */
case FINALIZERS:
break;
}
}
synchronized (Shutdown.class) {
sequence();
}
}
}

View file

@ -0,0 +1,128 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.internal.misc.SharedSecrets;
import static java.lang.StackWalker.Option.*;
import java.lang.StackWalker.StackFrame;
class StackFrameInfo implements StackFrame {
private final static JavaLangInvokeAccess JLIA =
SharedSecrets.getJavaLangInvokeAccess();
// Footprint improvement: MemberName::clazz can replace
// StackFrameInfo::declaringClass.
private final StackWalker walker;
private final Class<?> declaringClass;
private final Object memberName;
private final short bci;
private volatile StackTraceElement ste;
/*
* Create StackFrameInfo for StackFrameTraverser and LiveStackFrameTraverser
* to use
*/
StackFrameInfo(StackWalker walker) {
this.walker = walker;
this.declaringClass = null;
this.bci = -1;
this.memberName = JLIA.newMemberName();
}
// package-private called by StackStreamFactory to skip
// the capability check
Class<?> declaringClass() {
return declaringClass;
}
// ----- implementation of StackFrame methods
@Override
public String getClassName() {
return declaringClass.getName();
}
@Override
public Class<?> getDeclaringClass() {
walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
return declaringClass;
}
@Override
public String getMethodName() {
return JLIA.getName(memberName);
}
@Override
public int getByteCodeIndex() {
// bci not available for native methods
if (isNativeMethod())
return -1;
return bci;
}
@Override
public String getFileName() {
return toStackTraceElement().getFileName();
}
@Override
public int getLineNumber() {
// line number not available for native methods
if (isNativeMethod())
return -2;
return toStackTraceElement().getLineNumber();
}
@Override
public boolean isNativeMethod() {
return JLIA.isNative(memberName);
}
@Override
public String toString() {
return toStackTraceElement().toString();
}
@Override
public StackTraceElement toStackTraceElement() {
StackTraceElement s = ste;
if (s == null) {
synchronized (this) {
s = ste;
if (s == null) {
ste = s = StackTraceElement.of(this);
}
}
}
return s;
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 1994, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
/**
* Thrown when a stack overflow occurs because an application
* recurses too deeply.
*
* @author unascribed
* @since 1.0
*/
public
class StackOverflowError extends VirtualMachineError {
private static final long serialVersionUID = 8609175038441759607L;
/**
* Constructs a <code>StackOverflowError</code> with no detail message.
*/
public StackOverflowError() {
super();
}
/**
* Constructs a <code>StackOverflowError</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public StackOverflowError(String s) {
super(s);
}
}

View file

@ -0,0 +1,993 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import jdk.internal.reflect.MethodAccessor;
import jdk.internal.reflect.ConstructorAccessor;
import java.lang.StackWalker.Option;
import java.lang.StackWalker.StackFrame;
import java.lang.annotation.Native;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.util.HashSet;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import sun.security.action.GetPropertyAction;
import static java.lang.StackStreamFactory.WalkerState.*;
/**
* StackStreamFactory class provides static factory methods
* to get different kinds of stack walker/traverser.
*
* AbstractStackWalker provides the basic stack walking support
* fetching stack frames from VM in batches.
*
* AbstractStackWalker subclass is specialized for a specific kind of stack traversal
* to avoid overhead of Stream/Lambda
* 1. Support traversing Stream<StackFrame>
* 2. StackWalker::getCallerClass
* 3. AccessControlContext getting ProtectionDomain
*/
final class StackStreamFactory {
private StackStreamFactory() {}
// Stack walk implementation classes to be excluded during stack walking
// lazily add subclasses when they are loaded.
private final static Set<Class<?>> stackWalkImplClasses = init();
private static final int SMALL_BATCH = 8;
private static final int BATCH_SIZE = 32;
private static final int LARGE_BATCH_SIZE = 256;
private static final int MIN_BATCH_SIZE = SMALL_BATCH;
// These flags must match the values maintained in the VM
@Native private static final int DEFAULT_MODE = 0x0;
@Native private static final int FILL_CLASS_REFS_ONLY = 0x2;
@Native private static final int GET_CALLER_CLASS = 0x4;
@Native private static final int SHOW_HIDDEN_FRAMES = 0x20; // LambdaForms are hidden by the VM
@Native private static final int FILL_LIVE_STACK_FRAMES = 0x100;
/*
* For Throwable to use StackWalker, set useNewThrowable to true.
* Performance work and extensive testing is needed to replace the
* VM built-in backtrace filled in Throwable with the StackWalker.
*/
final static boolean isDebug =
"true".equals(GetPropertyAction.privilegedGetProperty("stackwalk.debug"));
static <T> StackFrameTraverser<T>
makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function)
{
if (walker.hasLocalsOperandsOption())
return new LiveStackInfoTraverser<>(walker, function);
else
return new StackFrameTraverser<>(walker, function);
}
/**
* Gets a stack stream to find caller class.
*/
static CallerClassFinder makeCallerFinder(StackWalker walker) {
return new CallerClassFinder(walker);
}
enum WalkerState {
NEW, // the stream is new and stack walking has not started
OPEN, // the stream is open when it is being traversed.
CLOSED; // the stream is closed when the stack walking is done
}
/**
* Subclass of AbstractStackWalker implements a specific stack walking logic.
* It needs to set up the frame buffer and stack walking mode.
*
* It initiates the VM stack walking via the callStackWalk method that serves
* as the anchored frame and VM will call up to AbstractStackWalker::doStackWalk.
*
* @param <R> the type of the result returned from stack walking
* @param <T> the type of the data gathered for each frame.
* For example, StackFrameInfo for StackWalker::walk or
* Class<?> for StackWalker::getCallerClass
*/
static abstract class AbstractStackWalker<R, T> {
protected final StackWalker walker;
protected final Thread thread;
protected final int maxDepth;
protected final long mode;
protected int depth; // traversed stack depth
protected FrameBuffer<? extends T> frameBuffer;
protected long anchor;
// buffers to fill in stack frame information
protected AbstractStackWalker(StackWalker walker, int mode) {
this(walker, mode, Integer.MAX_VALUE);
}
protected AbstractStackWalker(StackWalker walker, int mode, int maxDepth) {
this.thread = Thread.currentThread();
this.mode = toStackWalkMode(walker, mode);
this.walker = walker;
this.maxDepth = maxDepth;
this.depth = 0;
}
private int toStackWalkMode(StackWalker walker, int mode) {
int newMode = mode;
if (walker.hasOption(Option.SHOW_HIDDEN_FRAMES) &&
(mode & FILL_CLASS_REFS_ONLY) != FILL_CLASS_REFS_ONLY)
newMode |= SHOW_HIDDEN_FRAMES;
if (walker.hasLocalsOperandsOption())
newMode |= FILL_LIVE_STACK_FRAMES;
return newMode;
}
/**
* A callback method to consume the stack frames. This method is invoked
* once stack walking begins (i.e. it is only invoked when walkFrames is called).
*
* Each specialized AbstractStackWalker subclass implements the consumeFrames method
* to control the following:
* 1. fetch the subsequent batches of stack frames
* 2. reuse or expand the allocated buffers
* 3. create specialized StackFrame objects
*
* @return the number of consumed frames
*/
protected abstract R consumeFrames();
/**
* Initialize FrameBuffer. Subclass should implement this method to
* create its custom frame buffers.
*/
protected abstract void initFrameBuffer();
/**
* Returns the suggested next batch size.
*
* Subclass should override this method to change the batch size
*
* @param lastBatchFrameCount number of frames in the last batch; or zero
* @return suggested batch size
*/
protected abstract int batchSize(int lastBatchFrameCount);
/*
* Returns the next batch size, always >= minimum batch size (32)
*
* Subclass may override this method if the minimum batch size is different.
*/
protected int getNextBatchSize() {
int lastBatchSize = depth == 0 ? 0 : frameBuffer.curBatchFrameCount();
int nextBatchSize = batchSize(lastBatchSize);
if (isDebug) {
System.err.println("last batch size = " + lastBatchSize +
" next batch size = " + nextBatchSize);
}
return nextBatchSize >= MIN_BATCH_SIZE ? nextBatchSize : MIN_BATCH_SIZE;
}
/*
* Checks if this stream is in the given state. Otherwise, throws IllegalStateException.
*
* VM also validates this stream if it's anchored for stack walking
* when stack frames are fetched for each batch.
*/
final void checkState(WalkerState state) {
if (thread != Thread.currentThread()) {
throw new IllegalStateException("Invalid thread walking this stack stream: " +
Thread.currentThread().getName() + " " + thread.getName());
}
switch (state) {
case NEW:
if (anchor != 0) {
throw new IllegalStateException("This stack stream is being reused.");
}
break;
case OPEN:
if (anchor == 0 || anchor == -1L) {
throw new IllegalStateException("This stack stream is not valid for walking.");
}
break;
case CLOSED:
if (anchor != -1L) {
throw new IllegalStateException("This stack stream is not closed.");
}
}
}
/*
* Close this stream. This stream becomes invalid to walk.
*/
private void close() {
this.anchor = -1L;
}
/*
* Walks stack frames until {@link #consumeFrames} is done consuming
* the frames it is interested in.
*/
final R walk() {
checkState(NEW);
try {
// VM will need to stablize the stack before walking. It will invoke
// the AbstractStackWalker::doStackWalk method once it fetches the first batch.
// the callback will be invoked within the scope of the callStackWalk frame.
return beginStackWalk();
} finally {
close(); // done traversal; close the stream
}
}
private boolean skipReflectionFrames() {
return !walker.hasOption(Option.SHOW_REFLECT_FRAMES) &&
!walker.hasOption(Option.SHOW_HIDDEN_FRAMES);
}
/*
* Returns {@code Class} object at the current frame;
* or {@code null} if no more frame. If advanceToNextBatch is true,
* it will only fetch the next batch.
*/
final Class<?> peekFrame() {
while (frameBuffer.isActive() && depth < maxDepth) {
if (frameBuffer.isEmpty()) {
// fetch another batch of stack frames
getNextBatch();
} else {
Class<?> c = frameBuffer.get();
if (skipReflectionFrames() && isReflectionFrame(c)) {
if (isDebug)
System.err.println(" skip: frame " + frameBuffer.getIndex() + " " + c);
frameBuffer.next();
depth++;
continue;
} else {
return c;
}
}
}
return null;
}
/*
* This method is only invoked by VM.
*
* It will invoke the consumeFrames method to start the stack walking
* with the first batch of stack frames. Each specialized AbstractStackWalker
* subclass implements the consumeFrames method to control the following:
* 1. fetch the subsequent batches of stack frames
* 2. reuse or expand the allocated buffers
* 3. create specialized StackFrame objects
*/
private Object doStackWalk(long anchor, int skipFrames, int batchSize,
int bufStartIndex, int bufEndIndex) {
checkState(NEW);
frameBuffer.check(skipFrames);
if (isDebug) {
System.err.format("doStackWalk: skip %d start %d end %d%n",
skipFrames, bufStartIndex, bufEndIndex);
}
this.anchor = anchor; // set anchor for this bulk stack frame traversal
frameBuffer.setBatch(depth, bufStartIndex, bufEndIndex);
// traverse all frames and perform the action on the stack frames, if specified
return consumeFrames();
}
/*
* Get next batch of stack frames.
*/
private int getNextBatch() {
int nextBatchSize = Math.min(maxDepth - depth, getNextBatchSize());
if (!frameBuffer.isActive() || nextBatchSize <= 0) {
if (isDebug) {
System.out.format(" more stack walk done%n");
}
frameBuffer.freeze(); // stack walk done
return 0;
}
return fetchStackFrames(nextBatchSize);
}
/*
* This method traverses the next stack frame and returns the Class
* invoking that stack frame.
*
* This method can only be called during the walk method. This is intended
* to be used to walk the stack frames in one single invocation and
* this stack stream will be invalidated once walk is done.
*
* @see #tryNextFrame
*/
final Class<?> nextFrame() {
if (!hasNext()) {
return null;
}
Class<?> c = frameBuffer.next();
depth++;
return c;
}
/*
* Returns true if there is next frame to be traversed.
* This skips hidden frames unless this StackWalker has
* {@link Option#SHOW_REFLECT_FRAMES}
*/
final boolean hasNext() {
return peekFrame() != null;
}
/**
* Begin stack walking - pass the allocated arrays to the VM to fill in
* stack frame information.
*
* VM first anchors the frame of the current thread. A traversable stream
* on this thread's stack will be opened. The VM will fetch the first batch
* of stack frames and call AbstractStackWalker::doStackWalk to invoke the
* stack walking function on each stack frame.
*
* If all fetched stack frames are traversed, AbstractStackWalker::fetchStackFrames will
* fetch the next batch of stack frames to continue.
*/
private R beginStackWalk() {
// initialize buffers for VM to fill the stack frame info
initFrameBuffer();
return callStackWalk(mode, 0,
frameBuffer.curBatchFrameCount(),
frameBuffer.startIndex(),
frameBuffer.frames());
}
/*
* Fetches stack frames.
*
* @params batchSize number of elements of the frame buffers for this batch
* @returns number of frames fetched in this batch
*/
private int fetchStackFrames(int batchSize) {
int startIndex = frameBuffer.startIndex();
frameBuffer.resize(startIndex, batchSize);
int endIndex = fetchStackFrames(mode, anchor, batchSize,
startIndex,
frameBuffer.frames());
if (isDebug) {
System.out.format(" more stack walk requesting %d got %d to %d frames%n",
batchSize, frameBuffer.startIndex(), endIndex);
}
int numFrames = endIndex - startIndex;
if (numFrames == 0) {
frameBuffer.freeze(); // done stack walking
} else {
frameBuffer.setBatch(depth, startIndex, endIndex);
}
return numFrames;
}
/**
* Begins stack walking. This method anchors this frame and invokes
* AbstractStackWalker::doStackWalk after fetching the first batch of stack frames.
*
* @param mode mode of stack walking
* @param skipframes number of frames to be skipped before filling the frame buffer.
* @param batchSize the batch size, max. number of elements to be filled in the frame buffers.
* @param startIndex start index of the frame buffers to be filled.
* @param frames Either a Class<?> array, if mode is {@link #FILL_CLASS_REFS_ONLY}
* or a {@link StackFrameInfo} (or derivative) array otherwise.
* @return Result of AbstractStackWalker::doStackWalk
*/
private native R callStackWalk(long mode, int skipframes,
int batchSize, int startIndex,
T[] frames);
/**
* Fetch the next batch of stack frames.
*
* @param mode mode of stack walking
* @param anchor
* @param batchSize the batch size, max. number of elements to be filled in the frame buffers.
* @param startIndex start index of the frame buffers to be filled.
* @param frames Either a Class<?> array, if mode is {@link #FILL_CLASS_REFS_ONLY}
* or a {@link StackFrameInfo} (or derivative) array otherwise.
*
* @return the end index to the frame buffers
*/
private native int fetchStackFrames(long mode, long anchor,
int batchSize, int startIndex,
T[] frames);
}
/*
* This StackFrameTraverser supports {@link Stream} traversal.
*
* This class implements Spliterator::forEachRemaining and Spliterator::tryAdvance.
*/
static class StackFrameTraverser<T> extends AbstractStackWalker<T, StackFrameInfo>
implements Spliterator<StackFrame>
{
static {
stackWalkImplClasses.add(StackFrameTraverser.class);
}
private static final int CHARACTERISTICS = Spliterator.ORDERED | Spliterator.IMMUTABLE;
final class StackFrameBuffer extends FrameBuffer<StackFrameInfo> {
private StackFrameInfo[] stackFrames;
StackFrameBuffer(int initialBatchSize) {
super(initialBatchSize);
this.stackFrames = new StackFrameInfo[initialBatchSize];
for (int i = START_POS; i < initialBatchSize; i++) {
stackFrames[i] = new StackFrameInfo(walker);
}
}
@Override
StackFrameInfo[] frames() {
return stackFrames;
}
@Override
void resize(int startIndex, int elements) {
if (!isActive())
throw new IllegalStateException("inactive frame buffer can't be resized");
assert startIndex == START_POS :
"bad start index " + startIndex + " expected " + START_POS;
int size = startIndex+elements;
if (stackFrames.length < size) {
StackFrameInfo[] newFrames = new StackFrameInfo[size];
// copy initial magic...
System.arraycopy(stackFrames, 0, newFrames, 0, startIndex);
stackFrames = newFrames;
}
for (int i = startIndex; i < size; i++) {
stackFrames[i] = new StackFrameInfo(walker);
}
currentBatchSize = size;
}
@Override
StackFrameInfo nextStackFrame() {
if (isEmpty()) {
throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
}
StackFrameInfo frame = stackFrames[origin];
origin++;
return frame;
}
@Override
final Class<?> at(int index) {
return stackFrames[index].declaringClass();
}
}
final Function<? super Stream<StackFrame>, ? extends T> function; // callback
StackFrameTraverser(StackWalker walker,
Function<? super Stream<StackFrame>, ? extends T> function) {
this(walker, function, DEFAULT_MODE);
}
StackFrameTraverser(StackWalker walker,
Function<? super Stream<StackFrame>, ? extends T> function,
int mode) {
super(walker, mode);
this.function = function;
}
/**
* Returns next StackFrame object in the current batch of stack frames;
* or null if no more stack frame.
*/
StackFrame nextStackFrame() {
if (!hasNext()) {
return null;
}
StackFrameInfo frame = frameBuffer.nextStackFrame();
depth++;
return frame;
}
@Override
protected T consumeFrames() {
checkState(OPEN);
Stream<StackFrame> stream = StreamSupport.stream(this, false);
if (function != null) {
return function.apply(stream);
} else
throw new UnsupportedOperationException();
}
@Override
protected void initFrameBuffer() {
this.frameBuffer = new StackFrameBuffer(getNextBatchSize());
}
@Override
protected int batchSize(int lastBatchFrameCount) {
if (lastBatchFrameCount == 0) {
// First batch, use estimateDepth if not exceed the large batch size
// and not too small
int initialBatchSize = Math.max(walker.estimateDepth(), SMALL_BATCH);
return Math.min(initialBatchSize, LARGE_BATCH_SIZE);
} else {
if (lastBatchFrameCount > BATCH_SIZE) {
return lastBatchFrameCount;
} else {
return Math.min(lastBatchFrameCount*2, BATCH_SIZE);
}
}
}
// ------- Implementation of Spliterator
@Override
public Spliterator<StackFrame> trySplit() {
return null; // ordered stream and do not allow to split
}
@Override
public long estimateSize() {
return maxDepth;
}
@Override
public int characteristics() {
return CHARACTERISTICS;
}
@Override
public void forEachRemaining(Consumer<? super StackFrame> action) {
checkState(OPEN);
for (int n = 0; n < maxDepth; n++) {
StackFrame frame = nextStackFrame();
if (frame == null) break;
action.accept(frame);
}
}
@Override
public boolean tryAdvance(Consumer<? super StackFrame> action) {
checkState(OPEN);
int index = frameBuffer.getIndex();
if (hasNext()) {
StackFrame frame = nextStackFrame();
action.accept(frame);
if (isDebug) {
System.err.println("tryAdvance: " + index + " " + frame);
}
return true;
}
if (isDebug) {
System.err.println("tryAdvance: " + index + " NO element");
}
return false;
}
}
/*
* CallerClassFinder is specialized to return Class<?> for each stack frame.
* StackFrame is not requested.
*/
static final class CallerClassFinder extends AbstractStackWalker<Integer, Class<?>> {
static {
stackWalkImplClasses.add(CallerClassFinder.class);
}
private Class<?> caller;
CallerClassFinder(StackWalker walker) {
super(walker, FILL_CLASS_REFS_ONLY|GET_CALLER_CLASS);
}
final class ClassBuffer extends FrameBuffer<Class<?>> {
Class<?>[] classes; // caller class for fast path
ClassBuffer(int batchSize) {
super(batchSize);
classes = new Class<?>[batchSize];
}
@Override
Class<?>[] frames() { return classes;}
@Override
final Class<?> at(int index) { return classes[index];}
// ------ subclass may override the following methods -------
/**
* Resizes the buffers for VM to fill in the next batch of stack frames.
* The next batch will start at the given startIndex with the maximum number
* of elements.
*
* <p> Subclass may override this method to manage the allocated buffers.
*
* @param startIndex the start index for the first frame of the next batch to fill in.
* @param elements the number of elements for the next batch to fill in.
*
*/
@Override
void resize(int startIndex, int elements) {
if (!isActive())
throw new IllegalStateException("inactive frame buffer can't be resized");
assert startIndex == START_POS :
"bad start index " + startIndex + " expected " + START_POS;
int size = startIndex+elements;
if (classes.length < size) {
// copy the elements in classes array to the newly allocated one.
// classes[0] is a Thread object
Class<?>[] prev = classes;
classes = new Class<?>[size];
System.arraycopy(prev, 0, classes, 0, startIndex);
}
currentBatchSize = size;
}
}
Class<?> findCaller() {
walk();
return caller;
}
@Override
protected Integer consumeFrames() {
checkState(OPEN);
int n = 0;
Class<?>[] frames = new Class<?>[2];
// skip the API calling this getCallerClass method
// 0: StackWalker::getCallerClass
// 1: caller-sensitive method
// 2: caller class
while (n < 2 && (caller = nextFrame()) != null) {
if (isMethodHandleFrame(caller)) { continue; }
if (isReflectionFrame(caller)) { continue; }
frames[n++] = caller;
}
if (frames[1] == null) {
throw new IllegalCallerException("no caller frame");
}
return n;
}
@Override
protected void initFrameBuffer() {
this.frameBuffer = new ClassBuffer(getNextBatchSize());
}
@Override
protected int batchSize(int lastBatchFrameCount) {
return MIN_BATCH_SIZE;
}
@Override
protected int getNextBatchSize() {
return MIN_BATCH_SIZE;
}
}
static final class LiveStackInfoTraverser<T> extends StackFrameTraverser<T> {
static {
stackWalkImplClasses.add(LiveStackInfoTraverser.class);
}
// VM will fill in all method info and live stack info directly in StackFrameInfo
final class LiveStackFrameBuffer extends FrameBuffer<LiveStackFrameInfo> {
private LiveStackFrameInfo[] stackFrames;
LiveStackFrameBuffer(int initialBatchSize) {
super(initialBatchSize);
this.stackFrames = new LiveStackFrameInfo[initialBatchSize];
for (int i = START_POS; i < initialBatchSize; i++) {
stackFrames[i] = new LiveStackFrameInfo(walker);
}
}
@Override
LiveStackFrameInfo[] frames() {
return stackFrames;
}
@Override
void resize(int startIndex, int elements) {
if (!isActive()) {
throw new IllegalStateException("inactive frame buffer can't be resized");
}
assert startIndex == START_POS :
"bad start index " + startIndex + " expected " + START_POS;
int size = startIndex + elements;
if (stackFrames.length < size) {
LiveStackFrameInfo[] newFrames = new LiveStackFrameInfo[size];
// copy initial magic...
System.arraycopy(stackFrames, 0, newFrames, 0, startIndex);
stackFrames = newFrames;
}
for (int i = startIndex(); i < size; i++) {
stackFrames[i] = new LiveStackFrameInfo(walker);
}
currentBatchSize = size;
}
@Override
LiveStackFrameInfo nextStackFrame() {
if (isEmpty()) {
throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
}
LiveStackFrameInfo frame = stackFrames[origin];
origin++;
return frame;
}
@Override
final Class<?> at(int index) {
return stackFrames[index].declaringClass();
}
}
LiveStackInfoTraverser(StackWalker walker,
Function<? super Stream<StackFrame>, ? extends T> function) {
super(walker, function, DEFAULT_MODE);
}
@Override
protected void initFrameBuffer() {
this.frameBuffer = new LiveStackFrameBuffer(getNextBatchSize());
}
}
/*
* Frame buffer
*
* Each specialized AbstractStackWalker subclass may subclass the FrameBuffer.
*/
static abstract class FrameBuffer<F> {
static final int START_POS = 2; // 0th and 1st elements are reserved
// buffers for VM to fill stack frame info
int currentBatchSize; // current batch size
int origin; // index to the current traversed stack frame
int fence; // index to the last frame in the current batch
FrameBuffer(int initialBatchSize) {
if (initialBatchSize < MIN_BATCH_SIZE) {
throw new IllegalArgumentException(initialBatchSize +
" < minimum batch size: " + MIN_BATCH_SIZE);
}
this.origin = START_POS;
this.fence = 0;
this.currentBatchSize = initialBatchSize;
}
/**
* Returns an array of frames that may be used to store frame objects
* when walking the stack.
*
* May be an array of {@code Class<?>} if the {@code AbstractStackWalker}
* mode is {@link #FILL_CLASS_REFS_ONLY}, or an array of
* {@link StackFrameInfo} (or derivative) array otherwise.
*
* @return An array of frames that may be used to store frame objects
* when walking the stack. Must not be null.
*/
abstract F[] frames(); // must not return null
/**
* Resizes the buffers for VM to fill in the next batch of stack frames.
* The next batch will start at the given startIndex with the maximum number
* of elements.
*
* <p> Subclass may override this method to manage the allocated buffers.
*
* @param startIndex the start index for the first frame of the next batch to fill in.
* @param elements the number of elements for the next batch to fill in.
*
*/
abstract void resize(int startIndex, int elements);
/**
* Return the class at the given position in the current batch.
* @param index the position of the frame.
* @return the class at the given position in the current batch.
*/
abstract Class<?> at(int index);
// ------ subclass may override the following methods -------
/*
* Returns the start index for this frame buffer is refilled.
*
* This implementation reuses the allocated buffer for the next batch
* of stack frames. For subclass to retain the fetched stack frames,
* it should override this method to return the index at which the frame
* should be filled in for the next batch.
*/
int startIndex() {
return START_POS;
}
/**
* Returns next StackFrame object in the current batch of stack frames
*/
F nextStackFrame() {
throw new InternalError("should not reach here");
}
// ------ FrameBuffer implementation ------
final int curBatchFrameCount() {
return currentBatchSize-START_POS;
}
/*
* Tests if this frame buffer is empty. All frames are fetched.
*/
final boolean isEmpty() {
return origin >= fence || (origin == START_POS && fence == 0);
}
/*
* Freezes this frame buffer. The stack stream source is done fetching.
*/
final void freeze() {
origin = 0;
fence = 0;
}
/*
* Tests if this frame buffer is active. It is inactive when
* it is done for traversal. All stack frames have been traversed.
*/
final boolean isActive() {
return origin > 0 && (fence == 0 || origin < fence || fence == currentBatchSize);
}
/**
* Gets the class at the current frame and move to the next frame.
*/
final Class<?> next() {
if (isEmpty()) {
throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
}
Class<?> c = at(origin);
origin++;
if (isDebug) {
int index = origin-1;
System.out.format(" next frame at %d: %s (origin %d fence %d)%n", index,
Objects.toString(c), index, fence);
}
return c;
}
/**
* Gets the class at the current frame.
*/
final Class<?> get() {
if (isEmpty()) {
throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
}
return at(origin);
}
/*
* Returns the index of the current frame.
*/
final int getIndex() {
return origin;
}
/*
* Set the start and end index of a new batch of stack frames that have
* been filled in this frame buffer.
*/
final void setBatch(int depth, int startIndex, int endIndex) {
if (startIndex <= 0 || endIndex <= 0)
throw new IllegalArgumentException("startIndex=" + startIndex
+ " endIndex=" + endIndex);
this.origin = startIndex;
this.fence = endIndex;
if (depth == 0 && fence > 0) {
// filter the frames due to the stack stream implementation
for (int i = START_POS; i < fence; i++) {
Class<?> c = at(i);
if (isDebug) System.err.format(" frame %d: %s%n", i, c);
if (filterStackWalkImpl(c)) {
origin++;
} else {
break;
}
}
}
}
/*
* Checks if the origin is the expected start index.
*/
final void check(int skipFrames) {
int index = skipFrames + START_POS;
if (origin != index) {
// stack walk must continue with the previous frame depth
throw new IllegalStateException("origin " + origin + " != " + index);
}
}
}
private static native boolean checkStackWalkModes();
// avoid loading other subclasses as they may not be used
private static Set<Class<?>> init() {
if (!checkStackWalkModes()) {
throw new InternalError("StackWalker mode values do not match with JVM");
}
Set<Class<?>> classes = new HashSet<>();
classes.add(StackWalker.class);
classes.add(StackStreamFactory.class);
classes.add(AbstractStackWalker.class);
return classes;
}
private static boolean filterStackWalkImpl(Class<?> c) {
return stackWalkImplClasses.contains(c) ||
c.getName().startsWith("java.util.stream.");
}
// MethodHandle frames are not hidden and CallerClassFinder has
// to filter them out
private static boolean isMethodHandleFrame(Class<?> c) {
return c.getName().startsWith("java.lang.invoke.");
}
private static boolean isReflectionFrame(Class<?> c) {
// ## should filter all @Hidden frames?
return c == Method.class ||
c == Constructor.class ||
MethodAccessor.class.isAssignableFrom(c) ||
ConstructorAccessor.class.isAssignableFrom(c) ||
c.getName().startsWith("java.lang.invoke.LambdaForm");
}
}

View file

@ -0,0 +1,559 @@
/*
* Copyright (c) 2000, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.misc.VM;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleReferenceImpl;
import java.lang.module.ModuleDescriptor.Version;
import java.lang.module.ModuleReference;
import java.lang.module.ResolvedModule;
import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
/**
* An element in a stack trace, as returned by {@link
* Throwable#getStackTrace()}. Each element represents a single stack frame.
* All stack frames except for the one at the top of the stack represent
* a method invocation. The frame at the top of the stack represents the
* execution point at which the stack trace was generated. Typically,
* this is the point at which the throwable corresponding to the stack trace
* was created.
*
* @since 1.4
* @author Josh Bloch
*/
public final class StackTraceElement implements java.io.Serializable {
// For Throwables and StackWalker, the VM initially sets this field to a
// reference to the declaring Class. The Class reference is used to
// construct the 'format' bitmap, and then is cleared.
//
// For STEs constructed using the public constructors, this field is not used.
private transient Class<?> declaringClassObject;
// Normally initialized by VM
private String classLoaderName;
private String moduleName;
private String moduleVersion;
private String declaringClass;
private String methodName;
private String fileName;
private int lineNumber;
private byte format = 0; // Default to show all
/**
* Creates a stack trace element representing the specified execution
* point. The {@link #getModuleName module name} and {@link
* #getModuleVersion module version} of the stack trace element will
* be {@code null}.
*
* @param declaringClass the fully qualified name of the class containing
* the execution point represented by the stack trace element
* @param methodName the name of the method containing the execution point
* represented by the stack trace element
* @param fileName the name of the file containing the execution point
* represented by the stack trace element, or {@code null} if
* this information is unavailable
* @param lineNumber the line number of the source line containing the
* execution point represented by this stack trace element, or
* a negative number if this information is unavailable. A value
* of -2 indicates that the method containing the execution point
* is a native method
* @throws NullPointerException if {@code declaringClass} or
* {@code methodName} is null
* @since 1.5
* @revised 9
* @spec JPMS
*/
public StackTraceElement(String declaringClass, String methodName,
String fileName, int lineNumber) {
this(null, null, null, declaringClass, methodName, fileName, lineNumber);
}
/**
* Creates a stack trace element representing the specified execution
* point.
*
* @param classLoaderName the class loader name if the class loader of
* the class containing the execution point represented by
* the stack trace is named; otherwise {@code null}
* @param moduleName the module name if the class containing the
* execution point represented by the stack trace is in a named
* module; otherwise {@code null}
* @param moduleVersion the module version if the class containing the
* execution point represented by the stack trace is in a named
* module that has a version; otherwise {@code null}
* @param declaringClass the fully qualified name of the class containing
* the execution point represented by the stack trace element
* @param methodName the name of the method containing the execution point
* represented by the stack trace element
* @param fileName the name of the file containing the execution point
* represented by the stack trace element, or {@code null} if
* this information is unavailable
* @param lineNumber the line number of the source line containing the
* execution point represented by this stack trace element, or
* a negative number if this information is unavailable. A value
* of -2 indicates that the method containing the execution point
* is a native method
*
* @throws NullPointerException if {@code declaringClass} is {@code null}
* or {@code methodName} is {@code null}
*
* @since 9
* @spec JPMS
*/
public StackTraceElement(String classLoaderName,
String moduleName, String moduleVersion,
String declaringClass, String methodName,
String fileName, int lineNumber) {
this.classLoaderName = classLoaderName;
this.moduleName = moduleName;
this.moduleVersion = moduleVersion;
this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
this.methodName = Objects.requireNonNull(methodName, "Method name is null");
this.fileName = fileName;
this.lineNumber = lineNumber;
}
/*
* Private constructor for the factory methods to create StackTraceElement
* for Throwable and StackFrameInfo
*/
private StackTraceElement() {}
/**
* Returns the name of the source file containing the execution point
* represented by this stack trace element. Generally, this corresponds
* to the {@code SourceFile} attribute of the relevant {@code class}
* file (as per <i>The Java Virtual Machine Specification</i>, Section
* 4.7.7). In some systems, the name may refer to some source code unit
* other than a file, such as an entry in source repository.
*
* @return the name of the file containing the execution point
* represented by this stack trace element, or {@code null} if
* this information is unavailable.
*/
public String getFileName() {
return fileName;
}
/**
* Returns the line number of the source line containing the execution
* point represented by this stack trace element. Generally, this is
* derived from the {@code LineNumberTable} attribute of the relevant
* {@code class} file (as per <i>The Java Virtual Machine
* Specification</i>, Section 4.7.8).
*
* @return the line number of the source line containing the execution
* point represented by this stack trace element, or a negative
* number if this information is unavailable.
*/
public int getLineNumber() {
return lineNumber;
}
/**
* Returns the module name of the module containing the execution point
* represented by this stack trace element.
*
* @return the module name of the {@code Module} containing the execution
* point represented by this stack trace element; {@code null}
* if the module name is not available.
* @since 9
* @spec JPMS
* @see Module#getName()
*/
public String getModuleName() {
return moduleName;
}
/**
* Returns the module version of the module containing the execution point
* represented by this stack trace element.
*
* @return the module version of the {@code Module} containing the execution
* point represented by this stack trace element; {@code null}
* if the module version is not available.
* @since 9
* @spec JPMS
* @see java.lang.module.ModuleDescriptor.Version
*/
public String getModuleVersion() {
return moduleVersion;
}
/**
* Returns the name of the class loader of the class containing the
* execution point represented by this stack trace element.
*
* @return the name of the class loader of the class containing the execution
* point represented by this stack trace element; {@code null}
* if the class loader is not named.
*
* @since 9
* @spec JPMS
* @see java.lang.ClassLoader#getName()
*/
public String getClassLoaderName() {
return classLoaderName;
}
/**
* Returns the fully qualified name of the class containing the
* execution point represented by this stack trace element.
*
* @return the fully qualified name of the {@code Class} containing
* the execution point represented by this stack trace element.
*/
public String getClassName() {
return declaringClass;
}
/**
* Returns the name of the method containing the execution point
* represented by this stack trace element. If the execution point is
* contained in an instance or class initializer, this method will return
* the appropriate <i>special method name</i>, {@code <init>} or
* {@code <clinit>}, as per Section 3.9 of <i>The Java Virtual
* Machine Specification</i>.
*
* @return the name of the method containing the execution point
* represented by this stack trace element.
*/
public String getMethodName() {
return methodName;
}
/**
* Returns true if the method containing the execution point
* represented by this stack trace element is a native method.
*
* @return {@code true} if the method containing the execution point
* represented by this stack trace element is a native method.
*/
public boolean isNativeMethod() {
return lineNumber == -2;
}
/**
* Returns a string representation of this stack trace element.
*
* @apiNote The format of this string depends on the implementation, but the
* following examples may be regarded as typical:
* <ul>
* <li>
* "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Main.java:101)}"
* - See the description below.
* </li>
* <li>
* "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Main.java)}"
* - The line number is unavailable.
* </li>
* <li>
* "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Unknown Source)}"
* - Neither the file name nor the line number is available.
* </li>
* <li>
* "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Native Method)}"
* - The method containing the execution point is a native method.
* </li>
* <li>
* "{@code com.foo.loader//com.foo.bar.App.run(App.java:12)}"
* - The class of the execution point is defined in the unnamed module of
* the class loader named {@code com.foo.loader}.
* </li>
* <li>
* "{@code acme@2.1/org.acme.Lib.test(Lib.java:80)}"
* - The class of the execution point is defined in {@code acme} module
* loaded by by a built-in class loader such as the application class loader.
* </li>
* <li>
* "{@code MyClass.mash(MyClass.java:9)}"
* - {@code MyClass} class is on the application class path.
* </li>
* </ul>
*
* <p> The first example shows a stack trace element consisting of
* three elements, each separated by {@code "/"} followed with
* the source file name and the line number of the source line
* containing the execution point.
*
* The first element "{@code com.foo.loader}" is
* the name of the class loader. The second element "{@code foo@9.0}"
* is the module name and version. The third element is the method
* containing the execution point; "{@code com.foo.Main"}" is the
* fully-qualified class name and "{@code run}" is the name of the method.
* "{@code Main.java}" is the source file name and "{@code 101}" is
* the line number.
*
* <p> If a class is defined in an <em>unnamed module</em>
* then the second element is omitted as shown in
* "{@code com.foo.loader//com.foo.bar.App.run(App.java:12)}".
*
* <p> If the class loader is a <a href="ClassLoader.html#builtinLoaders">
* built-in class loader</a> or is not named then the first element
* and its following {@code "/"} are omitted as shown in
* "{@code acme@2.1/org.acme.Lib.test(Lib.java:80)}".
* If the first element is omitted and the module is an unnamed module,
* the second element and its following {@code "/"} are also omitted
* as shown in "{@code MyClass.mash(MyClass.java:9)}".
*
* <p> The {@code toString} method may return two different values on two
* {@code StackTraceElement} instances that are
* {@linkplain #equals(Object) equal}, for example one created via the
* constructor, and one obtained from {@link java.lang.Throwable} or
* {@link java.lang.StackWalker.StackFrame}, where an implementation may
* choose to omit some element in the returned string.
*
* @revised 9
* @spec JPMS
* @see Throwable#printStackTrace()
*/
public String toString() {
String s = "";
if (!dropClassLoaderName() && classLoaderName != null &&
!classLoaderName.isEmpty()) {
s += classLoaderName + "/";
}
if (moduleName != null && !moduleName.isEmpty()) {
s += moduleName;
if (!dropModuleVersion() && moduleVersion != null &&
!moduleVersion.isEmpty()) {
s += "@" + moduleVersion;
}
}
s = s.isEmpty() ? declaringClass : s + "/" + declaringClass;
return s + "." + methodName + "(" +
(isNativeMethod() ? "Native Method)" :
(fileName != null && lineNumber >= 0 ?
fileName + ":" + lineNumber + ")" :
(fileName != null ? ""+fileName+")" : "Unknown Source)")));
}
/**
* Returns true if the specified object is another
* {@code StackTraceElement} instance representing the same execution
* point as this instance. Two stack trace elements {@code a} and
* {@code b} are equal if and only if:
* <pre>{@code
* equals(a.getClassLoaderName(), b.getClassLoaderName()) &&
* equals(a.getModuleName(), b.getModuleName()) &&
* equals(a.getModuleVersion(), b.getModuleVersion()) &&
* equals(a.getClassName(), b.getClassName()) &&
* equals(a.getMethodName(), b.getMethodName())
* equals(a.getFileName(), b.getFileName()) &&
* a.getLineNumber() == b.getLineNumber()
*
* }</pre>
* where {@code equals} has the semantics of {@link
* java.util.Objects#equals(Object, Object) Objects.equals}.
*
* @param obj the object to be compared with this stack trace element.
* @return true if the specified object is another
* {@code StackTraceElement} instance representing the same
* execution point as this instance.
*
* @revised 9
* @spec JPMS
*/
public boolean equals(Object obj) {
if (obj==this)
return true;
if (!(obj instanceof StackTraceElement))
return false;
StackTraceElement e = (StackTraceElement)obj;
return Objects.equals(classLoaderName, e.classLoaderName) &&
Objects.equals(moduleName, e.moduleName) &&
Objects.equals(moduleVersion, e.moduleVersion) &&
e.declaringClass.equals(declaringClass) &&
e.lineNumber == lineNumber &&
Objects.equals(methodName, e.methodName) &&
Objects.equals(fileName, e.fileName);
}
/**
* Returns a hash code value for this stack trace element.
*/
public int hashCode() {
int result = 31*declaringClass.hashCode() + methodName.hashCode();
result = 31*result + Objects.hashCode(classLoaderName);
result = 31*result + Objects.hashCode(moduleName);
result = 31*result + Objects.hashCode(moduleVersion);
result = 31*result + Objects.hashCode(fileName);
result = 31*result + lineNumber;
return result;
}
/**
* Called from of() methods to set the 'format' bitmap using the Class
* reference stored in declaringClassObject, and then clear the reference.
*
* <p>
* If the module is a non-upgradeable JDK module, then set
* JDK_NON_UPGRADEABLE_MODULE to omit its version string.
* <p>
* If the loader is one of the built-in loaders (`boot`, `platform`, or `app`)
* then set BUILTIN_CLASS_LOADER to omit the first element (`<loader>/`).
*/
private synchronized void computeFormat() {
try {
Class<?> cls = (Class<?>) declaringClassObject;
ClassLoader loader = cls.getClassLoader0();
Module m = cls.getModule();
byte bits = 0;
// First element - class loader name
// Call package-private ClassLoader::name method
if (loader instanceof BuiltinClassLoader) {
bits |= BUILTIN_CLASS_LOADER;
}
// Second element - module name and version
// Omit if is a JDK non-upgradeable module (recorded in the hashes
// in java.base)
if (isHashedInJavaBase(m)) {
bits |= JDK_NON_UPGRADEABLE_MODULE;
}
format = bits;
} finally {
// Class reference no longer needed, clear it
declaringClassObject = null;
}
}
private static final byte BUILTIN_CLASS_LOADER = 0x1;
private static final byte JDK_NON_UPGRADEABLE_MODULE = 0x2;
private boolean dropClassLoaderName() {
return (format & BUILTIN_CLASS_LOADER) == BUILTIN_CLASS_LOADER;
}
private boolean dropModuleVersion() {
return (format & JDK_NON_UPGRADEABLE_MODULE) == JDK_NON_UPGRADEABLE_MODULE;
}
/**
* Returns true if the module is hashed with java.base.
* <p>
* This method returns false when running on the exploded image
* since JDK modules are not hashed. They have no Version attribute
* and so "@<version>" part will be omitted anyway.
*/
private static boolean isHashedInJavaBase(Module m) {
// return true if module system is not initialized as the code
// must be in java.base
if (!VM.isModuleSystemInited())
return true;
return ModuleLayer.boot() == m.getLayer() && HashedModules.contains(m);
}
/*
* Finds JDK non-upgradeable modules, i.e. the modules that are
* included in the hashes in java.base.
*/
private static class HashedModules {
static Set<String> HASHED_MODULES = hashedModules();
static Set<String> hashedModules() {
Optional<ResolvedModule> resolvedModule = ModuleLayer.boot()
.configuration()
.findModule("java.base");
assert resolvedModule.isPresent();
ModuleReference mref = resolvedModule.get().reference();
assert mref instanceof ModuleReferenceImpl;
ModuleHashes hashes = ((ModuleReferenceImpl)mref).recordedHashes();
if (hashes != null) {
Set<String> names = new HashSet<>(hashes.names());
names.add("java.base");
return names;
}
return Set.of();
}
static boolean contains(Module m) {
return HASHED_MODULES.contains(m.getName());
}
}
/*
* Returns an array of StackTraceElements of the given depth
* filled from the backtrace of a given Throwable.
*/
static StackTraceElement[] of(Throwable x, int depth) {
StackTraceElement[] stackTrace = new StackTraceElement[depth];
for (int i = 0; i < depth; i++) {
stackTrace[i] = new StackTraceElement();
}
// VM to fill in StackTraceElement
initStackTraceElements(stackTrace, x);
// ensure the proper StackTraceElement initialization
for (StackTraceElement ste : stackTrace) {
ste.computeFormat();
}
return stackTrace;
}
/*
* Returns a StackTraceElement from a given StackFrameInfo.
*/
static StackTraceElement of(StackFrameInfo sfi) {
StackTraceElement ste = new StackTraceElement();
initStackTraceElement(ste, sfi);
ste.computeFormat();
return ste;
}
/*
* Sets the given stack trace elements with the backtrace
* of the given Throwable.
*/
private static native void initStackTraceElements(StackTraceElement[] elements,
Throwable x);
/*
* Sets the given stack trace element with the given StackFrameInfo
*/
private static native void initStackTraceElement(StackTraceElement element,
StackFrameInfo sfi);
private static final long serialVersionUID = 6992337162326171013L;
}

View file

@ -0,0 +1,584 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang;
import jdk.internal.reflect.CallerSensitive;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* A stack walker.
*
* <p> The {@link StackWalker#walk walk} method opens a sequential stream
* of {@link StackFrame StackFrame}s for the current thread and then applies
* the given function to walk the {@code StackFrame} stream.
* The stream reports stack frame elements in order, from the top most frame
* that represents the execution point at which the stack was generated to
* the bottom most frame.
* The {@code StackFrame} stream is closed when the {@code walk} method returns.
* If an attempt is made to reuse the closed stream,
* {@code IllegalStateException} will be thrown.
*
* <p> The {@linkplain Option <em>stack walking options</em>} of a
* {@code StackWalker} determines the information of
* {@link StackFrame StackFrame} objects to be returned.
* By default, stack frames of the reflection API and implementation
* classes are {@linkplain Option#SHOW_HIDDEN_FRAMES hidden}
* and {@code StackFrame}s have the class name and method name
* available but not the {@link StackFrame#getDeclaringClass() Class reference}.
*
* <p> {@code StackWalker} is thread-safe. Multiple threads can share
* a single {@code StackWalker} object to traverse its own stack.
* A permission check is performed when a {@code StackWalker} is created,
* according to the options it requests.
* No further permission check is done at stack walking time.
*
* @apiNote
* Examples
*
* <p>1. To find the first caller filtering a known list of implementation class:
* <pre>{@code
* StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
* Optional<Class<?>> callerClass = walker.walk(s ->
* s.map(StackFrame::getDeclaringClass)
* .filter(interestingClasses::contains)
* .findFirst());
* }</pre>
*
* <p>2. To snapshot the top 10 stack frames of the current thread,
* <pre>{@code
* List<StackFrame> stack = StackWalker.getInstance().walk(s ->
* s.limit(10).collect(Collectors.toList()));
* }</pre>
*
* Unless otherwise noted, passing a {@code null} argument to a
* constructor or method in this {@code StackWalker} class
* will cause a {@link NullPointerException NullPointerException}
* to be thrown.
*
* @since 9
*/
public final class StackWalker {
/**
* A {@code StackFrame} object represents a method invocation returned by
* {@link StackWalker}.
*
* <p> The {@link #getDeclaringClass()} method may be unsupported as determined
* by the {@linkplain Option stack walking options} of a {@linkplain
* StackWalker stack walker}.
*
* @since 9
* @jvms 2.6
*/
public static interface StackFrame {
/**
* Gets the <a href="ClassLoader.html#name">binary name</a>
* of the declaring class of the method represented by this stack frame.
*
* @return the binary name of the declaring class of the method
* represented by this stack frame
*
* @jls 13.1 The Form of a Binary
*/
public String getClassName();
/**
* Gets the name of the method represented by this stack frame.
* @return the name of the method represented by this stack frame
*/
public String getMethodName();
/**
* Gets the declaring {@code Class} for the method represented by
* this stack frame.
*
* @return the declaring {@code Class} of the method represented by
* this stack frame
*
* @throws UnsupportedOperationException if this {@code StackWalker}
* is not configured with {@link Option#RETAIN_CLASS_REFERENCE
* Option.RETAIN_CLASS_REFERENCE}.
*/
public Class<?> getDeclaringClass();
/**
* Returns the index to the code array of the {@code Code} attribute
* containing the execution point represented by this stack frame.
* The code array gives the actual bytes of Java Virtual Machine code
* that implement the method.
*
* @return the index to the code array of the {@code Code} attribute
* containing the execution point represented by this stack frame,
* or a negative number if the method is native.
*
* @jvms 4.7.3 The {@code Code} Attribute
*/
public int getByteCodeIndex();
/**
* Returns the name of the source file containing the execution point
* represented by this stack frame. Generally, this corresponds
* to the {@code SourceFile} attribute of the relevant {@code class}
* file as defined by <cite>The Java Virtual Machine Specification</cite>.
* In some systems, the name may refer to some source code unit
* other than a file, such as an entry in a source repository.
*
* @return the name of the file containing the execution point
* represented by this stack frame, or {@code null} if
* this information is unavailable.
*
* @jvms 4.7.10 The {@code SourceFile} Attribute
*/
public String getFileName();
/**
* Returns the line number of the source line containing the execution
* point represented by this stack frame. Generally, this is
* derived from the {@code LineNumberTable} attribute of the relevant
* {@code class} file as defined by <cite>The Java Virtual Machine
* Specification</cite>.
*
* @return the line number of the source line containing the execution
* point represented by this stack frame, or a negative number if
* this information is unavailable.
*
* @jvms 4.7.12 The {@code LineNumberTable} Attribute
*/
public int getLineNumber();
/**
* Returns {@code true} if the method containing the execution point
* represented by this stack frame is a native method.
*
* @return {@code true} if the method containing the execution point
* represented by this stack frame is a native method.
*/
public boolean isNativeMethod();
/**
* Gets a {@code StackTraceElement} for this stack frame.
*
* @return {@code StackTraceElement} for this stack frame.
*/
public StackTraceElement toStackTraceElement();
}
/**
* Stack walker option to configure the {@linkplain StackFrame stack frame}
* information obtained by a {@code StackWalker}.
*
* @since 9
*/
public enum Option {
/**
* Retains {@code Class} object in {@code StackFrame}s
* walked by this {@code StackWalker}.
*
* <p> A {@code StackWalker} configured with this option will support
* {@link StackWalker#getCallerClass()} and
* {@link StackFrame#getDeclaringClass() StackFrame.getDeclaringClass()}.
*/
RETAIN_CLASS_REFERENCE,
/**
* Shows all reflection frames.
*
* <p>By default, reflection frames are hidden. A {@code StackWalker}
* configured with this {@code SHOW_REFLECT_FRAMES} option
* will show all reflection frames that
* include {@link java.lang.reflect.Method#invoke} and
* {@link java.lang.reflect.Constructor#newInstance(Object...)}
* and their reflection implementation classes.
*
* <p>The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
* reflection frames and it will also show other hidden frames that
* are implementation-specific.
*
* @apiNote
* This option includes the stack frames representing the invocation of
* {@code Method} and {@code Constructor}. Any utility methods that
* are equivalent to calling {@code Method.invoke} or
* {@code Constructor.newInstance} such as {@code Class.newInstance}
* are not filtered or controlled by any stack walking option.
*/
SHOW_REFLECT_FRAMES,
/**
* Shows all hidden frames.
*
* <p>A Java Virtual Machine implementation may hide implementation
* specific frames in addition to {@linkplain #SHOW_REFLECT_FRAMES
* reflection frames}. A {@code StackWalker} with this {@code SHOW_HIDDEN_FRAMES}
* option will show all hidden frames (including reflection frames).
*/
SHOW_HIDDEN_FRAMES;
}
enum ExtendedOption {
/**
* Obtain monitors, locals and operands.
*/
LOCALS_AND_OPERANDS
};
static final EnumSet<Option> DEFAULT_EMPTY_OPTION = EnumSet.noneOf(Option.class);
private final static StackWalker DEFAULT_WALKER =
new StackWalker(DEFAULT_EMPTY_OPTION);
private final Set<Option> options;
private final ExtendedOption extendedOption;
private final int estimateDepth;
/**
* Returns a {@code StackWalker} instance.
*
* <p> This {@code StackWalker} is configured to skip all
* {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
* no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
*
* @return a {@code StackWalker} configured to skip all
* {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
* no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
*
*/
public static StackWalker getInstance() {
// no permission check needed
return DEFAULT_WALKER;
}
/**
* Returns a {@code StackWalker} instance with the given option specifying
* the stack frame information it can access.
*
* <p>
* If a security manager is present and the given {@code option} is
* {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
* it calls its {@link SecurityManager#checkPermission checkPermission}
* method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
*
* @param option {@link Option stack walking option}
*
* @return a {@code StackWalker} configured with the given option
*
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method denies access.
*/
public static StackWalker getInstance(Option option) {
return getInstance(EnumSet.of(Objects.requireNonNull(option)));
}
/**
* Returns a {@code StackWalker} instance with the given {@code options} specifying
* the stack frame information it can access. If the given {@code options}
* is empty, this {@code StackWalker} is configured to skip all
* {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
* {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
*
* <p>
* If a security manager is present and the given {@code options} contains
* {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
* it calls its {@link SecurityManager#checkPermission checkPermission}
* method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
*
* @param options {@link Option stack walking option}
*
* @return a {@code StackWalker} configured with the given options
*
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method denies access.
*/
public static StackWalker getInstance(Set<Option> options) {
if (options.isEmpty()) {
return DEFAULT_WALKER;
}
EnumSet<Option> optionSet = toEnumSet(options);
checkPermission(optionSet);
return new StackWalker(optionSet);
}
/**
* Returns a {@code StackWalker} instance with the given {@code options} specifying
* the stack frame information it can access. If the given {@code options}
* is empty, this {@code StackWalker} is configured to skip all
* {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
* {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
*
* <p>
* If a security manager is present and the given {@code options} contains
* {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
* it calls its {@link SecurityManager#checkPermission checkPermission}
* method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
*
* <p>
* The {@code estimateDepth} specifies the estimate number of stack frames
* this {@code StackWalker} will traverse that the {@code StackWalker} could
* use as a hint for the buffer size.
*
* @param options {@link Option stack walking options}
* @param estimateDepth Estimate number of stack frames to be traversed.
*
* @return a {@code StackWalker} configured with the given options
*
* @throws IllegalArgumentException if {@code estimateDepth <= 0}
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method denies access.
*/
public static StackWalker getInstance(Set<Option> options, int estimateDepth) {
if (estimateDepth <= 0) {
throw new IllegalArgumentException("estimateDepth must be > 0");
}
EnumSet<Option> optionSet = toEnumSet(options);
checkPermission(optionSet);
return new StackWalker(optionSet, estimateDepth);
}
// ----- private constructors ------
private StackWalker(EnumSet<Option> options) {
this(options, 0, null);
}
private StackWalker(EnumSet<Option> options, int estimateDepth) {
this(options, estimateDepth, null);
}
private StackWalker(EnumSet<Option> options, int estimateDepth, ExtendedOption extendedOption) {
this.options = options;
this.estimateDepth = estimateDepth;
this.extendedOption = extendedOption;
}
private static void checkPermission(Set<Option> options) {
Objects.requireNonNull(options);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (options.contains(Option.RETAIN_CLASS_REFERENCE)) {
sm.checkPermission(new RuntimePermission("getStackWalkerWithClassReference"));
}
}
}
/*
* Returns a defensive copy
*/
private static EnumSet<Option> toEnumSet(Set<Option> options) {
Objects.requireNonNull(options);
if (options.isEmpty()) {
return DEFAULT_EMPTY_OPTION;
} else {
return EnumSet.copyOf(options);
}
}
/**
* Applies the given function to the stream of {@code StackFrame}s
* for the current thread, traversing from the top frame of the stack,
* which is the method calling this {@code walk} method.
*
* <p>The {@code StackFrame} stream will be closed when
* this method returns. When a closed {@code Stream<StackFrame>} object
* is reused, {@code IllegalStateException} will be thrown.
*
* @apiNote
* For example, to find the first 10 calling frames, first skipping those frames
* whose declaring class is in package {@code com.foo}:
* <blockquote>
* <pre>{@code
* List<StackFrame> frames = StackWalker.getInstance().walk(s ->
* s.dropWhile(f -> f.getClassName().startsWith("com.foo."))
* .limit(10)
* .collect(Collectors.toList()));
* }</pre></blockquote>
*
* <p>This method takes a {@code Function} accepting a {@code Stream<StackFrame>},
* rather than returning a {@code Stream<StackFrame>} and allowing the
* caller to directly manipulate the stream. The Java virtual machine is
* free to reorganize a thread's control stack, for example, via
* deoptimization. By taking a {@code Function} parameter, this method
* allows access to stack frames through a stable view of a thread's control
* stack.
*
* <p>Parallel execution is effectively disabled and stream pipeline
* execution will only occur on the current thread.
*
* @implNote The implementation stabilizes the stack by anchoring a frame
* specific to the stack walking and ensures that the stack walking is
* performed above the anchored frame. When the stream object is closed or
* being reused, {@code IllegalStateException} will be thrown.
*
* @param function a function that takes a stream of
* {@linkplain StackFrame stack frames} and returns a result.
* @param <T> The type of the result of applying the function to the
* stream of {@linkplain StackFrame stack frame}.
*
* @return the result of applying the function to the stream of
* {@linkplain StackFrame stack frame}.
*/
@CallerSensitive
public <T> T walk(Function<? super Stream<StackFrame>, ? extends T> function) {
// Returning a Stream<StackFrame> would be unsafe, as the stream could
// be used to access the stack frames in an uncontrolled manner. For
// example, a caller might pass a Spliterator of stack frames after one
// or more frames had been traversed. There is no robust way to detect
// whether the execution point when
// Spliterator.tryAdvance(java.util.function.Consumer<? super T>) is
// invoked is the exact same execution point where the stack frame
// traversal is expected to resume.
Objects.requireNonNull(function);
return StackStreamFactory.makeStackTraverser(this, function)
.walk();
}
/**
* Performs the given action on each element of {@code StackFrame} stream
* of the current thread, traversing from the top frame of the stack,
* which is the method calling this {@code forEach} method.
*
* <p> This method is equivalent to calling
* <blockquote>
* {@code walk(s -> { s.forEach(action); return null; });}
* </blockquote>
*
* @param action an action to be performed on each {@code StackFrame}
* of the stack of the current thread
*/
@CallerSensitive
public void forEach(Consumer<? super StackFrame> action) {
Objects.requireNonNull(action);
StackStreamFactory.makeStackTraverser(this, s -> {
s.forEach(action);
return null;
}).walk();
}
/**
* Gets the {@code Class} object of the caller who invoked the method
* that invoked {@code getCallerClass}.
*
* <p> This method filters {@linkplain Option#SHOW_REFLECT_FRAMES reflection
* frames}, {@link java.lang.invoke.MethodHandle}, and
* {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} regardless of the
* {@link Option#SHOW_REFLECT_FRAMES SHOW_REFLECT_FRAMES}
* and {@link Option#SHOW_HIDDEN_FRAMES SHOW_HIDDEN_FRAMES} options
* this {@code StackWalker} has been configured with.
*
* <p> This method should be called when a caller frame is present. If
* it is called from the bottom most frame on the stack,
* {@code IllegalCallerException} will be thrown.
*
* <p> This method throws {@code UnsupportedOperationException}
* if this {@code StackWalker} is not configured with the
* {@link Option#RETAIN_CLASS_REFERENCE RETAIN_CLASS_REFERENCE} option.
*
* @apiNote
* For example, {@code Util::getResourceBundle} loads a resource bundle
* on behalf of the caller. It invokes {@code getCallerClass} to identify
* the class whose method called {@code Util::getResourceBundle}.
* Then, it obtains the class loader of that class, and uses
* the class loader to load the resource bundle. The caller class
* in this example is {@code MyTool}.
*
* <pre>{@code
* class Util {
* private final StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
* public ResourceBundle getResourceBundle(String bundleName) {
* Class<?> caller = walker.getCallerClass();
* return ResourceBundle.getBundle(bundleName, Locale.getDefault(), caller.getClassLoader());
* }
* }
*
* class MyTool {
* private final Util util = new Util();
* private void init() {
* ResourceBundle rb = util.getResourceBundle("mybundle");
* }
* }
* }</pre>
*
* An equivalent way to find the caller class using the
* {@link StackWalker#walk walk} method is as follows
* (filtering the reflection frames, {@code MethodHandle} and hidden frames
* not shown below):
* <pre>{@code
* Optional<Class<?>> caller = walker.walk(s ->
* s.map(StackFrame::getDeclaringClass)
* .skip(2)
* .findFirst());
* }</pre>
*
* When the {@code getCallerClass} method is called from a method that
* is the bottom most frame on the stack,
* for example, {@code static public void main} method launched by the
* {@code java} launcher, or a method invoked from a JNI attached thread,
* {@code IllegalCallerException} is thrown.
*
* @return {@code Class} object of the caller's caller invoking this method.
*
* @throws UnsupportedOperationException if this {@code StackWalker}
* is not configured with {@link Option#RETAIN_CLASS_REFERENCE
* Option.RETAIN_CLASS_REFERENCE}.
* @throws IllegalCallerException if there is no caller frame, i.e.
* when this {@code getCallerClass} method is called from a method
* which is the last frame on the stack.
*/
@CallerSensitive
public Class<?> getCallerClass() {
if (!options.contains(Option.RETAIN_CLASS_REFERENCE)) {
throw new UnsupportedOperationException("This stack walker " +
"does not have RETAIN_CLASS_REFERENCE access");
}
return StackStreamFactory.makeCallerFinder(this).findCaller();
}
// ---- package access ----
static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption) {
EnumSet<Option> optionSet = toEnumSet(options);
checkPermission(optionSet);
return new StackWalker(optionSet, 0, extendedOption);
}
int estimateDepth() {
return estimateDepth;
}
boolean hasOption(Option option) {
return options.contains(option);
}
boolean hasLocalsOperandsOption() {
return extendedOption == ExtendedOption.LOCALS_AND_OPERANDS;
}
void ensureAccessEnabled(Option access) {
if (!hasOption(access)) {
throw new UnsupportedOperationException("No access to " + access +
": " + options.toString());
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more