From 46d230c9cc6acef12c8cc99a2e8efb57fb79673a Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Mon, 6 Nov 2017 17:35:40 -0500 Subject: [PATCH 01/10] 8187281: Remove intermittent from OnExitTest Reviewed-by: lancea --- test/jdk/java/lang/ProcessHandle/OnExitTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/test/jdk/java/lang/ProcessHandle/OnExitTest.java b/test/jdk/java/lang/ProcessHandle/OnExitTest.java index 2ae2652a21d..834477775e4 100644 --- a/test/jdk/java/lang/ProcessHandle/OnExitTest.java +++ b/test/jdk/java/lang/ProcessHandle/OnExitTest.java @@ -40,7 +40,6 @@ import org.testng.TestNG; /* * @test - * @key intermittent * @library /test/lib * @build jdk.test.lib.Utils * @run testng OnExitTest From 25032bad54b64b6ed688e488afbe46089a885571 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 6 Nov 2017 17:48:00 -0800 Subject: [PATCH 02/10] 8164512: Replace ClassLoader use of finalizer with phantom reference to unload native library Reviewed-by: alanb, bchristi, kbarrett, dholmes, plevart --- make/mapfiles/libjava/mapfile-vers | 4 +- make/mapfiles/libjava/reorder-sparc | 4 +- make/mapfiles/libjava/reorder-sparcv9 | 4 +- make/mapfiles/libjava/reorder-x86 | 4 +- make/test/JtregNativeJdk.gmk | 1 + .../share/classes/java/lang/ClassLoader.java | 339 +++++++++++------- .../share/classes/java/lang/Runtime.java | 7 +- .../share/classes/java/lang/System.java | 6 +- .../share/native/libjava/ClassLoader.c | 38 +- .../nativeLibrary/NativeLibraryTest.java | 129 +++++++ .../nativeLibrary/libnativeLibraryTest.c | 74 ++++ .../ClassLoader/nativeLibrary/p/Test.java | 37 ++ 12 files changed, 484 insertions(+), 163 deletions(-) create mode 100644 test/jdk/java/lang/ClassLoader/nativeLibrary/NativeLibraryTest.java create mode 100644 test/jdk/java/lang/ClassLoader/nativeLibrary/libnativeLibraryTest.c create mode 100644 test/jdk/java/lang/ClassLoader/nativeLibrary/p/Test.java diff --git a/make/mapfiles/libjava/mapfile-vers b/make/mapfiles/libjava/mapfile-vers index 1a8d712c7b8..d2c82345060 100644 --- a/make/mapfiles/libjava/mapfile-vers +++ b/make/mapfiles/libjava/mapfile-vers @@ -130,8 +130,8 @@ SUNWprivate_1.1 { Java_java_lang_ClassLoader_defineClass2; Java_java_lang_ClassLoader_findBuiltinLib; Java_java_lang_ClassLoader_findLoadedClass0; - Java_java_lang_ClassLoader_00024NativeLibrary_find; - Java_java_lang_ClassLoader_00024NativeLibrary_load; + Java_java_lang_ClassLoader_00024NativeLibrary_findEntry; + Java_java_lang_ClassLoader_00024NativeLibrary_load0; Java_java_lang_ClassLoader_00024NativeLibrary_unload; Java_java_lang_ClassLoader_registerNatives; Java_java_lang_Double_longBitsToDouble; diff --git a/make/mapfiles/libjava/reorder-sparc b/make/mapfiles/libjava/reorder-sparc index da91bfb6f68..990ca32b6fb 100644 --- a/make/mapfiles/libjava/reorder-sparc +++ b/make/mapfiles/libjava/reorder-sparc @@ -48,8 +48,8 @@ text: .text%Java_java_io_FileInputStream_available0; text: .text%Java_java_io_FileInputStream_close0; text: .text%Java_java_lang_System_mapLibraryName; text: .text%Java_java_io_UnixFileSystem_getBooleanAttributes0; -text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_load; -text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_find; +text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_load0; +text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_findEntry; text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2; text: .text%Java_java_io_UnixFileSystem_list; text: .text%JNU_ClassString; diff --git a/make/mapfiles/libjava/reorder-sparcv9 b/make/mapfiles/libjava/reorder-sparcv9 index aa605871ecc..4e3ce84b862 100644 --- a/make/mapfiles/libjava/reorder-sparcv9 +++ b/make/mapfiles/libjava/reorder-sparcv9 @@ -57,8 +57,8 @@ text: .text%JNU_CopyObjectArray; text: .text%Java_java_io_UnixFileSystem_getBooleanAttributes0; text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2; text: .text%Java_java_lang_System_mapLibraryName; -text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_load; -text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_find; +text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_load0; +text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_findEntry; text: .text%Java_java_io_UnixFileSystem_getLength; text: .text%Java_java_lang_Object_getClass; text: .text%Java_java_lang_ClassLoader_defineClass0; diff --git a/make/mapfiles/libjava/reorder-x86 b/make/mapfiles/libjava/reorder-x86 index 46948fc4ada..de28893a4d2 100644 --- a/make/mapfiles/libjava/reorder-x86 +++ b/make/mapfiles/libjava/reorder-x86 @@ -50,8 +50,8 @@ text: .text%Java_java_lang_ClassLoader_findBootstrapClass; text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2; text: .text%Java_java_lang_System_mapLibraryName; text: .text%cpchars: OUTPUTDIR/System.o; -text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_load; -text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_find; +text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_load0; +text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_findEntry; text: .text%Java_java_lang_Float_floatToRawIntBits; text: .text%Java_java_lang_Double_doubleToRawLongBits; text: .text%Java_java_io_FileInputStream_open0; diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk index 5d0b14d16c1..3e8d3af1d4e 100644 --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk @@ -44,6 +44,7 @@ $(eval $(call IncludeCustomExtension, test/JtregNativeJdk.gmk)) # Add more directories here when needed. BUILD_JDK_JTREG_NATIVE_SRC += \ $(TOPDIR)/test/jdk/native_sanity \ + $(TOPDIR)/test/jdk/java/lang/ClassLoader/nativeLibrary \ $(TOPDIR)/test/jdk/java/lang/String/nativeEncoding \ # diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java index 9a60f55ea48..b91b4619be6 100644 --- a/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/src/java.base/share/classes/java/lang/ClassLoader.java @@ -37,17 +37,20 @@ import java.security.CodeSource; import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.security.cert.Certificate; +import java.util.Arrays; import java.util.Collections; +import java.util.Deque; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.Hashtable; +import java.util.LinkedList; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Set; import java.util.Spliterator; import java.util.Spliterators; -import java.util.Stack; import java.util.Vector; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; @@ -58,9 +61,9 @@ import java.util.stream.StreamSupport; import jdk.internal.perf.PerfCounter; import jdk.internal.loader.BootLoader; import jdk.internal.loader.ClassLoaders; -import jdk.internal.misc.SharedSecrets; import jdk.internal.misc.Unsafe; import jdk.internal.misc.VM; +import jdk.internal.ref.CleanerFactory; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; import sun.reflect.misc.ReflectUtil; @@ -2375,75 +2378,161 @@ public abstract class ClassLoader { * @since 1.2 */ static class NativeLibrary { + // the class from which the library is loaded, also indicates + // the loader this native library belongs. + final Class fromClass; + // the canonicalized name of the native library. + // or static library name + final String name; + // Indicates if the native library is linked into the VM + final boolean isBuiltin; + // opaque handle to native library, used in native code. long handle; // the version of JNI environment the native library requires. - private int jniVersion; - // the class from which the library is loaded, also indicates - // the loader this native library belongs. - private Class fromClass; - // the canonicalized name of the native library. - // or static library name - String name; - // Indicates if the native library is linked into the VM - boolean isBuiltin; - // Indicates if the native library is loaded - boolean loaded; - native void load(String name, boolean isBuiltin); + int jniVersion; - native long find(String name); - native void unload(String name, boolean isBuiltin); + native boolean load0(String name, boolean isBuiltin); - public NativeLibrary(Class fromClass, String name, boolean isBuiltin) { + native long findEntry(String name); + + NativeLibrary(Class fromClass, String name, boolean isBuiltin) { this.name = name; this.fromClass = fromClass; this.isBuiltin = isBuiltin; } - @SuppressWarnings("deprecation") - protected void finalize() { - synchronized (loadedLibraryNames) { - if (fromClass.getClassLoader() != null && loaded) { - this.fromClass = null; // no context when unloaded + /* + * Loads the native library and registers for cleanup when its + * associated class loader is unloaded + */ + boolean load() { + if (handle != 0) { + throw new InternalError("Native library " + name + " has been loaded"); + } - /* remove the native library name */ - int size = loadedLibraryNames.size(); - for (int i = 0; i < size; i++) { - if (name.equals(loadedLibraryNames.elementAt(i))) { - loadedLibraryNames.removeElementAt(i); - break; + if (!load0(name, isBuiltin)) return false; + + // register the class loader for cleanup when unloaded + // built class loaders are never unloaded + ClassLoader loader = fromClass.getClassLoader(); + if (loader != null && + loader != getBuiltinPlatformClassLoader() && + loader != getBuiltinAppClassLoader()) { + CleanerFactory.cleaner().register(loader, + new Unloader(name, handle, isBuiltin)); + } + return true; + } + + static boolean loadLibrary(Class fromClass, String name, boolean isBuiltin) { + ClassLoader loader = + fromClass == null ? null : fromClass.getClassLoader(); + + synchronized (loadedLibraryNames) { + Map libs = + loader != null ? loader.nativeLibraries() : systemNativeLibraries(); + if (libs.containsKey(name)) { + return true; + } + + if (loadedLibraryNames.contains(name)) { + throw new UnsatisfiedLinkError("Native Library " + name + + " already loaded in another classloader"); + } + + /* + * When a library is being loaded, JNI_OnLoad function can cause + * another loadLibrary invocation that should succeed. + * + * We use a static stack to hold the list of libraries we are + * loading because this can happen only when called by the + * same thread because Runtime.load and Runtime.loadLibrary + * are synchronous. + * + * If there is a pending load operation for the library, we + * immediately return success; otherwise, we raise + * UnsatisfiedLinkError. + */ + for (NativeLibrary lib : nativeLibraryContext) { + if (name.equals(lib.name)) { + if (loader == lib.fromClass.getClassLoader()) { + return true; + } else { + throw new UnsatisfiedLinkError("Native Library " + + name + " is being loaded in another classloader"); } } - /* unload the library. */ - ClassLoader.nativeLibraryContext.push(this); + } + NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin); + // load the native library + nativeLibraryContext.push(lib); + try { + if (!lib.load()) return false; + } finally { + nativeLibraryContext.pop(); + } + // register the loaded native library + loadedLibraryNames.add(name); + libs.put(name, lib); + } + return true; + } + + // Invoked in the VM to determine the context class in JNI_OnLoad + // and JNI_OnUnload + static Class getFromClass() { + return nativeLibraryContext.peek().fromClass; + } + + // native libraries being loaded + static Deque nativeLibraryContext = new LinkedList<>(); + + /* + * The run() method will be invoked when this class loader becomes + * phantom reachable to unload the native library. + */ + static class Unloader implements Runnable { + // This represents the context when a native library is unloaded + // and getFromClass() will return null, + static final NativeLibrary UNLOADER = + new NativeLibrary(null, "dummy", false); + final String name; + final long handle; + final boolean isBuiltin; + + Unloader(String name, long handle, boolean isBuiltin) { + if (handle == 0) { + throw new IllegalArgumentException( + "Invalid handle for native library " + name); + } + + this.name = name; + this.handle = handle; + this.isBuiltin = isBuiltin; + } + + @Override + public void run() { + synchronized (loadedLibraryNames) { + /* remove the native library name */ + loadedLibraryNames.remove(name); + nativeLibraryContext.push(UNLOADER); try { - unload(name, isBuiltin); + unload(name, isBuiltin, handle); } finally { - ClassLoader.nativeLibraryContext.pop(); + nativeLibraryContext.pop(); } + } } } - // Invoked in the VM to determine the context class in - // JNI_Load/JNI_Unload - static Class getFromClass() { - return ClassLoader.nativeLibraryContext.peek().fromClass; - } + + // JNI FindClass expects the caller class if invoked from JNI_OnLoad + // and JNI_OnUnload is NativeLibrary class + static native void unload(String name, boolean isBuiltin, long handle); } - // All native library names we've loaded. - private static Vector loadedLibraryNames = new Vector<>(); - - // Native libraries belonging to system classes. - private static Vector systemNativeLibraries - = new Vector<>(); - - // Native libraries associated with the class loader. - private Vector nativeLibraries = new Vector<>(); - - // native libraries being loaded/unloaded. - private static Stack nativeLibraryContext = new Stack<>(); - // The paths searched for libraries private static String usr_paths[]; private static String sys_paths[]; @@ -2455,7 +2544,7 @@ public abstract class ClassLoader { int psCount = 0; if (ClassLoaderHelper.allowsQuotedPathElements && - ldPath.indexOf('\"') >= 0) { + ldPath.indexOf('\"') >= 0) { // First, remove quotes put around quoted parts of paths. // Second, use a quotation mark as a new path separator. // This will preserve any quoted old path separators. @@ -2465,7 +2554,7 @@ public abstract class ClassLoader { char ch = ldPath.charAt(i); if (ch == '\"') { while (++i < ldLen && - (ch = ldPath.charAt(i)) != '\"') { + (ch = ldPath.charAt(i)) != '\"') { buf[bufLen++] = ch; } } else { @@ -2481,7 +2570,7 @@ public abstract class ClassLoader { ps = '\"'; } else { for (int i = ldPath.indexOf(ps); i >= 0; - i = ldPath.indexOf(ps, i + 1)) { + i = ldPath.indexOf(ps, i + 1)) { psCount++; } } @@ -2491,11 +2580,11 @@ public abstract class ClassLoader { for (int j = 0; j < psCount; ++j) { int pathEnd = ldPath.indexOf(ps, pathStart); paths[j] = (pathStart < pathEnd) ? - ldPath.substring(pathStart, pathEnd) : "."; + ldPath.substring(pathStart, pathEnd) : "."; pathStart = pathEnd + 1; } paths[psCount] = (pathStart < ldLen) ? - ldPath.substring(pathStart, ldLen) : "."; + ldPath.substring(pathStart, ldLen) : "."; return paths; } @@ -2520,7 +2609,7 @@ public abstract class ClassLoader { File libfile = new File(libfilename); if (!libfile.isAbsolute()) { throw new UnsatisfiedLinkError( - "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); + "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); } if (loadLibrary0(fromClass, libfile)) { return; @@ -2551,10 +2640,11 @@ public abstract class ClassLoader { } } // Oops, it failed - throw new UnsatisfiedLinkError("no " + name + " in java.library.path"); + throw new UnsatisfiedLinkError("no " + name + + " in java.library.path: " + Arrays.toString(usr_paths)); } - static native String findBuiltinLib(String name); + private static native String findBuiltinLib(String name); private static boolean loadLibrary0(Class fromClass, final File file) { // Check to see if we're attempting to access a static library @@ -2575,85 +2665,72 @@ public abstract class ClassLoader { return false; } } - ClassLoader loader = - (fromClass == null) ? null : fromClass.getClassLoader(); - Vector libs = - loader != null ? loader.nativeLibraries : systemNativeLibraries; - synchronized (libs) { - int size = libs.size(); - for (int i = 0; i < size; i++) { - NativeLibrary lib = libs.elementAt(i); - if (name.equals(lib.name)) { - return true; - } - } - - synchronized (loadedLibraryNames) { - if (loadedLibraryNames.contains(name)) { - throw new UnsatisfiedLinkError - ("Native Library " + - name + - " already loaded in another classloader"); - } - /* If the library is being loaded (must be by the same thread, - * because Runtime.load and Runtime.loadLibrary are - * synchronous). The reason is can occur is that the JNI_OnLoad - * function can cause another loadLibrary invocation. - * - * Thus we can use a static stack to hold the list of libraries - * we are loading. - * - * If there is a pending load operation for the library, we - * immediately return success; otherwise, we raise - * UnsatisfiedLinkError. - */ - int n = nativeLibraryContext.size(); - for (int i = 0; i < n; i++) { - NativeLibrary lib = nativeLibraryContext.elementAt(i); - if (name.equals(lib.name)) { - if (loader == lib.fromClass.getClassLoader()) { - return true; - } else { - throw new UnsatisfiedLinkError - ("Native Library " + - name + - " is being loaded in another classloader"); - } - } - } - NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin); - nativeLibraryContext.push(lib); - try { - lib.load(name, isBuiltin); - } finally { - nativeLibraryContext.pop(); - } - if (lib.loaded) { - loadedLibraryNames.addElement(name); - libs.addElement(lib); - return true; - } - return false; - } - } + return NativeLibrary.loadLibrary(fromClass, name, isBuiltin); } - // Invoked in the VM class linking code. - static long findNative(ClassLoader loader, String name) { - Vector libs = - loader != null ? loader.nativeLibraries : systemNativeLibraries; - synchronized (libs) { - int size = libs.size(); - for (int i = 0; i < size; i++) { - NativeLibrary lib = libs.elementAt(i); - long entry = lib.find(name); - if (entry != 0) - return entry; - } + /* + * Invoked in the VM class linking code. + */ + private static long findNative(ClassLoader loader, String entryName) { + Map libs = + loader != null ? loader.nativeLibraries() : systemNativeLibraries(); + if (libs.isEmpty()) + return 0; + + // the native libraries map may be updated in another thread + // when a native library is being loaded. No symbol will be + // searched from it yet. + for (NativeLibrary lib : libs.values()) { + long entry = lib.findEntry(entryName); + if (entry != 0) return entry; } return 0; } + // All native library names we've loaded. + // This also serves as the lock to obtain nativeLibraries + // and write to nativeLibraryContext. + private static final Set loadedLibraryNames = new HashSet<>(); + + // Native libraries belonging to system classes. + private static volatile Map systemNativeLibraries; + + // Native libraries associated with the class loader. + private volatile Map nativeLibraries; + + /* + * Returns the native libraries map associated with bootstrap class loader + * This method will create the map at the first time when called. + */ + private static Map systemNativeLibraries() { + Map libs = systemNativeLibraries; + if (libs == null) { + synchronized (loadedLibraryNames) { + libs = systemNativeLibraries; + if (libs == null) { + libs = systemNativeLibraries = new ConcurrentHashMap<>(); + } + } + } + return libs; + } + + /* + * Returns the native libraries map associated with this class loader + * This method will create the map at the first time when called. + */ + private Map nativeLibraries() { + Map libs = nativeLibraries; + if (libs == null) { + synchronized (loadedLibraryNames) { + libs = nativeLibraries; + if (libs == null) { + libs = nativeLibraries = new ConcurrentHashMap<>(); + } + } + } + return libs; + } // -- Assertion management -- diff --git a/src/java.base/share/classes/java/lang/Runtime.java b/src/java.base/share/classes/java/lang/Runtime.java index 230d75a412d..dc36b769a07 100644 --- a/src/java.base/share/classes/java/lang/Runtime.java +++ b/src/java.base/share/classes/java/lang/Runtime.java @@ -765,7 +765,9 @@ public class Runtime { * with the VM, then the JNI_OnLoad_L function exported by the library * is invoked rather than attempting to load a dynamic library. * A filename matching the argument does not have to exist in the file - * system. See the JNI Specification for more details. + * system. + * See the JNI Specification + * for more details. * * Otherwise, the filename argument is mapped to a native library image in * an implementation-dependent manner. @@ -818,7 +820,8 @@ public class Runtime { * specific prefix, file extension or path. If a native library * called {@code libname} is statically linked with the VM, then the * JNI_OnLoad_{@code libname} function exported by the library is invoked. - * See the JNI Specification for more details. + * See the JNI Specification + * for more details. * * Otherwise, the libname argument is loaded from a system library * location and mapped to a native library image in an implementation- diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 86ec3c5cad3..d2a8f71b86c 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -1799,7 +1799,8 @@ public final class System { * is invoked rather than attempting to load a dynamic library. * A filename matching the argument does not have to exist in the * file system. - * See the JNI Specification for more details. + * See the JNI Specification + * for more details. * * Otherwise, the filename argument is mapped to a native library image in * an implementation-dependent manner. @@ -1835,7 +1836,8 @@ public final class System { * specific prefix, file extension or path. If a native library * called libname is statically linked with the VM, then the * JNI_OnLoad_libname function exported by the library is invoked. - * See the JNI Specification for more details. + * See the JNI Specification + * for more details. * * Otherwise, the libname argument is loaded from a system library * location and mapped to a native library image in an implementation- diff --git a/src/java.base/share/native/libjava/ClassLoader.c b/src/java.base/share/native/libjava/ClassLoader.c index f3803805c59..b3d2ef109de 100644 --- a/src/java.base/share/native/libjava/ClassLoader.c +++ b/src/java.base/share/native/libjava/ClassLoader.c @@ -260,7 +260,6 @@ Java_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader, static jfieldID handleID; static jfieldID jniVersionID; -static jfieldID loadedID; static void *procHandle; static jboolean initIDs(JNIEnv *env) @@ -276,9 +275,6 @@ static jboolean initIDs(JNIEnv *env) jniVersionID = (*env)->GetFieldID(env, this, "jniVersion", "I"); if (jniVersionID == 0) return JNI_FALSE; - loadedID = (*env)->GetFieldID(env, this, "loaded", "Z"); - if (loadedID == 0) - return JNI_FALSE; procHandle = getProcessHandle(); } return JNI_TRUE; @@ -335,30 +331,31 @@ static void *findJniFunction(JNIEnv *env, void *handle, /* * Class: java_lang_ClassLoader_NativeLibrary - * Method: load - * Signature: (Ljava/lang/String;Z)V + * Method: load0 + * Signature: (Ljava/lang/String;Z)Z */ -JNIEXPORT void JNICALL -Java_java_lang_ClassLoader_00024NativeLibrary_load +JNIEXPORT jboolean JNICALL +Java_java_lang_ClassLoader_00024NativeLibrary_load0 (JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) { const char *cname; jint jniVersion; jthrowable cause; void * handle; + jboolean loaded = JNI_FALSE; if (!initIDs(env)) - return; + return JNI_FALSE; cname = JNU_GetStringPlatformChars(env, name, 0); if (cname == 0) - return; + return JNI_FALSE; handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname); if (handle) { JNI_OnLoad_t JNI_OnLoad; JNI_OnLoad = (JNI_OnLoad_t)findJniFunction(env, handle, - isBuiltin ? cname : NULL, - JNI_TRUE); + isBuiltin ? cname : NULL, + JNI_TRUE); if (JNI_OnLoad) { JavaVM *jvm; (*env)->GetJavaVM(env, &jvm); @@ -400,20 +397,21 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load goto done; } (*env)->SetLongField(env, this, handleID, ptr_to_jlong(handle)); - (*env)->SetBooleanField(env, this, loadedID, JNI_TRUE); + loaded = JNI_TRUE; done: JNU_ReleaseStringPlatformChars(env, name, cname); + return loaded; } /* * Class: java_lang_ClassLoader_NativeLibrary * Method: unload - * Signature: (Z)V + * Signature: (Ljava/lang/String;ZJ)V */ JNIEXPORT void JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_unload -(JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) +(JNIEnv *env, jclass cls, jstring name, jboolean isBuiltin, jlong address) { const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; void *handle; @@ -426,10 +424,10 @@ Java_java_lang_ClassLoader_00024NativeLibrary_unload if (cname == NULL) { return; } - handle = jlong_to_ptr((*env)->GetLongField(env, this, handleID)); + handle = jlong_to_ptr(address); JNI_OnUnload = (JNI_OnUnload_t )findJniFunction(env, handle, - isBuiltin ? cname : NULL, - JNI_FALSE); + isBuiltin ? cname : NULL, + JNI_FALSE); if (JNI_OnUnload) { JavaVM *jvm; (*env)->GetJavaVM(env, &jvm); @@ -443,11 +441,11 @@ Java_java_lang_ClassLoader_00024NativeLibrary_unload /* * Class: java_lang_ClassLoader_NativeLibrary - * Method: find + * Method: findEntry * Signature: (Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL -Java_java_lang_ClassLoader_00024NativeLibrary_find +Java_java_lang_ClassLoader_00024NativeLibrary_findEntry (JNIEnv *env, jobject this, jstring name) { jlong handle; diff --git a/test/jdk/java/lang/ClassLoader/nativeLibrary/NativeLibraryTest.java b/test/jdk/java/lang/ClassLoader/nativeLibrary/NativeLibraryTest.java new file mode 100644 index 00000000000..488cec23612 --- /dev/null +++ b/test/jdk/java/lang/ClassLoader/nativeLibrary/NativeLibraryTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8164512 + * @summary verify if the native library is unloaded when the class loader is GC'ed + * @build p.Test + * @run main/othervm/native -Xcheck:jni NativeLibraryTest + */ + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class NativeLibraryTest { + static final Path CLASSES = Paths.get("classes"); + static int unloadedCount = 0; + + /* + * Called by JNI_OnUnload when the native library is unloaded + */ + static void nativeLibraryUnloaded() { + unloadedCount++; + } + + public static void main(String... args) throws Exception { + setup(); + + for (int count=1; count <= 5; count++) { + // create a class loader and load a native library + runTest(); + // unloading the class loader and native library + System.gc(); + // give Cleaner thread a chance to unload the native library + Thread.sleep(100); + + // unloadedCount is incremented when the native library is unloaded + if (count != unloadedCount) { + throw new RuntimeException("Expected unloaded=" + count + + " but got=" + unloadedCount); + } + } + } + + /* + * Loads p.Test class with a new class loader and its static initializer + * will load a native library. + * + * The class loader becomes unreachable when this method returns and + * the native library should be unloaded at some point after the class + * loader is garbage collected. + */ + static void runTest() throws Exception { + // invoke p.Test.run() that loads the native library + Runnable r = newTestRunnable(); + r.run(); + + // reload the native library by the same class loader + r.run(); + + // load the native library by another class loader + Runnable r1 = newTestRunnable(); + try { + r1.run(); + throw new RuntimeException("should fail to load the native library" + + " by another class loader"); + } catch (UnsatisfiedLinkError e) {} + } + + /* + * Loads p.Test class with a new class loader and returns + * a Runnable instance. + */ + static Runnable newTestRunnable() throws Exception { + TestLoader loader = new TestLoader(); + Class c = Class.forName("p.Test", true, loader); + return (Runnable) c.newInstance(); + } + + static class TestLoader extends URLClassLoader { + static URL[] toURLs() { + try { + return new URL[] { CLASSES.toUri().toURL() }; + } catch (MalformedURLException e) { + throw new Error(e); + } + } + + TestLoader() { + super("testloader", toURLs(), ClassLoader.getSystemClassLoader()); + } + } + + /* + * move p/Test.class out from classpath to the scratch directory + */ + static void setup() throws IOException { + String dir = System.getProperty("test.classes", "."); + Path file = Paths.get("p", "Test.class"); + Files.createDirectories(CLASSES.resolve("p")); + Files.move(Paths.get(dir).resolve(file), + CLASSES.resolve("p").resolve("Test.class")); + } +} diff --git a/test/jdk/java/lang/ClassLoader/nativeLibrary/libnativeLibraryTest.c b/test/jdk/java/lang/ClassLoader/nativeLibrary/libnativeLibraryTest.c new file mode 100644 index 00000000000..fd469e7245a --- /dev/null +++ b/test/jdk/java/lang/ClassLoader/nativeLibrary/libnativeLibraryTest.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include + +#include "jni.h" +#include "jni_util.h" + +static jint count = 0; +static jclass test_class; +static jint current_jni_version = JNI_VERSION_10; + +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved) { + JNIEnv *env; + jclass cl; + + (*vm)->GetEnv(vm, (void **) &env, current_jni_version); + + cl = (*env)->FindClass(env, "NativeLibraryTest"); + test_class = (*env)->NewGlobalRef(env, cl); + + // increment the count when JNI_OnLoad is called + count++; + + return current_jni_version; +} + +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved) { + JNIEnv *env; + jmethodID mid; + jclass cl; + + (*vm)->GetEnv(vm, (void **) &env, current_jni_version); + mid = (*env)->GetStaticMethodID(env, test_class, "nativeLibraryUnloaded", "()V"); + (*env)->CallStaticVoidMethod(env, test_class, mid); + if ((*env)->ExceptionCheck(env)) { + (*env)->ExceptionDescribe(env); + (*env)->FatalError(env, "Exception thrown"); + } + + cl = (*env)->FindClass(env, "p/Test"); + if (cl != NULL) { + (*env)->FatalError(env, "p/Test class should not be found"); + } +} + +JNIEXPORT jint JNICALL +Java_p_Test_count +(JNIEnv *env, jclass cls) { + return count; +} diff --git a/test/jdk/java/lang/ClassLoader/nativeLibrary/p/Test.java b/test/jdk/java/lang/ClassLoader/nativeLibrary/p/Test.java new file mode 100644 index 00000000000..b9612ff6484 --- /dev/null +++ b/test/jdk/java/lang/ClassLoader/nativeLibrary/p/Test.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package p; + +public class Test implements Runnable { + public static native int count(); + + /** + * Tests if the native library is loaded. + */ + public void run() { + System.loadLibrary("nativeLibraryTest"); + if (count() != 1) { + throw new RuntimeException("Expected count = 1 but got " + count()); + } + } +} From 018138a79c7b36f0ba19783fbcdb54cdc967b4a1 Mon Sep 17 00:00:00 2001 From: Priya Lakshmi Muthuswamy Date: Tue, 7 Nov 2017 12:18:29 +0100 Subject: [PATCH 03/10] 8186807: JSObject gets ScriptFunction when ScriptObjectMirror is expected Reviewed-by: sundar, hannesw --- .../internal/objects/NativeFunction.java | 8 +- .../runtime/test/JDK_8186807_Test.java | 76 +++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 test/nashorn/src/jdk/nashorn/internal/runtime/test/JDK_8186807_Test.java diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFunction.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFunction.java index 3b797947ffa..61df4e4abb5 100644 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFunction.java +++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFunction.java @@ -35,6 +35,7 @@ import java.lang.invoke.MethodHandles; import java.util.List; import jdk.dynalink.linker.support.Lookup; import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; @@ -101,8 +102,13 @@ public final class NativeFunction { if (self instanceof ScriptFunction) { return ScriptRuntime.apply((ScriptFunction)self, thiz, args); - } else if (self instanceof JSObject) { + } else if (self instanceof ScriptObjectMirror) { return ((JSObject)self).call(thiz, args); + } else if (self instanceof JSObject) { + final Global global = Global.instance(); + final Object result = ((JSObject) self).call(ScriptObjectMirror.wrap(thiz, global), + ScriptObjectMirror.wrapArray(args, global)); + return ScriptObjectMirror.unwrap(result, global); } throw new AssertionError("Should not reach here"); } diff --git a/test/nashorn/src/jdk/nashorn/internal/runtime/test/JDK_8186807_Test.java b/test/nashorn/src/jdk/nashorn/internal/runtime/test/JDK_8186807_Test.java new file mode 100644 index 00000000000..1f0336d4788 --- /dev/null +++ b/test/nashorn/src/jdk/nashorn/internal/runtime/test/JDK_8186807_Test.java @@ -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 jdk.nashorn.internal.runtime.test; + +import jdk.nashorn.api.scripting.AbstractJSObject; +import jdk.nashorn.api.scripting.NashornScriptEngine; +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import jdk.nashorn.api.scripting.ScriptObjectMirror; +import static org.testng.Assert.assertEquals; +import org.testng.annotations.Test; +import javax.script.ScriptException; + + +/** + * @test + * @bug 8186807 + * @summary JSObject gets ScriptFunction when ScriptObjectMirror is expected + * @modules jdk.scripting.nashorn/jdk.nashorn.internal.runtime + * @run testng/othervm -Dnashorn.unstable.relink.threshold=1 jdk.nashorn.internal.runtime.test.JDK_8186807_Test + */ + +public class JDK_8186807_Test { + + @Test + public void testScript() throws ScriptException { + NashornScriptEngine engine = (NashornScriptEngine) new NashornScriptEngineFactory().getScriptEngine(); + engine.put("a", new Func()); + engine.eval("var Assert = Java.type('org.testng.Assert')\n" + + "var fn=function() {return 2;}\n" + + "var arr = [ a, fn, a ];\n" + + "var result;\n" + + "for (i in arr) {\n" + + " result = Function.prototype.apply.apply(arr[i],[null,[fn]]);\n" + + " if(i==0 || i==2)\n" + + " Assert.assertTrue(result==1);\n" + + " if(i==1)\n" + + " Assert.assertTrue(result==2);\n" + + "}"); + } + + static class Func extends AbstractJSObject { + @Override + public boolean isFunction() { + return true; + } + + @Override + public Object call(Object thiz, Object... args) { + assertEquals(args[0].getClass(), ScriptObjectMirror.class); + return 1; + } + } +} From c5c047de472672b5a5c91a95a1c5ad21a4a86418 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 7 Nov 2017 17:08:59 +0000 Subject: [PATCH 04/10] 8190482: InnocuousThread creation should not require the caller to possess enableContextClassLoaderOverride Reviewed-by: rriggs, mchung --- .../jdk/internal/misc/InnocuousThread.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java b/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java index 056350f25c3..e62a0321a7f 100644 --- a/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java +++ b/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java @@ -62,10 +62,16 @@ public final class InnocuousThread extends Thread { * set to the system class loader. */ public static Thread newThread(String name, Runnable target) { - return new InnocuousThread(INNOCUOUSTHREADGROUP, - target, - name, - ClassLoader.getSystemClassLoader()); + return AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Thread run() { + return new InnocuousThread(INNOCUOUSTHREADGROUP, + target, + name, + ClassLoader.getSystemClassLoader()); + } + }); } /** @@ -80,8 +86,14 @@ public final class InnocuousThread extends Thread { * Returns a new InnocuousThread with null context class loader. */ public static Thread newSystemThread(String name, Runnable target) { - return new InnocuousThread(INNOCUOUSTHREADGROUP, - target, name, null); + return AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Thread run() { + return new InnocuousThread(INNOCUOUSTHREADGROUP, + target, name, null); + } + }); } private InnocuousThread(ThreadGroup group, Runnable target, String name, ClassLoader tccl) { From 6a099cc68bf16ab88b0e7f08f820d9959daff737 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Tue, 7 Nov 2017 10:02:48 -0800 Subject: [PATCH 05/10] 8190816: PropertiesTest.sh fails to make $WRITABLEJDK writable Reviewed-by: naoto, rgoel --- test/jdk/java/util/Currency/PropertiesTest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/util/Currency/PropertiesTest.sh b/test/jdk/java/util/Currency/PropertiesTest.sh index 215be9229ae..2056d76f53d 100644 --- a/test/jdk/java/util/Currency/PropertiesTest.sh +++ b/test/jdk/java/util/Currency/PropertiesTest.sh @@ -104,7 +104,7 @@ run PropertiesTest -c dump1 dump2 ${PROPS} WRITABLEJDK=.${FS}testjava cp -H -R $TESTJAVA $WRITABLEJDK || exit 1 PROPLOCATION=${WRITABLEJDK}${FS}lib -chmod -R a+rx $WRITABLEJDK || exit 1 +chmod -R u+w $WRITABLEJDK || exit 1 cp ${PROPS} $PROPLOCATION || exit 1 echo "Properties location: ${PROPLOCATION}" From ec403d47b4c05d7c645e5578024a77425533d837 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Tue, 7 Nov 2017 10:35:58 -0800 Subject: [PATCH 06/10] 8190814: javax/imageio/stream/NullStreamCheckTest writes to the repo Reviewed-by: pnarayanan, jdv, prr --- .../imageio/stream/NullStreamCheckTest.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/test/jdk/javax/imageio/stream/NullStreamCheckTest.java b/test/jdk/javax/imageio/stream/NullStreamCheckTest.java index f763b9de1e6..88aef56dfb8 100644 --- a/test/jdk/javax/imageio/stream/NullStreamCheckTest.java +++ b/test/jdk/javax/imageio/stream/NullStreamCheckTest.java @@ -58,17 +58,6 @@ public class NullStreamCheckTest { static BufferedImage inputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - // creates test file needed for read and write in local directory. - private static File createTestFile(String name) throws IOException { - String sep = System.getProperty("file.separator"); - String dir = System.getProperty("test.src", "."); - String filePath = dir+sep; - File directory = new File(filePath); - File tmpTestFile = File.createTempFile(name, ".png", directory); - directory.delete(); - return tmpTestFile; - } - /* if we catch expected IOException message return * false otherwise return true. */ @@ -86,7 +75,7 @@ public class NullStreamCheckTest { } private static void verifyFileWrite() throws IOException { - File outputTestFile = createTestFile("outputTestFile"); + File outputTestFile = File.createTempFile("outputTestFile", ".png"); try { ImageIO.write(inputImage, "png", outputTestFile); } catch (IOException ex) { @@ -113,7 +102,7 @@ public class NullStreamCheckTest { } private static void verifyFileRead() throws IOException { - File inputTestFile = createTestFile("inputTestFile"); + File inputTestFile = File.createTempFile("inputTestFile", ".png"); try { ImageIO.read(inputTestFile); } catch (IOException ex) { @@ -141,7 +130,7 @@ public class NullStreamCheckTest { private static void verifyUrlRead() throws IOException { URL url; - File inputTestUrlFile = createTestFile("inputTestFile"); + File inputTestUrlFile = File.createTempFile("inputTestFile", ".png"); try { try { url = inputTestUrlFile.toURI().toURL(); From 2564212f92b6b4f9ec9ab44fa329fd1bdf39cff0 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Tue, 7 Nov 2017 16:19:55 -0800 Subject: [PATCH 07/10] 8181151: Fix lint warnings in JAXP repo: cast Reviewed-by: lancea, rriggs --- .../java_cup/internal/runtime/lr_parser.java | 2 +- .../xalan/internal/lib/ExsltDatetime.java | 6 +- .../internal/xsltc/compiler/AttributeSet.java | 6 +- .../internal/xsltc/compiler/BinOpExpr.java | 6 +- .../internal/xsltc/compiler/FilterExpr.java | 4 +- .../xsltc/compiler/FunctionAvailableCall.java | 4 +- .../internal/xsltc/compiler/FunctionCall.java | 8 +- .../internal/xsltc/compiler/LogicalExpr.java | 6 +- .../internal/xsltc/compiler/Message.java | 4 +- .../xalan/internal/xsltc/compiler/Mode.java | 12 +- .../xalan/internal/xsltc/compiler/Number.java | 4 +- .../xalan/internal/xsltc/compiler/Parser.java | 6 +- .../xalan/internal/xsltc/compiler/Sort.java | 8 +- .../xsltc/compiler/SyntaxTreeNode.java | 5 +- .../internal/xsltc/compiler/TestSeq.java | 4 +- .../xsltc/compiler/UnionPathExpr.java | 4 +- .../internal/xsltc/compiler/XPathParser.java | 266 +++++++++--------- .../xsltc/compiler/util/MethodGenerator.java | 19 +- .../xalan/internal/xsltc/trax/SAX2DOM.java | 4 +- .../xsltc/trax/SAX2StAXEventWriter.java | 5 +- .../internal/xsltc/trax/TemplatesImpl.java | 4 +- .../xsltc/trax/TransformerFactoryImpl.java | 6 +- .../internal/xsltc/trax/TransformerImpl.java | 4 +- .../internal/xsltc/trax/XSLTCSource.java | 4 +- .../xerces/internal/dom/CoreDocumentImpl.java | 4 +- .../xerces/internal/dom/DOMNormalizer.java | 4 +- .../internal/dom/DOMStringListImpl.java | 4 +- .../xerces/internal/dom/DocumentImpl.java | 4 +- .../internal/impl/XMLDTDScannerImpl.java | 10 +- .../internal/impl/XMLErrorReporter.java | 7 +- .../internal/impl/XMLNamespaceBinder.java | 8 +- .../xerces/internal/impl/XMLScanner.java | 6 +- .../internal/impl/dtd/XMLDTDLoader.java | 8 +- .../internal/impl/dtd/XMLDTDProcessor.java | 6 +- .../internal/impl/dtd/XMLDTDValidator.java | 6 +- .../xerces/internal/impl/dv/util/Base64.java | 8 +- .../internal/impl/dv/xs/BaseDVFactory.java | 6 +- .../dv/xs/ExtendedSchemaDVFactoryImpl.java | 6 +- .../internal/impl/dv/xs/FullDVFactory.java | 6 +- .../impl/dv/xs/SchemaDVFactoryImpl.java | 6 +- .../internal/impl/dv/xs/XSSimpleTypeDecl.java | 14 +- .../internal/impl/xs/AttributePSVImpl.java | 4 +- .../internal/impl/xs/ElementPSVImpl.java | 4 +- .../impl/xs/SubstitutionGroupHandler.java | 6 +- .../internal/impl/xs/XMLSchemaValidator.java | 13 +- .../internal/impl/xs/XSComplexTypeDecl.java | 6 +- .../internal/impl/xs/XSConstraints.java | 29 +- .../internal/impl/xs/XSGrammarBucket.java | 6 +- .../internal/impl/xs/models/CMBuilder.java | 5 +- .../xs/traversers/XSAttributeChecker.java | 6 +- .../impl/xs/traversers/XSDHandler.java | 16 +- .../xs/traversers/XSDSimpleTypeTraverser.java | 6 +- .../traversers/XSDUniqueOrKeyTraverser.java | 8 +- .../internal/impl/xs/util/XSGrammarPool.java | 4 +- .../jaxp/validation/SimpleXMLSchema.java | 6 +- .../validation/SoftReferenceGrammarPool.java | 8 +- .../internal/parsers/AbstractDOMParser.java | 8 +- .../util/DOMEntityResolverWrapper.java | 6 +- .../xerces/internal/util/SymbolHash.java | 6 +- .../internal/xinclude/XIncludeHandler.java | 20 +- .../internal/dtm/ref/DTMManagerDefault.java | 6 +- .../xml/internal/dtm/ref/DTMNodeList.java | 6 +- .../xml/internal/dtm/ref/DTMNodeProxy.java | 4 +- .../serialize/BaseMarkupSerializer.java | 4 +- .../serializer/NamespaceMappings.java | 6 +- .../xml/internal/serializer/ToStream.java | 9 +- .../org/apache/xpath/internal/NodeSet.java | 10 +- .../apache/xpath/internal/VariableStack.java | 8 +- .../xpath/internal/axes/LocPathIterator.java | 6 +- .../apache/xpath/internal/compiler/Lexer.java | 11 +- .../apache/xpath/internal/compiler/OpMap.java | 6 +- .../internal/jaxp/JAXPExtensionsProvider.java | 6 +- .../javax/xml/xpath/XPathException.java | 4 +- .../bootstrap/DOMImplementationRegistry.java | 9 +- .../org/xml/sax/helpers/NamespaceSupport.java | 8 +- 75 files changed, 385 insertions(+), 399 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java b/src/java.xml/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java index 98f7bbbe41d..e0ceedac972 100644 --- a/src/java.xml/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java +++ b/src/java.xml/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java @@ -946,7 +946,7 @@ public abstract class lr_parser { if (debug) debug_message("# Pop stack by one, state was # " + (stack.peek()).parse_state); - left_pos = ((Symbol)stack.pop()).left; + left_pos = stack.pop().left; tos--; /* if we have hit bottom, we fail */ diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/lib/ExsltDatetime.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/lib/ExsltDatetime.java index 479f152813c..4e8f766f0a1 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/lib/ExsltDatetime.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/lib/ExsltDatetime.java @@ -1,6 +1,6 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * @LastModified: Nov 2017 */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -616,7 +616,7 @@ public class ExsltDatetime public static boolean leapYear() { Calendar cal = Calendar.getInstance(); - int yr = (int)cal.get(Calendar.YEAR); + int yr = cal.get(Calendar.YEAR); return (yr % 400 == 0 || (yr % 100 != 0 && yr % 4 == 0)); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/AttributeSet.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/AttributeSet.java index 43eef701616..6812385191f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/AttributeSet.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/AttributeSet.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. - * @LastModified: Oct 2017 + * @LastModified: Nov 2017 */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -115,7 +115,7 @@ final class AttributeSet extends TopLevelElement { final List contents = getContents(); final int count = contents.size(); for (int i=0; i attributes = elements(); while (attributes.hasNext()) { - SyntaxTreeNode element = (SyntaxTreeNode)attributes.next(); + SyntaxTreeNode element = attributes.next(); if (element instanceof XslAttribute) { final XslAttribute attribute = (XslAttribute)element; attribute.translate(classGen, methodGen); diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/BinOpExpr.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/BinOpExpr.java index 20f7310a363..b61c668b31f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/BinOpExpr.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/BinOpExpr.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * @LastModified: Oct 2017 + * @LastModified: Nov 2017 */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -83,11 +83,11 @@ final class BinOpExpr extends Expression { new MethodType(Type.Void, tleft, tright)); if (ptype != null) { - final Type arg1 = (Type) ptype.argsType().get(0); + final Type arg1 = ptype.argsType().get(0); if (!arg1.identicalTo(tleft)) { _left = new CastExpr(_left, arg1); } - final Type arg2 = (Type) ptype.argsType().get(1); + final Type arg2 = ptype.argsType().get(1); if (!arg2.identicalTo(tright)) { _right = new CastExpr(_right, arg1); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterExpr.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterExpr.java index 77462ab101a..92e83abbb57 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterExpr.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterExpr.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * @LastModified: Oct 2017 + * @LastModified: Nov 2017 */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -75,7 +75,7 @@ class FilterExpr extends Expression { if (_predicates != null) { final int n = _predicates.size(); for (int i = 0; i < n; i++) { - final Expression exp = (Expression)_predicates.get(i); + final Expression exp = _predicates.get(i); exp.setParser(parser); exp.setParent(this); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java index 8c5ea0d8a1a..bcee236a83c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * @LastModified: Oct 2017 + * @LastModified: Nov 2017 */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -53,7 +53,7 @@ final class FunctionAvailableCall extends FunctionCall { */ public FunctionAvailableCall(QName fname, List arguments) { super(fname, arguments); - _arg = (Expression)arguments.get(0); + _arg = arguments.get(0); _type = null; if (_arg instanceof LiteralExpr) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java index 3e88bdfb51e..ade55416067 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. - * @LastModified: Oct 2017 + * @LastModified: Nov 2017 */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -443,7 +443,7 @@ class FunctionCall extends Expression { if (ptype != null) { for (int i = 0; i < n; i++) { - final Type argType = (Type) ptype.argsType().get(i); + final Type argType = ptype.argsType().get(i); final Expression exp = _arguments.get(i); if (!argType.identicalTo(exp.getType())) { try { @@ -557,7 +557,7 @@ class FunctionCall extends Expression { hasThisArgument = true; Expression firstArg = _arguments.get(0); - Type firstArgType = (Type)firstArg.typeCheck(stable); + Type firstArgType = firstArg.typeCheck(stable); if (_namespace_format == NAMESPACE_FORMAT_CLASS && firstArgType instanceof ObjectType @@ -608,7 +608,7 @@ class FunctionCall extends Expression { _type = null; // reset internal type for (int j, i = 0; i < nMethods; i++) { // Check if all paramteters to this method can be converted - final Method method = (Method)methods.get(i); + final Method method = methods.get(i); final Class[] paramTypes = method.getParameterTypes(); int currMethodDistance = 0; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/LogicalExpr.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/LogicalExpr.java index 56868aec957..27d9f3ae297 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/LogicalExpr.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/LogicalExpr.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * @LastModified: Oct 2017 + * @LastModified: Nov 2017 */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -137,11 +137,11 @@ final class LogicalExpr extends Expression { // Yes, the operation is supported if (haveType != null) { // Check if left-hand side operand must be type casted - Type arg1 = (Type)haveType.argsType().get(0); + Type arg1 = haveType.argsType().get(0); if (!arg1.identicalTo(tleft)) _left = new CastExpr(_left, arg1); // Check if right-hand side operand must be type casted - Type arg2 = (Type) haveType.argsType().get(1); + Type arg2 = haveType.argsType().get(1); if (!arg2.identicalTo(tright)) _right = new CastExpr(_right, arg1); // Return the result type for the operator we will use diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java index 71dc212dc40..4b578abee91 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * @LastModified: Oct 2017 + * @LastModified: Nov 2017 */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -67,7 +67,7 @@ final class Message extends Instruction { il.append(new PUSH(cpg, "")); break; case 1: - SyntaxTreeNode child = (SyntaxTreeNode) elementAt(0); + SyntaxTreeNode child = elementAt(0); if (child instanceof Text) { il.append(new PUSH(cpg, ((Text) child).getText())); break; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Mode.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Mode.java index 48c1efcb290..b6363668a0f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Mode.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Mode.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. - * @LastModified: Oct 2017 + * @LastModified: Nov 2017 */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -229,12 +229,12 @@ final class Mode implements Constants { } private int partition(List