# HG changeset patch # User lana # Date 1462475469 0 # Node ID 41844efbbcce4cc3ff63ae882c6a40104c1f9041 # Parent 5c95f33249167bf4bc63f8e50c8affbb6df4ce42# Parent dd626e6f59677eb64f959c32195436ec3c81c038 Merge diff -r 5c95f3324916 -r 41844efbbcce jdk/make/Tools.gmk --- a/jdk/make/Tools.gmk Thu May 05 17:35:48 2016 +0000 +++ b/jdk/make/Tools.gmk Thu May 05 19:11:09 2016 +0000 @@ -96,7 +96,13 @@ TOOL_SPP = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes build.tools.spp.Spp # Nimbus is used somewhere in the swing build. + +ifeq ($(BOOT_JDK_MODULAR), true) + COMPILENIMBUS_ADD_MODS := -addmods java.xml.bind +endif + TOOL_GENERATENIMBUS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ + $(COMPILENIMBUS_ADD_MODS) \ build.tools.generatenimbus.Generator TOOL_WRAPPERGENERATOR = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ diff -r 5c95f3324916 -r 41844efbbcce jdk/make/gendata/GendataBreakIterator.gmk --- a/jdk/make/gendata/GendataBreakIterator.gmk Thu May 05 17:35:48 2016 +0000 +++ b/jdk/make/gendata/GendataBreakIterator.gmk Thu May 05 19:11:09 2016 +0000 @@ -62,10 +62,13 @@ BIN := $(BREAK_ITERATOR_CLASSES)/jdk.localedata)) ifeq ($(BOOT_JDK_MODULAR), true) - BREAK_ITERATOR_BOOTCLASSPATH := -Xpatch:$(BREAK_ITERATOR_CLASSES) \ - -XaddExports:java.base/sun.text=ALL-UNNAMED \ - -XaddExports:java.base/sun.text.resources=ALL-UNNAMED \ - -XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED + BREAK_ITERATOR_BOOTCLASSPATH := \ + -Xpatch:java.base=$(BREAK_ITERATOR_CLASSES)/java.base \ + -Xpatch:jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \ + -XaddExports:java.base/sun.text=ALL-UNNAMED \ + -XaddExports:java.base/sun.text.resources=ALL-UNNAMED \ + -XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \ + # else BREAK_ITERATOR_BOOTCLASSPATH := -Xbootclasspath/p:$(call PathList, \ $(BREAK_ITERATOR_CLASSES)/java.base \ diff -r 5c95f3324916 -r 41844efbbcce jdk/make/launcher/Launcher-java.desktop.gmk --- a/jdk/make/launcher/Launcher-java.desktop.gmk Thu May 05 17:35:48 2016 +0000 +++ b/jdk/make/launcher/Launcher-java.desktop.gmk Thu May 05 19:11:09 2016 +0000 @@ -31,7 +31,7 @@ ifndef BUILD_HEADLESS_ONLY $(eval $(call SetupBuildLauncher, appletviewer, \ MAIN_CLASS := sun.applet.Main, \ - JAVA_ARGS := -addmods ALL-SYSTEM, \ + JAVA_ARGS := -addmods ALL-DEFAULT, \ LIBS_unix := $(X_LIBS), \ )) endif diff -r 5c95f3324916 -r 41844efbbcce jdk/make/launcher/Launcher-java.scripting.gmk --- a/jdk/make/launcher/Launcher-java.scripting.gmk Thu May 05 17:35:48 2016 +0000 +++ b/jdk/make/launcher/Launcher-java.scripting.gmk Thu May 05 19:11:09 2016 +0000 @@ -27,4 +27,5 @@ $(eval $(call SetupBuildLauncher, jrunscript, \ MAIN_CLASS := com.sun.tools.script.shell.Main, \ + JAVA_ARGS := -addmods ALL-DEFAULT, \ )) diff -r 5c95f3324916 -r 41844efbbcce jdk/make/launcher/Launcher-jdk.compiler.gmk --- a/jdk/make/launcher/Launcher-jdk.compiler.gmk Thu May 05 17:35:48 2016 +0000 +++ b/jdk/make/launcher/Launcher-jdk.compiler.gmk Thu May 05 19:11:09 2016 +0000 @@ -27,7 +27,8 @@ $(eval $(call SetupBuildLauncher, javac, \ MAIN_CLASS := com.sun.tools.javac.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ + JAVA_ARGS := -addmods ALL-DEFAULT, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ )) diff -r 5c95f3324916 -r 41844efbbcce jdk/make/launcher/Launcher-jdk.javadoc.gmk --- a/jdk/make/launcher/Launcher-jdk.javadoc.gmk Thu May 05 17:35:48 2016 +0000 +++ b/jdk/make/launcher/Launcher-jdk.javadoc.gmk Thu May 05 19:11:09 2016 +0000 @@ -27,6 +27,7 @@ $(eval $(call SetupBuildLauncher, javadoc, \ MAIN_CLASS := jdk.javadoc.internal.tool.Main, \ + JAVA_ARGS := -addmods ALL-DEFAULT, \ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ )) diff -r 5c95f3324916 -r 41844efbbcce jdk/make/launcher/Launcher-jdk.jlink.gmk --- a/jdk/make/launcher/Launcher-jdk.jlink.gmk Thu May 05 17:35:48 2016 +0000 +++ b/jdk/make/launcher/Launcher-jdk.jlink.gmk Thu May 05 19:11:09 2016 +0000 @@ -32,6 +32,7 @@ $(eval $(call SetupBuildLauncher, jlink,\ MAIN_CLASS := jdk.tools.jlink.internal.Main, \ + JAVA_ARGS := -addmods ALL-DEFAULT, \ CFLAGS := -DENABLE_ARG_FILES \ -DEXPAND_CLASSPATH_WILDCARDS \ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ diff -r 5c95f3324916 -r 41844efbbcce jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk --- a/jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk Thu May 05 17:35:48 2016 +0000 +++ b/jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk Thu May 05 19:11:09 2016 +0000 @@ -27,6 +27,6 @@ $(eval $(call SetupBuildLauncher, jjs, \ MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \ - JAVA_ARGS := -addmods ALL-SYSTEM, \ + JAVA_ARGS := -addmods ALL-DEFAULT, \ CFLAGS := -DENABLE_ARG_FILES, \ )) diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java --- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java Thu May 05 19:11:09 2016 +0000 @@ -102,7 +102,7 @@ @Override FileTypeDetector getFileTypeDetector() { - String userHome = GetPropertyAction.getProperty("user.home"); + String userHome = GetPropertyAction.privilegedGetProperty("user.home"); Path userMimeTypes = Paths.get(userHome, ".mime.types"); Path etcMimeTypes = Paths.get("/etc/mime.types"); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c --- a/jdk/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -53,7 +53,7 @@ start = t.tv_sec * 1000 + t.tv_usec / 1000; for (;;) { - int res = epoll_wait(epfd, events, numfds, timeout); + int res = epoll_wait(epfd, events, numfds, remaining); if (res < 0 && errno == EINTR) { if (remaining >= 0) { gettimeofday(&t, NULL); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java --- a/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Thu May 05 19:11:09 2016 +0000 @@ -84,7 +84,8 @@ static { IOUtil.load(); initStructSizes(); - String datamodel = GetPropertyAction.getProperty("sun.arch.data.model"); + String datamodel = + GetPropertyAction.privilegedGetProperty("sun.arch.data.model"); is64bit = "64".equals(datamodel); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java --- a/jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java Thu May 05 19:11:09 2016 +0000 @@ -29,8 +29,6 @@ import java.io.IOException; import java.util.*; import java.util.regex.Pattern; -import java.security.AccessController; -import sun.security.action.GetPropertyAction; import static sun.nio.fs.MacOSXNativeDispatcher.*; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java --- a/jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java Thu May 05 19:11:09 2016 +0000 @@ -46,8 +46,8 @@ @Override FileTypeDetector getFileTypeDetector() { - Path userMimeTypes = Paths.get( - GetPropertyAction.getProperty("user.home"), ".mime.types"); + Path userMimeTypes = Paths.get(GetPropertyAction + .privilegedGetProperty("user.home"), ".mime.types"); return chain(new MimeTypesFileTypeDetector(userMimeTypes), new UTIFileTypeDetector()); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/io/File.java --- a/jdk/src/java.base/share/classes/java/io/File.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/io/File.java Thu May 05 19:11:09 2016 +0000 @@ -1896,7 +1896,7 @@ // temporary directory location private static final File tmpdir = new File( - GetPropertyAction.getProperty("java.io.tmpdir")); + GetPropertyAction.privilegedGetProperty("java.io.tmpdir")); static File location() { return tmpdir; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/Class.java --- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/Class.java Thu May 05 19:11:09 2016 +0000 @@ -470,7 +470,7 @@ * expression with an empty argument list. The class is initialized if it * has not already been initialized. * - *

Note that this method propagates any exception thrown by the + * @deprecated This method propagates any exception thrown by the * nullary constructor, including a checked exception. Use of * this method effectively bypasses the compile-time exception * checking that would otherwise be performed by the compiler. @@ -500,6 +500,7 @@ * of this class. */ @CallerSensitive + @Deprecated(since="9") public T newInstance() throws InstantiationException, IllegalAccessException { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/ClassLoader.java --- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu May 05 19:11:09 2016 +0000 @@ -2615,7 +2615,7 @@ ServicesCatalog createOrGetServicesCatalog() { ServicesCatalog catalog = servicesCatalog; if (catalog == null) { - catalog = new ServicesCatalog(); + catalog = ServicesCatalog.create(); boolean set = trySetObjectField("servicesCatalog", catalog); if (!set) { // beaten by someone else diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java --- a/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java Thu May 05 19:11:09 2016 +0000 @@ -468,7 +468,7 @@ */ public abstract static class Redirect { private static final File NULL_FILE = new File( - (GetPropertyAction.getProperty("os.name") + (GetPropertyAction.privilegedGetProperty("os.name") .startsWith("Windows") ? "NUL" : "/dev/null") ); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java --- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Thu May 05 19:11:09 2016 +0000 @@ -78,7 +78,8 @@ * Performance work and extensive testing is needed to replace the * VM built-in backtrace filled in Throwable with the StackWalker. */ - final static boolean isDebug = getProperty("stackwalk.debug", false); + final static boolean isDebug = + "true".equals(GetPropertyAction.privilegedGetProperty("stackwalk.debug")); static StackFrameTraverser makeStackTraverser(StackWalker walker, Function, ? extends T> function) @@ -988,11 +989,4 @@ c.getName().startsWith("java.lang.invoke.LambdaForm"); } - private static boolean getProperty(String key, boolean value) { - String s = GetPropertyAction.getProperty(key); - if (s != null) { - return Boolean.parseBoolean(s); - } - return value; - } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/System.java --- a/jdk/src/java.base/share/classes/java/lang/System.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/System.java Thu May 05 19:11:09 2016 +0000 @@ -69,7 +69,6 @@ import jdk.internal.logger.LocalizedLoggerWrapper; import jdk.internal.module.ModuleBootstrap; -import jdk.internal.module.Modules; import jdk.internal.module.ServicesCatalog; /** @@ -1924,10 +1923,6 @@ // initialize the module system System.bootLayer = ModuleBootstrap.boot(); - // base module needs to be loose (CODETOOLS-7901619) - Module base = Object.class.getModule(); - Modules.addReads(base, null); - // module system initialized VM.initLevel(2); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Thu May 05 19:11:09 2016 +0000 @@ -33,8 +33,6 @@ import sun.invoke.util.Wrapper; import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.util.Arrays; import java.util.Objects; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Thu May 05 19:11:09 2016 +0000 @@ -88,7 +88,7 @@ static { final String key = "jdk.internal.lambda.dumpProxyClasses"; - String path = GetPropertyAction.getProperty(key); + String path = GetPropertyAction.privilegedGetProperty(key); dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Thu May 05 19:11:09 2016 +0000 @@ -396,7 +396,7 @@ LambdaForm lform = new LambdaForm(name + ":VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype)), ARG_LIMIT + 1, names); - lform.prepare(); + lform.compileToBytecode(); return lform; } @@ -448,7 +448,7 @@ LambdaForm lform = new LambdaForm(name + ":VarHandle_exactInvoker" + shortenSignature(basicTypeSignature(mtype)), ARG_LIMIT, names); - lform.prepare(); + lform.compileToBytecode(); return lform; } @@ -497,44 +497,33 @@ /*non-public*/ static @ForceInline - MethodHandle checkVarHandleGenericType(VarHandle vh, VarHandle.AccessDescriptor vad) { - MethodType expected = vad.symbolicMethodType; - MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh); - - MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform); - if (mn == null) - throw vh.unsupported(); - // TODO the following MH is not constant, cache in stable field array - // on VarForm? - MethodHandle mh = DirectMethodHandle.make(mn); - if (actual == expected) { + MethodHandle checkVarHandleGenericType(VarHandle handle, VarHandle.AccessDescriptor ad) { + // Test for exact match on invoker types + // TODO match with erased types and add cast of return value to lambda form + MethodHandle mh = handle.getMethodHandle(ad.mode); + if (mh.type() == ad.symbolicMethodTypeInvoker) { return mh; } else { - // Adapt to the actual (which should never fail since mh's method - // type is in the basic form), then to the expected (which my fail - // if the symbolic type descriptor does not match) - // TODO optimize for the case of actual.erased() == expected.erased() - return mh.asType(actual.insertParameterTypes(0, VarHandle.class)). - asType(expected.insertParameterTypes(0, VarHandle.class)); + return mh.asType(ad.symbolicMethodTypeInvoker); } } /*non-public*/ static @ForceInline - void checkVarHandleExactType(VarHandle vh, VarHandle.AccessDescriptor vad) { - MethodType expected = vad.symbolicMethodType; - MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh); - if (actual != expected) - throw newWrongMethodTypeException(expected, actual); + void checkVarHandleExactType(VarHandle handle, VarHandle.AccessDescriptor ad) { + MethodType erasedTarget = handle.vform.methodType_table[ad.type]; + MethodType erasedSymbolic = ad.symbolicMethodTypeErased; + if (erasedTarget != erasedSymbolic) + throw newWrongMethodTypeException(erasedTarget, erasedSymbolic); } /*non-public*/ static @ForceInline - MemberName getVarHandleMemberName(VarHandle vh, VarHandle.AccessDescriptor vad) { - MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform); + MemberName getVarHandleMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) { + MemberName mn = handle.vform.memberName_table[ad.mode]; if (mn == null) { - throw vh.unsupported(); + throw handle.unsupported(); } return mn; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu May 05 19:11:09 2016 +0000 @@ -430,14 +430,14 @@ // If not polymorphic in the return type, such as the compareAndSet // methods that return boolean - if (ak.isPolyMorphicInReturnType) { - if (ak.returnType != mtype.returnType()) { + if (ak.at.isMonomorphicInReturnType) { + if (ak.at.returnType != mtype.returnType()) { // The caller contains a different return type than that // defined by the method throw newNoSuchMethodErrorOnVarHandle(name, mtype); } // Adjust the return type of the signature method type - sigType = sigType.changeReturnType(ak.returnType); + sigType = sigType.changeReturnType(ak.at.returnType); } // Get the guard method type for linking @@ -455,26 +455,25 @@ MemberName linker = new MemberName( VarHandleGuards.class, "guard_" + getVarHandleMethodSignature(sigType), guardType, REF_invokeStatic); - try { - return MemberName.getFactory().resolveOrFail( - REF_invokeStatic, linker, VarHandleGuards.class, ReflectiveOperationException.class); - } catch (ReflectiveOperationException ex) { - // Fall back to lambda form linkage if guard method is not available - // TODO Optionally log fallback ? + + linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker, + VarHandleGuards.class); + if (linker != null) { + return linker; } + // Fall back to lambda form linkage if guard method is not available + // TODO Optionally log fallback ? } return Invokers.varHandleInvokeLinkerMethod(name, mtype); } static String getVarHandleMethodSignature(MethodType mt) { - StringBuilder sb = new StringBuilder(mt.parameterCount() + 1); + StringBuilder sb = new StringBuilder(mt.parameterCount() + 2); for (int i = 0; i < mt.parameterCount(); i++) { Class pt = mt.parameterType(i); sb.append(getCharType(pt)); } - sb.append('_').append(getCharType(mt.returnType())); - return sb.toString(); } static char getCharType(Class pt) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Thu May 05 19:11:09 2016 +0000 @@ -53,7 +53,7 @@ static final boolean VAR_HANDLE_GUARDS; static { - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); DEBUG_METHOD_HANDLE_NAMES = Boolean.parseBoolean( props.getProperty("java.lang.invoke.MethodHandle.DEBUG_NAMES")); DUMP_CLASS_FILES = Boolean.parseBoolean( diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Thu May 05 19:11:09 2016 +0000 @@ -197,7 +197,7 @@ // DEBUG = false; // implied // DUMPER = null; // implied - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); final String strategy = props.getProperty("java.lang.invoke.stringConcat"); CACHE_ENABLE = Boolean.parseBoolean( diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java Thu May 05 19:11:09 2016 +0000 @@ -24,42 +24,102 @@ */ package java.lang.invoke; +import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.Stable; import java.lang.invoke.VarHandle.AccessMode; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * A var handle form containing a set of member name, one for each operation. * Each member characterizes a static method. */ -class VarForm { +final class VarForm { + + final @Stable MethodType[] methodType_table; + + final @Stable MemberName[] memberName_table; + + VarForm(Class implClass, Class receiver, Class value, Class... intermediate) { + this.methodType_table = new MethodType[VarHandle.AccessType.values().length]; + + // TODO lazily calculate + this.memberName_table = linkFromStatic(implClass); + + // (Receiver, ) + List> l = new ArrayList<>(); + if (receiver != null) + l.add(receiver); + l.addAll(Arrays.asList(intermediate)); - // Holds VarForm for VarHandle implementation classes - private static final ClassValue VFORMS - = new ClassValue<>() { - @Override - protected VarForm computeValue(Class impl) { - return new VarForm(linkFromStatic(impl)); - } - }; + // (Receiver, )Value + methodType_table[VarHandle.AccessType.GET.ordinal()] = + MethodType.methodType(value, l).erase(); + + // (Receiver, , Value)void + l.add(value); + methodType_table[VarHandle.AccessType.SET.ordinal()] = + MethodType.methodType(void.class, l).erase(); - final @Stable MemberName[] table; + // (Receiver, , Value)Value + methodType_table[VarHandle.AccessType.GET_AND_UPDATE.ordinal()] = + MethodType.methodType(value, l).erase(); - VarForm(MemberName[] table) { - this.table = table; + // (Receiver, , Value, Value)boolean + l.add(value); + methodType_table[VarHandle.AccessType.COMPARE_AND_SWAP.ordinal()] = + MethodType.methodType(boolean.class, l).erase(); + + // (Receiver, , Value, Value)Value + methodType_table[VarHandle.AccessType.COMPARE_AND_EXCHANGE.ordinal()] = + MethodType.methodType(value, l).erase(); } - /** - * Creates a var form given an VarHandle implementation class. - * Each signature polymorphic method is linked to a static method of the - * same name on the implementation class or a super class. - */ - static VarForm createFromStatic(Class impl) { - return VFORMS.get(impl); + @ForceInline + final MethodType getMethodType(int type) { + return methodType_table[type]; + } + + @ForceInline + final MemberName getMemberName(int mode) { + // TODO calculate lazily + MemberName mn = memberName_table[mode]; + if (mn == null) { + throw new UnsupportedOperationException(); + } + return mn; } + + @Stable + MethodType[] methodType_V_table; + + @ForceInline + final MethodType[] getMethodType_V_init() { + MethodType[] table = new MethodType[VarHandle.AccessType.values().length]; + for (int i = 0; i < methodType_table.length; i++) { + MethodType mt = methodType_table[i]; + // TODO only adjust for sig-poly methods returning Object + table[i] = mt.changeReturnType(void.class); + } + methodType_V_table = table; + return table; + } + + @ForceInline + final MethodType getMethodType_V(int type) { + MethodType[] table = methodType_V_table; + if (table == null) { + table = getMethodType_V_init(); + } + return table[type]; + } + + /** * Link all signature polymorphic methods. */ diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java Thu May 05 19:11:09 2016 +0000 @@ -27,10 +27,9 @@ import jdk.internal.HotSpotIntrinsicCandidate; import jdk.internal.vm.annotation.ForceInline; +import jdk.internal.vm.annotation.Stable; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -406,42 +405,10 @@ * @since 9 */ public abstract class VarHandle { - // Use explicit final fields rather than an @Stable array as - // this can reduce the memory per handle - // e.g. by 24 bytes on 64 bit architectures - final MethodType typeGet; - final MethodType typeSet; - final MethodType typeCompareSwap; - final MethodType typeCompareExchange; - final MethodType typeGetAndUpdate; - final VarForm vform; - VarHandle(VarForm vform, Class receiver, Class value, Class... intermediate) { + VarHandle(VarForm vform) { this.vform = vform; - - // (Receiver, ) - List> l = new ArrayList<>(); - if (receiver != null) - l.add(receiver); - l.addAll(Arrays.asList(intermediate)); - - // (Receiver, )Value - this.typeGet = MethodType.methodType(value, l); - - // (Receiver, , Value)void - l.add(value); - this.typeSet = MethodType.methodType(void.class, l); - - // (Receiver, , Value)Value - this.typeGetAndUpdate = MethodType.methodType(value, l); - - // (Receiver, , Value, Value)boolean - l.add(value); - this.typeCompareSwap = MethodType.methodType(boolean.class, l); - - // (Receiver, , Value, Value)Value - this.typeCompareExchange = MethodType.methodType(value, l); } RuntimeException unsupported() { @@ -1090,36 +1057,83 @@ Object addAndGet(Object... args); enum AccessType { - GET, // 0 - SET, // 1 - COMPARE_AND_SWAP, // 2 - COMPARE_AND_EXCHANGE, // 3 - GET_AND_UPDATE; // 4 + GET(Object.class) { + @Override + MethodType accessModeType(Class receiver, Class value, + Class... intermediate) { + Class[] ps = allocateParameters(0, receiver, intermediate); + fillParameters(ps, receiver, intermediate); + return MethodType.methodType(value, ps); + } + }, + SET(void.class) { + @Override + MethodType accessModeType(Class receiver, Class value, + Class... intermediate) { + Class[] ps = allocateParameters(1, receiver, intermediate); + int i = fillParameters(ps, receiver, intermediate); + ps[i] = value; + return MethodType.methodType(void.class, ps); + } + }, + COMPARE_AND_SWAP(boolean.class) { + @Override + MethodType accessModeType(Class receiver, Class value, + Class... intermediate) { + Class[] ps = allocateParameters(2, receiver, intermediate); + int i = fillParameters(ps, receiver, intermediate); + ps[i++] = value; + ps[i] = value; + return MethodType.methodType(boolean.class, ps); + } + }, + COMPARE_AND_EXCHANGE(Object.class) { + @Override + MethodType accessModeType(Class receiver, Class value, + Class... intermediate) { + Class[] ps = allocateParameters(2, receiver, intermediate); + int i = fillParameters(ps, receiver, intermediate); + ps[i++] = value; + ps[i] = value; + return MethodType.methodType(value, ps); + } + }, + GET_AND_UPDATE(Object.class) { + @Override + MethodType accessModeType(Class receiver, Class value, + Class... intermediate) { + Class[] ps = allocateParameters(1, receiver, intermediate); + int i = fillParameters(ps, receiver, intermediate); + ps[i] = value; + return MethodType.methodType(value, ps); + } + }; - MethodType getMethodType(VarHandle vh) { - return getMethodType(this.ordinal(), vh); + final Class returnType; + final boolean isMonomorphicInReturnType; + + AccessType(Class returnType) { + this.returnType = returnType; + isMonomorphicInReturnType = returnType != Object.class; } - @ForceInline - static MethodType getMethodType(int ordinal, VarHandle vh) { - if (ordinal == 0) { - return vh.typeGet; - } - else if (ordinal == 1) { - return vh.typeSet; - } - else if (ordinal == 2) { - return vh.typeCompareSwap; - } - else if (ordinal == 3) { - return vh.typeCompareExchange; - } - else if (ordinal == 4) { - return vh.typeGetAndUpdate; - } - else { - throw new IllegalStateException("Illegal access type: " + ordinal); - } + abstract MethodType accessModeType(Class receiver, Class value, + Class... intermediate); + + private static Class[] allocateParameters(int values, + Class receiver, Class... intermediate) { + int size = ((receiver != null) ? 1 : 0) + intermediate.length + values; + return new Class[size]; + } + + private static int fillParameters(Class[] ps, + Class receiver, Class... intermediate) { + int i = 0; + if (receiver != null) + ps[i++] = receiver; + for (int j = 0; j < intermediate.length; j++) + ps[i++] = intermediate[j]; + return i; } } @@ -1133,115 +1147,115 @@ * method * {@link VarHandle#get VarHandle.get} */ - GET("get", AccessType.GET, Object.class), + GET("get", AccessType.GET), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#set VarHandle.set} */ - SET("set", AccessType.SET, void.class), + SET("set", AccessType.SET), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#getVolatile VarHandle.getVolatile} */ - GET_VOLATILE("getVolatile", AccessType.GET, Object.class), + GET_VOLATILE("getVolatile", AccessType.GET), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#setVolatile VarHandle.setVolatile} */ - SET_VOLATILE("setVolatile", AccessType.SET, void.class), + SET_VOLATILE("setVolatile", AccessType.SET), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#getAcquire VarHandle.getAcquire} */ - GET_ACQUIRE("getAcquire", AccessType.GET, Object.class), + GET_ACQUIRE("getAcquire", AccessType.GET), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#setRelease VarHandle.setRelease} */ - SET_RELEASE("setRelease", AccessType.SET, void.class), + SET_RELEASE("setRelease", AccessType.SET), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#getOpaque VarHandle.getOpaque} */ - GET_OPAQUE("getOpaque", AccessType.GET, Object.class), + GET_OPAQUE("getOpaque", AccessType.GET), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#setOpaque VarHandle.setOpaque} */ - SET_OPAQUE("setOpaque", AccessType.SET, void.class), + SET_OPAQUE("setOpaque", AccessType.SET), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#compareAndSet VarHandle.compareAndSet} */ - COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class), + COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile} */ - COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class), + COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire} */ - COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class), + COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease} */ - COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class), + COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet} */ - WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class), + WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#weakCompareAndSetVolatile VarHandle.weakCompareAndSetVolatile} */ - WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP, boolean.class), + WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire} */ - WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class), + WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease} */ - WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class), + WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#getAndSet VarHandle.getAndSet} */ - GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class), + GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#getAndAdd VarHandle.getAndAdd} */ - GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class), + GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE), /** * The access mode whose access is specified by the corresponding * method * {@link VarHandle#addAndGet VarHandle.addAndGet} */ - ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class), + ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE), ; static final Map methodNameToAccessMode; @@ -1256,10 +1270,8 @@ final String methodName; final AccessType at; - final boolean isPolyMorphicInReturnType; - final Class returnType; - AccessMode(final String methodName, AccessType at, Class returnType) { + AccessMode(final String methodName, AccessType at) { this.methodName = methodName; this.at = at; @@ -1267,10 +1279,7 @@ assert methodName.equals(toMethodName(name())); // Assert that return type is correct // Otherwise, when disabled avoid using reflection - assert returnType == getReturnType(methodName); - - this.returnType = returnType; - isPolyMorphicInReturnType = returnType != Object.class; + assert at.returnType == getReturnType(methodName); } /** @@ -1324,17 +1333,21 @@ @ForceInline static MemberName getMemberName(int ordinal, VarForm vform) { - return vform.table[ordinal]; + return vform.memberName_table[ordinal]; } } static final class AccessDescriptor { - final MethodType symbolicMethodType; + final MethodType symbolicMethodTypeErased; + final MethodType symbolicMethodTypeInvoker; + final Class returnType; final int type; final int mode; public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) { - this.symbolicMethodType = symbolicMethodType; + this.symbolicMethodTypeErased = symbolicMethodType.erase(); + this.symbolicMethodTypeInvoker = symbolicMethodType.insertParameterTypes(0, VarHandle.class); + this.returnType = symbolicMethodType.returnType(); this.type = type; this.mode = mode; } @@ -1346,6 +1359,7 @@ * @return the variable type of variables referenced by this VarHandle */ public final Class varType() { + MethodType typeSet = accessModeType(AccessMode.SET); return typeSet.parameterType(typeSet.parameterCount() - 1); } @@ -1356,6 +1370,7 @@ * list is unmodifiable */ public final List> coordinateTypes() { + MethodType typeGet = accessModeType(AccessMode.GET); return typeGet.parameterList(); } @@ -1374,9 +1389,15 @@ * @return the access mode type for the given access mode */ public final MethodType accessModeType(AccessMode accessMode) { - return accessMode.at.getMethodType(this); + TypesAndInvokers tis = getTypesAndInvokers(); + MethodType mt = tis.methodType_table[accessMode.at.ordinal()]; + if (mt == null) { + mt = tis.methodType_table[accessMode.at.ordinal()] = + accessModeTypeUncached(accessMode); + } + return mt; } - + abstract MethodType accessModeTypeUncached(AccessMode accessMode); /** * Returns {@code true} if the given access mode is supported, otherwise @@ -1417,9 +1438,8 @@ public final MethodHandle toMethodHandle(AccessMode accessMode) { MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform); if (mn != null) { - return DirectMethodHandle.make(mn). - bindTo(this). - asType(accessMode.at.getMethodType(this)); + MethodHandle mh = getMethodHandle(accessMode.ordinal()); + return mh.bindTo(this); } else { // Ensure an UnsupportedOperationException is thrown @@ -1428,6 +1448,51 @@ } } + @Stable + TypesAndInvokers typesAndInvokers; + + static class TypesAndInvokers { + final @Stable + MethodType[] methodType_table = + new MethodType[VarHandle.AccessType.values().length]; + + final @Stable + MethodHandle[] methodHandle_table = + new MethodHandle[AccessMode.values().length]; + } + + @ForceInline + private final TypesAndInvokers getTypesAndInvokers() { + TypesAndInvokers tis = typesAndInvokers; + if (tis == null) { + tis = typesAndInvokers = new TypesAndInvokers(); + } + return tis; + } + + @ForceInline + final MethodHandle getMethodHandle(int mode) { + TypesAndInvokers tis = getTypesAndInvokers(); + MethodHandle mh = tis.methodHandle_table[mode]; + if (mh == null) { + mh = tis.methodHandle_table[mode] = getMethodHandleUncached(tis, mode); + } + return mh; + } + private final MethodHandle getMethodHandleUncached(TypesAndInvokers tis, int mode) { + MethodType mt = accessModeType(AccessMode.values()[mode]). + insertParameterTypes(0, VarHandle.class); + MemberName mn = vform.getMemberName(mode); + DirectMethodHandle dmh = DirectMethodHandle.make(mn); + // Such a method handle must not be publically exposed directly + // otherwise it can be cracked, it must be transformed or rebound + // before exposure + MethodHandle mh = dmh.copyWith(mt, dmh.form); + assert mh.type().erase() == mn.getMethodType().erase(); + return mh; + } + + /*non-public*/ final void updateVarForm(VarForm newVForm) { if (vform == newVForm) return; @@ -1453,6 +1518,10 @@ catch (ReflectiveOperationException e) { throw newInternalError(e); } + + // The VarHandleGuards must be initialized to ensure correct + // compilation of the guard methods + UNSAFE.ensureClassInitialized(VarHandleGuards.class); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java Thu May 05 19:11:09 2016 +0000 @@ -30,1361 +30,1008 @@ final class VarHandleGuards { @ForceInline - final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) { - MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform); - if (mn == null) { - throw handle.unsupported(); - } - return mn; - } - - @ForceInline @LambdaForm.Compiled final static Object guard_L_L(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - Object r = MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - return symbolic.returnType().cast(r); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + Object r = MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); + return ad.returnType.cast(r); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static void guard_LL_V(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static Object guard_LL_L(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - return symbolic.returnType().cast(r); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); + return ad.returnType.cast(r); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LLL_Z(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static Object guard_LLL_L(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - return symbolic.returnType().cast(r); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); + return ad.returnType.cast(r); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static int guard_L_I(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static void guard_LI_V(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static int guard_LI_I(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LII_Z(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static int guard_LII_I(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static long guard_L_J(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static void guard_LJ_V(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static long guard_LJ_J(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static long guard_LJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static float guard_L_F(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (float) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (float) vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static void guard_LF_V(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static float guard_LF_F(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (float) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LFF_Z(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static float guard_LFF_F(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static double guard_L_D(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (double) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (double) vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static void guard_LD_V(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static double guard_LD_D(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (double) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LDD_Z(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static double guard_LDD_D(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static Object guard__L(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - Object r = MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); - return symbolic.returnType().cast(r); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + Object r = MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode)); + return ad.returnType.cast(r); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return vh_invoker.invokeBasic(handle); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle); } } @ForceInline @LambdaForm.Compiled final static void guard_L_V(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LL_Z(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static int guard__I(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle); } } @ForceInline @LambdaForm.Compiled final static void guard_I_V(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static int guard_I_I(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static boolean guard_II_Z(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static int guard_II_I(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static long guard__J(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle); } } @ForceInline @LambdaForm.Compiled final static void guard_J_V(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static long guard_J_J(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static boolean guard_JJ_Z(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static long guard_JJ_J(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static float guard__F(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (float) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (float) vh_invoker.invokeBasic(handle); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle); } } @ForceInline @LambdaForm.Compiled final static void guard_F_V(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static float guard_F_F(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (float) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (float) vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static boolean guard_FF_Z(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static float guard_FF_F(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (float) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static double guard__D(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (double) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (double) vh_invoker.invokeBasic(handle); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle); } } @ForceInline @LambdaForm.Compiled final static void guard_D_V(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static double guard_D_D(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (double) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (double) vh_invoker.invokeBasic(handle, arg0); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0); } } @ForceInline @LambdaForm.Compiled final static boolean guard_DD_Z(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static double guard_DD_D(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (double) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static Object guard_LI_L(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - return symbolic.returnType().cast(r); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); + return ad.returnType.cast(r); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static void guard_LIL_V(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static Object guard_LIL_L(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - return symbolic.returnType().cast(r); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); + return ad.returnType.cast(r); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LILL_Z(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static Object guard_LILL_L(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - return symbolic.returnType().cast(r); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); + return ad.returnType.cast(r); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static void guard_LII_V(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LIII_Z(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static int guard_LIII_I(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static long guard_LI_J(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static void guard_LIJ_V(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static long guard_LIJ_J(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LIJJ_Z(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static long guard_LIJJ_J(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static float guard_LI_F(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (float) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static void guard_LIF_V(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static float guard_LIF_F(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LIFF_Z(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static float guard_LIFF_F(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static double guard_LI_D(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (double) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static void guard_LID_V(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static double guard_LID_D(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LIDD_Z(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static double guard_LIDD_D(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static int guard_LJ_I(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle, arg0, arg1); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1); } } @ForceInline @LambdaForm.Compiled final static void guard_LJI_V(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static int guard_LJI_I(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LJII_Z(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static int guard_LJII_I(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static void guard_LJJ_V(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } - else if (target.erase() == symbolic.erase()) { - MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad)); + else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) { + MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - vh_invoker.invokeBasic(handle, arg0, arg1, arg2); + MethodHandle mh = handle.getMethodHandle(ad.mode); + mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2); } } @ForceInline @LambdaForm.Compiled final static boolean guard_LJJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } @ForceInline @LambdaForm.Compiled final static long guard_LJJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable { - MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle); - MethodType symbolic = ad.symbolicMethodType; - if (target == symbolic) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); - } - else if (target.erase() == symbolic.erase()) { - return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad)); + if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) { + return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode)); } else { - MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic); - return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3); + MethodHandle mh = handle.getMethodHandle(ad.mode); + return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java Thu May 05 19:11:09 2016 +0000 @@ -280,28 +280,29 @@ // "@ForceInline\n" + // "@LambdaForm.Compiled\n" + // "final static throws Throwable {\n" + -// " MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);\n" + -// " MethodType symbolic = ad.symbolicMethodType;\n" + -// " if (target == symbolic) {\n" + -// " MethodHandle.linkToStatic();\n" + -// " }\n" + -// " else if (target.erase() == symbolic.erase()) {\n" + +// " if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodType) {\n" + // " MethodHandle.linkToStatic();\n" + // " }\n" + // " else {\n" + -// " MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);\n" + -// " vh_invoker.invokeBasic();\n" + +// " MethodHandle mh = handle.getMethodHandle(ad.mode);\n" + +// " mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic();\n" + // " }\n" + // "}"; // -// static final String GET_MEMBER_NAME_METHOD = +// static final String GUARD_METHOD_TEMPLATE_V = // "@ForceInline\n" + -// "final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {\n" + -// " MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);\n" + -// " if (mn == null) {\n" + -// " throw handle.unsupported();\n" + +// "@LambdaForm.Compiled\n" + +// "final static throws Throwable {\n" + +// " if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodType) {\n" + +// " MethodHandle.linkToStatic();\n" + // " }\n" + -// " return mn;\n" + +// " else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodType) {\n" + +// " MethodHandle.linkToStatic();\n" + +// " }\n" + +// " else {\n" + +// " MethodHandle mh = handle.getMethodHandle(ad.mode);\n" + +// " mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic();\n" + +// " }\n" + // "}"; // // // A template for deriving the operations @@ -345,8 +346,6 @@ // System.out.println("final class VarHandleGuards {"); // // System.out.println(); -// System.out.println(GET_MEMBER_NAME_METHOD); -// System.out.println(); // // // Declare the stream of shapes // Stream hts = Stream.of( @@ -445,7 +444,10 @@ // // List LINK_TO_STATIC_ARGS = params.keySet().stream(). // collect(toList()); -// LINK_TO_STATIC_ARGS.add("getMemberName(handle, ad)"); +// LINK_TO_STATIC_ARGS.add("handle.vform.getMemberName(ad.mode)"); +// List LINK_TO_STATIC_ARGS_V = params.keySet().stream(). +// collect(toList()); +// LINK_TO_STATIC_ARGS_V.add("handle.vform.getMemberName_V(ad.mode)"); // // List LINK_TO_INVOKER_ARGS = params.keySet().stream(). // collect(toList()); @@ -464,9 +466,12 @@ // // String RETURN_ERASED = returnType != Object.class // ? "" -// : " return symbolic.returnType().cast(r);"; +// : " return ad.returnType.cast(r);"; // -// return GUARD_METHOD_TEMPLATE. +// String template = returnType == void.class +// ? GUARD_METHOD_TEMPLATE_V +// : GUARD_METHOD_TEMPLATE; +// return template. // replace("", METHOD). // replace("", NAME). // replaceAll("", RETURN). @@ -474,6 +479,8 @@ // replace("", RETURN_ERASED). // replaceAll("", LINK_TO_STATIC_ARGS.stream(). // collect(joining(", "))). +// replaceAll("", LINK_TO_STATIC_ARGS_V.stream(). +// collect(joining(", "))). // replace("", LINK_TO_INVOKER_ARGS.stream(). // collect(joining(", "))) // ; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template --- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template Thu May 05 19:11:09 2016 +0000 @@ -41,12 +41,12 @@ #end[Object] FieldInstanceReadOnly(Class receiverType, long fieldOffset{#if[Object]?, Class fieldType}) { - this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.class); + this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.FORM); } protected FieldInstanceReadOnly(Class receiverType, long fieldOffset{#if[Object]?, Class fieldType}, - Class handle) { - super(VarForm.createFromStatic(handle), receiverType, {#if[Object]?fieldType:$type$.class}); + VarForm form) { + super(form); this.fieldOffset = fieldOffset; this.receiverType = receiverType; #if[Object] @@ -54,6 +54,11 @@ #end[Object] } + @Override + final MethodType accessModeTypeUncached(AccessMode accessMode) { + return accessMode.at.accessModeType(receiverType, {#if[Object]?fieldType:$type$.class}); + } + @ForceInline static $type$ get(FieldInstanceReadOnly handle, Object holder) { return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), @@ -77,12 +82,14 @@ return UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)), handle.fieldOffset); } + + static final VarForm FORM = new VarForm(FieldInstanceReadOnly.class, Object.class, $type$.class); } - static class FieldInstanceReadWrite extends FieldInstanceReadOnly { + static final class FieldInstanceReadWrite extends FieldInstanceReadOnly { FieldInstanceReadWrite(Class receiverType, long fieldOffset{#if[Object]?, Class fieldType}) { - super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.class); + super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.FORM); } @ForceInline @@ -202,6 +209,8 @@ value) + value; } #end[AtomicAdd] + + static final VarForm FORM = new VarForm(FieldInstanceReadWrite.class, Object.class, $type$.class); } @@ -213,12 +222,12 @@ #end[Object] FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class fieldType}) { - this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.class); + this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM); } protected FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class fieldType}, - Class handle) { - super(VarForm.createFromStatic(handle), null, {#if[Object]?fieldType:$type$.class}); + VarForm form) { + super(form); this.base = base; this.fieldOffset = fieldOffset; #if[Object] @@ -226,6 +235,11 @@ #end[Object] } + @Override + final MethodType accessModeTypeUncached(AccessMode accessMode) { + return accessMode.at.accessModeType(null, {#if[Object]?fieldType:$type$.class}); + } + @ForceInline static $type$ get(FieldStaticReadOnly handle) { return UNSAFE.get$Type$(handle.base, @@ -249,12 +263,14 @@ return UNSAFE.get$Type$Acquire(handle.base, handle.fieldOffset); } + + static final VarForm FORM = new VarForm(FieldStaticReadOnly.class, null, $type$.class); } - static class FieldStaticReadWrite extends FieldStaticReadOnly { + static final class FieldStaticReadWrite extends FieldStaticReadOnly { FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class fieldType}) { - super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.class); + super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM); } @ForceInline @@ -375,6 +391,8 @@ value) + value; } #end[AtomicAdd] + + static final VarForm FORM = new VarForm(FieldStaticReadWrite.class, null, $type$.class); } @@ -387,8 +405,7 @@ #end[Object] Array(int abase, int ashift{#if[Object]?, Class arrayType}) { - super(VarForm.createFromStatic(Array.class), - {#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class); + super(Array.FORM); this.abase = abase; this.ashift = ashift; #if[Object] @@ -397,6 +414,11 @@ #end[Object] } + @Override + final MethodType accessModeTypeUncached(AccessMode accessMode) { + return accessMode.at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class); + } + @ForceInline static $type$ get(Array handle, Object oarray, int index) { #if[Object] @@ -630,5 +652,7 @@ value) + value; } #end[AtomicAdd] + + static final VarForm FORM = new VarForm(Array.class, {#if[Object]?Object[].class:$type$[].class}, {#if[Object]?Object.class:$type$.class}, int.class); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template --- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template Thu May 05 19:11:09 2016 +0000 @@ -59,13 +59,11 @@ #end[floatingPoint] - private static class ByteArrayViewVarHandle extends VarHandle { + private static abstract class ByteArrayViewVarHandle extends VarHandle { final boolean be; - ByteArrayViewVarHandle(Class implSubType, - Class arrayType, Class component, boolean be) { - super(VarForm.createFromStatic(implSubType), - arrayType, component, int.class); + ByteArrayViewVarHandle(VarForm form, boolean be) { + super(form); this.be = be; } } @@ -73,7 +71,12 @@ static final class ArrayHandle extends ByteArrayViewVarHandle { ArrayHandle(boolean be) { - super(ArrayHandle.class, byte[].class, $type$.class, be); + super(ArrayHandle.FORM, be); + } + + @Override + final MethodType accessModeTypeUncached(AccessMode accessMode) { + return accessMode.at.accessModeType(byte[].class, $type$.class, int.class); } @ForceInline @@ -286,13 +289,20 @@ convEndian(handle.be, value))) + value; } #end[AtomicAdd] + + static final VarForm FORM = new VarForm(ArrayHandle.class, byte[].class, $type$.class, int.class); } static final class ByteBufferHandle extends ByteArrayViewVarHandle { ByteBufferHandle(boolean be) { - super(ByteBufferHandle.class, ByteBuffer.class, $type$.class, be); + super(ByteBufferHandle.FORM, be); + } + + @Override + final MethodType accessModeTypeUncached(AccessMode accessMode) { + return accessMode.at.accessModeType(ByteBuffer.class, $type$.class, int.class); } @ForceInline @@ -513,5 +523,7 @@ convEndian(handle.be, value))) + value; } #end[AtomicAdd] + + static final VarForm FORM = new VarForm(ByteBufferHandle.class, ByteBuffer.class, $type$.class, int.class); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/Configuration.java --- a/jdk/src/java.base/share/classes/java/lang/module/Configuration.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/Configuration.java Thu May 05 19:11:09 2016 +0000 @@ -25,6 +25,7 @@ package java.lang.module; +import java.io.PrintStream; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -183,17 +184,20 @@ this.nameToModule = Collections.emptyMap(); } - private Configuration(Configuration parent, Resolver resolver) { - Map> graph = resolver.finish(this); + private Configuration(Configuration parent, + Resolver resolver, + boolean check) + { + Map> g = resolver.finish(this, check); Map nameToModule = new HashMap<>(); - for (ResolvedModule resolvedModule : graph.keySet()) { + for (ResolvedModule resolvedModule : g.keySet()) { nameToModule.put(resolvedModule.name(), resolvedModule); } this.parent = parent; - this.graph = graph; - this.modules = Collections.unmodifiableSet(graph.keySet()); + this.graph = g; + this.modules = Collections.unmodifiableSet(g.keySet()); this.nameToModule = Collections.unmodifiableMap(nameToModule); } @@ -283,10 +287,10 @@ Objects.requireNonNull(after); Objects.requireNonNull(roots); - Resolver resolver = new Resolver(before, this, after); + Resolver resolver = new Resolver(before, this, after, null); resolver.resolveRequires(roots); - return new Configuration(this, resolver); + return new Configuration(this, resolver, true); } @@ -340,10 +344,32 @@ Objects.requireNonNull(after); Objects.requireNonNull(roots); - Resolver resolver = new Resolver(before, this, after); + Resolver resolver = new Resolver(before, this, after, null); resolver.resolveRequires(roots).resolveUses(); - return new Configuration(this, resolver); + return new Configuration(this, resolver, true); + } + + + /** + * Resolves a collection of root modules, with service binding, and with + * the empty configuration as its parent. The post resolution checks + * are optionally run. + * + * This method is used to create the configuration for the boot layer. + */ + static Configuration resolveRequiresAndUses(ModuleFinder finder, + Collection roots, + boolean check, + PrintStream traceOutput) + { + Configuration parent = empty(); + + Resolver resolver + = new Resolver(finder, parent, ModuleFinder.empty(), traceOutput); + resolver.resolveRequires(roots).resolveUses(); + + return new Configuration(parent, resolver, check); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java --- a/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Thu May 05 19:11:09 2016 +0000 @@ -27,13 +27,17 @@ import java.io.InputStream; import java.io.IOException; +import java.io.PrintStream; import java.io.UncheckedIOException; +import java.net.URI; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -45,7 +49,7 @@ import static java.util.Objects.*; import jdk.internal.module.Checks; -import jdk.internal.module.Hasher.DependencyHashes; +import jdk.internal.module.ModuleHashes; /** @@ -372,8 +376,9 @@ private Provides(String service, Set providers, boolean check) { this.service = check ? requireServiceTypeName(service) : service; - providers = check ? Collections.unmodifiableSet(new HashSet<>(providers)) - : Collections.unmodifiableSet(providers); + providers = check + ? Collections.unmodifiableSet(new LinkedHashSet<>(providers)) + : Collections.unmodifiableSet(providers); if (providers.isEmpty()) throw new IllegalArgumentException("Empty providers set"); if (check) @@ -787,7 +792,7 @@ private final String osVersion; private final Set conceals; private final Set packages; - private final DependencyHashes hashes; + private final ModuleHashes hashes; private ModuleDescriptor(String name, boolean automatic, @@ -802,7 +807,7 @@ String osArch, String osVersion, Set conceals, - DependencyHashes hashes) + ModuleHashes hashes) { this.name = name; @@ -878,7 +883,8 @@ String osArch, String osVersion, Set conceals, - Set packages) { + Set packages, + ModuleHashes hashes) { this.name = name; this.automatic = automatic; this.synthetic = synthetic; @@ -894,7 +900,7 @@ this.osName = osName; this.osArch = osArch; this.osVersion = osVersion; - this.hashes = null; + this.hashes = hashes; } /** @@ -1063,9 +1069,9 @@ } /** - * Returns the object with the hashes of the dependences. + * Returns the object with the hashes of other modules */ - Optional hashes() { + Optional hashes() { return Optional.ofNullable(hashes); } @@ -1103,7 +1109,7 @@ String osArch; String osVersion; String mainClass; - DependencyHashes hashes; + ModuleHashes hashes; /** * Initializes a new builder with the given module name. @@ -1580,7 +1586,7 @@ return this; } - /* package */ Builder hashes(DependencyHashes hashes) { + /* package */ Builder hashes(ModuleHashes hashes) { this.hashes = hashes; return this; } @@ -1719,7 +1725,9 @@ hc = hc * 43 + Objects.hashCode(osVersion); hc = hc * 43 + Objects.hashCode(conceals); hc = hc * 43 + Objects.hashCode(hashes); - if (hc != 0) hash = hc; + if (hc == 0) + hc = -1; + hash = hc; } return hc; } @@ -1925,11 +1933,12 @@ static { /** - * Setup the shared secret to allow code in other packages create - * ModuleDescriptor and associated objects directly. + * Setup the shared secret to allow code in other packages access + * private package methods in java.lang.module. */ jdk.internal.misc.SharedSecrets .setJavaLangModuleAccess(new jdk.internal.misc.JavaLangModuleAccess() { + @Override public Requires newRequires(Set ms, String mn) { return new Requires(ms, mn, false); @@ -1974,7 +1983,8 @@ String osArch, String osVersion, Set conceals, - Set packages) { + Set packages, + ModuleHashes hashes) { return new ModuleDescriptor(name, automatic, synthetic, @@ -1988,7 +1998,29 @@ osArch, osVersion, conceals, - packages); + packages, + hashes); + } + + @Override + public Configuration resolveRequiresAndUses(ModuleFinder finder, + Collection roots, + boolean check, + PrintStream traceOutput) + { + return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput); + } + + @Override + public ModuleReference newPatchedModule(ModuleDescriptor descriptor, + URI location, + Supplier s) { + return new ModuleReference(descriptor, location, s, true, null); + } + + @Override + public Optional hashes(ModuleDescriptor descriptor) { + return descriptor.hashes(); } }); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/ModuleInfo.java --- a/jdk/src/java.base/share/classes/java/lang/module/ModuleInfo.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleInfo.java Thu May 05 19:11:09 2016 +0000 @@ -37,11 +37,12 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.function.Supplier; -import jdk.internal.module.Hasher.DependencyHashes; +import jdk.internal.module.ModuleHashes; import static jdk.internal.module.ClassFileConstants.*; @@ -337,7 +338,7 @@ // computeIfAbsent Set providers = pm.get(sn); if (providers == null) { - providers = new HashSet<>(); + providers = new LinkedHashSet<>(); // preserve order pm.put(sn, providers); } providers.add(cn); @@ -425,7 +426,7 @@ map.put(dn, hash); } - builder.hashes(new DependencyHashes(algorithm, map)); + builder.hashes(new ModuleHashes(algorithm, map)); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/ModulePath.java --- a/jdk/src/java.base/share/classes/java/lang/module/ModulePath.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/ModulePath.java Thu May 05 19:11:09 2016 +0000 @@ -40,7 +40,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -52,7 +52,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -190,18 +189,16 @@ } } - if (attrs.isRegularFile() || attrs.isDirectory()) { - // packaged or exploded module - ModuleReference mref = readModule(entry, attrs); - if (mref != null) { - String name = mref.descriptor().name(); - return Collections.singletonMap(name, mref); - } + // packaged or exploded module + ModuleReference mref = readModule(entry, attrs); + if (mref != null) { + String name = mref.descriptor().name(); + return Collections.singletonMap(name, mref); + } else { + // skipped + return Collections.emptyMap(); } - // not recognized - throw new FindException("Unrecognized module: " + entry); - } catch (IOException ioe) { throw new FindException(ioe); } @@ -238,16 +235,13 @@ // module found if (mref != null) { - // can have at most one version of a module in the directory String name = mref.descriptor().name(); if (nameToReference.put(name, mref) != null) { throw new FindException("Two versions of module " - + name + " found in " + dir); + + name + " found in " + dir); } - } - } } @@ -257,28 +251,40 @@ /** * Locates a packaged or exploded module, returning a {@code ModuleReference} - * to the module. Returns {@code null} if the module is not recognized - * as a packaged or exploded module. + * to the module. Returns {@code null} if the entry is skipped because it is + * to a directory that does not contain a module-info.class or it's a hidden + * file. * * @throws IOException if an I/O error occurs - * @throws FindException if an error occurs parsing the module descriptor + * @throws FindException if the file is not recognized as a module or an + * error occurs parsing its module descriptor */ private ModuleReference readModule(Path entry, BasicFileAttributes attrs) throws IOException { try { - ModuleReference mref = null; if (attrs.isDirectory()) { - mref = readExplodedModule(entry); - } if (attrs.isRegularFile()) { - if (entry.toString().endsWith(".jar")) { - mref = readJar(entry); - } else if (isLinkPhase && entry.toString().endsWith(".jmod")) { - mref = readJMod(entry); + return readExplodedModule(entry); // may return null + } + + String fn = entry.getFileName().toString(); + if (attrs.isRegularFile()) { + if (fn.endsWith(".jar")) { + return readJar(entry); + } else if (fn.endsWith(".jmod")) { + if (isLinkPhase) + return readJMod(entry); + throw new FindException("JMOD files not supported: " + entry); } } - return mref; + + // skip hidden files + if (fn.startsWith(".") || Files.isHidden(entry)) { + return null; + } else { + throw new FindException("Unrecognized module: " + entry); + } } catch (InvalidModuleDescriptorException e) { throw new FindException("Error reading module: " + entry, e); @@ -292,15 +298,17 @@ return zf.stream() .filter(e -> e.getName().startsWith("classes/") && e.getName().endsWith(".class")) - .map(e -> toPackageName(e)) + .map(e -> toPackageName(e.getName().substring(8))) .filter(pkg -> pkg.length() > 0) // module-info - .distinct() .collect(Collectors.toSet()); } /** * Returns a {@code ModuleReference} to a module in jmod file on the * file system. + * + * @throws IOException + * @throws InvalidModuleDescriptorException */ private ModuleReference readJMod(Path file) throws IOException { try (ZipFile zf = new ZipFile(file.toString())) { @@ -419,13 +427,12 @@ // scan the entries in the JAR file to locate the .class and service // configuration file - Stream stream = jf.stream() - .map(e -> e.getName()) - .filter(e -> (e.endsWith(".class") || e.startsWith(SERVICES_PREFIX))) - .distinct(); - Map> map - = stream.collect(Collectors.partitioningBy(s -> s.endsWith(".class"), - Collectors.toSet())); + Map> map = + jf.stream() + .map(JarEntry::getName) + .filter(s -> (s.endsWith(".class") ^ s.startsWith(SERVICES_PREFIX))) + .collect(Collectors.partitioningBy(s -> s.endsWith(".class"), + Collectors.toSet())); Set classFiles = map.get(Boolean.TRUE); Set configFiles = map.get(Boolean.FALSE); @@ -433,19 +440,18 @@ classFiles.stream() .map(c -> toPackageName(c)) .distinct() - .forEach(p -> builder.exports(p)); + .forEach(builder::exports); // map names of service configuration files to service names Set serviceNames = configFiles.stream() .map(this::toServiceName) - .filter(Optional::isPresent) - .map(Optional::get) + .flatMap(Optional::stream) .collect(Collectors.toSet()); // parse each service configuration file for (String sn : serviceNames) { JarEntry entry = jf.getJarEntry(SERVICES_PREFIX + sn); - Set providerClasses = new HashSet<>(); + Set providerClasses = new LinkedHashSet<>(); try (InputStream in = jf.getInputStream(entry)) { BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); @@ -475,19 +481,25 @@ private Set jarPackages(JarFile jf) { return jf.stream() .filter(e -> e.getName().endsWith(".class")) - .map(e -> toPackageName(e)) + .map(e -> toPackageName(e.getName())) .filter(pkg -> pkg.length() > 0) // module-info - .distinct() .collect(Collectors.toSet()); } /** * Returns a {@code ModuleReference} to a module in modular JAR file on * the file system. + * + * @throws IOException + * @throws FindException + * @throws InvalidModuleDescriptorException */ private ModuleReference readJar(Path file) throws IOException { - try (JarFile jf = new JarFile(file.toString())) { - + try (JarFile jf = new JarFile(file.toFile(), + true, // verify + ZipFile.OPEN_READ, + JarFile.Release.RUNTIME)) + { ModuleDescriptor md; JarEntry entry = jf.getJarEntry(MODULE_INFO); if (entry == null) { @@ -520,7 +532,6 @@ path.toString().endsWith(".class"))) .map(path -> toPackageName(dir.relativize(path))) .filter(pkg -> pkg.length() > 0) // module-info - .distinct() .collect(Collectors.toSet()); } catch (IOException x) { throw new UncheckedIOException(x); @@ -530,6 +541,9 @@ /** * Returns a {@code ModuleReference} to an exploded module on the file * system or {@code null} if {@code module-info.class} not found. + * + * @throws IOException + * @throws InvalidModuleDescriptorException */ private ModuleReference readExplodedModule(Path dir) throws IOException { Path mi = dir.resolve(MODULE_INFO); @@ -559,19 +573,6 @@ } } - private String toPackageName(ZipEntry entry) { - String name = entry.getName(); - assert name.endsWith(".class"); - // jmod classes in classes/, jar in / - int start = name.startsWith("classes/") ? 8 : 0; - int index = name.lastIndexOf("/"); - if (index > start) { - return name.substring(start, index).replace('/', '.'); - } else { - return ""; - } - } - private String toPackageName(Path path) { String name = path.toString(); assert name.endsWith(".class"); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java --- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java Thu May 05 19:11:09 2016 +0000 @@ -142,10 +142,11 @@ * @see ClassLoader#defineClass(String, ByteBuffer, java.security.ProtectionDomain) */ default Optional read(String name) throws IOException { - Optional in = open(name); - if (in.isPresent()) { - byte[] bytes = in.get().readAllBytes(); - return Optional.of(ByteBuffer.wrap(bytes)); + Optional oin = open(name); + if (oin.isPresent()) { + try (InputStream in = oin.get()) { + return Optional.of(ByteBuffer.wrap(in.readAllBytes())); + } } else { return Optional.empty(); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/ModuleReference.java --- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReference.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReference.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -32,7 +32,7 @@ import java.util.Optional; import java.util.function.Supplier; -import jdk.internal.module.Hasher.HashSupplier; +import jdk.internal.module.ModuleHashes.HashSupplier; /** @@ -54,12 +54,33 @@ private final URI location; private final Supplier readerSupplier; + // true if this is a reference to a patched module + private boolean patched; + // the function that computes the hash of this module reference private final HashSupplier hasher; // cached hash string to avoid needing to compute it many times private String cachedHash; + + /** + * Constructs a new instance of this class. + */ + ModuleReference(ModuleDescriptor descriptor, + URI location, + Supplier readerSupplier, + boolean patched, + HashSupplier hasher) + + { + this.descriptor = Objects.requireNonNull(descriptor); + this.location = location; + this.readerSupplier = Objects.requireNonNull(readerSupplier); + this.patched = patched; + this.hasher = hasher; + } + /** * Constructs a new instance of this class. */ @@ -67,11 +88,9 @@ URI location, Supplier readerSupplier, HashSupplier hasher) + { - this.descriptor = Objects.requireNonNull(descriptor); - this.location = location; - this.readerSupplier = Objects.requireNonNull(readerSupplier); - this.hasher = hasher; + this(descriptor, location, readerSupplier, false, hasher); } @@ -96,10 +115,9 @@ URI location, Supplier readerSupplier) { - this(descriptor, location, readerSupplier, null); + this(descriptor, location, readerSupplier, false, null); } - /** * Returns the module descriptor. * @@ -151,6 +169,20 @@ /** + * Returns {@code true} if this module has been patched via -Xpatch. + */ + boolean isPatched() { + return patched; + } + + /** + * Returns the hash supplier for this module. + */ + HashSupplier hasher() { + return hasher; + } + + /** * Computes the hash of this module, returning it as a hex string. * Returns {@code null} if the hash cannot be computed. * @@ -166,8 +198,6 @@ return result; } - private int hash; - /** * Computes a hash code for this module reference. * @@ -181,12 +211,17 @@ public int hashCode() { int hc = hash; if (hc == 0) { - hc = Objects.hash(descriptor, location, readerSupplier, hasher); - if (hc != 0) hash = hc; + hc = Objects.hash(descriptor, location, readerSupplier, hasher, + Boolean.valueOf(patched)); + if (hc == 0) + hc = -1; + hash = hc; } return hc; } + private int hash; + /** * Tests this module reference for equality with the given object. * @@ -214,7 +249,8 @@ return Objects.equals(this.descriptor, that.descriptor) && Objects.equals(this.location, that.location) && Objects.equals(this.readerSupplier, that.readerSupplier) - && Objects.equals(this.hasher, that.hasher); + && Objects.equals(this.hasher, that.hasher) + && this.patched == that.patched; } /** diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/ModuleReferences.java --- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReferences.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReferences.java Thu May 05 19:11:09 2016 +0000 @@ -48,8 +48,8 @@ import jdk.internal.misc.JavaLangAccess; import jdk.internal.misc.SharedSecrets; -import jdk.internal.module.Hasher; -import jdk.internal.module.Hasher.HashSupplier; +import jdk.internal.module.ModuleHashes; +import jdk.internal.module.ModuleHashes.HashSupplier; import jdk.internal.module.ModulePatcher; import sun.net.www.ParseUtil; @@ -89,7 +89,7 @@ static ModuleReference newJarModule(ModuleDescriptor md, Path file) { URI uri = file.toUri(); Supplier supplier = () -> new JarModuleReader(file, uri); - HashSupplier hasher = (algorithm) -> Hasher.generate(file, algorithm); + HashSupplier hasher = (a) -> ModuleHashes.computeHashAsString(file, a); return newModule(md, uri, supplier, hasher); } @@ -99,7 +99,7 @@ static ModuleReference newJModModule(ModuleDescriptor md, Path file) { URI uri = file.toUri(); Supplier supplier = () -> new JModModuleReader(file, uri); - HashSupplier hasher = (algorithm) -> Hasher.generate(file, algorithm); + HashSupplier hasher = (a) -> ModuleHashes.computeHashAsString(file, a); return newModule(md, file.toUri(), supplier, hasher); } @@ -122,7 +122,7 @@ private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Lock readLock = lock.readLock(); private final Lock writeLock = lock.writeLock(); - private volatile boolean closed; + private boolean closed; SafeCloseModuleReader() { } @@ -198,7 +198,10 @@ static JarFile newJarFile(Path path) { try { - return new JarFile(path.toFile()); + return new JarFile(path.toFile(), + true, // verify + ZipFile.OPEN_READ, + JarFile.Release.RUNTIME); } catch (IOException ioe) { throw new UncheckedIOException(ioe); } @@ -219,6 +222,8 @@ if (je != null) { String encodedPath = ParseUtil.encodePath(name, false); String uris = "jar:" + uri + "!/" + encodedPath; + if (jf.isMultiRelease()) + uris += "#runtime"; return Optional.of(URI.create(uris)); } else { return Optional.empty(); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/Resolver.java --- a/jdk/src/java.base/share/classes/java/lang/module/Resolver.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/Resolver.java Thu May 05 19:11:09 2016 +0000 @@ -25,8 +25,8 @@ package java.lang.module; +import java.io.PrintStream; import java.lang.module.ModuleDescriptor.Requires.Modifier; -import java.lang.reflect.Layer; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -43,7 +43,7 @@ import java.util.StringJoiner; import java.util.stream.Collectors; -import jdk.internal.module.Hasher; +import jdk.internal.module.ModuleHashes; /** * The resolver used by {@link Configuration#resolveRequires} and @@ -55,6 +55,7 @@ private final ModuleFinder beforeFinder; private final Configuration parent; private final ModuleFinder afterFinder; + private final PrintStream traceOutput; // maps module name to module reference private final Map nameToReference = new HashMap<>(); @@ -62,10 +63,12 @@ Resolver(ModuleFinder beforeFinder, Configuration parent, - ModuleFinder afterFinder) { + ModuleFinder afterFinder, + PrintStream traceOutput) { this.beforeFinder = beforeFinder; this.parent = parent; this.afterFinder = afterFinder; + this.traceOutput = traceOutput; } @@ -76,8 +79,6 @@ */ Resolver resolveRequires(Collection roots) { - long start = trace_start("Resolve"); - // create the visit stack to get us started Deque q = new ArrayDeque<>(); for (String root : roots) { @@ -95,10 +96,9 @@ } } - if (TRACE) { + if (isTracing()) { trace("Root module %s located", root); - if (mref.location().isPresent()) - trace(" (%s)", mref.location().get()); + mref.location().ifPresent(uri -> trace(" (%s)", uri)); } assert mref.descriptor().name().equals(root); @@ -108,13 +108,6 @@ resolve(q); - if (TRACE) { - long duration = System.currentTimeMillis() - start; - Set names = nameToReference.keySet(); - trace("Resolver completed in %s ms", duration); - names.stream().sorted().forEach(name -> trace(" %s", name)); - } - return this; } @@ -153,11 +146,10 @@ q.offer(mref.descriptor()); resolved.add(mref.descriptor()); - if (TRACE) { + if (isTracing()) { trace("Module %s located, required by %s", dn, descriptor.name()); - if (mref.location().isPresent()) - trace(" (%s)", mref.location().get()); + mref.location().ifPresent(uri -> trace(" (%s)", uri)); } } @@ -175,8 +167,6 @@ */ Resolver resolveUses() { - long start = trace_start("Bind"); - // Scan the finders for all available service provider modules. As // java.base uses services then then module finders will be scanned // anyway. @@ -230,10 +220,10 @@ String pn = provider.name(); if (!nameToReference.containsKey(pn)) { - - if (TRACE && mref.location().isPresent()) - trace(" (%s)", mref.location().get()); - + if (isTracing()) { + mref.location() + .ifPresent(uri -> trace(" (%s)", uri)); + } nameToReference.put(pn, mref); q.push(provider); } @@ -248,14 +238,6 @@ } while (!candidateConsumers.isEmpty()); - - if (TRACE) { - long duration = System.currentTimeMillis() - start; - Set names = nameToReference.keySet(); - trace("Bind completed in %s ms", duration); - names.stream().sorted().forEach(name -> trace(" %s", name)); - } - return this; } @@ -264,23 +246,33 @@ * Execute post-resolution checks and returns the module graph of resolved * modules as {@code Map}. The resolved modules will be in the given * configuration. + * + * @param check {@true} to execute the post resolution checks */ - Map> finish(Configuration cf) { + Map> finish(Configuration cf, + boolean check) + { + if (isTracing()) { + trace("Result:"); + Set names = nameToReference.keySet(); + names.stream().sorted().forEach(name -> trace(" %s", name)); + } - detectCycles(); - - checkPlatformConstraints(); - - checkHashes(); + if (check) { + detectCycles(); + checkPlatformConstraints(); + checkHashes(); + } Map> graph = makeGraph(cf); - checkExportSuppliers(graph); + if (check) { + checkExportSuppliers(graph); + } return graph; } - /** * Checks the given module graph for cycles. * @@ -420,52 +412,44 @@ } - /** * Checks the hashes in the module descriptor to ensure that they match - * the hash of the dependency's module reference. + * any recorded hashes. */ private void checkHashes() { - for (ModuleReference mref : nameToReference.values()) { ModuleDescriptor descriptor = mref.descriptor(); - // get map of module names to hash - Optional ohashes = descriptor.hashes(); + // get map of module hashes + Optional ohashes = descriptor.hashes(); if (!ohashes.isPresent()) continue; - Hasher.DependencyHashes hashes = ohashes.get(); - - // check dependences - for (ModuleDescriptor.Requires d : descriptor.requires()) { - String dn = d.name(); - String recordedHash = hashes.hashFor(dn); - - if (recordedHash != null) { + ModuleHashes hashes = ohashes.get(); - ModuleReference other = nameToReference.get(dn); - if (other == null) { - other = parent.findModule(dn) - .map(ResolvedModule::reference) - .orElse(null); - } - if (other == null) - throw new InternalError(dn + " not found"); + String algorithm = hashes.algorithm(); + for (String dn : hashes.names()) { + ModuleReference other = nameToReference.get(dn); + if (other == null) { + other = parent.findModule(dn) + .map(ResolvedModule::reference) + .orElse(null); + } - String actualHash = other.computeHash(hashes.algorithm()); + // skip checking the hash if the module has been patched + if (other != null && !other.isPatched()) { + String recordedHash = hashes.hashFor(dn); + String actualHash = other.computeHash(algorithm); if (actualHash == null) fail("Unable to compute the hash of module %s", dn); - if (!recordedHash.equals(actualHash)) { - fail("Hash of %s (%s) differs to expected hash (%s)", - dn, actualHash, recordedHash); + fail("Hash of %s (%s) differs to expected hash (%s)" + + " recorded in %s", dn, actualHash, recordedHash, + descriptor.name()); } + } + } - } - - } } - } @@ -666,7 +650,7 @@ // source is exported to descriptor2 String source = export.source(); ModuleDescriptor other - = packageToExporter.put(source, descriptor2); + = packageToExporter.put(source, descriptor2); if (other != null && other != descriptor2) { // package might be local to descriptor1 @@ -690,33 +674,38 @@ } } - // uses S - for (String service : descriptor1.uses()) { - String pn = packageName(service); - if (!packageToExporter.containsKey(pn)) { - fail("Module %s does not read a module that exports %s", - descriptor1.name(), pn); - } - } + // uses/provides checks not applicable to automatic modules + if (!descriptor1.isAutomatic()) { - // provides S - for (Map.Entry entry : - descriptor1.provides().entrySet()) { - String service = entry.getKey(); - ModuleDescriptor.Provides provides = entry.getValue(); - - String pn = packageName(service); - if (!packageToExporter.containsKey(pn)) { - fail("Module %s does not read a module that exports %s", - descriptor1.name(), pn); + // uses S + for (String service : descriptor1.uses()) { + String pn = packageName(service); + if (!packageToExporter.containsKey(pn)) { + fail("Module %s does not read a module that exports %s", + descriptor1.name(), pn); + } } - for (String provider : provides.providers()) { - if (!packages.contains(packageName(provider))) { - fail("Provider %s not in module %s", - provider, descriptor1.name()); + // provides S + for (Map.Entry entry : + descriptor1.provides().entrySet()) { + String service = entry.getKey(); + ModuleDescriptor.Provides provides = entry.getValue(); + + String pn = packageName(service); + if (!packageToExporter.containsKey(pn)) { + fail("Module %s does not read a module that exports %s", + descriptor1.name(), pn); + } + + for (String provider : provides.providers()) { + if (!packages.contains(packageName(provider))) { + fail("Provider %s not in module %s", + provider, descriptor1.name()); + } } } + } } @@ -796,27 +785,18 @@ throw new ResolutionException(msg); } - /** - * Tracing support, limited to boot layer for now. + * Tracing support */ - private final static boolean TRACE - = Boolean.getBoolean("jdk.launcher.traceResolver") - && (Layer.boot() == null); - - private String op; - - private long trace_start(String op) { - this.op = op; - return System.currentTimeMillis(); + private boolean isTracing() { + return traceOutput != null; } private void trace(String fmt, Object ... args) { - if (TRACE) { - System.out.print("[" + op + "] "); - System.out.format(fmt, args); - System.out.println(); + if (traceOutput != null) { + traceOutput.format("[Resolver] " + fmt, args); + traceOutput.println(); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java --- a/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Thu May 05 19:11:09 2016 +0000 @@ -44,6 +44,7 @@ import jdk.internal.jimage.ImageLocation; import jdk.internal.jimage.ImageReader; import jdk.internal.jimage.ImageReaderFactory; +import jdk.internal.module.ModuleHashes; import jdk.internal.module.SystemModules; import jdk.internal.module.ModulePatcher; import jdk.internal.perf.PerfCounter; @@ -101,13 +102,16 @@ for (int i = 0; i < n; i++) { String mn = moduleNames[i]; ModuleDescriptor md; + String hash; if (fastLoad) { md = descriptors[i]; + hash = SystemModules.MODULES_TO_HASH[i]; } else { // fallback to read module-info.class // if fast loading of ModuleDescriptors is disabled ImageLocation location = imageReader.findLocation(mn, "module-info.class"); md = ModuleDescriptor.read(imageReader.getResourceBuffer(location)); + hash = null; } if (!md.name().equals(mn)) throw new InternalError(); @@ -123,7 +127,8 @@ } }; - ModuleReference mref = new ModuleReference(md, uri, readerSupplier); + ModuleReference mref = + new ModuleReference(md, uri, readerSupplier, hashSupplier(hash)); // may need a reference to a patched module if -Xpatch specified mref = ModulePatcher.interposeIfNeeded(mref); @@ -142,6 +147,18 @@ initTime.addElapsedTimeFrom(t0); } + private static ModuleHashes.HashSupplier hashSupplier(String hash) { + if (hash == null) + return null; + + return new ModuleHashes.HashSupplier() { + @Override + public String generate(String algorithm) { + return hash; + } + }; + } + SystemModuleFinder() { } @Override diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/reflect/Layer.java --- a/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java Thu May 05 19:11:09 2016 +0000 @@ -27,6 +27,7 @@ import java.lang.module.Configuration; import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleDescriptor.Provides; import java.lang.module.ResolvedModule; import java.util.Collections; import java.util.HashMap; @@ -41,6 +42,8 @@ import jdk.internal.loader.Loader; import jdk.internal.loader.LoaderPool; import jdk.internal.misc.SharedSecrets; +import jdk.internal.module.ServicesCatalog; +import jdk.internal.module.ServicesCatalog.ServiceProvider; import sun.security.util.SecurityConstants; @@ -549,4 +552,55 @@ public static Layer boot() { return SharedSecrets.getJavaLangAccess().getBootLayer(); } + + + /** + * Returns the ServicesCatalog for this Layer, creating it if not + * already created. + */ + ServicesCatalog getServicesCatalog() { + ServicesCatalog servicesCatalog = this.servicesCatalog; + if (servicesCatalog != null) + return servicesCatalog; + + Map> map = new HashMap<>(); + for (Module m : nameToModule.values()) { + ModuleDescriptor descriptor = m.getDescriptor(); + for (Provides provides : descriptor.provides().values()) { + String service = provides.service(); + Set providers + = map.computeIfAbsent(service, k -> new HashSet<>()); + for (String pn : provides.providers()) { + providers.add(new ServiceProvider(m, pn)); + } + } + } + + ServicesCatalog catalog = new ServicesCatalog() { + @Override + public void register(Module module) { + throw new UnsupportedOperationException(); + } + @Override + public Set findServices(String service) { + Set providers = map.get(service); + if (providers == null) { + return Collections.emptySet(); + } else { + return Collections.unmodifiableSet(providers); + } + } + }; + + synchronized (this) { + servicesCatalog = this.servicesCatalog; + if (servicesCatalog == null) { + this.servicesCatalog = servicesCatalog = catalog; + } + } + + return servicesCatalog; + } + + private volatile ServicesCatalog servicesCatalog; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/reflect/Module.java --- a/jdk/src/java.base/share/classes/java/lang/reflect/Module.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Module.java Thu May 05 19:11:09 2016 +0000 @@ -43,11 +43,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Function; import java.util.stream.Stream; @@ -142,9 +138,6 @@ this.name = null; this.loader = loader; this.descriptor = null; - - // unnamed modules are loose - this.loose = true; } @@ -245,17 +238,27 @@ } - // -- readability -- + // -- + + // the special Module to mean reads or exported to "all unnamed modules" + private static final Module ALL_UNNAMED_MODULE = new Module(null); - // true if this module reads all unnamed modules (a.k.a. loose module) - private volatile boolean loose; + // special Module to mean exported to "everyone" + private static final Module EVERYONE_MODULE = new Module(null); + + // exported to all modules + private static final Set EVERYONE = Collections.singleton(EVERYONE_MODULE); + + + // -- readability -- // the modules that this module permanently reads // (will be final when the modules are defined in reverse topology order) private volatile Set reads; - // created lazily, additional modules that this module reflectively reads - private volatile WeakSet transientReads; + // additional module (2nd key) that some module (1st key) reflectively reads + private static final WeakPairMap transientReads + = new WeakPairMap<>(); /** @@ -284,22 +287,19 @@ // check if this module reads other if (other.isNamed()) { - Set reads = this.reads; // volatile read if (reads != null && reads.contains(other)) return true; - - } else { - - // loose modules read all unnamed modules - if (this.loose) - return true; - } // check if this module reads the other module reflectively - WeakSet tr = this.transientReads; // volatile read - if (tr != null && tr.contains(other)) + if (transientReads.containsKeyPair(this, other)) + return true; + + // if other is an unnamed module then check if this module reads + // all unnamed modules + if (!other.isNamed() + && transientReads.containsKeyPair(this, ALL_UNNAMED_MODULE)) return true; return false; @@ -346,8 +346,7 @@ } /** - * Makes the given {@code Module} readable to this module without - * notifying the VM. + * Updates this module to read another module without notifying the VM. * * @apiNote This method is for VM white-box testing. */ @@ -361,40 +360,28 @@ * If {@code syncVM} is {@code true} then the VM is notified. */ private void implAddReads(Module other, boolean syncVM) { + Objects.requireNonNull(other); // nothing to do if (other == this || !this.isNamed()) return; - // if the other is null then change this module to be loose. - if (other == null) { - if (syncVM) - addReads0(this, null); - this.loose = true; - return; - } - // check if we already read this module Set reads = this.reads; if (reads != null && reads.contains(other)) return; // update VM first, just in case it fails - if (syncVM) - addReads0(this, other); + if (syncVM) { + if (other == ALL_UNNAMED_MODULE) { + addReads0(this, null); + } else { + addReads0(this, other); + } + } // add reflective read - WeakSet tr = this.transientReads; - if (tr == null) { - synchronized (this) { - tr = this.transientReads; - if (tr == null) { - tr = new WeakSet<>(); - this.transientReads = tr; - } - } - } - tr.add(other); + transientReads.putIfAbsent(this, other, Boolean.TRUE); } @@ -404,15 +391,10 @@ // (will be final when the modules are defined in reverse topology order) private volatile Map> exports; - // created lazily, additional exports added at run-time - private volatile Map> transientExports; - - // the special Module to mean exported to all modules - private static final Module EVERYONE_MODULE = new Module(null); - private static final Set EVERYONE = Collections.singleton(EVERYONE_MODULE); - - // the special Module to mean exported to all unnamed modules - private static final Module ALL_UNNAMED_MODULE = new Module(null); + // additional exports added at run-time + // this module (1st key), other module (2nd key), exported packages (value) + private static final WeakPairMap> + transientExports = new WeakPairMap<>(); /** @@ -489,23 +471,9 @@ if (exports != null) { Set targets = exports.get(pn); - if (targets != null) { - - // exported to all modules - if (targets.contains(EVERYONE_MODULE)) - return true; - - if (other != EVERYONE_MODULE) { - // exported to other - if (targets.contains(other)) - return true; - - // other is an unnamed module && exported to all unnamed - if (!other.isNamed() && targets.contains(ALL_UNNAMED_MODULE)) - return true; - } - - } + if ((targets != null) + && (targets.contains(other) || targets.contains(EVERYONE_MODULE))) + return true; } return false; } @@ -515,29 +483,27 @@ * package package to the given module. */ private boolean isExportedReflectively(String pn, Module other) { - Map> te = this.transientExports; - if (te != null) { - WeakSet targets = te.get(pn); + // exported to all modules + Map exports = transientExports.get(this, EVERYONE_MODULE); + if (exports != null && exports.containsKey(pn)) + return true; - if (targets != null) { - - // exported to all modules - if (targets.contains(EVERYONE_MODULE)) - return true; + if (other != EVERYONE_MODULE) { - if (other != EVERYONE_MODULE) { + // exported to other + exports = transientExports.get(this, other); + if (exports != null && exports.containsKey(pn)) + return true; - // exported to other - if (targets.contains(other)) - return true; - - // other is an unnamed module && exported to all unnamed - if (!other.isNamed() && targets.contains(ALL_UNNAMED_MODULE)) - return true; - } + // other is an unnamed module && exported to all unnamed + if (!other.isNamed()) { + exports = transientExports.get(this, ALL_UNNAMED_MODULE); + if (exports != null && exports.containsKey(pn)) + return true; } } + return false; } @@ -638,34 +604,19 @@ } } - // create transientExports if needed - Map> te = this.transientExports; // read - if (te == null) { - synchronized (this) { - te = this.transientExports; - if (te == null) { - te = new ConcurrentHashMap<>(); - this.transientExports = te; // volatile write - } - } - } - // add package name to transientExports if absent - WeakSet s = te.get(pn); - if (s == null) { - s = new WeakSet<>(); - WeakSet prev = te.putIfAbsent(pn, s); - if (prev != null) - s = prev; - } - s.add(other); + transientExports + .computeIfAbsent(this, other, + (_this, _other) -> new ConcurrentHashMap<>()) + .putIfAbsent(pn, Boolean.TRUE); } // -- services -- - // created lazily, additional service types that this module uses - private volatile WeakSet> transientUses; + // additional service type (2nd key) that some module (1st key) uses + private static final WeakPairMap, Boolean> transientUses + = new WeakPairMap<>(); /** * If the caller's module is this module then update this module to add a @@ -702,17 +653,7 @@ } if (!canUse(st)) { - WeakSet> uses = this.transientUses; - if (uses == null) { - synchronized (this) { - uses = this.transientUses; - if (uses == null) { - uses = new WeakSet<>(); - this.transientUses = uses; - } - } - } - uses.add(st); + transientUses.putIfAbsent(this, st, Boolean.TRUE); } } @@ -746,11 +687,7 @@ return true; // uses added via addUses - WeakSet> uses = this.transientUses; - if (uses != null && uses.contains(st)) - return true; - - return false; + return transientUses.containsKeyPair(this, st); } @@ -885,7 +822,7 @@ // -- creating Module objects -- /** - * Find the runtime Module corresponding to the given ReadDependence + * Find the runtime Module corresponding to the given ResolvedModule * in the given parent Layer (or its parents). */ private static Module find(ResolvedModule resolvedModule, Layer layer) { @@ -969,7 +906,7 @@ // automatic modules reads all unnamed modules if (descriptor.isAutomatic()) { - m.implAddReads(null, true); + m.implAddReads(ALL_UNNAMED_MODULE, true); } // exports @@ -1097,7 +1034,7 @@ * the representation is the string {@code "module"}, followed by a space, * and then the module name. For an unnamed module, the representation is * the string {@code "unnamed module"}, followed by a space, and then an - * implementation specific identifier for the unnamed module. + * implementation specific string that identifies the unnamed module. * * @return The string representation of this module */ @@ -1112,46 +1049,6 @@ } - // -- supporting classes -- - - - /** - * A "not-a-Set" set of weakly referenced objects that supports concurrent - * access. - */ - private static class WeakSet { - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - private final Lock readLock = lock.readLock(); - private final Lock writeLock = lock.writeLock(); - - private final WeakHashMap map = new WeakHashMap<>(); - - /** - * Adds the specified element to the set. - */ - void add(E e) { - writeLock.lock(); - try { - map.put(e, Boolean.TRUE); - } finally { - writeLock.unlock(); - } - } - - /** - * Returns {@code true} if this set contains the specified element. - */ - boolean contains(E e) { - readLock.lock(); - try { - return map.containsKey(e); - } finally { - readLock.unlock(); - } - } - } - - // -- native methods -- // JVM_DefineModule @@ -1196,8 +1093,12 @@ m1.implAddReads(m2, true); } @Override + public void addReadsAllUnnamed(Module m) { + m.implAddReads(Module.ALL_UNNAMED_MODULE); + } + @Override public void addExports(Module m, String pn, Module other) { - m.implAddExports(pn, Objects.requireNonNull(other), true); + m.implAddExports(pn, other, true); } @Override public void addExportsToAll(Module m, String pn) { @@ -1211,6 +1112,10 @@ public void addPackage(Module m, String pn) { m.implAddPackage(pn, true); } + @Override + public ServicesCatalog getServicesCatalog(Layer layer) { + return layer.getServicesCatalog(); + } }); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java --- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Thu May 05 19:11:09 2016 +0000 @@ -582,7 +582,7 @@ } private static final String DEBUG = - GetPropertyAction.getProperty("jdk.proxy.debug", ""); + GetPropertyAction.privilegedGetProperty("jdk.proxy.debug", ""); private static boolean isDebug() { return !DEBUG.isEmpty(); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/lang/reflect/WeakPairMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/WeakPairMap.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,354 @@ +/* + * 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.reflect; + +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.Collection; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiFunction; + +/** + * A WeakHashMap-like data structure that uses a pair of weakly-referenced keys + * with identity equality semantics to associate a strongly-referenced value. + * Unlike WeakHashMap, this data structure is thread-safe. + * + * @param the type of 1st key in key pair + * @param the type of 2nd key in key pair + * @param the type of value + * @author Peter Levart + */ +final class WeakPairMap { + + private final ConcurrentHashMap, V> map = new ConcurrentHashMap<>(); + private final ReferenceQueue queue = new ReferenceQueue<>(); + + /** + * Tests if the specified pair of keys are associated with a value + * in the WeakPairMap. + * + * @param k1 the 1st of the pair of keys + * @param k2 the 2nd of the pair of keys + * @return true if and only if the specified key pair is in this WeakPairMap, + * as determined by the identity comparison; false otherwise + * @throws NullPointerException if any of the specified keys is null + */ + public boolean containsKeyPair(K1 k1, K2 k2) { + expungeStaleAssociations(); + return map.containsKey(Pair.lookup(k1, k2)); + } + + /** + * Returns the value to which the specified pair of keys is mapped, or null + * if this WeakPairMap contains no mapping for the key pair. + *

More formally, if this WeakPairMap contains a mapping from a key pair + * {@code (_k1, _k2)} to a value {@code v} such that + * {@code k1 == _k1 && k2 == _k2}, then this method returns {@code v}; + * otherwise it returns {@code null}. + * (There can be at most one such mapping.) + * + * @param k1 the 1st of the pair of keys for which the mapped value is to + * be returned + * @param k2 the 2nd of the pair of keys for which the mapped value is to + * be returned + * @return the value to which the specified key pair is mapped, or null if + * this map contains no mapping for the key pair + * @throws NullPointerException if any of the specified keys is null + */ + public V get(K1 k1, K2 k2) { + expungeStaleAssociations(); + return map.get(Pair.lookup(k1, k2)); + } + + /** + * Maps the specified key pair to the specified value in this WeakPairMap. + * Neither the keys nor the value can be null. + *

The value can be retrieved by calling the {@link #get} method + * with the the same keys (compared by identity). + * + * @param k1 the 1st of the pair of keys with which the specified value is to + * be associated + * @param k2 the 2nd of the pair of keys with which the specified value is to + * be associated + * @param v value to be associated with the specified key pair + * @return the previous value associated with key pair, or {@code null} if + * there was no mapping for key pair + * @throws NullPointerException if any of the specified keys or value is null + */ + public V put(K1 k1, K2 k2, V v) { + expungeStaleAssociations(); + return map.put(Pair.weak(k1, k2, queue), v); + } + + /** + * If the specified key pair is not already associated with a value, + * associates it with the given value and returns {@code null}, else does + * nothing and returns the currently associated value. + * + * @param k1 the 1st of the pair of keys with which the specified value is to + * be associated + * @param k2 the 2nd of the pair of keys with which the specified value is to + * be associated + * @param v value to be associated with the specified key pair + * @return the previous value associated with key pair, or {@code null} if + * there was no mapping for key pair + * @throws NullPointerException if any of the specified keys or value is null + */ + public V putIfAbsent(K1 k1, K2 k2, V v) { + expungeStaleAssociations(); + return map.putIfAbsent(Pair.weak(k1, k2, queue), v); + } + + /** + * If the specified key pair is not already associated with a value, + * attempts to compute its value using the given mapping function + * and enters it into this WeakPairMap unless {@code null}. The entire + * method invocation is performed atomically, so the function is + * applied at most once per key pair. Some attempted update operations + * on this WeakPairMap by other threads may be blocked while computation + * is in progress, so the computation should be short and simple, + * and must not attempt to update any other mappings of this WeakPairMap. + * + * @param k1 the 1st of the pair of keys with which the + * computed value is to be associated + * @param k2 the 2nd of the pair of keys with which the + * computed value is to be associated + * @param mappingFunction the function to compute a value + * @return the current (existing or computed) value associated with + * the specified key pair, or null if the computed value is null + * @throws NullPointerException if any of the specified keys or + * mappingFunction is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map + * that would otherwise never complete + * @throws RuntimeException or Error if the mappingFunction does so, in + * which case the mapping is left unestablished + */ + public V computeIfAbsent(K1 k1, K2 k2, + BiFunction + mappingFunction) { + expungeStaleAssociations(); + try { + return map.computeIfAbsent( + Pair.weak(k1, k2, queue), + pair -> mappingFunction.apply(pair.first(), pair.second())); + } finally { + Reference.reachabilityFence(k1); + Reference.reachabilityFence(k2); + } + } + + /** + * Returns a {@link Collection} view of the values contained in this + * WeakPairMap. The collection is backed by the WeakPairMap, so changes to + * the map are reflected in the collection, and vice-versa. The collection + * supports element removal, which removes the corresponding + * mapping from this map, via the {@code Iterator.remove}, + * {@code Collection.remove}, {@code removeAll}, + * {@code retainAll}, and {@code clear} operations. It does not + * support the {@code add} or {@code addAll} operations. + * + * @return the collection view + */ + public Collection values() { + expungeStaleAssociations(); + return map.values(); + } + + /** + * Removes associations from this WeakPairMap for which at least one of the + * keys in key pair has been found weakly-reachable and corresponding + * WeakRefPeer(s) enqueued. Called as part of each public operation. + */ + private void expungeStaleAssociations() { + WeakRefPeer peer; + while ((peer = (WeakRefPeer) queue.poll()) != null) { + map.remove(peer.weakPair()); + } + } + + /** + * Common interface of both {@link Weak} and {@link Lookup} key pairs. + */ + private interface Pair { + + static Pair weak(K1 k1, K2 k2, + ReferenceQueue queue) { + return new Weak<>(k1, k2, queue); + } + + static Pair lookup(K1 k1, K2 k2) { + return new Lookup<>(k1, k2); + } + + /** + * @return The 1st of the pair of keys (may be null for {@link Weak} + * when it gets cleared) + */ + K1 first(); + + /** + * @return The 2nd of the pair of keys (may be null for {@link Weak} + * when it gets cleared) + */ + K2 second(); + + static int hashCode(Object first, Object second) { + // assert first != null && second != null; + return System.identityHashCode(first) ^ + System.identityHashCode(second); + } + + static boolean equals(Object first, Object second, Pair p) { + return first != null && second != null && + first == p.first() && second == p.second(); + } + + /** + * A Pair where both keys are weakly-referenced. + * It is composed of two instances of {@link WeakRefPeer}s: + *
{@code
+         *
+         *     +-referent-> [K1]                +-referent-> [K2]
+         *     |                                |
+         *   +----------------+               +----------------+
+         *   | Pair.Weak <:   |-----peer----->| (anonymous) <: |
+         *   | WeakRefPeer,   |               | WeakRefPeer    |
+         *   | Pair           |<--weakPair()--|                |
+         *   +----------------+               +----------------+
+         *     |            ^
+         *     |            |
+         *     +-weakPair()-+
+         *
+         * }
+ *

+ * Pair.Weak is used for CHM keys. Both peers are associated with the + * same {@link ReferenceQueue} so when either of their referents + * becomes weakly-reachable, the corresponding entries can be + * {@link #expungeStaleAssociations() expunged} from the map. + */ + final class Weak extends WeakRefPeer implements Pair { + + // saved hash so it can be retrieved after the reference is cleared + private final int hash; + // link to peer + private final WeakRefPeer peer; + + Weak(K1 k1, K2 k2, ReferenceQueue queue) { + super(k1, queue); + hash = Pair.hashCode(k1, k2); + peer = new WeakRefPeer<>(k2, queue) { + // link back to peer + @Override + Weak weakPair() { return Weak.this; } + }; + } + + @Override + Weak weakPair() { + return this; + } + + @Override + public K1 first() { + return get(); + } + + @Override + public K2 second() { + return peer.get(); + } + + @Override + public int hashCode() { + return hash; + } + + @Override + public boolean equals(Object obj) { + return this == obj || + (obj instanceof Pair && + Pair.equals(first(), second(), (Pair) obj)); + } + } + + /** + * Optimized lookup Pair, used as lookup key in methods like + * {@link java.util.Map#get(Object)} or + * {@link java.util.Map#containsKey(Object)}) where + * there is a great chance its allocation is eliminated + * by escape analysis when such lookups are inlined by JIT. + * All its methods are purposely designed so that 'this' is never + * passed to any other method or used as identity. + */ + final class Lookup implements Pair { + private final K1 k1; + private final K2 k2; + + Lookup(K1 k1, K2 k2) { + this.k1 = Objects.requireNonNull(k1); + this.k2 = Objects.requireNonNull(k2); + } + + @Override + public K1 first() { + return k1; + } + + @Override + public K2 second() { + return k2; + } + + @Override + public int hashCode() { + return Pair.hashCode(k1, k2); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Pair && + Pair.equals(k1, k2, (Pair) obj); + } + } + } + + /** + * Common abstract supertype of a pair of WeakReference peers. + */ + private static abstract class WeakRefPeer extends WeakReference { + + WeakRefPeer(K k, ReferenceQueue queue) { + super(Objects.requireNonNull(k), queue); + } + + /** + * @return the {@link Pair.Weak} side of the pair of peers. + */ + abstract Pair.Weak weakPair(); + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/math/BigDecimal.java --- a/jdk/src/java.base/share/classes/java/math/BigDecimal.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/math/BigDecimal.java Thu May 05 19:11:09 2016 +0000 @@ -1536,7 +1536,7 @@ * be performed to generate a result with the specified scale, the * specified rounding mode is applied. * - *

The new {@link #divide(BigDecimal, int, RoundingMode)} method + * @deprecated The method {@link #divide(BigDecimal, int, RoundingMode)} * should be used in preference to this legacy method. * * @param divisor value by which this {@code BigDecimal} is to be divided. @@ -1558,6 +1558,7 @@ * @see #ROUND_HALF_EVEN * @see #ROUND_UNNECESSARY */ + @Deprecated(since="9") public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) { if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY) throw new IllegalArgumentException("Invalid rounding mode"); @@ -1602,7 +1603,7 @@ * rounding must be performed to generate a result with the given * scale, the specified rounding mode is applied. * - *

The new {@link #divide(BigDecimal, RoundingMode)} method + * @deprecated The method {@link #divide(BigDecimal, RoundingMode)} * should be used in preference to this legacy method. * * @param divisor value by which this {@code BigDecimal} is to be divided. @@ -1623,6 +1624,7 @@ * @see #ROUND_HALF_EVEN * @see #ROUND_UNNECESSARY */ + @Deprecated(since="9") public BigDecimal divide(BigDecimal divisor, int roundingMode) { return this.divide(divisor, scale, roundingMode); } @@ -2267,14 +2269,20 @@ * Rounding mode to round away from zero. Always increments the * digit prior to a nonzero discarded fraction. Note that this rounding * mode never decreases the magnitude of the calculated value. + * + * @deprecated Use {@link RoundingMode#UP} instead. */ + @Deprecated(since="9") public static final int ROUND_UP = 0; /** * Rounding mode to round towards zero. Never increments the digit * prior to a discarded fraction (i.e., truncates). Note that this * rounding mode never increases the magnitude of the calculated value. + * + * @deprecated Use {@link RoundingMode#DOWN} instead. */ + @Deprecated(since="9") public static final int ROUND_DOWN = 1; /** @@ -2283,7 +2291,10 @@ * {@code ROUND_UP}; if negative, behaves as for * {@code ROUND_DOWN}. Note that this rounding mode never * decreases the calculated value. + * + * @deprecated Use {@link RoundingMode#CEILING} instead. */ + @Deprecated(since="9") public static final int ROUND_CEILING = 2; /** @@ -2292,7 +2303,10 @@ * {@code ROUND_DOWN}; if negative, behave as for * {@code ROUND_UP}. Note that this rounding mode never * increases the calculated value. + * + * @deprecated Use {@link RoundingMode#FLOOR} instead. */ + @Deprecated(since="9") public static final int ROUND_FLOOR = 3; /** @@ -2302,7 +2316,10 @@ * ≥ 0.5; otherwise, behaves as for {@code ROUND_DOWN}. Note * that this is the rounding mode that most of us were taught in * grade school. + * + * @deprecated Use {@link RoundingMode#HALF_UP} instead. */ + @Deprecated(since="9") public static final int ROUND_HALF_UP = 4; /** @@ -2311,7 +2328,10 @@ * down. Behaves as for {@code ROUND_UP} if the discarded * fraction is {@literal >} 0.5; otherwise, behaves as for * {@code ROUND_DOWN}. + * + * @deprecated Use {@link RoundingMode#HALF_DOWN} instead. */ + @Deprecated(since="9") public static final int ROUND_HALF_DOWN = 5; /** @@ -2323,7 +2343,10 @@ * {@code ROUND_HALF_DOWN} if it's even. Note that this is the * rounding mode that minimizes cumulative error when applied * repeatedly over a sequence of calculations. + * + * @deprecated Use {@link RoundingMode#HALF_EVEN} instead. */ + @Deprecated(since="9") public static final int ROUND_HALF_EVEN = 6; /** @@ -2331,7 +2354,10 @@ * result, hence no rounding is necessary. If this rounding mode is * specified on an operation that yields an inexact result, an * {@code ArithmeticException} is thrown. + * + * @deprecated Use {@link RoundingMode#UNNECESSARY} instead. */ + @Deprecated(since="9") public static final int ROUND_UNNECESSARY = 7; @@ -2408,7 +2434,7 @@ * Instead, {@code setScale} returns an object with the proper * scale; the returned object may or may not be newly allocated. * - *

The new {@link #setScale(int, RoundingMode)} method should + * @deprecated The method {@link #setScale(int, RoundingMode)} should * be used in preference to this legacy method. * * @param newScale scale of the {@code BigDecimal} value to be returned. @@ -2431,6 +2457,7 @@ * @see #ROUND_HALF_EVEN * @see #ROUND_UNNECESSARY */ + @Deprecated(since="9") public BigDecimal setScale(int newScale, int roundingMode) { if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY) throw new IllegalArgumentException("Invalid rounding mode"); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/math/RoundingMode.java --- a/jdk/src/java.base/share/classes/java/math/RoundingMode.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/math/RoundingMode.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -90,6 +90,7 @@ * @author Joseph D. Darcy * @since 1.5 */ +@SuppressWarnings("deprecation") // Legacy rounding mode constants in BigDecimal public enum RoundingMode { /** diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java --- a/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Thu May 05 19:11:09 2016 +0000 @@ -52,7 +52,8 @@ protected InetAddress connectedAddress = null; private int connectedPort = -1; - private static final String os = GetPropertyAction.getProperty("os.name"); + private static final String os = + GetPropertyAction.privilegedGetProperty("os.name"); /** * flag set if the native connect() call not to be used diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/net/InetAddress.java --- a/jdk/src/java.base/share/classes/java/net/InetAddress.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java Thu May 05 19:11:09 2016 +0000 @@ -1124,7 +1124,7 @@ private static NameService createNameService() { String hostsFileName = - GetPropertyAction.getProperty("jdk.net.hosts.file"); + GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file"); NameService theNameService; if (hostsFileName != null) { theNameService = new HostsFileNameService(hostsFileName); @@ -1643,9 +1643,11 @@ * property can vary across implementations of the java. * classes. The default is an empty String "". */ - String prefix = GetPropertyAction.getProperty("impl.prefix", ""); + String prefix = GetPropertyAction.privilegedGetProperty("impl.prefix", ""); try { - impl = Class.forName("java.net." + prefix + implName).newInstance(); + @SuppressWarnings("deprecation") + Object tmp = Class.forName("java.net." + prefix + implName).newInstance(); + impl = tmp; } catch (ClassNotFoundException e) { System.err.println("Class not found: java.net." + prefix + implName + ":\ncheck impl.prefix property " + @@ -1662,7 +1664,9 @@ if (impl == null) { try { - impl = Class.forName(implName).newInstance(); + @SuppressWarnings("deprecation") + Object tmp = Class.forName(implName).newInstance(); + impl = tmp; } catch (Exception e) { throw new Error("System property impl.prefix incorrect"); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/net/ProxySelector.java --- a/jdk/src/java.base/share/classes/java/net/ProxySelector.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/net/ProxySelector.java Thu May 05 19:11:09 2016 +0000 @@ -71,7 +71,9 @@ try { Class c = Class.forName("sun.net.spi.DefaultProxySelector"); if (c != null && ProxySelector.class.isAssignableFrom(c)) { - theProxySelector = (ProxySelector) c.newInstance(); + @SuppressWarnings("deprecation") + ProxySelector tmp = (ProxySelector) c.newInstance(); + theProxySelector = tmp; } } catch (Exception e) { theProxySelector = null; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java --- a/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java Thu May 05 19:11:09 2016 +0000 @@ -178,7 +178,7 @@ userName = pw.getUserName(); password = new String(pw.getPassword()); } else { - userName = GetPropertyAction.getProperty("user.name"); + userName = GetPropertyAction.privilegedGetProperty("user.name"); } if (userName == null) return false; @@ -1088,7 +1088,7 @@ userName = System.getProperty("user.name"); } catch (SecurityException se) { /* swallow Exception */ } } else { - userName = GetPropertyAction.getProperty("user.name"); + userName = GetPropertyAction.privilegedGetProperty("user.name"); } return userName; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/net/URL.java --- a/jdk/src/java.base/share/classes/java/net/URL.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/net/URL.java Thu May 05 19:11:09 2016 +0000 @@ -1198,8 +1198,9 @@ public URLStreamHandler createURLStreamHandler(String protocol) { String name = PREFIX + "." + protocol + ".Handler"; try { - Class c = Class.forName(name); - return (URLStreamHandler)c.newInstance(); + @SuppressWarnings("deprecation") + Object o = Class.forName(name).newInstance(); + return (URLStreamHandler)o; } catch (ClassNotFoundException x) { // ignore } catch (Exception e) { @@ -1212,7 +1213,7 @@ private static URLStreamHandler lookupViaProperty(String protocol) { String packagePrefixList = - GetPropertyAction.getProperty(protocolPathProp); + GetPropertyAction.privilegedGetProperty(protocolPathProp); if (packagePrefixList == null) { // not set return null; @@ -1234,7 +1235,9 @@ } } if (cls != null) { - handler = (URLStreamHandler)cls.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = cls.newInstance(); + handler = (URLStreamHandler)tmp; } } catch (Exception e) { // any number of exceptions can get thrown here diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/net/URLConnection.java --- a/jdk/src/java.base/share/classes/java/net/URLConnection.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java Thu May 05 19:11:09 2016 +0000 @@ -1323,7 +1323,9 @@ } } if (cls != null) { - return (ContentHandler) cls.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = cls.newInstance(); + return (ContentHandler) tmp; } } catch(Exception ignored) { } } @@ -1397,7 +1399,7 @@ */ private String getContentHandlerPkgPrefixes() { String packagePrefixList = - GetPropertyAction.getProperty(contentPathProp, ""); + GetPropertyAction.privilegedGetProperty(contentPathProp, ""); if (packagePrefixList != "") { packagePrefixList += "|"; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/net/URLEncoder.java --- a/jdk/src/java.base/share/classes/java/net/URLEncoder.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/net/URLEncoder.java Thu May 05 19:11:09 2016 +0000 @@ -133,7 +133,7 @@ dontNeedEncoding.set('.'); dontNeedEncoding.set('*'); - dfltEncName = GetPropertyAction.getProperty("file.encoding"); + dfltEncName = GetPropertyAction.privilegedGetProperty("file.encoding"); } /** diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java --- a/jdk/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java Thu May 05 19:11:09 2016 +0000 @@ -94,9 +94,10 @@ if (cn == null) return null; try { - Class c = Class.forName(cn, true, - ClassLoader.getSystemClassLoader()); - return (AsynchronousChannelProvider)c.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = Class.forName(cn, true, + ClassLoader.getSystemClassLoader()).newInstance(); + return (AsynchronousChannelProvider)tmp; } catch (ClassNotFoundException x) { throw new ServiceConfigurationError(null, x); } catch (IllegalAccessException x) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java --- a/jdk/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java Thu May 05 19:11:09 2016 +0000 @@ -95,9 +95,10 @@ if (cn == null) return false; try { - Class c = Class.forName(cn, true, - ClassLoader.getSystemClassLoader()); - provider = (SelectorProvider)c.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = Class.forName(cn, true, + ClassLoader.getSystemClassLoader()).newInstance(); + provider = (SelectorProvider)tmp; return true; } catch (ClassNotFoundException x) { throw new ServiceConfigurationError(null, x); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/nio/charset/Charset.java --- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java Thu May 05 19:11:09 2016 +0000 @@ -283,8 +283,8 @@ if (level == null) { if (!VM.isBooted()) return false; - bugLevel = level = - GetPropertyAction.getProperty("sun.nio.cs.bugLevel", ""); + bugLevel = level = GetPropertyAction + .privilegedGetProperty("sun.nio.cs.bugLevel", ""); } return level.equals(bl); } @@ -609,7 +609,8 @@ public static Charset defaultCharset() { if (defaultCharset == null) { synchronized (Charset.class) { - String csn = GetPropertyAction.getProperty("file.encoding"); + String csn = GetPropertyAction + .privilegedGetProperty("file.encoding"); Charset cs = lookup(csn); if (cs != null) defaultCharset = cs; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java --- a/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java Thu May 05 19:11:09 2016 +0000 @@ -46,7 +46,7 @@ // temporary directory location private static final Path tmpdir = - Paths.get(GetPropertyAction.getProperty("java.io.tmpdir")); + Paths.get(GetPropertyAction.privilegedGetProperty("java.io.tmpdir")); private static final boolean isPosix = FileSystems.getDefault().supportedFileAttributeViews().contains("posix"); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/security/Policy.java --- a/jdk/src/java.base/share/classes/java/security/Policy.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/security/Policy.java Thu May 05 19:11:09 2016 +0000 @@ -222,8 +222,9 @@ public Policy run() { try { ClassLoader scl = ClassLoader.getSystemClassLoader(); - Class c = Class.forName(policyProvider, true, scl); - return (Policy)c.newInstance(); + @SuppressWarnings("deprecation") + Object o = Class.forName(policyProvider, true, scl).newInstance(); + return (Policy)o; } catch (Exception e) { if (debug != null) { debug.println("policy provider " + policyProvider + diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java --- a/jdk/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java Thu May 05 19:11:09 2016 +0000 @@ -147,6 +147,7 @@ if (prop != null) { try { Class c = Class.forName(prop, true, ClassLoader.getSystemClassLoader()); + @SuppressWarnings("deprecation") ZoneRulesProvider provider = ZoneRulesProvider.class.cast(c.newInstance()); registerProvider(provider); loaded.add(provider); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/Locale.java --- a/jdk/src/java.base/share/classes/java/util/Locale.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/Locale.java Thu May 05 19:11:09 2016 +0000 @@ -858,7 +858,7 @@ private static Locale initDefault() { String language, region, script, country, variant; - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); language = props.getProperty("user.language", "en"); // for compatibility, check for old user.region property region = props.getProperty("user.region"); @@ -883,7 +883,7 @@ } private static Locale initDefault(Locale.Category category) { - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); return getInstance( props.getProperty(category.languageKey, defaultLocale.getLanguage()), diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java --- a/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Thu May 05 19:11:09 2016 +0000 @@ -140,9 +140,8 @@ // Check whether the strict encoding is specified. // The possible encoding is either "ISO-8859-1" or "UTF-8". - private static final String encoding = - GetPropertyAction - .getProperty("java.util.PropertyResourceBundle.encoding", "") + private static final String encoding = GetPropertyAction + .privilegedGetProperty("java.util.PropertyResourceBundle.encoding", "") .toUpperCase(Locale.ROOT); /** diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/ServiceLoader.java --- a/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Thu May 05 19:11:09 2016 +0000 @@ -29,8 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.lang.module.ModuleDescriptor; -import java.lang.module.ModuleDescriptor.Provides; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Layer; @@ -85,7 +83,7 @@ * and deployed as a named module must have an appropriate uses clause * in its module descriptor to declare that the module uses * implementations of the service. A corresponding requirement is that a - * provider deployed as a named modules must have an appropriate + * provider deployed as a named module must have an appropriate * provides clause in its module descriptor to declare that the module * provides an implementation of the service. The uses and * provides allow consumers of a service to be linked to @@ -550,35 +548,29 @@ /** * Implements lazy service provider lookup of service providers that * are provided by modules in a module Layer. - * - * For now, this iterator examines all modules in each Layer. This will - * be replaced once we decide on how the service-use graph is exposed - * in the module API. */ private class LayerLookupIterator extends RestrictedIterator { final String serviceName; Layer currentLayer; - Iterator descriptorIterator; - Iterator providersIterator; - - Module nextModule; - String nextProvider; + Iterator iterator; + ServiceProvider nextProvider; LayerLookupIterator() { serviceName = service.getName(); currentLayer = layer; // need to get us started - descriptorIterator = descriptors(layer, serviceName); + iterator = providers(currentLayer, serviceName); } - Iterator descriptors(Layer layer, String service) { - return layer.modules().stream() - .map(Module::getDescriptor) - .filter(d -> d.provides().get(service) != null) - .iterator(); + Iterator providers(Layer layer, String service) { + ServicesCatalog catalog = SharedSecrets + .getJavaLangReflectModuleAccess() + .getServicesCatalog(layer); + + return catalog.findServices(serviceName).iterator(); } @Override @@ -591,30 +583,18 @@ while (true) { // next provider - if (providersIterator != null && providersIterator.hasNext()) { - nextProvider = providersIterator.next(); + if (iterator != null && iterator.hasNext()) { + nextProvider = iterator.next(); return true; } - // next descriptor - if (descriptorIterator.hasNext()) { - ModuleDescriptor descriptor = descriptorIterator.next(); - - nextModule = currentLayer.findModule(descriptor.name()).get(); - - Provides provides = descriptor.provides().get(serviceName); - providersIterator = provides.providers().iterator(); - - continue; - } - // next layer Layer parent = currentLayer.parent().orElse(null); if (parent == null) return false; currentLayer = parent; - descriptorIterator = descriptors(currentLayer, serviceName); + iterator = providers(currentLayer, serviceName); } } @@ -623,13 +603,14 @@ if (!hasNextService()) throw new NoSuchElementException(); - assert nextModule != null && nextProvider != null; - - String cn = nextProvider; + ServiceProvider provider = nextProvider; nextProvider = null; + Module module = provider.module(); + String cn = provider.providerName(); + // attempt to load the provider - Class c = loadClassInModule(nextModule, cn); + Class c = loadClassInModule(module, cn); if (c == null) fail(service, "Provider " + cn + " not found"); if (!service.isAssignableFrom(c)) @@ -830,7 +811,9 @@ } S p = null; try { - p = service.cast(c.newInstance()); + @SuppressWarnings("deprecation") + Object tmp = c.newInstance(); + p = service.cast(tmp); } catch (Throwable x) { fail(service, "Provider " + cn + " could not be instantiated", diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/TimeZone.java --- a/jdk/src/java.base/share/classes/java/util/TimeZone.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/TimeZone.java Thu May 05 19:11:09 2016 +0000 @@ -42,6 +42,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.time.ZoneId; +import java.util.Properties; import sun.security.action.GetPropertyAction; import sun.util.calendar.ZoneInfo; import sun.util.calendar.ZoneInfoFile; @@ -660,12 +661,13 @@ private static synchronized TimeZone setDefaultZone() { TimeZone tz; // get the time zone ID from the system properties - String zoneID = GetPropertyAction.getProperty("user.timezone"); + Properties props = GetPropertyAction.privilegedGetProperties(); + String zoneID = props.getProperty("user.timezone"); // if the time zone ID is not set (yet), perform the // platform to Java time zone ID mapping. if (zoneID == null || zoneID.isEmpty()) { - String javaHome = GetPropertyAction.getProperty("java.home"); + String javaHome = props.getProperty("java.home"); try { zoneID = getSystemTimeZoneID(javaHome); if (zoneID == null) { @@ -693,13 +695,7 @@ assert tz != null; final String id = zoneID; - AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Void run() { - System.setProperty("user.timezone", id); - return null; - } - }); + props.setProperty("user.timezone", id); defaultTimeZone = tz; return tz; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Thu May 05 19:11:09 2016 +0000 @@ -3507,6 +3507,7 @@ * Creates and returns the common pool, respecting user settings * specified via system properties. */ + @SuppressWarnings("deprecation") // Class.newInstance static ForkJoinPool makeCommonPool() { int parallelism = -1; ForkJoinWorkerThreadFactory factory = null; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/jar/JarFile.java --- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java Thu May 05 19:11:09 2016 +0000 @@ -155,7 +155,7 @@ BASE_VERSION = 8; // one less than lowest version for versioned entries int runtimeVersion = jdk.Version.current().major(); String jarVersion = - GetPropertyAction.getProperty("jdk.util.jar.version"); + GetPropertyAction.privilegedGetProperty("jdk.util.jar.version"); if (jarVersion != null) { int jarVer = Integer.parseInt(jarVersion); runtimeVersion = (jarVer > runtimeVersion) @@ -163,7 +163,7 @@ } RUNTIME_VERSION = runtimeVersion; String enableMultiRelease = GetPropertyAction - .getProperty("jdk.util.jar.enableMultiRelease", "true"); + .privilegedGetProperty("jdk.util.jar.enableMultiRelease", "true"); switch (enableMultiRelease) { case "true": default: @@ -658,6 +658,28 @@ return vze == null ? ze : vze; } + /** + * Returns the real name of a {@code JarEntry}. If this {@code JarFile} is + * a multi-release jar file and is configured to be processed as such, the + * name returned by this method is the path name of the versioned entry + * that the {@code JarEntry} represents, rather than the path name of the + * base entry that {@link JarEntry#getName()} returns. If the + * {@code JarEntry} does not represent a versioned entry, or the + * jar file is not a multi-release jar file or {@code JarFile} is not + * configured for processing a multi-release jar file, this method returns + * the same name that {@link JarEntry#getName()} returns. + * + * @param entry the JarEntry + * @return the real name of the JarEntry + * @since 9 + */ + String getRealName(JarEntry entry) { + if (entry instanceof JarFileEntry) { + return ((JarFileEntry)entry).realName(); + } + return entry.getName(); + } + private class JarFileEntry extends JarEntry { final private String name; @@ -684,7 +706,7 @@ throw new RuntimeException(e); } if (certs == null && jv != null) { - certs = jv.getCerts(JarFile.this, reifiedEntry()); + certs = jv.getCerts(JarFile.this, realEntry()); } return certs == null ? null : certs.clone(); } @@ -695,17 +717,20 @@ throw new RuntimeException(e); } if (signers == null && jv != null) { - signers = jv.getCodeSigners(JarFile.this, reifiedEntry()); + signers = jv.getCodeSigners(JarFile.this, realEntry()); } return signers == null ? null : signers.clone(); } - JarFileEntry reifiedEntry() { + JarFileEntry realEntry() { if (isMultiRelease()) { String entryName = super.getName(); return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this); } return this; } + String realName() { + return super.getName(); + } @Override public String getName() { @@ -876,11 +901,11 @@ private JarEntry verifiableEntry(ZipEntry ze) { if (ze instanceof JarFileEntry) { // assure the name and entry match for verification - return ((JarFileEntry)ze).reifiedEntry(); + return ((JarFileEntry)ze).realEntry(); } ze = getJarEntry(ze.getName()); if (ze instanceof JarFileEntry) { - return ((JarFileEntry)ze).reifiedEntry(); + return ((JarFileEntry)ze).realEntry(); } return (JarEntry)ze; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java --- a/jdk/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java Thu May 05 19:11:09 2016 +0000 @@ -60,4 +60,8 @@ public List getManifestDigests(JarFile jar) { return jar.getManifestDigests(); } + + public String getRealName(JarFile jar, JarEntry entry) { + return jar.getRealName(entry); + } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/jar/Pack200.java --- a/jdk/src/java.base/share/classes/java/util/jar/Pack200.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/jar/Pack200.java Thu May 05 19:11:09 2016 +0000 @@ -695,7 +695,7 @@ Class impl = (PACK_PROVIDER.equals(prop))? packerImpl: unpackerImpl; if (impl == null) { // The first time, we must decide which class to use. - implName = GetPropertyAction.getProperty(prop,""); + implName = GetPropertyAction.privilegedGetProperty(prop,""); if (implName != null && !implName.equals("")) impl = Class.forName(implName); else if (PACK_PROVIDER.equals(prop)) @@ -704,7 +704,9 @@ impl = com.sun.java.util.jar.pack.UnpackerImpl.class; } // We have a class. Now instantiate it. - return impl.newInstance(); + @SuppressWarnings("deprecation") + Object result = impl.newInstance(); + return result; } catch (ClassNotFoundException e) { throw new Error("Class not found: " + implName + ":\ncheck property " + prop + diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java --- a/jdk/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java Thu May 05 19:11:09 2016 +0000 @@ -94,7 +94,7 @@ } private static final String nl = - GetPropertyAction.getProperty("line.separator"); + GetPropertyAction.privilegedGetProperty("line.separator"); /** * Returns a multi-line string containing the description of the syntax diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java --- a/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java Thu May 05 19:11:09 2016 +0000 @@ -55,7 +55,7 @@ */ private static final boolean inhibitZip64 = Boolean.parseBoolean( - GetPropertyAction.getProperty("jdk.util.zip.inhibitZip64")); + GetPropertyAction.privilegedGetProperty("jdk.util.zip.inhibitZip64")); private static class XEntry { final ZipEntry entry; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java Thu May 05 19:11:09 2016 +0000 @@ -97,6 +97,7 @@ } } log("class " + clsName + " is loaded"); + @SuppressWarnings("deprecation") SSLServerSocketFactory fac = (SSLServerSocketFactory)cls.newInstance(); log("instantiated an instance of class " + clsName); theFactory = fac; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java Thu May 05 19:11:09 2016 +0000 @@ -51,7 +51,7 @@ static final boolean DEBUG; static { - String s = GetPropertyAction.getProperty("javax.net.debug", "") + String s = GetPropertyAction.privilegedGetProperty("javax.net.debug", "") .toLowerCase(Locale.ENGLISH); DEBUG = s.contains("all") || s.contains("ssl"); @@ -106,6 +106,7 @@ } } log("class " + clsName + " is loaded"); + @SuppressWarnings("deprecation") SSLSocketFactory fac = (SSLSocketFactory)cls.newInstance(); log("instantiated an instance of class " + clsName); theFactory = fac; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/javax/security/auth/login/Configuration.java --- a/jdk/src/java.base/share/classes/javax/security/auth/login/Configuration.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/javax/security/auth/login/Configuration.java Thu May 05 19:11:09 2016 +0000 @@ -250,7 +250,9 @@ finalClass, false, Thread.currentThread().getContextClassLoader() ).asSubclass(Configuration.class); - return implClass.newInstance(); + @SuppressWarnings("deprecation") + Configuration result = implClass.newInstance(); + return result; } }); AccessController.doPrivileged( diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/javax/security/auth/login/LoginContext.java --- a/jdk/src/java.base/share/classes/javax/security/auth/login/LoginContext.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/javax/security/auth/login/LoginContext.java Thu May 05 19:11:09 2016 +0000 @@ -304,7 +304,9 @@ Class c = Class.forName( defaultHandler, true, finalLoader).asSubclass(CallbackHandler.class); - return c.newInstance(); + @SuppressWarnings("deprecation") + CallbackHandler result = c.newInstance(); + return result; } }); } catch (java.security.PrivilegedActionException pae) { @@ -697,8 +699,9 @@ if (moduleStack[i].module == null) { try { - moduleStack[i].module = (LoginModule) Class.forName( - name, false, contextClassLoader).newInstance(); + @SuppressWarnings("deprecation") + Object tmp = Class.forName(name, false, contextClassLoader).newInstance(); + moduleStack[i].module = (LoginModule) tmp; if (debug != null) { debug.println(name + " loaded via reflection"); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/Version.java --- a/jdk/src/java.base/share/classes/jdk/Version.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/Version.java Thu May 05 19:11:09 2016 +0000 @@ -273,7 +273,8 @@ */ public static Version current() { if (current == null) { - current = parse(GetPropertyAction.getProperty("java.version")); + current = parse( + GetPropertyAction.privilegedGetProperty("java.version")); } return current; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java --- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java Thu May 05 19:11:09 2016 +0000 @@ -124,7 +124,9 @@ ClassLoader cl = newJrtFsLoader(jrtfs); try { Class c = Class.forName(JrtFileSystemProvider.class.getName(), false, cl); - return ((FileSystemProvider)c.newInstance()).newFileSystem(uri, newEnv); + @SuppressWarnings("deprecation") + Object tmp = c.newInstance(); + return ((FileSystemProvider)tmp).newFileSystem(uri, newEnv); } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java --- a/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -68,7 +68,7 @@ } // ServiceCatalog for the boot class loader - private static final ServicesCatalog SERVICES_CATALOG = new ServicesCatalog(); + private static final ServicesCatalog SERVICES_CATALOG = ServicesCatalog.create(); // ClassLoaderValue map for boot class loader private static final ConcurrentHashMap CLASS_LOADER_VALUE_MAP = diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java --- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Thu May 05 19:11:09 2016 +0000 @@ -104,7 +104,7 @@ * A module defined/loaded by a built-in class loader. * * A LoadedModule encapsulates a ModuleReference along with its CodeSource - * URL to avoid needing to create this URL when define classes. + * URL to avoid needing to create this URL when defining classes. */ private static class LoadedModule { private final BuiltinClassLoader loader; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java --- a/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Thu May 05 19:11:09 2016 +0000 @@ -85,7 +85,7 @@ private static final boolean DISABLE_JAR_CHECKING; static { - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); JAVA_VERSION = props.getProperty("java.version"); DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null); String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking"); @@ -372,9 +372,15 @@ return java.security.AccessController.doPrivileged( new java.security.PrivilegedExceptionAction<>() { public Loader run() throws IOException { + String protocol = url.getProtocol(); // lower cased in URL String file = url.getFile(); - if (file != null && file.endsWith("/")) { - if ("file".equals(url.getProtocol())) { + if ("jar".equals(protocol) + && file != null && (file.indexOf("!/") == file.length() - 2)) { + // extract the nested URL + URL nestedUrl = new URL(file.substring(0, file.length() - 2)); + return new JarLoader(nestedUrl, jarHandler, lmap); + } else if (file != null && file.endsWith("/")) { + if ("file".equals(protocol)) { return new FileLoader(url); } else { return new Loader(url); @@ -718,13 +724,13 @@ final URL url; try { + String nm; if (jar.isMultiRelease()) { - // add #runtime fragment to tell JarURLConnection to use - // runtime versioning if the underlying jar file is multi-release - url = new URL(getBaseURL(), ParseUtil.encodePath(name, false) + "#runtime"); + nm = SharedSecrets.javaUtilJarAccess().getRealName(jar, entry); } else { - url = new URL(getBaseURL(), ParseUtil.encodePath(name, false)); + nm = name; } + url = new URL(getBaseURL(), ParseUtil.encodePath(nm, false)); if (check) { URLClassPath.check(url); } @@ -940,7 +946,8 @@ ensureOpen(); - if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary + // Only get manifest when necessary + if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { Manifest man = jar.getManifest(); if (man != null) { Attributes attr = man.getMainAttributes(); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java --- a/jdk/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java Thu May 05 19:11:09 2016 +0000 @@ -81,7 +81,7 @@ // Get configuration error policy private static ErrorPolicy configurationErrorPolicy() { String errorPolicy = - GetPropertyAction.getProperty("jdk.logger.finder.error"); + GetPropertyAction.privilegedGetProperty("jdk.logger.finder.error"); if (errorPolicy == null || errorPolicy.isEmpty()) { return ErrorPolicy.WARNING; } @@ -96,7 +96,7 @@ // This is further submitted to the configuration error policy. private static boolean ensureSingletonProvider() { return Boolean.parseBoolean( - GetPropertyAction.getProperty("jdk.logger.finder.singleton")); + GetPropertyAction.privilegedGetProperty("jdk.logger.finder.singleton")); } private static Iterator findLoggerFinderProviders() { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java --- a/jdk/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java Thu May 05 19:11:09 2016 +0000 @@ -56,7 +56,7 @@ static Level getDefaultLevel() { String levelName = GetPropertyAction - .getProperty("jdk.system.logger.level", "INFO"); + .privilegedGetProperty("jdk.system.logger.level", "INFO"); try { return Level.valueOf(levelName); } catch (IllegalArgumentException iae) { @@ -426,7 +426,7 @@ static private final String[] skips; static { String additionalPkgs = - GetPropertyAction.getProperty("jdk.logger.packages"); + GetPropertyAction.privilegedGetProperty("jdk.logger.packages"); skips = additionalPkgs == null ? new String[0] : additionalPkgs.split(","); } @@ -485,7 +485,7 @@ // jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java // to fail - because that test has a testcase which somehow references // PlatformLogger and counts the number of generated lambda classes. - String format = GetPropertyAction.getProperty(key); + String format = GetPropertyAction.privilegedGetProperty(key); if (format == null && defaultPropertyGetter != null) { format = defaultPropertyGetter.apply(key); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java --- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,13 +25,24 @@ package jdk.internal.misc; +import java.io.PrintStream; +import java.lang.module.Configuration; +import jdk.internal.module.ModuleHashes; + import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleDescriptor.Exports; import java.lang.module.ModuleDescriptor.Requires; import java.lang.module.ModuleDescriptor.Provides; import java.lang.module.ModuleDescriptor.Version; +import java.lang.module.ModuleFinder; +import java.util.Collection; +import java.lang.module.ModuleReader; +import java.lang.module.ModuleReference; +import java.net.URI; import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.function.Supplier; /** * Provides access to non-public methods in java.lang.module. @@ -89,5 +100,29 @@ String osArch, String osVersion, Set conceals, - Set packages); + Set packages, + ModuleHashes hashes); + + /** + * Resolves a collection of root modules, with service binding + * and the empty configuration as the parent. The post resolution + * checks are optionally run. + */ + Configuration resolveRequiresAndUses(ModuleFinder finder, + Collection roots, + boolean check, + PrintStream traceOutput); + + /** + * Creates a ModuleReference to a "patched" module. + */ + ModuleReference newPatchedModule(ModuleDescriptor descriptor, + URI location, + Supplier readerSupplier); + + /** + * Returns the object with the hashes of other modules + */ + Optional hashes(ModuleDescriptor descriptor); + } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangReflectModuleAccess.java --- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangReflectModuleAccess.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangReflectModuleAccess.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -26,9 +26,12 @@ package jdk.internal.misc; import java.lang.module.ModuleDescriptor; +import java.lang.reflect.Layer; import java.lang.reflect.Module; import java.net.URI; +import jdk.internal.module.ServicesCatalog; + /** * Provides access to non-public methods in java.lang.reflect.Module */ @@ -57,6 +60,11 @@ void addReads(Module m1, Module m2); /** + * Updates module m to read all unnamed modules. + */ + void addReadsAllUnnamed(Module m); + + /** * Updates module m1 to export a package to module m2. The export does * not result in a strong reference to m2 (m2 can be GC'ed). */ @@ -76,4 +84,10 @@ * Add a package to the given module. */ void addPackage(Module m, String pkg); -} + + /** + * Returns the ServicesCatalog for the given Layer. + */ + ServicesCatalog getServicesCatalog(Layer layer); + +} \ No newline at end of file diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilJarAccess.java --- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilJarAccess.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilJarAccess.java Thu May 05 19:11:09 2016 +0000 @@ -41,4 +41,5 @@ public Enumeration entries2(JarFile jar); public void setEagerValidation(JarFile jar, boolean eager); public List getManifestDigests(JarFile jar); + public String getRealName(JarFile jar, JarEntry entry); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/Builder.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/Builder.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/Builder.java Thu May 05 19:11:09 2016 +0000 @@ -74,6 +74,8 @@ String osName; String osArch; String osVersion; + String algorithm; + Map hashes; Builder(String name, int reqs, int exports, int provides, int conceals, int packages) { @@ -252,6 +254,25 @@ } /** + * Sets the algorithm of the module hashes + */ + public Builder algorithm(String algorithm) { + this.algorithm = algorithm; + return this; + } + + /** + * Sets the module hash for the given module name + */ + public Builder moduleHash(String mn, String hash) { + if (hashes == null) + hashes = new HashMap<>(); + + hashes.put(mn, hash); + return this; + } + + /** * Returns the set of packages that is the union of the exported and * concealed packages. */ @@ -273,6 +294,9 @@ public ModuleDescriptor build() { assert name != null; + ModuleHashes moduleHashes = + hashes != null ? new ModuleHashes(algorithm, hashes) : null; + return jlma.newModuleDescriptor(name, false, // automatic false, // assume not synthetic for now @@ -286,6 +310,7 @@ osArch, osVersion, conceals, - computePackages(exports, conceals)); + computePackages(exports, conceals), + moduleHashes); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java Thu May 05 19:11:09 2016 +0000 @@ -34,6 +34,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -42,7 +43,6 @@ import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.module.Hasher.DependencyHashes; import static jdk.internal.module.ClassFileConstants.*; @@ -148,7 +148,7 @@ for (int i=0; i new HashSet<>()).add(cn); + provides.computeIfAbsent(sn, k -> new LinkedHashSet<>()).add(cn); off += 4; } provides.entrySet().forEach(e -> builder.provides(e.getKey(), @@ -281,10 +281,10 @@ * u4 attribute_length; * * // the number of entries in the packages table - * u2 package_count; + * u2 packages_count; * { // index to CONSTANT_CONSTANT_utf8_info structure with the package name * u2 package_index - * } package[package_count]; + * } packages[package_count]; * * } */ @@ -579,9 +579,9 @@ * alternative is to store it as an array of u1. */ static class HashesAttribute extends Attribute { - private final DependencyHashes hashes; + private final ModuleHashes hashes; - HashesAttribute(DependencyHashes hashes) { + HashesAttribute(ModuleHashes hashes) { super(HASHES); this.hashes = hashes; } @@ -613,7 +613,7 @@ map.put(dn, hash); } - DependencyHashes hashes = new DependencyHashes(algorithm, map); + ModuleHashes hashes = new ModuleHashes(algorithm, map); return new HashesAttribute(hashes); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/Hasher.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/Hasher.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. 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.internal.module; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.file.Path; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -/** - * Supporting class for computing, encoding and decoding hashes (message - * digests). - */ - -public class Hasher { - private Hasher() { } - - /** - * A supplier of an encoded message digest. - */ - public static interface HashSupplier { - String generate(String algorithm); - } - - /** - * Encapsulates the result of hashing the contents of a number of module - * artifacts. - */ - public static class DependencyHashes { - private final String algorithm; - private final Map nameToHash; - - public DependencyHashes(String algorithm, Map nameToHash) { - this.algorithm = algorithm; - this.nameToHash = nameToHash; - } - - /** - * Returns the algorithm used to hash the dependences ("SHA-256" or - * "MD5" for example). - */ - public String algorithm() { - return algorithm; - } - - /** - * Returns the set of module names for which hashes are recorded. - */ - public Set names() { - return nameToHash.keySet(); - } - - /** - * Retruns the hash string for the given module name, {@code null} - * if there is no hash recorded for the module. - */ - public String hashFor(String dn) { - return nameToHash.get(dn); - } - } - - - /** - * Computes the hash for the given file with the given message digest - * algorithm. Returns the results a base64-encoded String. - * - * @throws UncheckedIOException if an I/O error occurs - * @throws RuntimeException if the algorithm is not available - */ - public static String generate(Path file, String algorithm) { - try { - MessageDigest md = MessageDigest.getInstance(algorithm); - - // Ideally we would just mmap the file but this consumes too much - // memory when jlink is running concurrently on very large jmods - try (FileChannel fc = FileChannel.open(file)) { - ByteBuffer bb = ByteBuffer.allocate(32*1024); - int nread; - while ((nread = fc.read(bb)) > 0) { - bb.flip(); - md.update(bb); - assert bb.remaining() == 0; - bb.clear(); - } - } - - byte[] bytes = md.digest(); - return Base64.getEncoder().encodeToString(bytes); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } catch (IOException ioe) { - throw new UncheckedIOException(ioe); - } - } - - /** - * Computes the hash for every entry in the given map, returning a - * {@code DependencyHashes} to encapsulate the result. The map key is - * the entry name, typically the module name. The map value is the file - * path to the entry (module artifact). - * - * @return DependencyHashes encapsulate the hashes - */ - public static DependencyHashes generate(Map map, String algorithm) { - Map nameToHash = new HashMap<>(); - for (Map.Entry entry: map.entrySet()) { - String name = entry.getKey(); - Path path = entry.getValue(); - nameToHash.put(name, generate(path, algorithm)); - } - return new DependencyHashes(algorithm, nameToHash); - } -} diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Thu May 05 19:11:09 2016 +0000 @@ -26,12 +26,15 @@ package jdk.internal.module; import java.io.File; +import java.io.PrintStream; import java.lang.module.Configuration; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleFinder; import java.lang.module.ModuleReference; -import java.lang.module.ModuleFinder; import java.lang.module.ResolvedModule; import java.lang.reflect.Layer; import java.lang.reflect.Module; +import java.net.URI; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; @@ -41,10 +44,10 @@ import java.util.Optional; import java.util.Set; import java.util.function.Function; -import java.util.stream.Collectors; import jdk.internal.loader.BootLoader; import jdk.internal.loader.BuiltinClassLoader; +import jdk.internal.misc.SharedSecrets; import jdk.internal.perf.PerfCounter; /** @@ -54,10 +57,9 @@ * the module system. In summary, the boot method creates a Configuration by * resolving a set of module names specified via the launcher (or equivalent) * -m and -addmods options. The modules are located on a module path that is - * constructed from the upgrade, system and application module paths. The - * Configuration is reified by creating the boot Layer with each module in the - * the configuration defined to one of the built-in class loaders. The mapping - * of modules to class loaders is statically mapped in a helper class. + * constructed from the upgrade module path, system modules, and application + * module path. The Configuration is instantiated as the boot Layer with each + * module in the the configuration defined to one of the built-in class loaders. */ public final class ModuleBootstrap { @@ -65,6 +67,11 @@ private static final String JAVA_BASE = "java.base"; + private static final String JAVA_SE = "java.se"; + + // the token for "all default modules" + private static final String ALL_DEFAULT = "ALL-DEFAULT"; + // the token for "all unnamed modules" private static final String ALL_UNNAMED = "ALL-UNNAMED"; @@ -94,47 +101,65 @@ long t0 = System.nanoTime(); - // system module path - ModuleFinder systemModulePath = ModuleFinder.ofSystem(); + // system modules + ModuleFinder systemModules = ModuleFinder.ofSystem(); + + PerfCounters.systemModulesTime.addElapsedTimeFrom(t0); - // Once we have the system module path then we define the base module. - // We do this here so that java.base is defined to the VM as early as + + long t1 = System.nanoTime(); + + // Once we have the system modules then we define the base module to + // the VM. We do this here so that java.base is defined as early as // possible and also that resources in the base module can be located // for error messages that may happen from here on. - Optional obase = systemModulePath.find(JAVA_BASE); - if (!obase.isPresent()) + ModuleReference base = systemModules.find(JAVA_BASE).orElse(null); + if (base == null) throw new InternalError(JAVA_BASE + " not found"); - ModuleReference base = obase.get(); + URI baseUri = base.location().orElse(null); + if (baseUri == null) + throw new InternalError(JAVA_BASE + " does not have a location"); BootLoader.loadModule(base); - Modules.defineModule(null, base.descriptor(), base.location().orElse(null)); + Modules.defineModule(null, base.descriptor(), baseUri); + PerfCounters.defineBaseTime.addElapsedTimeFrom(t1); + + + long t2 = System.nanoTime(); // -upgrademodulepath option specified to launcher ModuleFinder upgradeModulePath = createModulePathFinder("jdk.upgrade.module.path"); + if (upgradeModulePath != null) + systemModules = ModuleFinder.compose(upgradeModulePath, systemModules); // -modulepath option specified to the launcher ModuleFinder appModulePath = createModulePathFinder("jdk.module.path"); - // The module finder: [-upgrademodulepath] system-module-path [-modulepath] - ModuleFinder finder = systemModulePath; - if (upgradeModulePath != null) - finder = ModuleFinder.compose(upgradeModulePath, finder); + // The module finder: [-upgrademodulepath] system [-modulepath] + ModuleFinder finder = systemModules; if (appModulePath != null) finder = ModuleFinder.compose(finder, appModulePath); - // launcher -m option to specify the initial module + // The root modules to resolve + Set roots = new HashSet<>(); + + // launcher -m option to specify the main/initial module String mainModule = System.getProperty("jdk.module.main"); + if (mainModule != null) + roots.add(mainModule); // additional module(s) specified by -addmods + boolean addAllDefaultModules = false; boolean addAllSystemModules = false; boolean addAllApplicationModules = false; - Set addModules = null; String propValue = System.getProperty("jdk.launcher.addmods"); if (propValue != null) { - addModules = new HashSet<>(); for (String mod: propValue.split(",")) { switch (mod) { + case ALL_DEFAULT: + addAllDefaultModules = true; + break; case ALL_SYSTEM: addAllSystemModules = true; break; @@ -142,28 +167,12 @@ addAllApplicationModules = true; break; default : - addModules.add(mod); + roots.add(mod); } } } - // The root modules to resolve - Set roots = new HashSet<>(); - - // main/initial module - if (mainModule != null) { - roots.add(mainModule); - if (addAllApplicationModules) - fail(ALL_MODULE_PATH + " not allowed with initial module"); - } - - // If -addmods is specified then those modules need to be resolved - if (addModules != null) - roots.addAll(addModules); - - // -limitmods - boolean limitmods = false; propValue = System.getProperty("jdk.launcher.limitmods"); if (propValue != null) { Set mods = new HashSet<>(); @@ -171,62 +180,101 @@ mods.add(mod); } finder = limitFinder(finder, mods, roots); - limitmods = true; } - - // If there is no initial module specified then assume that the - // initial module is the unnamed module of the application class - // loader. By convention, and for compatibility, this is - // implemented by putting the names of all modules on the system - // module path into the set of modules to resolve. - // - // If `-addmods ALL-SYSTEM` is used then all modules on the system - // module path will be resolved, irrespective of whether an initial - // module is specified. - // - // If `-addmods ALL-MODULE-PATH` is used, and no initial module is - // specified, then all modules on the application module path will - // be resolved. - // - if (mainModule == null || addAllSystemModules) { - Set mrefs; - if (addAllApplicationModules) { - assert mainModule == null; - mrefs = finder.findAll(); - } else { - mrefs = systemModulePath.findAll(); - if (limitmods) { - ModuleFinder f = finder; - mrefs = mrefs.stream() - .filter(m -> f.find(m.descriptor().name()).isPresent()) - .collect(Collectors.toSet()); + // If there is no initial module specified then assume that the initial + // module is the unnamed module of the application class loader. This + // is implemented by resolving "java.se" and all (non-java.*) modules + // that export an API. If "java.se" is not observable then all java.* + // modules are resolved. + if (mainModule == null || addAllDefaultModules) { + boolean hasJava = false; + if (systemModules.find(JAVA_SE).isPresent()) { + // java.se is a system module + if (finder == systemModules || finder.find(JAVA_SE).isPresent()) { + // java.se is observable + hasJava = true; + roots.add(JAVA_SE); } } - // map to module names - for (ModuleReference mref : mrefs) { - roots.add(mref.descriptor().name()); + + for (ModuleReference mref : systemModules.findAll()) { + String mn = mref.descriptor().name(); + if (hasJava && mn.startsWith("java.")) + continue; + + // add as root if observable and exports at least one package + if ((finder == systemModules || finder.find(mn).isPresent())) { + ModuleDescriptor descriptor = mref.descriptor(); + for (ModuleDescriptor.Exports e : descriptor.exports()) { + if (!e.isQualified()) { + roots.add(mn); + break; + } + } + } } } - long t1 = System.nanoTime(); + // If `-addmods ALL-SYSTEM` is specified then all observable system + // modules will be resolved. + if (addAllSystemModules) { + ModuleFinder f = finder; // observable modules + systemModules.findAll() + .stream() + .map(ModuleReference::descriptor) + .map(ModuleDescriptor::name) + .filter(mn -> f.find(mn).isPresent()) // observable + .forEach(mn -> roots.add(mn)); + } + + // If `-addmods ALL-MODULE-PATH` is specified then all observable + // modules on the application module path will be resolved. + if (appModulePath != null && addAllApplicationModules) { + ModuleFinder f = finder; // observable modules + appModulePath.findAll() + .stream() + .map(ModuleReference::descriptor) + .map(ModuleDescriptor::name) + .filter(mn -> f.find(mn).isPresent()) // observable + .forEach(mn -> roots.add(mn)); + } + + PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t2); + + + long t3 = System.nanoTime(); + + // determine if post resolution checks are needed + boolean needPostResolutionChecks = true; + if (baseUri.getScheme().equals("jrt") // toLowerCase not needed here + && (upgradeModulePath == null) + && (appModulePath == null) + && (System.getProperty("jdk.launcher.patch.0") == null)) { + needPostResolutionChecks = false; + } + + PrintStream traceOutput = null; + if (Boolean.getBoolean("jdk.launcher.traceResolver")) + traceOutput = System.out; // run the resolver to create the configuration - - Configuration cf = Configuration.empty() + Configuration cf = SharedSecrets.getJavaLangModuleAccess() .resolveRequiresAndUses(finder, - ModuleFinder.empty(), - roots); + roots, + needPostResolutionChecks, + traceOutput); // time to create configuration - PerfCounters.resolveTime.addElapsedTimeFrom(t1); + PerfCounters.resolveTime.addElapsedTimeFrom(t3); + // mapping of modules to class loaders Function clf = ModuleLoaderMap.mappingFunction(cf); // check that all modules to be mapped to the boot loader will be - // loaded from the system module path - if (finder != systemModulePath) { + // loaded from the runtime image + if (needPostResolutionChecks) { for (ResolvedModule resolvedModule : cf.modules()) { ModuleReference mref = resolvedModule.reference(); String name = mref.descriptor().name(); @@ -237,20 +285,22 @@ && upgradeModulePath.find(name).isPresent()) fail(name + ": cannot be loaded from upgrade module path"); - if (!systemModulePath.find(name).isPresent()) + if (!systemModules.find(name).isPresent()) fail(name + ": cannot be loaded from application module path"); } } } - long t2 = System.nanoTime(); + + long t4 = System.nanoTime(); // define modules to VM/runtime Layer bootLayer = Layer.empty().defineModules(cf, clf); - PerfCounters.layerCreateTime.addElapsedTimeFrom(t2); + PerfCounters.layerCreateTime.addElapsedTimeFrom(t4); - long t3 = System.nanoTime(); + + long t5 = System.nanoTime(); // define the module to its class loader, except java.base for (ResolvedModule resolvedModule : cf.modules()) { @@ -264,7 +314,8 @@ } } - PerfCounters.loadModulesTime.addElapsedTimeFrom(t3); + PerfCounters.loadModulesTime.addElapsedTimeFrom(t5); + // -XaddReads and -XaddExports addExtraReads(bootLayer); @@ -295,25 +346,21 @@ // module name -> reference Map map = new HashMap<>(); + + // root modules and their transitive dependences cf.modules().stream() .map(ResolvedModule::reference) .forEach(mref -> map.put(mref.descriptor().name(), mref)); + // additional modules + otherMods.stream() + .map(finder::find) + .flatMap(Optional::stream) + .forEach(mref -> map.putIfAbsent(mref.descriptor().name(), mref)); + // set of modules that are observable Set mrefs = new HashSet<>(map.values()); - // add the other modules - for (String mod : otherMods) { - Optional omref = finder.find(mod); - if (omref.isPresent()) { - ModuleReference mref = omref.get(); - map.putIfAbsent(mod, mref); - mrefs.add(mref); - } else { - // no need to fail - } - } - return new ModuleFinder() { @Override public Optional find(String name) { @@ -369,15 +416,15 @@ Module other; if (ALL_UNNAMED.equals(name)) { - other = null; // loose + Modules.addReadsAllUnnamed(m); } else { om = bootLayer.findModule(name); if (!om.isPresent()) fail("Unknown module: " + name); other = om.get(); + Modules.addReads(m, other); } - Modules.addReads(m, other); } } } @@ -439,10 +486,6 @@ * Decodes the values of -XaddReads or -XaddExports options * * The format of the options is: $KEY=$MODULE(,$MODULE)* - * - * For transition purposes, this method allows the first usage to be - * $KEY=$MODULE(,$KEY=$MODULE) - * This format will eventually be removed. */ private static Map> decode(String prefix) { int index = 0; @@ -467,42 +510,15 @@ if (rhs.isEmpty()) fail("Unable to parse: " + value); - // new format $MODULE(,$MODULE)* or old format $(MODULE)=... - pos = rhs.indexOf('='); - // old format only allowed in first -X option - if (pos >= 0 && index > 0) - fail("Unable to parse: " + value); - - if (pos == -1) { - - // new format: $KEY=$MODULE(,$MODULE)* - - Set values = map.get(key); - if (values != null) - fail(key + " specified more than once"); + // value is (,)* + if (map.containsKey(key)) + fail(key + " specified more than once"); - values = new HashSet<>(); - map.put(key, values); - for (String s : rhs.split(",")) { - if (s.length() > 0) values.add(s); - } - - } else { - - // old format: $KEY=$MODULE(,$KEY=$MODULE)* - - assert index == 0; // old format only allowed in first usage - - for (String expr : value.split(",")) { - if (expr.length() > 0) { - String[] s = expr.split("="); - if (s.length != 2) - fail("Unable to parse: " + expr); - - map.computeIfAbsent(s[0], k -> new HashSet<>()).add(s[1]); - } - } + Set values = new HashSet<>(); + map.put(key, values); + for (String s : rhs.split(",")) { + if (s.length() > 0) values.add(s); } index++; @@ -521,6 +537,13 @@ } static class PerfCounters { + + static PerfCounter systemModulesTime + = PerfCounter.newPerfCounter("jdk.module.bootstrap.systemModulesTime"); + static PerfCounter defineBaseTime + = PerfCounter.newPerfCounter("jdk.module.bootstrap.defineBaseTime"); + static PerfCounter optionsAndRootsTime + = PerfCounter.newPerfCounter("jdk.module.bootstrap.optionsAndRootsTime"); static PerfCounter resolveTime = PerfCounter.newPerfCounter("jdk.module.bootstrap.resolveTime"); static PerfCounter layerCreateTime diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/ModuleHashes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleHashes.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,147 @@ +/* + * 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 jdk.internal.module; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * The result of hashing the contents of a number of module artifacts. + */ + +public final class ModuleHashes { + + /** + * A supplier of an encoded message digest. + */ + public static interface HashSupplier { + String generate(String algorithm); + } + + + private final String algorithm; + private final Map nameToHash; + + /** + * Creates a {@code ModuleHashes}. + * + * @param algorithm the algorithm used to create the hashes + * @param nameToHash the map of module name to hash value (in string form) + */ + public ModuleHashes(String algorithm, Map nameToHash) { + this.algorithm = algorithm; + this.nameToHash = Collections.unmodifiableMap(nameToHash); + } + + /** + * Returns the algorithm used to hash the modules ("SHA-256" for example). + */ + public String algorithm() { + return algorithm; + } + + /** + * Returns the set of module names for which hashes are recorded. + */ + public Set names() { + return nameToHash.keySet(); + } + + /** + * Returns the hash string for the given module name, {@code null} + * if there is no hash recorded for the module. + */ + public String hashFor(String mn) { + return nameToHash.get(mn); + } + + /** + * Returns unmodifiable map of module name to hash string. + */ + public Map hashes() { + return nameToHash; + } + + /** + * Computes the hash for the given file with the given message digest + * algorithm. Returns the results a base64-encoded String. + * + * @throws UncheckedIOException if an I/O error occurs + * @throws RuntimeException if the algorithm is not available + */ + public static String computeHashAsString(Path file, String algorithm) { + try { + MessageDigest md = MessageDigest.getInstance(algorithm); + + // Ideally we would just mmap the file but this consumes too much + // memory when jlink is running concurrently on very large jmods + try (FileChannel fc = FileChannel.open(file)) { + ByteBuffer bb = ByteBuffer.allocate(32*1024); + while (fc.read(bb) > 0) { + bb.flip(); + md.update(bb); + assert bb.remaining() == 0; + bb.clear(); + } + } + + byte[] bytes = md.digest(); + return Base64.getEncoder().encodeToString(bytes); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + + /** + * Computes the hash for every entry in the given map, returning a + * {@code ModuleHashes} to encapsulate the result. The map key is + * the entry name, typically the module name. The map value is the file + * path to the entry (module artifact). + * + * @return ModuleHashes encapsulate the hashes + */ + public static ModuleHashes generate(Map map, String algorithm) { + Map nameToHash = new HashMap<>(); + for (Map.Entry entry: map.entrySet()) { + String name = entry.getKey(); + Path path = entry.getValue(); + nameToHash.put(name, computeHashAsString(path, algorithm)); + } + return new ModuleHashes(algorithm, nameToHash); + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -41,7 +41,6 @@ import jdk.internal.org.objectweb.asm.ClassVisitor; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.module.Hasher.DependencyHashes; import static jdk.internal.module.ClassFileAttributes.*; @@ -69,7 +68,7 @@ private String osVersion; // the hashes for the Hashes attribute - private DependencyHashes hashes; + private ModuleHashes hashes; private ModuleInfoExtender(InputStream in) { this.in = in; @@ -113,10 +112,10 @@ /** * The Hashes attribute will be emitted to the module-info with - * the hashes encapsulated in the given {@code DependencyHashes} + * the hashes encapsulated in the given {@code ModuleHashes} * object. */ - public ModuleInfoExtender hashes(DependencyHashes hashes) { + public ModuleInfoExtender hashes(ModuleHashes hashes) { this.hashes = hashes; return this; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -49,28 +49,22 @@ * Writes the given module descriptor to a module-info.class file, * returning it in a byte array. */ - private static byte[] toModuleInfo(ModuleDescriptor descriptor) { + private static byte[] toModuleInfo(ModuleDescriptor md) { ClassWriter cw = new ClassWriter(0); - String name = descriptor.name().replace('.', '/') + "/module-info"; + String name = md.name().replace('.', '/') + "/module-info"; cw.visit(Opcodes.V1_8, ACC_MODULE, name, null, null, null); - cw.visitAttribute(new ModuleAttribute(descriptor)); - cw.visitAttribute(new ConcealedPackagesAttribute(descriptor.conceals())); - - Optional oversion = descriptor.version(); - if (oversion.isPresent()) - cw.visitAttribute(new VersionAttribute(oversion.get())); - - Optional omain = descriptor.mainClass(); - if (omain.isPresent()) - cw.visitAttribute(new MainClassAttribute(omain.get())); + cw.visitAttribute(new ModuleAttribute(md)); + cw.visitAttribute(new ConcealedPackagesAttribute(md.conceals())); + md.version().ifPresent(v -> cw.visitAttribute(new VersionAttribute(v))); + md.mainClass().ifPresent(mc -> cw.visitAttribute(new MainClassAttribute(mc))); // write the TargetPlatform attribute if have any of OS name/arch/version - String osName = descriptor.osName().orElse(null); - String osArch = descriptor.osArch().orElse(null); - String osVersion = descriptor.osVersion().orElse(null); + String osName = md.osName().orElse(null); + String osArch = md.osArch().orElse(null); + String osVersion = md.osVersion().orElse(null); if (osName != null || osArch != null || osVersion != null) { cw.visitAttribute(new TargetPlatformAttribute(osName, osArch, diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java Thu May 05 19:11:09 2016 +0000 @@ -91,56 +91,29 @@ Map> map = new HashMap<>(); while (value != null) { - int pos = value.indexOf('='); + + // =(:)* - if (pos == -1 && index > 0) + int pos = value.indexOf('='); + if (pos == -1) throwIAE("Unable to parse: " + value); - if (pos == 0) throwIAE("Missing module name: " + value); - if (pos > 0) { - - // new format: =(:)* - - String mn = value.substring(0, pos); - List list = map.get(mn); - if (list != null) - throwIAE("Module " + mn + " specified more than once"); - list = new ArrayList<>(); - map.put(mn, list); - - String paths = value.substring(pos+1); - for (String path : paths.split(File.pathSeparator)) { - if (!path.isEmpty()) { - list.add(Paths.get(path)); - } - } - - } else { + String mn = value.substring(0, pos); + List list = map.get(mn); + if (list != null) + throwIAE("Module " + mn + " specified more than once"); + list = new ArrayList<>(); + map.put(mn, list); - // old format: (:)* - - assert index == 0; // old format only allowed in first -Xpatch - - String[] dirs = value.split(File.pathSeparator); - for (String d : dirs) { - if (d.length() > 0) { - Path top = Paths.get(d); - try { - Files.list(top).forEach(e -> { - String mn = e.getFileName().toString(); - Path dir = top.resolve(mn); - map.computeIfAbsent(mn, k -> new ArrayList<>()) - .add(dir); - }); - } catch (IOException ignore) { } - } + String paths = value.substring(pos+1); + for (String path : paths.split(File.pathSeparator)) { + if (!path.isEmpty()) { + list.add(Paths.get(path)); } - } - index++; value = System.getProperty(PATCH_PROPERTY_PREFIX + index); } @@ -175,7 +148,8 @@ for (Path file : paths) { if (Files.isRegularFile(file)) { - // JAR file + // JAR file - do not open as a multi-release JAR as this + // is not supported by the boot class loader try (JarFile jf = new JarFile(file.toFile())) { jf.stream() .filter(e -> e.getName().endsWith(".class")) @@ -209,10 +183,11 @@ descriptor = JLMA.newModuleDescriptor(descriptor, packages); } - // return a new module reference + // return a module reference to the patched module URI location = mref.location().orElse(null); - return new ModuleReference(descriptor, location, - () -> new PatchedModuleReader(paths, mref)); + return JLMA.newPatchedModule(descriptor, + location, + () -> new PatchedModuleReader(paths, mref)); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/Modules.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -58,7 +58,7 @@ * Creates a new Module. The module has the given ModuleDescriptor and * is defined to the given class loader. * - * The resulting Module is in a larva state in that it does not not read + * The resulting Module is in a larval state in that it does not not read * any other module and does not have any exports. * * The URI is for information purposes only. @@ -74,7 +74,7 @@ * Define a new module to the VM. The module has the given set of * concealed packages and is defined to the given class loader. * - * The resulting Module is in a larva state in that it does not not read + * The resulting Module is in a larval state in that it does not not read * any other module and does not have any exports. */ public static Module defineModule(ClassLoader loader, @@ -96,6 +96,13 @@ } /** + * Update module {@code m} to read all unnamed modules. + */ + public static void addReadsAllUnnamed(Module m) { + JLRMA.addReadsAllUnnamed(m); + } + + /** * Updates module m1 to export a package to module m2. * Same as m1.addExports(pkg, m2) but without a caller check. */ diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/ServicesCatalog.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/ServicesCatalog.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ServicesCatalog.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -29,94 +29,105 @@ import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleDescriptor.Provides; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.concurrent.ConcurrentHashMap; /** - * A services catalog. Each {@code ClassLoader} has an optional {@code - * ServicesCatalog} for modules that provide services. This is to support - * ClassLoader centric ServiceLoader.load methods. + * A services catalog. Each {@code ClassLoader} and {@code Layer} has + * an optional {@code ServicesCatalog} for modules that provide services. + * + * @see java.util.ServiceLoader */ -public class ServicesCatalog { - - // use RW locks as register is rare - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - private final Lock readLock = lock.readLock(); - private final Lock writeLock = lock.writeLock(); +public interface ServicesCatalog { /** * Represents a service provider in the services catalog. */ - public class ServiceProvider { + public final class ServiceProvider { private final Module module; private final String providerName; - ServiceProvider(Module module, String providerName) { + + public ServiceProvider(Module module, String providerName) { this.module = module; this.providerName = providerName; } + public Module module() { return module; } + public String providerName() { return providerName; } - } - // service providers - private final Map> loaderServices = new HashMap<>(); - - /** - * Creates a new module catalog. - */ - public ServicesCatalog() { } - - /** - * Registers the module in this module catalog. - */ - public void register(Module m) { - ModuleDescriptor descriptor = m.getDescriptor(); + @Override + public int hashCode() { + return Objects.hash(module, providerName); + } - writeLock.lock(); - try { - // extend the services map - for (Provides ps : descriptor.provides().values()) { - String service = ps.service(); - Set providerNames = ps.providers(); - - // create a new set to replace the existing - Set result = new HashSet<>(); - Set providers = loaderServices.get(service); - if (providers != null) { - result.addAll(providers); - } - for (String pn : providerNames) { - result.add(new ServiceProvider(m, pn)); - } - loaderServices.put(service, Collections.unmodifiableSet(result)); - } - - } finally { - writeLock.unlock(); + @Override + public boolean equals(Object ob) { + if (!(ob instanceof ServiceProvider)) + return false; + ServiceProvider that = (ServiceProvider)ob; + return Objects.equals(this.module, that.module) + && Objects.equals(this.providerName, that.providerName); } } /** + * Registers the providers in the given module in this services catalog. + * + * @throws UnsupportedOperationException + * If this services catalog is immutable + */ + void register(Module module); + + /** * Returns the (possibly empty) set of service providers that implement the * given service type. - * - * @see java.util.ServiceLoader + */ + Set findServices(String service); + + /** + * Creates a ServicesCatalog that supports concurrent registration and + * and lookup. */ - public Set findServices(String service) { - readLock.lock(); - try { - return loaderServices.getOrDefault(service, Collections.emptySet()); - } finally { - readLock.unlock(); - } + static ServicesCatalog create() { + return new ServicesCatalog() { + + private Map> map = new ConcurrentHashMap<>(); + + @Override + public void register(Module m) { + ModuleDescriptor descriptor = m.getDescriptor(); + + for (Provides provides : descriptor.provides().values()) { + String service = provides.service(); + Set providerNames = provides.providers(); + + // create a new set to replace the existing + Set result = new HashSet<>(); + Set providers = map.get(service); + if (providers != null) { + result.addAll(providers); + } + for (String pn : providerNames) { + result.add(new ServiceProvider(m, pn)); + } + map.put(service, Collections.unmodifiableSet(result)); + } + + } + + @Override + public Set findServices(String service) { + return map.getOrDefault(service, Collections.emptySet()); + } + + }; } -} +} \ No newline at end of file diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java Thu May 05 19:11:09 2016 +0000 @@ -40,21 +40,26 @@ */ public final class SystemModules { /** - * Name of the installed modules. + * Name of the system modules. * - * This array provides a way for InstalledModuleFinder to fallback + * This array provides a way for SystemModuleFinder to fallback * and read module-info.class from the run-time image instead of * the fastpath. */ public static final String[] MODULE_NAMES = new String[1]; /** + * Hash of system modules. + */ + public static String[] MODULES_TO_HASH = new String[1]; + + /** * Number of packages in the boot layer from the installed modules. * * Don't make it final to avoid inlining during compile time as * the value will be changed at jlink time. */ - public static final int PACKAGES_IN_BOOT_LAYER = 1024; + public static int PACKAGES_IN_BOOT_LAYER = 1024; /** * Returns a non-empty array of ModuleDescriptors in the run-time image. @@ -64,4 +69,5 @@ public static ModuleDescriptor[] modules() { return new ModuleDescriptor[0]; } -} \ No newline at end of file + +} diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/reflect/MethodAccessorGenerator.java --- a/jdk/src/java.base/share/classes/jdk/internal/reflect/MethodAccessorGenerator.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/MethodAccessorGenerator.java Thu May 05 19:11:09 2016 +0000 @@ -392,6 +392,7 @@ // matter. return AccessController.doPrivileged( new PrivilegedAction() { + @SuppressWarnings("deprecation") // Class.newInstance public MagicAccessorImpl run() { try { return (MagicAccessorImpl) diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java --- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Thu May 05 19:11:09 2016 +0000 @@ -343,8 +343,8 @@ private static void printStackTraceIfNeeded(Throwable e) { if (!printStackWhenAccessFailsSet && VM.initLevel() >= 1) { - String s = GetPropertyAction - .getProperty("sun.reflect.debugModuleAccessChecks"); + String s = GetPropertyAction.privilegedGetProperty( + "sun.reflect.debugModuleAccessChecks"); printStackWhenAccessFails = (s != null && !s.equalsIgnoreCase("false")); printStackWhenAccessFailsSet = true; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java --- a/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Thu May 05 19:11:09 2016 +0000 @@ -398,7 +398,7 @@ return; } - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); String val = props.getProperty("sun.reflect.noInflation"); if (val != null && val.equals("true")) { noInflation = true; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/module-info.java --- a/jdk/src/java.base/share/classes/module-info.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/module-info.java Thu May 05 19:11:09 2016 +0000 @@ -166,6 +166,8 @@ java.sql, java.xml, jdk.charsets, + jdk.jartool, + jdk.jlink, jdk.net, jdk.scripting.nashorn, jdk.unsupported, diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java --- a/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Thu May 05 19:11:09 2016 +0000 @@ -84,8 +84,10 @@ import jdk.internal.misc.VM; -public enum LauncherHelper { - INSTANCE; +public final class LauncherHelper { + + // No instantiation + private LauncherHelper() {} // used to identify JavaFX applications private static final String JAVAFX_APPLICATION_MARKER = diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties --- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Thu May 05 19:11:09 2016 +0000 @@ -27,7 +27,7 @@ java.launcher.opt.header = Usage: {0} [options] class [args...]\n\ \ (to execute a class)\n or {0} [options] -jar jarfile [args...]\n\ \ (to execute a jar file)\n\ -\ or {0} [-options] -mp -m | /\n\ +\ or {0} [options] -mp -m [/] [args...]\n\ \ (to execute the main class in a module)\n\ where options include:\n @@ -51,8 +51,9 @@ \ A {0} separated list of directories, each directory\n\ \ is a directory of modules that replace upgradeable\n\ \ modules in the runtime image\n\ -\ -m | /\n\ -\ the initial or main module to resolve\n\ +\ -m [/]\n\ +\ the initial module to resolve, and the name of the main class\n\ +\ to execute if not specified by the module\n\ \ -addmods [,...]\n\ \ root modules to resolve in addition to the initial module\n\ \ -limitmods [,...]\n\ diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/ResourceManager.java --- a/jdk/src/java.base/share/classes/sun/net/ResourceManager.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/ResourceManager.java Thu May 05 19:11:09 2016 +0000 @@ -53,8 +53,8 @@ private static final AtomicInteger numSockets; static { - String prop = - GetPropertyAction.getProperty("sun.net.maxDatagramSockets"); + String prop = GetPropertyAction + .privilegedGetProperty("sun.net.maxDatagramSockets"); int defmax = DEFAULT_MAX_SOCKETS; try { if (prop != null) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java --- a/jdk/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java Thu May 05 19:11:09 2016 +0000 @@ -67,8 +67,9 @@ return false; } try { - Class c = Class.forName(cm, true, null); - provider = (FtpClientProvider) c.newInstance(); + @SuppressWarnings("deprecation") + Object o = Class.forName(cm, true, null).newInstance(); + provider = (FtpClientProvider)o; return true; } catch (ClassNotFoundException | IllegalAccessException | diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/sdp/SdpSupport.java --- a/jdk/src/java.base/share/classes/sun/net/sdp/SdpSupport.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/sdp/SdpSupport.java Thu May 05 19:11:09 2016 +0000 @@ -40,7 +40,7 @@ */ public final class SdpSupport { - private static final String os = GetPropertyAction.getProperty("os.name"); + private static final String os = GetPropertyAction.privilegedGetProperty("os.name"); private static final boolean isSupported = (os.equals("SunOS") || (os.equals("Linux"))); private static final JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess(); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/smtp/SmtpClient.java --- a/jdk/src/java.base/share/classes/sun/net/smtp/SmtpClient.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/smtp/SmtpClient.java Thu May 05 19:11:09 2016 +0000 @@ -157,7 +157,7 @@ } try { String s; - mailhost = GetPropertyAction.getProperty("mail.host"); + mailhost = GetPropertyAction.privilegedGetProperty("mail.host"); if (mailhost != null) { openServer(mailhost); return; @@ -183,7 +183,7 @@ setConnectTimeout(to); try { String s; - mailhost = GetPropertyAction.getProperty("mail.host"); + mailhost = GetPropertyAction.privilegedGetProperty("mail.host"); if (mailhost != null) { openServer(mailhost); return; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java --- a/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java Thu May 05 19:11:09 2016 +0000 @@ -183,7 +183,7 @@ } String execPathList; - execPathList = GetPropertyAction.getProperty("exec.path"); + execPathList = GetPropertyAction.privilegedGetProperty("exec.path"); if (execPathList == null) { // exec.path property not set return false; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java --- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java Thu May 05 19:11:09 2016 +0000 @@ -145,7 +145,7 @@ } static { - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); String keepAlive = props.getProperty("http.keepAlive"); String retryPost = props.getProperty("sun.net.http.retryPost"); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Thu May 05 19:11:09 2016 +0000 @@ -278,7 +278,7 @@ if (user == null) { user = "anonymous"; - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); String vers = props.getProperty("java.version"); password = props.getProperty("ftp.protocol.user", "Java" + vers + "@"); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Thu May 05 19:11:09 2016 +0000 @@ -94,7 +94,7 @@ } static { - authPref = GetPropertyAction.getProperty("http.auth.preference"); + authPref = GetPropertyAction.privilegedGetProperty("http.auth.preference"); // http.auth.preference can be set to SPNEGO or Kerberos. // In fact they means "Negotiate with SPNEGO" and "Negotiate with diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu May 05 19:11:09 2016 +0000 @@ -207,9 +207,9 @@ }; static { - Properties props = GetPropertyAction.getProperties(); - maxRedirects = GetIntegerAction.getProperty("http.maxRedirects", - defaultmaxRedirects); + Properties props = GetPropertyAction.privilegedGetProperties(); + maxRedirects = GetIntegerAction.privilegedGetProperty( + "http.maxRedirects", defaultmaxRedirects); version = props.getProperty("java.version"); String agent = props.getProperty("http.agent"); if (agent == null) { @@ -225,14 +225,14 @@ enableESBuffer = Boolean.parseBoolean( props.getProperty("sun.net.http.errorstream.enableBuffering")); - timeout4ESBuffer = GetIntegerAction - .getProperty("sun.net.http.errorstream.timeout", 300); + timeout4ESBuffer = GetIntegerAction.privilegedGetProperty( + "sun.net.http.errorstream.timeout", 300); if (timeout4ESBuffer <= 0) { timeout4ESBuffer = 300; // use the default } - bufSize4ES = GetIntegerAction - .getProperty("sun.net.http.errorstream.bufferSize", 4096); + bufSize4ES = GetIntegerAction.privilegedGetProperty( + "sun.net.http.errorstream.bufferSize", 4096); if (bufSize4ES <= 0) { bufSize4ES = 4096; // use the default } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java Thu May 05 19:11:09 2016 +0000 @@ -139,7 +139,7 @@ // String ciphers []; String cipherString = - GetPropertyAction.getProperty("https.cipherSuites"); + GetPropertyAction.privilegedGetProperty("https.cipherSuites"); if (cipherString == null || "".equals(cipherString)) { ciphers = null; @@ -163,7 +163,7 @@ // String protocols []; String protocolString = - GetPropertyAction.getProperty("https.protocols"); + GetPropertyAction.privilegedGetProperty("https.protocols"); if (protocolString == null || "".equals(protocolString)) { protocols = null; @@ -183,7 +183,8 @@ } private String getUserAgent() { - String userAgent = GetPropertyAction.getProperty("https.agent"); + String userAgent = + GetPropertyAction.privilegedGetProperty("https.agent"); if (userAgent == null || userAgent.length() == 0) { userAgent = "JSSE"; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java Thu May 05 19:11:09 2016 +0000 @@ -161,7 +161,7 @@ public Permission getPermission() throws IOException { Permission p = permission; if (p == null) { - String home = GetPropertyAction.getProperty("java.home"); + String home = GetPropertyAction.privilegedGetProperty("java.home"); p = new FilePermission(home + File.separator + "-", "read"); permission = p; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/net/www/protocol/netdoc/Handler.java --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/netdoc/Handler.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/netdoc/Handler.java Thu May 05 19:11:09 2016 +0000 @@ -56,9 +56,9 @@ URL ru; boolean localonly = Boolean.parseBoolean( - GetPropertyAction.getProperty("newdoc.localonly")); + GetPropertyAction.privilegedGetProperty("newdoc.localonly")); - String docurl = GetPropertyAction.getProperty("doc.url"); + String docurl = GetPropertyAction.privilegedGetProperty("doc.url"); String file = u.getFile(); if (!localonly) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java Thu May 05 19:11:09 2016 +0000 @@ -1019,7 +1019,7 @@ if (!propertyChecked) { synchronized (FileChannelImpl.class) { if (!propertyChecked) { - String value = GetPropertyAction.getProperty( + String value = GetPropertyAction.privilegedGetProperty( "sun.nio.ch.disableSystemWideOverlappingFileLockCheck"); isSharedFileLockTable = ((value == null) || value.equals("false")); propertyChecked = true; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/nio/ch/Net.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java Thu May 05 19:11:09 2016 +0000 @@ -374,8 +374,8 @@ } public static boolean isFastTcpLoopbackRequested() { - String loopbackProp = - GetPropertyAction.getProperty("jdk.net.useFastTcpLoopback"); + String loopbackProp = GetPropertyAction + .privilegedGetProperty("jdk.net.useFastTcpLoopback"); boolean enable; if ("".equals(loopbackProp)) { enable = true; @@ -633,8 +633,8 @@ static { int availLevel = isExclusiveBindAvailable(); if (availLevel >= 0) { - String exclBindProp = - GetPropertyAction.getProperty("sun.net.useExclusiveBind"); + String exclBindProp = GetPropertyAction + .privilegedGetProperty("sun.net.useExclusiveBind"); if (exclBindProp != null) { exclusiveBind = exclBindProp.isEmpty() ? true : Boolean.parseBoolean(exclBindProp); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/nio/ch/ThreadPool.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/ThreadPool.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/ThreadPool.java Thu May 05 19:11:09 2016 +0000 @@ -165,14 +165,11 @@ GetPropertyAction(DEFAULT_THREAD_POOL_THREAD_FACTORY)); if (propValue != null) { try { - Class c = Class - .forName(propValue, true, ClassLoader.getSystemClassLoader()); - return ((ThreadFactory)c.newInstance()); - } catch (ClassNotFoundException x) { - throw new Error(x); - } catch (InstantiationException x) { - throw new Error(x); - } catch (IllegalAccessException x) { + @SuppressWarnings("deprecation") + Object tmp = Class + .forName(propValue, true, ClassLoader.getSystemClassLoader()).newInstance(); + return (ThreadFactory)tmp; + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException x) { throw new Error(x); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/nio/ch/Util.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java Thu May 05 19:11:09 2016 +0000 @@ -64,7 +64,8 @@ * for potential future-proofing. */ private static long getMaxCachedBufferSize() { - String s = GetPropertyAction.getProperty("jdk.nio.maxCachedBufferSize"); + String s = GetPropertyAction + .privilegedGetProperty("jdk.nio.maxCachedBufferSize"); if (s != null) { try { long m = Long.parseLong(s); @@ -465,7 +466,8 @@ if (bugLevel == null) { if (!jdk.internal.misc.VM.isBooted()) return false; - String value = GetPropertyAction.getProperty("sun.nio.ch.bugLevel"); + String value = GetPropertyAction + .privilegedGetProperty("sun.nio.ch.bugLevel"); bugLevel = (value != null) ? value : ""; } return bugLevel.equals(bl); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/nio/cs/FastCharsetProvider.java --- a/jdk/src/java.base/share/classes/sun/nio/cs/FastCharsetProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/cs/FastCharsetProvider.java Thu May 05 19:11:09 2016 +0000 @@ -115,10 +115,11 @@ // Instantiate the charset and cache it try { - Class c = Class.forName(packagePrefix + "." + cln, + @SuppressWarnings("deprecation") + Object o= Class.forName(packagePrefix + "." + cln, true, - this.getClass().getClassLoader()); - cs = (Charset)c.newInstance(); + this.getClass().getClassLoader()).newInstance(); + cs = (Charset)o; cache.put(csn, cs); return cs; } catch (ClassNotFoundException | diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template --- a/jdk/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template Thu May 05 19:11:09 2016 +0000 @@ -110,10 +110,11 @@ // Instantiate the charset and cache it try { - Class c = Class.forName(packagePrefix + "." + cln, - true, - this.getClass().getClassLoader()); - cs = (Charset)c.newInstance(); + @SuppressWarnings("deprecation") + Object o = Class.forName(packagePrefix + "." + cln, + true, + this.getClass().getClassLoader()).newInstance(); + cs = (Charset)o; cache.put(csn, cs); return cs; } catch (ClassNotFoundException | @@ -164,7 +165,7 @@ return; initialized = true; - String map = getProperty("sun.nio.cs.map"); + String map = GetPropertyAction.privilegedGetProperty("sun.nio.cs.map"); if (map != null) { String[] maps = map.split(","); for (int i = 0; i < maps.length; i++) { @@ -199,9 +200,4 @@ } } - private static String getProperty(String key) { - return GetPropertyAction.getProperty(key); - } - - } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/nio/fs/Util.java --- a/jdk/src/java.base/share/classes/sun/nio/fs/Util.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/fs/Util.java Thu May 05 19:11:09 2016 +0000 @@ -38,7 +38,7 @@ private Util() { } private static final Charset jnuEncoding = Charset.forName( - GetPropertyAction.getProperty("sun.jnu.encoding")); + GetPropertyAction.privilegedGetProperty("sun.jnu.encoding")); /** * Returns {@code Charset} corresponding to the sun.jnu.encoding property diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/action/GetIntegerAction.java --- a/jdk/src/java.base/share/classes/sun/security/action/GetIntegerAction.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/action/GetIntegerAction.java Thu May 05 19:11:09 2016 +0000 @@ -118,9 +118,14 @@ * if no security manager is present. This is unsafe for inclusion in a * public API but allowable here since this class is now encapsulated. * + * Note that this method performs a privileged action using caller-provided + * inputs. The caller of this method should take care to ensure that the + * inputs are not tainted and the returned property is not made accessible + * to untrusted code if it contains sensitive information. + * * @param theProp the name of the system property. */ - public static Integer getProperty(String theProp) { + public static Integer privilegedGetProperty(String theProp) { if (System.getSecurityManager() == null) { return Integer.getInteger(theProp); } else { @@ -134,10 +139,16 @@ * if no security manager is present. This is unsafe for inclusion in a * public API but allowable here since this class is now encapsulated. * + * Note that this method performs a privileged action using caller-provided + * inputs. The caller of this method should take care to ensure that the + * inputs are not tainted and the returned property is not made accessible + * to untrusted code if it contains sensitive information. + * * @param theProp the name of the system property. * @param defaultVal the default value. */ - public static Integer getProperty(String theProp, int defaultVal) { + public static Integer privilegedGetProperty(String theProp, + int defaultVal) { Integer value; if (System.getSecurityManager() == null) { value = Integer.getInteger(theProp); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/action/GetPropertyAction.java --- a/jdk/src/java.base/share/classes/sun/security/action/GetPropertyAction.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/action/GetPropertyAction.java Thu May 05 19:11:09 2016 +0000 @@ -93,9 +93,14 @@ * if no security manager is present. This is unsafe for inclusion in a * public API but allowable here since this class is now encapsulated. * + * Note that this method performs a privileged action using caller-provided + * inputs. The caller of this method should take care to ensure that the + * inputs are not tainted and the returned property is not made accessible + * to untrusted code if it contains sensitive information. + * * @param theProp the name of the system property. */ - public static String getProperty(String theProp) { + public static String privilegedGetProperty(String theProp) { if (System.getSecurityManager() == null) { return System.getProperty(theProp); } else { @@ -109,10 +114,16 @@ * if no security manager is present. This is unsafe for inclusion in a * public API but allowable here since this class is now encapsulated. * + * Note that this method performs a privileged action using caller-provided + * inputs. The caller of this method should take care to ensure that the + * inputs are not tainted and the returned property is not made accessible + * to untrusted code if it contains sensitive information. + * * @param theProp the name of the system property. * @param defaultVal the default value. */ - public static String getProperty(String theProp, String defaultVal) { + public static String privilegedGetProperty(String theProp, + String defaultVal) { if (System.getSecurityManager() == null) { return System.getProperty(theProp, defaultVal); } else { @@ -126,8 +137,13 @@ * having to go through doPrivileged if no security manager is present. * This is unsafe for inclusion in a public API but allowable here since * this class is now encapsulated. + * + * Note that this method performs a privileged action, and callers of + * this method should take care to ensure that the returned properties + * are not made accessible to untrusted code since it may contain + * sensitive information. */ - public static Properties getProperties() { + public static Properties privilegedGetProperties() { if (System.getSecurityManager() == null) { return System.getProperties(); } else { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java --- a/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java Thu May 05 19:11:09 2016 +0000 @@ -185,7 +185,9 @@ try { Class c = Class.forName("apple.security.AppleProvider"); if (Provider.class.isAssignableFrom(c)) { - return (Provider) c.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = c.newInstance(); + return (Provider) tmp; } else { return null; } @@ -386,6 +388,7 @@ Provider p = AccessController.doPrivileged (new PrivilegedExceptionAction() { + @SuppressWarnings("deprecation") // Class.newInstance public Provider run() throws Exception { return (Provider) provClass.newInstance(); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java --- a/jdk/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java Thu May 05 19:11:09 2016 +0000 @@ -218,11 +218,10 @@ } } - Object inst = null; + @SuppressWarnings("deprecation") + Object inst = (keyClass != null) ? keyClass.newInstance() : null; PKCS8Key result; - if (keyClass != null) - inst = keyClass.newInstance(); if (inst instanceof PKCS8Key) { result = (PKCS8Key) inst; result.algid = algid; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java --- a/jdk/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java Thu May 05 19:11:09 2016 +0000 @@ -70,7 +70,7 @@ * By default this is false. * This incompatibility was introduced by 4532506. */ - String prop = GetPropertyAction.getProperty(SERIAL_PROP); + String prop = GetPropertyAction.privilegedGetProperty(SERIAL_PROP); SERIAL_INTEROP = "true".equalsIgnoreCase(prop); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Thu May 05 19:11:09 2016 +0000 @@ -43,7 +43,6 @@ import static sun.security.provider.certpath.OCSP.*; import static sun.security.provider.certpath.PKIX.*; -import sun.security.action.GetPropertyAction; import sun.security.x509.*; import static sun.security.x509.PKIXExtensions.*; import sun.security.util.Debug; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java --- a/jdk/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java Thu May 05 19:11:09 2016 +0000 @@ -84,7 +84,7 @@ public static final int MAX_RESTRICTED_EXPLEN = 64; private static final boolean restrictExpLen = - "true".equalsIgnoreCase(GetPropertyAction.getProperty( + "true".equalsIgnoreCase(GetPropertyAction.privilegedGetProperty( "sun.security.rsa.restrictRSAExponent", "true")); // instance used for static translateKey(); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/ssl/ClientKeyExchangeService.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/ClientKeyExchangeService.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/ClientKeyExchangeService.java Thu May 05 19:11:09 2016 +0000 @@ -50,7 +50,7 @@ providers = new HashMap<>(); static { - String path = GetPropertyAction.getProperty("java.home"); + String path = GetPropertyAction.privilegedGetProperty("java.home"); ServiceLoader sc = AccessController.doPrivileged( (PrivilegedAction>) diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/ssl/Debug.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java Thu May 05 19:11:09 2016 +0000 @@ -45,7 +45,7 @@ private static String args; static { - args = GetPropertyAction.getProperty("javax.net.debug", ""); + args = GetPropertyAction.privilegedGetProperty("javax.net.debug", ""); args = args.toLowerCase(Locale.ENGLISH); if (args.equals("help")) { Help(); @@ -178,11 +178,11 @@ /** * Return the value of the boolean System property propName. * - * Note use of doPrivileged(). Do make accessible to applications. + * Note use of privileged action. Do NOT make accessible to applications. */ static boolean getBooleanProperty(String propName, boolean defaultValue) { // if set, require value of either true or false - String b = GetPropertyAction.getProperty(propName); + String b = GetPropertyAction.privilegedGetProperty(propName); if (b == null) { return defaultValue; } else if (b.equalsIgnoreCase("false")) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Thu May 05 19:11:09 2016 +0000 @@ -656,7 +656,8 @@ // the provider service. Instead, please handle the initialization // exception in the caller's constructor. static { - String property = GetPropertyAction.getProperty(PROPERTY_NAME); + String property = GetPropertyAction + .privilegedGetProperty(PROPERTY_NAME); if (property != null && property.length() != 0) { // remove double quote marks from beginning/end of the property if (property.length() > 1 && property.charAt(0) == '"' && diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Thu May 05 19:11:09 2016 +0000 @@ -119,8 +119,8 @@ private long statusRespTimeout; static { - String property = - GetPropertyAction.getProperty("jdk.tls.ephemeralDHKeySize"); + String property = GetPropertyAction + .privilegedGetProperty("jdk.tls.ephemeralDHKeySize"); if (property == null || property.length() == 0) { useLegacyEphemeralDHKeys = false; useSmartEphemeralDHKeys = false; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java Thu May 05 19:11:09 2016 +0000 @@ -73,8 +73,8 @@ DEFAULT_CACHE_LIFETIME)); cacheLifetime = life > 0 ? life : 0; - String uriStr = - GetPropertyAction.getProperty("jdk.tls.stapling.responderURI"); + String uriStr = GetPropertyAction + .privilegedGetProperty("jdk.tls.stapling.responderURI"); URI tmpURI; try { tmpURI = ((uriStr != null && !uriStr.isEmpty()) ? diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu May 05 19:11:09 2016 +0000 @@ -728,6 +728,7 @@ provClass = Class.forName(provName); } + @SuppressWarnings("deprecation") Object obj = provClass.newInstance(); if (!(obj instanceof Provider)) { MessageFormat form = new MessageFormat diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/util/Debug.java --- a/jdk/src/java.base/share/classes/sun/security/util/Debug.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/util/Debug.java Thu May 05 19:11:09 2016 +0000 @@ -43,10 +43,10 @@ private static String args; static { - args = GetPropertyAction.getProperty("java.security.debug"); + args = GetPropertyAction.privilegedGetProperty("java.security.debug"); - String args2 = - GetPropertyAction.getProperty("java.security.auth.debug"); + String args2 = GetPropertyAction + .privilegedGetProperty("java.security.auth.debug"); if (args == null) { args = args2; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java --- a/jdk/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java Thu May 05 19:11:09 2016 +0000 @@ -196,8 +196,9 @@ // A new keystore is always created in the primary keystore format if (stream == null) { try { - keystore = primaryKeyStore.newInstance(); - + @SuppressWarnings("deprecation") + KeyStoreSpi tmp = primaryKeyStore.newInstance(); + keystore = tmp; } catch (InstantiationException | IllegalAccessException e) { // can safely ignore } @@ -214,7 +215,9 @@ bufferedStream.mark(Integer.MAX_VALUE); try { - keystore = primaryKeyStore.newInstance(); + @SuppressWarnings("deprecation") + KeyStoreSpi tmp = primaryKeyStore.newInstance(); + keystore = tmp; type = primaryType; keystore.engineLoad(bufferedStream, password); @@ -232,7 +235,9 @@ throw e; } - keystore = secondaryKeyStore.newInstance(); + @SuppressWarnings("deprecation") + KeyStoreSpi tmp= secondaryKeyStore.newInstance(); + keystore = tmp; type = secondaryType; bufferedStream.reset(); keystore.engineLoad(bufferedStream, password); @@ -284,7 +289,9 @@ boolean result = false; try { - keystore = primaryKeyStore.newInstance(); + @SuppressWarnings("deprecation") + KeyStoreSpi tmp = primaryKeyStore.newInstance(); + keystore = tmp; type = primaryType; result = keystore.engineProbe(stream); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/security/x509/X509Key.java --- a/jdk/src/java.base/share/classes/sun/security/x509/X509Key.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/x509/X509Key.java Thu May 05 19:11:09 2016 +0000 @@ -255,11 +255,10 @@ } } - Object inst = null; + @SuppressWarnings("deprecation") + Object inst = (keyClass != null) ? keyClass.newInstance() : null; X509Key result; - if (keyClass != null) - inst = keyClass.newInstance(); if (inst instanceof X509Key) { result = (X509Key) inst; result.algid = algid; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java --- a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java Thu May 05 19:11:09 2016 +0000 @@ -157,8 +157,9 @@ cal = LocalGregorianCalendar.getLocalGregorianCalendar(calendarName); } else { try { - Class cl = Class.forName(className); - cal = (CalendarSystem) cl.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = Class.forName(className).newInstance(); + cal = (CalendarSystem) tmp; } catch (Exception e) { throw new InternalError(e); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java --- a/jdk/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java Thu May 05 19:11:09 2016 +0000 @@ -144,7 +144,7 @@ // Append an era to the predefined eras if it's given by the property. String prop = GetPropertyAction - .getProperty("jdk.calendar.japanese.supplemental.era"); + .privilegedGetProperty("jdk.calendar.japanese.supplemental.era"); if (prop != null) { Era era = parseEraEntry(prop); if (era != null) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java --- a/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java Thu May 05 19:11:09 2016 +0000 @@ -246,7 +246,7 @@ static { String oldmapping = GetPropertyAction - .getProperty("sun.timezone.ids.oldmapping", "false") + .privilegedGetProperty("sun.timezone.ids.oldmapping", "false") .toLowerCase(Locale.ROOT); USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true")); AccessController.doPrivileged(new PrivilegedAction() { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java --- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Thu May 05 19:11:09 2016 +0000 @@ -116,7 +116,7 @@ adapterCache = new ConcurrentHashMap<>(); static { - String order = GetPropertyAction.getProperty("java.locale.providers"); + String order = GetPropertyAction.privilegedGetProperty("java.locale.providers"); List typeList = new ArrayList<>(); // Check user specified adapter preference @@ -171,8 +171,9 @@ if (cached == null) { try { // lazily load adapters here - adapter = (LocaleProviderAdapter)Class.forName(type.getAdapterClassName()) - .newInstance(); + @SuppressWarnings("deprecation") + Object tmp = Class.forName(type.getAdapterClassName()).newInstance(); + adapter = (LocaleProviderAdapter)tmp; cached = adapterInstances.putIfAbsent(type, adapter); if (cached != null) { adapter = cached; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java --- a/jdk/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java Thu May 05 19:11:09 2016 +0000 @@ -73,7 +73,7 @@ try { return AccessController.doPrivileged(new PrivilegedExceptionAction

() { @Override - @SuppressWarnings("unchecked") + @SuppressWarnings(value={"unchecked", "deprecation"}) public P run() { P delegate = null; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java --- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java Thu May 05 19:11:09 2016 +0000 @@ -42,7 +42,7 @@ super(provider, dir); // check os.version - String osversion = GetPropertyAction.getProperty("os.version"); + String osversion = GetPropertyAction.privilegedGetProperty("os.version"); String[] vers = Util.split(osversion, '.'); assert vers.length >= 2; int majorVersion = Integer.parseInt(vers[0]); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java --- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Thu May 05 19:11:09 2016 +0000 @@ -85,7 +85,7 @@ @Override FileTypeDetector getFileTypeDetector() { Path userMimeTypes = Paths.get( - GetPropertyAction.getProperty("user.home"), ".mime.types"); + GetPropertyAction.privilegedGetProperty("user.home"), ".mime.types"); Path etcMimeTypes = Paths.get("/etc/mime.types"); return chain(new GioFileTypeDetector(), diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c --- a/jdk/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -94,6 +94,7 @@ return 0; } start = now; + a.dp_timeout = remaining; } } else { return res; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/java/io/UnixFileSystem.java --- a/jdk/src/java.base/unix/classes/java/io/UnixFileSystem.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/java/io/UnixFileSystem.java Thu May 05 19:11:09 2016 +0000 @@ -36,7 +36,7 @@ private final String javaHome; public UnixFileSystem() { - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); slash = props.getProperty("file.separator").charAt(0); colon = props.getProperty("path.separator").charAt(0); javaHome = props.getProperty("java.home"); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java --- a/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java Thu May 05 19:11:09 2016 +0000 @@ -125,7 +125,7 @@ } String helperPath() { - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); return helperPath(props.getProperty("java.home"), props.getProperty("os.arch")); } @@ -159,7 +159,7 @@ } static Platform get() { - String osName = GetPropertyAction.getProperty("os.name"); + String osName = GetPropertyAction.privilegedGetProperty("os.name"); if (osName.equals("Linux")) { return LINUX; } if (osName.contains("OS X")) { return BSD; } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/java/net/DefaultDatagramSocketImplFactory.java --- a/jdk/src/java.base/unix/classes/java/net/DefaultDatagramSocketImplFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/java/net/DefaultDatagramSocketImplFactory.java Thu May 05 19:11:09 2016 +0000 @@ -40,7 +40,7 @@ static { String prefix = null; try { - prefix = GetPropertyAction.getProperty("impl.prefix", null); + prefix = GetPropertyAction.privilegedGetProperty("impl.prefix"); if (prefix != null) prefixImplClass = Class.forName("java.net."+prefix+"DatagramSocketImpl"); } catch (Exception e) { @@ -61,7 +61,9 @@ throws SocketException { if (prefixImplClass != null) { try { - return (DatagramSocketImpl)prefixImplClass.newInstance(); + @SuppressWarnings("deprecation") + DatagramSocketImpl result = (DatagramSocketImpl)prefixImplClass.newInstance(); + return result; } catch (Exception e) { throw new SocketException("can't instantiate DatagramSocketImpl"); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/sun/net/NetHooks.java --- a/jdk/src/java.base/unix/classes/sun/net/NetHooks.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/sun/net/NetHooks.java Thu May 05 19:11:09 2016 +0000 @@ -28,9 +28,6 @@ import java.net.InetAddress; import java.io.FileDescriptor; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import sun.security.action.GetPropertyAction; /** * Defines static methods to be invoked prior to binding or connecting TCP sockets. diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java --- a/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java Thu May 05 19:11:09 2016 +0000 @@ -55,8 +55,9 @@ private PrintStream log; public SdpProvider() { + Properties props = GetPropertyAction.privilegedGetProperties(); // if this property is not defined then there is nothing to do. - String file = GetPropertyAction.getProperty("com.sun.sdp.conf"); + String file = props.getProperty("com.sun.sdp.conf"); if (file == null) { this.enabled = false; this.rules = null; @@ -65,17 +66,15 @@ // load configuration file List list = null; - if (file != null) { - try { - list = loadRulesFromFile(file); - } catch (IOException e) { - fail("Error reading %s: %s", file, e.getMessage()); - } + try { + list = loadRulesFromFile(file); + } catch (IOException e) { + fail("Error reading %s: %s", file, e.getMessage()); } // check if debugging is enabled PrintStream out = null; - String logfile = GetPropertyAction.getProperty("com.sun.sdp.debug"); + String logfile = props.getProperty("com.sun.sdp.debug"); if (logfile != null) { out = System.out; if (logfile.length() > 0) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java --- a/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Thu May 05 19:11:09 2016 +0000 @@ -76,7 +76,7 @@ private String hostname; /* Domain to use if not specified by user */ private static String defaultDomain = - GetPropertyAction.getProperty("http.auth.ntlm.domain", ""); + GetPropertyAction.privilegedGetProperty("http.auth.ntlm.domain", ""); public static boolean supportsTransparentAuth () { return false; @@ -141,7 +141,7 @@ password = pw.getPassword(); init0(); try { - String version = GetPropertyAction.getProperty("ntlm.version"); + String version = GetPropertyAction.privilegedGetProperty("ntlm.version"); client = new Client(version, hostname, username, ntdomain, password); } catch (NTLMException ne) { try { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java --- a/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Thu May 05 19:11:09 2016 +0000 @@ -48,7 +48,9 @@ throw new AssertionError(x); } try { - return c.newInstance(); + @SuppressWarnings("deprecation") + AsynchronousChannelProvider result = c.newInstance(); + return result; } catch (IllegalAccessException | InstantiationException x) { throw new AssertionError(x); } @@ -59,7 +61,7 @@ * Returns the default AsynchronousChannelProvider. */ public static AsynchronousChannelProvider create() { - String osname = GetPropertyAction.getProperty("os.name"); + String osname = GetPropertyAction.privilegedGetProperty("os.name"); if (osname.equals("SunOS")) return createProvider("sun.nio.ch.SolarisAsynchronousChannelProvider"); if (osname.equals("Linux")) diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java --- a/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Thu May 05 19:11:09 2016 +0000 @@ -46,8 +46,8 @@ private static final boolean disableSynchronousRead; static { - String propValue = GetPropertyAction - .getProperty("sun.nio.ch.disableSynchronousRead", "false"); + String propValue = GetPropertyAction.privilegedGetProperty( + "sun.nio.ch.disableSynchronousRead", "false"); disableSynchronousRead = (propValue.length() == 0) ? true : Boolean.valueOf(propValue); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java --- a/jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java Thu May 05 19:11:09 2016 +0000 @@ -44,7 +44,9 @@ throw new AssertionError(x); } try { - return c.newInstance(); + @SuppressWarnings("deprecation") + FileSystemProvider result = c.newInstance(); + return result; } catch (IllegalAccessException | InstantiationException x) { throw new AssertionError(x); } @@ -54,7 +56,7 @@ * Returns the default FileSystemProvider. */ public static FileSystemProvider create() { - String osname = GetPropertyAction.getProperty("os.name"); + String osname = GetPropertyAction.privilegedGetProperty("os.name"); if (osname.equals("SunOS")) return createProvider("sun.nio.fs.SolarisFileSystemProvider"); if (osname.equals("Linux")) diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java Thu May 05 19:11:09 2016 +0000 @@ -57,7 +57,7 @@ // process working directory then paths must be resolved against the // default directory. String propValue = GetPropertyAction - .getProperty("sun.nio.fs.chdirAllowed", "false"); + .privilegedGetProperty("sun.nio.fs.chdirAllowed", "false"); boolean chdirAllowed = (propValue.length() == 0) ? true : Boolean.valueOf(propValue); if (chdirAllowed) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/windows/classes/java/io/WinNTFileSystem.java --- a/jdk/src/java.base/windows/classes/java/io/WinNTFileSystem.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/windows/classes/java/io/WinNTFileSystem.java Thu May 05 19:11:09 2016 +0000 @@ -42,7 +42,7 @@ private final char semicolon; public WinNTFileSystem() { - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); slash = props.getProperty("file.separator").charAt(0); semicolon = props.getProperty("path.separator").charAt(0); altSlash = (this.slash == '\\') ? '/' : '\\'; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/windows/classes/java/net/DefaultDatagramSocketImplFactory.java --- a/jdk/src/java.base/windows/classes/java/net/DefaultDatagramSocketImplFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/windows/classes/java/net/DefaultDatagramSocketImplFactory.java Thu May 05 19:11:09 2016 +0000 @@ -56,7 +56,7 @@ static { Class prefixImplClassLocal = null; - Properties props = GetPropertyAction.getProperties(); + Properties props = GetPropertyAction.privilegedGetProperties(); preferIPv4Stack = Boolean.parseBoolean( props.getProperty("java.net.preferIPv4Stack")); @@ -90,7 +90,9 @@ throws SocketException { if (prefixImplClass != null) { try { - return (DatagramSocketImpl) prefixImplClass.newInstance(); + @SuppressWarnings("deprecation") + Object result = prefixImplClass.newInstance(); + return (DatagramSocketImpl) result; } catch (Exception e) { throw new SocketException("can't instantiate DatagramSocketImpl"); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java --- a/jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Thu May 05 19:11:09 2016 +0000 @@ -53,8 +53,8 @@ private static String defaultDomain; /* Domain to use if not specified by user */ static { - defaultDomain = GetPropertyAction.getProperty("http.auth.ntlm.domain", - "domain"); + defaultDomain = GetPropertyAction + .privilegedGetProperty("http.auth.ntlm.domain", "domain"); }; private void init0() { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java --- a/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java Thu May 05 19:11:09 2016 +0000 @@ -120,7 +120,7 @@ static boolean isFastFileTransferRequested() { String fileTransferProp = GetPropertyAction - .getProperty("jdk.nio.enableFastFileTransfer"); + .privilegedGetProperty("jdk.nio.enableFastFileTransfer"); boolean enable; if ("".equals(fileTransferProp)) { enable = true; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java --- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java Thu May 05 19:11:09 2016 +0000 @@ -114,8 +114,8 @@ // indicates if accurate metadata is required (interesting on NTFS only) private static final boolean ensureAccurateMetadata; static { - String propValue = GetPropertyAction - .getProperty("sun.nio.fs.ensureAccurateMetadata", "false"); + String propValue = GetPropertyAction.privilegedGetProperty( + "sun.nio.fs.ensureAccurateMetadata", "false"); ensureAccurateMetadata = (propValue.length() == 0) ? true : Boolean.valueOf(propValue); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,12 +25,15 @@ package sun.lwawt.macosx; +import sun.lwawt.LWWindowPeer; + import java.awt.*; import java.beans.*; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.concurrent.Callable; +import sun.awt.AWTAccessor; import javax.accessibility.*; import javax.swing.*; @@ -421,6 +424,8 @@ } public static AccessibleAction getAccessibleAction(final Accessible a, final Component c) { + if (a == null) return null; + return invokeAndWait(new Callable() { public AccessibleAction call() throws Exception { final AccessibleContext ac = a.getAccessibleContext(); @@ -667,4 +672,28 @@ } }, c); } + + /** + * @return AWTView ptr, a peer of the CPlatformView associated with the toplevel container of the Accessible, if any + */ + private static long getAWTView(Accessible a) { + Accessible ax = CAccessible.getSwingAccessible(a); + if (!(ax instanceof Component)) return 0; + + return invokeAndWait(new Callable() { + public Long call() throws Exception { + Component cont = (Component) ax; + while (cont != null && !(cont instanceof Window)) { + cont = cont.getParent(); + } + if (cont != null) { + LWWindowPeer peer = (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(cont); + if (peer != null) { + return ((CPlatformWindow) peer.getPlatformWindow()).getContentView().getAWTView(); + } + } + return 0L; + } + }, (Component)ax); + } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -264,6 +264,8 @@ final double localY = boundsUnion.getY(); final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen(); + if (componentLocation == null) return ret; + final double screenX = componentLocation.getX() + localX; final double screenY = componentLocation.getY() + localY; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.h --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.h Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.h Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -62,6 +62,8 @@ - (void) deliverJavaMouseEvent: (NSEvent *) event; - (jobject) awtComponent:(JNIEnv *)env; ++ (AWTView *) awtView:(JNIEnv *)env ofAccessible:(jobject)jaccessible; + // Input method-related events - (void)setInputMethod:(jobject)inputMethod; - (void)abandonInput; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Thu May 05 19:11:09 2016 +0000 @@ -29,6 +29,7 @@ #import "AWTWindow.h" #import "JavaComponentAccessibility.h" #import "JavaTextAccessibility.h" +#import "JavaAccessibilityUtilities.h" #import "GeomUtilities.h" #import "OSVersion.h" #import "ThreadUtilities.h" @@ -129,7 +130,7 @@ self.cglLayer = nil; JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - (*env)->DeleteGlobalRef(env, m_cPlatformView); + (*env)->DeleteWeakGlobalRef(env, m_cPlatformView); m_cPlatformView = NULL; if (fInputMethodLOCKABLE != NULL) @@ -396,7 +397,11 @@ static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); - JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + JNFCallVoidMethod(env, jlocal, jm_deliverMouseEvent, jEvent); + (*env)->DeleteLocalRef(env, jlocal); + } (*env)->DeleteLocalRef(env, jEvent); } @@ -459,8 +464,11 @@ static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView, "deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); - JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jEvent); - + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + JNFCallVoidMethod(env, jlocal, jm_deliverKeyEvent, jEvent); + (*env)->DeleteLocalRef(env, jlocal); + } if (characters != NULL) { (*env)->DeleteLocalRef(env, characters); } @@ -475,7 +483,12 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverResize, jc_PlatformView, "deliverResize", "(IIII)V"); - JNFCallVoidMethod(env, m_cPlatformView, jm_deliverResize, x,y,w,h); + + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + JNFCallVoidMethod(env, jlocal, jm_deliverResize, x,y,w,h); + (*env)->DeleteLocalRef(env, jlocal); + } } @@ -504,7 +517,11 @@ */ static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V"); - JNFCallVoidMethod(env, m_cPlatformView, jm_deliverWindowDidExposeEvent); + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + JNFCallVoidMethod(env, jlocal, jm_deliverWindowDidExposeEvent); + (*env)->DeleteLocalRef(env, jlocal); + } /* } */ @@ -541,7 +558,13 @@ } return NULL; } - jobject peer = JNFGetObjectField(env, m_cPlatformView, jf_Peer); + + jobject peer = NULL; + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + peer = JNFGetObjectField(env, jlocal, jf_Peer); + (*env)->DeleteLocalRef(env, jlocal); + } static JNF_CLASS_CACHE(jc_LWWindowPeer, "sun/lwawt/LWWindowPeer"); static JNF_MEMBER_CACHE(jf_Target, jc_LWWindowPeer, "target", "Ljava/awt/Component;"); if (peer == NULL) { @@ -549,12 +572,27 @@ JNFDumpJavaStack(env); return NULL; } - return JNFGetObjectField(env, peer, jf_Target); + jobject comp = JNFGetObjectField(env, peer, jf_Target); + (*env)->DeleteLocalRef(env, peer); + return comp; +} + ++ (AWTView *) awtView:(JNIEnv*)env ofAccessible:(jobject)jaccessible +{ + static JNF_STATIC_MEMBER_CACHE(jm_getAWTView, sjc_CAccessibility, "getAWTView", "(Ljavax/accessibility/Accessible;)J"); + + jlong jptr = JNFCallStaticLongMethod(env, jm_getAWTView, jaccessible); + if (jptr == 0) return nil; + + return (AWTView *)jlong_to_ptr(jptr); } - (id)getAxData:(JNIEnv*)env { - return [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:[self awtComponent:env] withIndex:-1 withView:self withJavaRole:nil] autorelease]; + jobject jcomponent = [self awtComponent:env]; + id ax = [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease]; + (*env)->DeleteLocalRef(env, jcomponent); + return ax; } - (NSArray *)accessibilityAttributeNames @@ -1299,7 +1337,7 @@ JNF_COCOA_ENTER(env); NSRect rect = NSMakeRect(originX, originY, width, height); - jobject cPlatformView = (*env)->NewGlobalRef(env, obj); + jobject cPlatformView = (*env)->NewWeakGlobalRef(env, obj); [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityAction.m --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityAction.m Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityAction.m Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -35,9 +35,9 @@ { self = [super init]; if (self) { - fAccessibleAction = JNFNewGlobalRef(env, accessibleAction); + fAccessibleAction = JNFNewWeakGlobalRef(env, accessibleAction); fIndex = index; - fComponent = JNFNewGlobalRef(env, component); + fComponent = JNFNewWeakGlobalRef(env, component); } return self; } @@ -46,10 +46,10 @@ { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - JNFDeleteGlobalRef(env, fAccessibleAction); + JNFDeleteWeakGlobalRef(env, fAccessibleAction); fAccessibleAction = NULL; - JNFDeleteGlobalRef(env, fComponent); + JNFDeleteWeakGlobalRef(env, fComponent); fComponent = NULL; [super dealloc]; @@ -61,7 +61,18 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; - return JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fComponent)); // AWT_THREADING Safe (AWTRunLoopMode) + jobject fCompLocal = (*env)->NewLocalRef(env, fComponent); + if ((*env)->IsSameObject(env, fCompLocal, NULL)) { + return @"unknown"; + } + NSString *str = nil; + jobject jstr = JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fCompLocal); + if (jstr != NULL) { + NSString *str = JNFJavaToNSString(env, jstr); // AWT_THREADING Safe (AWTRunLoopMode) + (*env)->DeleteLocalRef(env, jstr); + } + (*env)->DeleteLocalRef(env, fCompLocal); + return str == nil ? @"unknown" : str; } - (void)perform @@ -82,9 +93,9 @@ { self = [super init]; if (self) { - fTabGroup = JNFNewGlobalRef(env, tabGroup); + fTabGroup = JNFNewWeakGlobalRef(env, tabGroup); fIndex = index; - fComponent = JNFNewGlobalRef(env, component); + fComponent = JNFNewWeakGlobalRef(env, component); } return self; } @@ -93,10 +104,10 @@ { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - JNFDeleteGlobalRef(env, fTabGroup); + JNFDeleteWeakGlobalRef(env, fTabGroup); fTabGroup = NULL; - JNFDeleteGlobalRef(env, fComponent); + JNFDeleteWeakGlobalRef(env, fComponent); fComponent = NULL; [super dealloc]; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.m --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.m Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.m Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -77,7 +77,9 @@ jobject axRole = JNFCallStaticObjectMethod(env, sjm_getAccessibleRole, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode) if (axRole == NULL) return @"unknown"; - return JNFJavaToNSString(env, axRole); + NSString* str = JNFJavaToNSString(env, axRole); + (*env)->DeleteLocalRef(env, axRole); + return str; } jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component) @@ -126,21 +128,27 @@ { static JNF_STATIC_MEMBER_CACHE(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;"); jobject axVertState = JNFGetStaticObjectField(env, jm_VERTICAL); - return containsAxState(env, axContext, axVertState, component); + BOOL vertical = containsAxState(env, axContext, axVertState, component); + (*env)->DeleteLocalRef(env, axVertState); + return vertical; } BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component) { static JNF_STATIC_MEMBER_CACHE(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;"); jobject axHorizState = JNFGetStaticObjectField(env, jm_HORIZONTAL); - return containsAxState(env, axContext, axHorizState, component); + BOOL horizontal = containsAxState(env, axContext, axHorizState, component); + (*env)->DeleteLocalRef(env, axHorizState); + return horizontal; } BOOL isShowing(JNIEnv *env, jobject axContext, jobject component) { static JNF_STATIC_MEMBER_CACHE(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;"); jobject axVisibleState = JNFGetStaticObjectField(env, jm_SHOWING); - return containsAxState(env, axContext, axVisibleState, component); + BOOL showing = containsAxState(env, axContext, axVisibleState, component); + (*env)->DeleteLocalRef(env, axVisibleState); + return showing; } NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component) diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -75,7 +75,6 @@ static NSMutableDictionary *sAttributeNamesForRoleCache = nil; static NSObject *sAttributeNamesLOCK = nil; - @interface TabGroupAccessibility : JavaComponentAccessibility { NSInteger _numTabs; } @@ -137,8 +136,11 @@ fView = [view retain]; fJavaRole = [javaRole retain]; - fAccessible = JNFNewGlobalRef(env, accessible); - fComponent = JNFNewGlobalRef(env, [(AWTView *)fView awtComponent:env]); + fAccessible = (*env)->NewWeakGlobalRef(env, accessible); + + jobject jcomponent = [(AWTView *)fView awtComponent:env]; + fComponent = (*env)->NewWeakGlobalRef(env, jcomponent); + (*env)->DeleteLocalRef(env, jcomponent); fIndex = index; @@ -166,10 +168,10 @@ JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - JNFDeleteGlobalRef(env, fAccessible); + (*env)->DeleteWeakGlobalRef(env, fAccessible); fAccessible = NULL; - JNFDeleteGlobalRef(env, fComponent); + (*env)->DeleteWeakGlobalRef(env, fComponent); fComponent = NULL; [fParent release]; @@ -279,7 +281,7 @@ + (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored { - jobjectArray jchildrenAndRoles = JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) + jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) if (jchildrenAndRoles == NULL) return nil; jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles); @@ -294,14 +296,21 @@ NSString *childJavaRole = nil; if (jchildJavaRole != NULL) { - childJavaRole = JNFJavaToNSString(env, JNFGetObjectField(env, jchildJavaRole, sjf_key)); + jobject jkey = JNFGetObjectField(env, jchildJavaRole, sjf_key); + childJavaRole = JNFJavaToNSString(env, jkey); + (*env)->DeleteLocalRef(env, jkey); } JavaComponentAccessibility *child = [self createWithParent:parent accessible:jchild role:childJavaRole index:childIndex withEnv:env withView:parent->fView]; + + (*env)->DeleteLocalRef(env, jchild); + (*env)->DeleteLocalRef(env, jchildJavaRole); + [children addObject:child]; childIndex++; } - + (*env)->DeleteLocalRef(env, jchildrenAndRoles); + return children; } @@ -310,7 +319,7 @@ jobject jcomponent = [(AWTView *)view awtComponent:env]; jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent); NSString *javaRole = getJavaRole(env, jaccessible, jcomponent); - + (*env)->DeleteLocalRef(env, jcomponent); return [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view]; } @@ -325,7 +334,10 @@ jobject jCAX = [JavaComponentAccessibility getCAccessible:jaccessible withEnv:env]; if (jCAX == NULL) return nil; JavaComponentAccessibility *value = (JavaComponentAccessibility *) jlong_to_ptr(JNFGetLongField(env, jCAX, jf_ptr)); - if (value != nil) return [[value retain] autorelease]; + if (value != nil) { + (*env)->DeleteLocalRef(env, jCAX); + return [[value retain] autorelease]; + } // otherwise, create a new instance JavaComponentAccessibility *newChild = nil; @@ -348,6 +360,7 @@ // must hard retain pointer poked into Java object [newChild retain]; JNFSetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild)); + (*env)->DeleteLocalRef(env, jCAX); // return autoreleased instance return [newChild autorelease]; @@ -380,7 +393,7 @@ // Get all the other accessibility attributes states we need in one swell foop. // javaRole isn't pulled in because we need protected access to AccessibleRole.key - jbooleanArray attributeStates = JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) + jbooleanArray attributeStates = (jbooleanArray)JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (attributeStates == NULL) return nil; jboolean *attributeStatesArray = (*env)->GetBooleanArrayElements(env, attributeStates, 0); if (attributeStatesArray == NULL) { @@ -475,6 +488,7 @@ JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent]; [fActions setObject:action forKey:[self isMenu] ? NSAccessibilityPickAction : NSAccessibilityPressAction]; [action release]; + (*env)->DeleteLocalRef(env, axAction); } } @@ -485,7 +499,9 @@ - (id)parent { + static JNF_CLASS_CACHE(sjc_Window, "java/awt/Window"); static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleParent, sjc_CAccessibility, "getAccessibleParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;"); + static JNF_STATIC_MEMBER_CACHE(sjm_getSwingAccessible, sjc_CAccessible, "getSwingAccessible", "(Ljavax/accessibility/Accessible;)Ljavax/accessibility/Accessible;"); if(fParent == nil) { JNIEnv* env = [ThreadUtilities getJNIEnv]; @@ -495,10 +511,21 @@ if (jparent == NULL) { fParent = fView; } else { - fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:fView]; + AWTView *view = fView; + jobject jax = JNFCallStaticObjectMethod(env, sjm_getSwingAccessible, fAccessible); + + if (JNFIsInstanceOf(env, jax, &sjc_Window)) { + // In this case jparent is an owner toplevel and we should retrieve its own view + view = [AWTView awtView:env ofAccessible:jparent]; + } + if (view != nil) { + fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:view]; + } if (fParent == nil) { fParent = fView; } + (*env)->DeleteLocalRef(env, jparent); + (*env)->DeleteLocalRef(env, jax ); } [fParent retain]; } @@ -546,7 +573,10 @@ return NO; } - return isShowing(env, [self axContextWithEnv:env], fComponent); + jobject axContext = [self axContextWithEnv:env]; + BOOL showing = isShowing(env, axContext, fComponent); + (*env)->DeleteLocalRef(env, axContext); + return showing; } // the array of names for each role is cached in the sAttributeNamesForRoleCache @@ -723,7 +753,12 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSString(env, val); + if (val == NULL) { + return @"unknown"; + } + NSString* str = JNFJavaToNSString(env, val); + (*env)->DeleteLocalRef(env, val); + return str; } - (BOOL)accessibilityIsHelpAttributeSettable @@ -739,7 +774,12 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axValue = JNFCallStaticObjectMethod(env, jm_getMaximumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSNumber(env, axValue); + if (axValue == NULL) { + return [NSNumber numberWithInt:0]; + } + NSNumber* num = JNFJavaToNSNumber(env, axValue); + (*env)->DeleteLocalRef(env, axValue); + return num; } - (BOOL)accessibilityIsMaxValueAttributeSettable @@ -755,7 +795,12 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axValue = JNFCallStaticObjectMethod(env, jm_getMinimumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSNumber(env, axValue); + if (axValue == NULL) { + return [NSNumber numberWithInt:0]; + } + NSNumber* num = JNFJavaToNSNumber(env, axValue); + (*env)->DeleteLocalRef(env, axValue); + return num; } - (BOOL)accessibilityIsMinValueAttributeSettable @@ -770,13 +815,16 @@ // cmcnote - should batch these two calls into one that returns an array of two bools, one for vertical and one for horiz if (isVertical(env, axContext, fComponent)) { + (*env)->DeleteLocalRef(env, axContext); return NSAccessibilityVerticalOrientationValue; } if (isHorizontal(env, axContext, fComponent)) { + (*env)->DeleteLocalRef(env, axContext); return NSAccessibilityHorizontalOrientationValue; } + (*env)->DeleteLocalRef(env, axContext); return nil; } @@ -808,6 +856,7 @@ // Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent. NSSize size = getAxComponentSize(env, axComponent, fComponent); NSPoint point = getAxComponentLocationOnScreen(env, axComponent, fComponent); + (*env)->DeleteLocalRef(env, axComponent); point.y += size.height; @@ -857,8 +906,9 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axRole = JNFCallStaticObjectMethod(env, jm_getAccessibleRoleDisplayString, fAccessible, fComponent); - if(axRole != NULL) { + if (axRole != NULL) { value = JNFJavaToNSString(env, axRole); + (*env)->DeleteLocalRef(env, axRole); } else { value = @"unknown"; } @@ -893,7 +943,9 @@ - (NSValue *)accessibilitySizeAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)]; + NSValue* size = [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)]; + (*env)->DeleteLocalRef(env, axComponent); + return size; } - (BOOL)accessibilityIsSizeAttributeSettable @@ -952,7 +1004,12 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSString(env, val); + if (val == NULL) { + return @"unknown"; + } + NSString* str = JNFJavaToNSString(env, val); + (*env)->DeleteLocalRef(env, val); + return str; } - (BOOL)accessibilityIsTitleAttributeSettable @@ -984,8 +1041,20 @@ // a text value is taken care of in JavaTextAccessibility // cmcnote should coalesce these calls into one java call + NSNumber *num = nil; jobject axValue = JNFCallStaticObjectMethod(env, sjm_getAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSNumber(env, JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent)); // AWT_THREADING Safe (AWTRunLoop) + if (axValue != NULL) { + jobject str = JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent); + if (str != NULL) { + num = JNFJavaToNSNumber(env, str); // AWT_THREADING Safe (AWTRunLoop) + (*env)->DeleteLocalRef(env, str); + } + (*env)->DeleteLocalRef(env, axValue); + } + if (num == nil) { + num = [NSNumber numberWithInt:0]; + } + return num; } - (BOOL)accessibilityIsValueAttributeSettable @@ -1084,7 +1153,10 @@ id value = nil; if (JNFIsInstanceOf(env, jparent, &jc_Container)) { jobject jaccessible = JNFCallStaticObjectMethod(env, jm_accessibilityHitTest, jparent, (jfloat)point.x, (jfloat)point.y); // AWT_THREADING Safe (AWTRunLoop) - value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView]; + if (jaccessible != NULL) { + value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView]; + (*env)->DeleteLocalRef(env, jaccessible); + } } if (value == nil) { @@ -1116,6 +1188,7 @@ if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) { value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView]; } + (*env)->DeleteLocalRef(env, focused); } if (value == nil) { @@ -1222,38 +1295,46 @@ for (i = 0; i < _numTabs; i++) { aTab = (JavaComponentAccessibility *)[tabs objectAtIndex:i]; if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) { + (*env)->DeleteLocalRef(env, selAccessible); return aTab; } } - + (*env)->DeleteLocalRef(env, selAccessible); return nil; } - (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored { - jobjectArray jtabsAndRoles = JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) + jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) if(jtabsAndRoles == NULL) return nil; jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles); - if (arrayLen == 0) return nil; - + if (arrayLen == 0) { + (*env)->DeleteLocalRef(env, jtabsAndRoles); + return nil; + } NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)]; // all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1. - if (jtabJavaRole == NULL) return nil; - - NSString *tabJavaRole = JNFJavaToNSString(env, JNFGetObjectField(env, jtabJavaRole, sjf_key)); + if (jtabJavaRole == NULL) { + (*env)->DeleteLocalRef(env, jtabsAndRoles); + return nil; + } + jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key); + NSString *tabJavaRole = JNFJavaToNSString(env, jkey); + (*env)->DeleteLocalRef(env, jkey); NSInteger i; NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly for(i = 0; i < arrayLen; i+=2) { jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i); JavaComponentAccessibility *tab = [[[TabGroupControlAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease]; + (*env)->DeleteLocalRef(env, jtab); [tabs addObject:tab]; tabIndex++; } - + (*env)->DeleteLocalRef(env, jtabsAndRoles); return tabs; } @@ -1272,7 +1353,9 @@ { JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; - return [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; + id tabs = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; + (*env)->DeleteLocalRef(env, axContext); + return tabs; } - (BOOL)accessibilityIsTabsAttributeSettable @@ -1292,7 +1375,9 @@ { JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; - return [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; + NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; + (*env)->DeleteLocalRef(env, axContext); + return cont; } - (BOOL)accessibilityIsContentsAttributeSettable @@ -1305,7 +1390,9 @@ { JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; - return [self currentTabWithEnv:env withAxContext:axContext]; + id val = [self currentTabWithEnv:env withAxContext:axContext]; + (*env)->DeleteLocalRef(env, axContext); + return val; } - (BOOL)accessibilityIsValueAttributeSettable @@ -1322,6 +1409,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; setAxContextSelection(env, axContext, fIndex, fComponent); + (*env)->DeleteLocalRef(env, axContext); } - (NSArray *)accessibilityChildrenAttribute @@ -1357,6 +1445,7 @@ result = children; } } + (*env)->DeleteLocalRef(env, axContext); } else { result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount]; } @@ -1375,7 +1464,7 @@ self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole]; if (self) { if (tabGroup != NULL) { - fTabGroupAxContext = JNFNewGlobalRef(env, tabGroup); + fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroup); } else { fTabGroupAxContext = NULL; } @@ -1388,7 +1477,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; if (fTabGroupAxContext != NULL) { - JNFDeleteGlobalRef(env, fTabGroupAxContext); + JNFDeleteWeakGlobalRef(env, fTabGroupAxContext); fTabGroupAxContext = NULL; } @@ -1399,9 +1488,14 @@ { JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; + jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent); // Returns the current selection of the page tab list - return [NSNumber numberWithBool:ObjectEquals(env, axContext, getAxContextSelection(env, [self tabGroup], fIndex, fComponent), fComponent)]; + id val = [NSNumber numberWithBool:ObjectEquals(env, axContext, selAccessible, fComponent)]; + + (*env)->DeleteLocalRef(env, selAccessible); + (*env)->DeleteLocalRef(env, axContext); + return val; } - (void)getActionsWithEnv:(JNIEnv *)env @@ -1416,7 +1510,8 @@ if (fTabGroupAxContext == NULL) { JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env]; - fTabGroupAxContext = JNFNewGlobalRef(env, tabGroupAxContext); + fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext); + (*env)->DeleteLocalRef(env, tabGroupAxContext); } return fTabGroupAxContext; } @@ -1451,8 +1546,10 @@ if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) { jobject elementAxContext = [aElement axContextWithEnv:env]; if (isHorizontal(env, elementAxContext, fComponent)) { + (*env)->DeleteLocalRef(env, elementAxContext); return aElement; } + (*env)->DeleteLocalRef(env, elementAxContext); } } @@ -1478,8 +1575,10 @@ if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) { jobject elementAxContext = [aElement axContextWithEnv:env]; if (isVertical(env, elementAxContext, fComponent)) { + (*env)->DeleteLocalRef(env, elementAxContext); return aElement; } + (*env)->DeleteLocalRef(env, elementAxContext); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaTextAccessibility.m --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaTextAccessibility.m Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaTextAccessibility.m Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -112,7 +112,9 @@ // if it's static text, the AppKit AXValue is the java accessibleName jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axName != NULL) { - return JNFJavaToNSString(env, axName); + NSString* str = JNFJavaToNSString(env, axName); + (*env)->DeleteLocalRef(env, axName); + return str; } // value is still nil if no accessibleName for static text. Below, try to get the accessibleText. } @@ -120,12 +122,18 @@ // cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923 jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axText == NULL) return nil; - + (*env)->DeleteLocalRef(env, axText); + jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axEditableText == NULL) return nil; static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;"); - NSString *string = JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent)); // AWT_THREADING Safe (AWTRunLoop) + jobject jrange = JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent); + NSString *string = JNFJavaToNSString(env, jrange); // AWT_THREADING Safe (AWTRunLoop) + + (*env)->DeleteLocalRef(env, jrange); + (*env)->DeleteLocalRef(env, axEditableText); + if (string == nil) string = @""; return string; } @@ -139,6 +147,7 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axEditableText == NULL) return NO; + (*env)->DeleteLocalRef(env, axEditableText); return YES; } @@ -157,7 +166,9 @@ static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axText == NULL) return @""; - return JNFJavaToNSString(env, axText); + NSString* str = JNFJavaToNSString(env, axText); + (*env)->DeleteLocalRef(env, axText); + return str; } - (BOOL)accessibilityIsSelectedTextAttributeSettable @@ -220,7 +231,9 @@ // also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)]; + NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)]; + (*env)->DeleteLocalRef(env, axText); + return num; } - (BOOL)accessibilityIsNumberOfCharactersAttributeSettable @@ -285,7 +298,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D"); - jdoubleArray axBounds = JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) + jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) if (axBounds == NULL) return nil; // We cheat because we know that the array is 4 elements long (x, y, width, height) @@ -324,7 +337,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); - jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop) + jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop) if (axTextRange == NULL) return nil; return javaIntArrayToNSRangeValue(env,axTextRange); @@ -350,10 +363,12 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;"); - jstring jstringForRange = JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) + jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) if (jstringForRange == NULL) return @""; - return JNFJavaToNSString(env, jstringForRange); + NSString* str = JNFJavaToNSString(env, jstringForRange); + (*env)->DeleteLocalRef(env, jstringForRange); + return str; } // @@ -406,7 +421,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); - jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop) + jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop) if (axTextRange == NULL) return nil; return javaIntArrayToNSRangeValue(env, axTextRange); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLLayer.h --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLLayer.h Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLLayer.h Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -31,7 +31,7 @@ @interface CGLLayer : CAOpenGLLayer { @private - JNFJObjectWrapper *javaLayer; + JNFWeakJObjectWrapper *javaLayer; // intermediate buffer, used the RQ lock to synchronize GLuint textureID; @@ -45,7 +45,7 @@ #endif /* REMOTELAYER */ } -@property (nonatomic, retain) JNFJObjectWrapper *javaLayer; +@property (nonatomic, retain) JNFWeakJObjectWrapper *javaLayer; @property (readwrite, assign) GLuint textureID; @property (readwrite, assign) GLenum target; @property (readwrite, assign) float textureWidth; @@ -57,7 +57,7 @@ @property (nonatomic, retain) NSObject *jrsRemoteLayer; #endif -- (id) initWithJavaLayer:(JNFJObjectWrapper *)javaLayer; +- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)javaLayer; - (void) blitTexture; @end diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLLayer.m --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLLayer.m Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLLayer.m Thu May 05 19:11:09 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -46,7 +46,7 @@ @synthesize jrsRemoteLayer; #endif -- (id) initWithJavaLayer:(JNFJObjectWrapper *)layer; +- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer; { AWT_ASSERT_APPKIT_THREAD; // Initialize ourselves @@ -133,6 +133,15 @@ { AWT_ASSERT_APPKIT_THREAD; + JNIEnv *env = [ThreadUtilities getJNIEnv]; + static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer"); + static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V"); + + jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env]; + if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) { + return; + } + // Set the current context to the one given to us. CGLSetCurrentContext(glContext); @@ -141,12 +150,7 @@ glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, textureWidth, textureHeight); - - JNIEnv *env = [ThreadUtilities getJNIEnv]; - static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer"); - static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V"); - jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env]; JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext); (*env)->DeleteLocalRef(env, javaLayerLocalRef); @@ -171,7 +175,7 @@ JNF_COCOA_ENTER(env); - JNFJObjectWrapper *javaLayer = [JNFJObjectWrapper wrapperWithJObject:obj withEnv:env]; + JNFWeakJObjectWrapper *javaLayer = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env]; [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ AWT_ASSERT_APPKIT_THREAD; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.httpclient/share/classes/java/net/http/FilterFactory.java --- a/jdk/src/java.httpclient/share/classes/java/net/http/FilterFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.httpclient/share/classes/java/net/http/FilterFactory.java Thu May 05 19:11:09 2016 +0000 @@ -39,7 +39,9 @@ List l = new LinkedList<>(); for (Class clazz : filterClasses) { try { - l.add(clazz.newInstance()); + @SuppressWarnings("deprecation") + HeaderFilter headerFilter = clazz.newInstance(); + l.add(headerFilter); } catch (ReflectiveOperationException e) { throw new InternalError(e); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.httpclient/share/classes/java/net/http/Utils.java --- a/jdk/src/java.httpclient/share/classes/java/net/http/Utils.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.httpclient/share/classes/java/net/http/Utils.java Thu May 05 19:11:09 2016 +0000 @@ -146,7 +146,7 @@ } else { sb.append(uri.getScheme()) .append("://") - .append(uri.getHost()) + .append(uri.getAuthority()) .append(uri.getPath()); urlstring = sb.toString(); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.logging/share/classes/java/util/logging/LogManager.java --- a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java Thu May 05 19:11:09 2016 +0000 @@ -231,13 +231,15 @@ cname = System.getProperty("java.util.logging.manager"); if (cname != null) { try { - Class clz = ClassLoader.getSystemClassLoader() - .loadClass(cname); - mgr = (LogManager) clz.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = ClassLoader.getSystemClassLoader() + .loadClass(cname).newInstance(); + mgr = (LogManager) tmp; } catch (ClassNotFoundException ex) { - Class clz = Thread.currentThread() - .getContextClassLoader().loadClass(cname); - mgr = (LogManager) clz.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = Thread.currentThread() + .getContextClassLoader().loadClass(cname).newInstance(); + mgr = (LogManager) tmp; } } } catch (Exception ex) { @@ -991,8 +993,9 @@ List handlers = new ArrayList<>(names.length); for (String type : names) { try { - Class clz = ClassLoader.getSystemClassLoader().loadClass(type); - Handler hdl = (Handler) clz.newInstance(); + @SuppressWarnings("deprecation") + Object o = ClassLoader.getSystemClassLoader().loadClass(type).newInstance(); + Handler hdl = (Handler) o; // Check if there is a property defining the // this handler's level. String levs = getProperty(type + ".level"); @@ -1330,11 +1333,13 @@ // calling readConfiguration(InputStream) with a suitable stream. try { Class clz = ClassLoader.getSystemClassLoader().loadClass(cname); - clz.newInstance(); + @SuppressWarnings("deprecation") + Object witness = clz.newInstance(); return; } catch (ClassNotFoundException ex) { Class clz = Thread.currentThread().getContextClassLoader().loadClass(cname); - clz.newInstance(); + @SuppressWarnings("deprecation") + Object witness = clz.newInstance(); return; } } catch (Exception ex) { @@ -1561,7 +1566,8 @@ for (String word : names) { try { Class clz = ClassLoader.getSystemClassLoader().loadClass(word); - clz.newInstance(); + @SuppressWarnings("deprecation") + Object witness = clz.newInstance(); } catch (Exception ex) { System.err.println("Can't load config class \"" + word + "\""); System.err.println("" + ex); @@ -2307,8 +2313,9 @@ String val = getProperty(name); try { if (val != null) { - Class clz = ClassLoader.getSystemClassLoader().loadClass(val); - return (Filter) clz.newInstance(); + @SuppressWarnings("deprecation") + Object o = ClassLoader.getSystemClassLoader().loadClass(val).newInstance(); + return (Filter) o; } } catch (Exception ex) { // We got one of a variety of exceptions in creating the @@ -2328,8 +2335,9 @@ String val = getProperty(name); try { if (val != null) { - Class clz = ClassLoader.getSystemClassLoader().loadClass(val); - return (Formatter) clz.newInstance(); + @SuppressWarnings("deprecation") + Object o = ClassLoader.getSystemClassLoader().loadClass(val).newInstance(); + return (Formatter) o; } } catch (Exception ex) { // We got one of a variety of exceptions in creating the diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.logging/share/classes/java/util/logging/MemoryHandler.java --- a/jdk/src/java.logging/share/classes/java/util/logging/MemoryHandler.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.logging/share/classes/java/util/logging/MemoryHandler.java Thu May 05 19:11:09 2016 +0000 @@ -117,7 +117,9 @@ Class clz; try { clz = ClassLoader.getSystemClassLoader().loadClass(targetName); - target = (Handler) clz.newInstance(); + @SuppressWarnings("deprecation") + Object o = clz.newInstance(); + target = (Handler) o; } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { throw new RuntimeException("MemoryHandler can't load handler target \"" + targetName + "\"" , e); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.management/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java --- a/jdk/src/java.management/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.management/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Thu May 05 19:11:09 2016 +0000 @@ -655,7 +655,9 @@ final Object[] openArray = (Object[]) openValue; final Collection valueCollection; try { - valueCollection = cast(collectionClass.newInstance()); + @SuppressWarnings("deprecation") + Collection tmp = collectionClass.newInstance(); + valueCollection = cast(tmp); } catch (Exception e) { throw invalidObjectException("Cannot create collection", e); } @@ -1114,7 +1116,9 @@ try { final Class targetClass = getTargetClass(); ReflectUtil.checkPackageAccess(targetClass); - o = targetClass.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = targetClass.newInstance(); + o = tmp; for (int i = 0; i < itemNames.length; i++) { if (cd.containsKey(itemNames[i])) { Object openItem = cd.get(itemNames[i]); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.management/share/classes/javax/management/MBeanServerFactory.java --- a/jdk/src/java.management/share/classes/javax/management/MBeanServerFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.management/share/classes/javax/management/MBeanServerFactory.java Thu May 05 19:11:09 2016 +0000 @@ -458,6 +458,7 @@ **/ private static MBeanServerBuilder newBuilder(Class builderClass) { try { + @SuppressWarnings("deprecation") final Object abuilder = builderClass.newInstance(); return (MBeanServerBuilder)abuilder; } catch (RuntimeException x) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java --- a/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java Thu May 05 19:11:09 2016 +0000 @@ -531,7 +531,9 @@ // We have just proved that this cast is correct Class providerClassT = Util.cast(providerClass); try { - return providerClassT.newInstance(); + @SuppressWarnings("deprecation") + T result = providerClassT.newInstance(); + return result; } catch (Exception e) { final String msg = "Exception when instantiating provider [" + className + diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.naming/share/classes/com/sun/naming/internal/FactoryEnumeration.java --- a/jdk/src/java.naming/share/classes/com/sun/naming/internal/FactoryEnumeration.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.naming/share/classes/com/sun/naming/internal/FactoryEnumeration.java Thu May 05 19:11:09 2016 +0000 @@ -86,7 +86,9 @@ answer = cls; } // Instantiate Class to get factory - answer = ((Class) answer).newInstance(); + @SuppressWarnings("deprecation") + Object tmp = ((Class) answer).newInstance(); + answer = tmp; ref = new NamedWeakReference<>(answer, className); factories.set(posn-1, ref); // replace Class object or null return answer; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.naming/share/classes/com/sun/naming/internal/ResourceManager.java --- a/jdk/src/java.naming/share/classes/com/sun/naming/internal/ResourceManager.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.naming/share/classes/com/sun/naming/internal/ResourceManager.java Thu May 05 19:11:09 2016 +0000 @@ -399,7 +399,9 @@ className = parser.nextToken() + classSuffix; try { // System.out.println("loading " + className); - factory = helper.loadClass(className, loader).newInstance(); + @SuppressWarnings("deprecation") // Class.newInstance + Object tmp = helper.loadClass(className, loader).newInstance(); + factory = tmp; } catch (InstantiationException e) { NamingException ne = new NamingException("Cannot instantiate " + className); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.naming/share/classes/javax/naming/ldap/StartTlsRequest.java --- a/jdk/src/java.naming/share/classes/javax/naming/ldap/StartTlsRequest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.naming/share/classes/javax/naming/ldap/StartTlsRequest.java Thu May 05 19:11:09 2016 +0000 @@ -192,18 +192,12 @@ } try { VersionHelper helper = VersionHelper.getVersionHelper(); - Class clas = helper.loadClass( - "com.sun.jndi.ldap.ext.StartTlsResponseImpl"); - - resp = (StartTlsResponse) clas.newInstance(); + @SuppressWarnings("deprecation") + Object o = helper.loadClass( + "com.sun.jndi.ldap.ext.StartTlsResponseImpl").newInstance(); + resp = (StartTlsResponse) o; - } catch (IllegalAccessException e) { - throw wrapException(e); - - } catch (InstantiationException e) { - throw wrapException(e); - - } catch (ClassNotFoundException e) { + } catch (IllegalAccessException | InstantiationException | ClassNotFoundException e) { throw wrapException(e); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.naming/share/classes/javax/naming/spi/NamingManager.java --- a/jdk/src/java.naming/share/classes/javax/naming/spi/NamingManager.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.naming/share/classes/javax/naming/spi/NamingManager.java Thu May 05 19:11:09 2016 +0000 @@ -159,7 +159,9 @@ } } - return (clas != null) ? (ObjectFactory) clas.newInstance() : null; + @SuppressWarnings("deprecation") // Class.newInstance + ObjectFactory result = (clas != null) ? (ObjectFactory) clas.newInstance() : null; + return result; } @@ -710,8 +712,9 @@ if (factory == null) { try { - factory = (InitialContextFactory) - helper.loadClass(className).newInstance(); + @SuppressWarnings("deprecation") + Object o = helper.loadClass(className).newInstance(); + factory = (InitialContextFactory) o; } catch (Exception e) { NoInitialContextException ne = new NoInitialContextException( diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.prefs/share/classes/java/util/prefs/Preferences.java --- a/jdk/src/java.prefs/share/classes/java/util/prefs/Preferences.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.prefs/share/classes/java/util/prefs/Preferences.java Thu May 05 19:11:09 2016 +0000 @@ -238,10 +238,11 @@ // dependent on the invoking thread. // Checking AllPermission also seems wrong. try { - return (PreferencesFactory) - Class.forName(factoryName, false, - ClassLoader.getSystemClassLoader()) + @SuppressWarnings("deprecation") + Object result =Class.forName(factoryName, false, + ClassLoader.getSystemClassLoader()) .newInstance(); + return (PreferencesFactory)result; } catch (Exception ex) { try { // workaround for javaws, plugin, @@ -250,11 +251,12 @@ if (sm != null) { sm.checkPermission(new java.security.AllPermission()); } - return (PreferencesFactory) - Class.forName(factoryName, false, - Thread.currentThread() - .getContextClassLoader()) + @SuppressWarnings("deprecation") + Object result = Class.forName(factoryName, false, + Thread.currentThread() + .getContextClassLoader()) .newInstance(); + return (PreferencesFactory) result; } catch (Exception e) { throw new InternalError( "Can't instantiate Preferences factory " @@ -299,9 +301,10 @@ platformFactory = "java.util.prefs.FileSystemPreferencesFactory"; } try { - return (PreferencesFactory) - Class.forName(platformFactory, false, - Preferences.class.getClassLoader()).newInstance(); + @SuppressWarnings("deprecation") + Object result = Class.forName(platformFactory, false, + Preferences.class.getClassLoader()).newInstance(); + return (PreferencesFactory) result; } catch (Exception e) { throw new InternalError( "Can't instantiate platform default Preferences factory " diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationID.java --- a/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationID.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationID.java Thu May 05 19:11:09 2016 +0000 @@ -272,6 +272,7 @@ Class refClass = Class.forName(RemoteRef.packagePrefix + "." + in.readUTF()) .asSubclass(RemoteRef.class); + @SuppressWarnings("deprecation") RemoteRef ref = refClass.newInstance(); ref.readExternal(in); activator = (Activator) diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.rmi/share/classes/java/rmi/server/RMIClassLoader.java --- a/jdk/src/java.rmi/share/classes/java/rmi/server/RMIClassLoader.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.rmi/share/classes/java/rmi/server/RMIClassLoader.java Thu May 05 19:11:09 2016 +0000 @@ -681,7 +681,9 @@ Class.forName(providerClassName, false, ClassLoader.getSystemClassLoader()) .asSubclass(RMIClassLoaderSpi.class); - return providerClass.newInstance(); + @SuppressWarnings("deprecation") + RMIClassLoaderSpi result = providerClass.newInstance(); + return result; } catch (ClassNotFoundException e) { throw new NoClassDefFoundError(e.getMessage()); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.rmi/share/classes/java/rmi/server/RemoteObject.java --- a/jdk/src/java.rmi/share/classes/java/rmi/server/RemoteObject.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.rmi/share/classes/java/rmi/server/RemoteObject.java Thu May 05 19:11:09 2016 +0000 @@ -439,18 +439,16 @@ RemoteRef.packagePrefix + "." + refClassName; Class refClass = Class.forName(internalRefClassName); try { - ref = (RemoteRef) refClass.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = refClass.newInstance(); + ref = (RemoteRef) tmp; /* * If this step fails, assume we found an internal * class that is not meant to be a serializable ref * type. */ - } catch (InstantiationException e) { - throw new ClassNotFoundException(internalRefClassName, e); - } catch (IllegalAccessException e) { - throw new ClassNotFoundException(internalRefClassName, e); - } catch (ClassCastException e) { + } catch (InstantiationException | IllegalAccessException | ClassCastException e) { throw new ClassNotFoundException(internalRefClassName, e); } ref.readExternal(in); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.rmi/share/classes/sun/rmi/server/Activation.java --- a/jdk/src/java.rmi/share/classes/sun/rmi/server/Activation.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/Activation.java Thu May 05 19:11:09 2016 +0000 @@ -2066,7 +2066,9 @@ try { Class execPolicyClass = getRMIClass(execPolicyClassName); - execPolicy = execPolicyClass.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = execPolicyClass.newInstance(); + execPolicy = tmp; execPolicyMethod = execPolicyClass.getMethod("checkExecCommand", ActivationGroupDesc.class, diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.smartcardio/share/classes/javax/smartcardio/TerminalFactory.java --- a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/TerminalFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/TerminalFactory.java Thu May 05 19:11:09 2016 +0000 @@ -111,8 +111,9 @@ type = "PC/SC"; Provider sun = Security.getProvider("SunPCSC"); if (sun == null) { - Class clazz = Class.forName("sun.security.smartcardio.SunPCSC"); - sun = (Provider)clazz.newInstance(); + @SuppressWarnings("deprecation") + Object o = Class.forName("sun.security.smartcardio.SunPCSC").newInstance(); + sun = (Provider)o; } factory = TerminalFactory.getInstance(type, null, sun); } catch (Exception e) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java --- a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java Thu May 05 19:11:09 2016 +0000 @@ -2962,7 +2962,9 @@ SQLData obj = null; try { ReflectUtil.checkPackageAccess(c); - obj = (SQLData) c.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = c.newInstance(); + obj = (SQLData) tmp; } catch(Exception ex) { throw new SQLException("Unable to Instantiate: ", ex); } @@ -5710,7 +5712,9 @@ SQLData obj = null; try { ReflectUtil.checkPackageAccess(c); - obj = (SQLData) c.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = c.newInstance(); + obj = (SQLData) tmp; } catch(Exception ex) { throw new SQLException("Unable to Instantiate: ", ex); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.sql.rowset/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java --- a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Thu May 05 19:11:09 2016 +0000 @@ -574,7 +574,9 @@ SQLData obj = null; try { ReflectUtil.checkPackageAccess(c); - obj = (SQLData)c.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = c.newInstance(); + obj = (SQLData)tmp; } catch (Exception ex) { throw new SQLException("Unable to Instantiate: ", ex); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetProvider.java --- a/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetProvider.java Thu May 05 19:11:09 2016 +0000 @@ -136,8 +136,9 @@ } // getFactoryClass takes care of adding the read edge if // necessary - Class c = getFactoryClass(factoryClassName, null, false); - factory = (RowSetFactory) c.newInstance(); + @SuppressWarnings("deprecation") + Object o = getFactoryClass(factoryClassName, null, false).newInstance(); + factory = (RowSetFactory) o; } } catch (Exception e) { throw new SQLException( "RowSetFactory: " + factoryClassName + @@ -202,6 +203,7 @@ // getFactoryClass takes care of adding the read edge if // necessary Class providerClass = getFactoryClass(factoryClassName, cl, false); + @SuppressWarnings("deprecation") RowSetFactory instance = (RowSetFactory) providerClass.newInstance(); if (debug) { trace("Created new instance of " + providerClass + diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SQLInputImpl.java --- a/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SQLInputImpl.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SQLInputImpl.java Thu May 05 19:11:09 2016 +0000 @@ -478,7 +478,9 @@ SQLData obj = null; try { ReflectUtil.checkPackageAccess(c); - obj = (SQLData)c.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = c.newInstance(); + obj = (SQLData)tmp; } catch (Exception ex) { throw new SQLException("Unable to Instantiate: ", ex); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/spi/SyncFactory.java --- a/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/spi/SyncFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/spi/SyncFactory.java Thu May 05 19:11:09 2016 +0000 @@ -582,14 +582,12 @@ * there. **/ c = Class.forName(providerID, true, cl); - return (SyncProvider) c.newInstance(); + @SuppressWarnings("deprecation") + Object result = c.newInstance(); + return (SyncProvider)result; - } catch (IllegalAccessException e) { + } catch (IllegalAccessException | InstantiationException | ClassNotFoundException e) { throw new SyncFactoryException("IllegalAccessException: " + e.getMessage()); - } catch (InstantiationException e) { - throw new SyncFactoryException("InstantiationException: " + e.getMessage()); - } catch (ClassNotFoundException e) { - throw new SyncFactoryException("ClassNotFoundException: " + e.getMessage()); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java Thu May 05 19:11:09 2016 +0000 @@ -152,7 +152,9 @@ log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \"" + implementingClass + "\""); } - return implementingClass.newInstance(); + @SuppressWarnings("deprecation") + SignatureAlgorithmSpi result = implementingClass.newInstance(); + return result; } catch (IllegalAccessException ex) { Object exArgs[] = { algorithmURI, ex.getMessage() }; throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java Thu May 05 19:11:09 2016 +0000 @@ -115,7 +115,9 @@ Class implementingClass = canonicalizerHash.get(algorithmURI); - canonicalizerSpi = implementingClass.newInstance(); + @SuppressWarnings("deprecation") + CanonicalizerSpi tmp = implementingClass.newInstance(); + canonicalizerSpi = tmp; canonicalizerSpi.reset = true; } catch (Exception e) { Object exArgs[] = { algorithmURI }; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java Thu May 05 19:11:09 2016 +0000 @@ -182,6 +182,7 @@ public static void register(String className, boolean globalResolver) throws ClassNotFoundException, IllegalAccessException, InstantiationException { JavaUtils.checkRegisterPermission(); + @SuppressWarnings("deprecation") KeyResolverSpi keyResolverSpi = (KeyResolverSpi) Class.forName(className).newInstance(); keyResolverSpi.setGlobalResolver(globalResolver); @@ -207,7 +208,9 @@ KeyResolverSpi keyResolverSpi = null; Exception ex = null; try { - keyResolverSpi = (KeyResolverSpi) Class.forName(className).newInstance(); + @SuppressWarnings("deprecation") + Object tmp = Class.forName(className).newInstance(); + keyResolverSpi = (KeyResolverSpi) tmp; } catch (ClassNotFoundException e) { ex = e; } catch (IllegalAccessException e) { @@ -272,6 +275,7 @@ JavaUtils.checkRegisterPermission(); List keyResolverList = new ArrayList(classNames.size()); for (String className : classNames) { + @SuppressWarnings("deprecation") KeyResolverSpi keyResolverSpi = (KeyResolverSpi) Class.forName(className).newInstance(); keyResolverSpi.setGlobalResolver(false); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverSpi.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverSpi.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverSpi.java Thu May 05 19:11:09 2016 +0000 @@ -110,7 +110,9 @@ KeyResolverSpi tmp = this; if (globalResolver) { try { - tmp = getClass().newInstance(); + @SuppressWarnings("deprecation") + KeyResolverSpi krs = getClass().newInstance(); + tmp = krs; } catch (InstantiationException e) { throw new KeyResolverException("", e); } catch (IllegalAccessException e) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java Thu May 05 19:11:09 2016 +0000 @@ -160,7 +160,9 @@ throw new InvalidTransformException("signature.Transform.UnknownTransform", exArgs); } try { - transformSpi = transformSpiClass.newInstance(); + @SuppressWarnings("deprecation") + TransformSpi tmp = transformSpiClass.newInstance(); + transformSpi = tmp; } catch (InstantiationException ex) { Object exArgs[] = { algorithmURI }; throw new InvalidTransformException( @@ -345,7 +347,9 @@ } TransformSpi newTransformSpi = null; try { - newTransformSpi = transformSpiClass.newInstance(); + @SuppressWarnings("deprecation") + TransformSpi tmp = transformSpiClass.newInstance(); + newTransformSpi = tmp; } catch (InstantiationException ex) { Object exArgs[] = { algorithmURI }; throw new InvalidTransformException( diff -r 5c95f3324916 -r 41844efbbcce jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java Thu May 05 19:11:09 2016 +0000 @@ -99,8 +99,10 @@ ResourceResolver resolverTmp = resolver; if (!resolver.resolverSpi.engineIsThreadSafe()) { try { - resolverTmp = - new ResourceResolver(resolver.resolverSpi.getClass().newInstance()); + @SuppressWarnings("deprecation") + ResourceResolver tmp = new ResourceResolver(resolver.resolverSpi.getClass().newInstance()); + resolverTmp = tmp; + ; } catch (InstantiationException e) { throw new ResourceResolverException("", e, context.attr, context.baseUri); } catch (IllegalAccessException e) { @@ -246,6 +248,7 @@ public static void register(Class className, boolean start) { JavaUtils.checkRegisterPermission(); try { + @SuppressWarnings("deprecation") ResourceResolverSpi resourceResolverSpi = className.newInstance(); register(resourceResolverSpi, start); } catch (IllegalAccessException e) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java --- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java Thu May 05 19:11:09 2016 +0000 @@ -121,6 +121,7 @@ Class translatorClass = getTranslatorClass(o.getClass()); if (translatorClass != null) { try { + @SuppressWarnings("deprecation") Translator t = (Translator)translatorClass.newInstance(); t.setSource(o); a = t; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/AbstractCharsetProvider.java --- a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/AbstractCharsetProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/AbstractCharsetProvider.java Thu May 05 19:11:09 2016 +0000 @@ -148,6 +148,7 @@ true, this.getClass().getClassLoader()); + @SuppressWarnings("deprecation") Charset cs = (Charset)c.newInstance(); cache.put(csn, new SoftReference(cs)); return cs; diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Util.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Util.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Util.java Thu May 05 19:11:09 2016 +0000 @@ -88,8 +88,9 @@ p = Security.getProvider(providerName); if (p == null) { try { - Class clazz = Class.forName(className); - p = (Provider)clazz.newInstance(); + @SuppressWarnings("deprecation") + Object o = Class.forName(className).newInstance(); + p = (Provider)o; } catch (Exception e) { throw new ProviderException ("Could not find provider " + providerName, e); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java Thu May 05 19:11:09 2016 +0000 @@ -1446,7 +1446,9 @@ } return null; } - return (CallbackHandler)c.newInstance(); + @SuppressWarnings("deprecation") + Object result = c.newInstance(); + return (CallbackHandler)result; } }); // save it diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/spi/HttpServerProvider.java --- a/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/spi/HttpServerProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/spi/HttpServerProvider.java Thu May 05 19:11:09 2016 +0000 @@ -89,9 +89,10 @@ if (cn == null) return false; try { - Class c = Class.forName(cn, true, - ClassLoader.getSystemClassLoader()); - provider = (HttpServerProvider)c.newInstance(); + @SuppressWarnings("deprecation") + Object o = Class.forName(cn, true, + ClassLoader.getSystemClassLoader()).newInstance(); + provider = (HttpServerProvider)o; return true; } catch (ClassNotFoundException | IllegalAccessException | diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/TerminalFactory.java --- a/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/TerminalFactory.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/TerminalFactory.java Thu May 05 19:11:09 2016 +0000 @@ -82,7 +82,9 @@ } else { try { - t = (Terminal) Thread.currentThread().getContextClassLoader().loadClass(type).newInstance(); + @SuppressWarnings("deprecation") + Object o = Thread.currentThread().getContextClassLoader().loadClass(type).newInstance(); + t = (Terminal) o; } catch (Exception e) { throw new IllegalArgumentException(MessageFormat.format("Invalid terminal type: {0}", type), e); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/console/internal/ConsoleRunner.java --- a/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/console/internal/ConsoleRunner.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/console/internal/ConsoleRunner.java Thu May 05 19:11:09 2016 +0000 @@ -61,6 +61,7 @@ List completorList = new ArrayList(); for (StringTokenizer tok = new StringTokenizer(completors, ","); tok.hasMoreTokens();) { + @SuppressWarnings("deprecation") Object obj = Class.forName(tok.nextToken()).newInstance(); completorList.add((Completer) obj); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java --- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java Thu May 05 19:11:09 2016 +0000 @@ -136,10 +136,10 @@ jartool.moduleVersion = Version.parse(arg); } }, - new Option(true, OptionType.CREATE_UPDATE, "--hash-dependencies") { + new Option(true, OptionType.CREATE_UPDATE, "--hash-modules") { void process(Main jartool, String opt, String arg) throws BadArgs { try { - jartool.dependenciesToHash = Pattern.compile(arg); + jartool.modulesToHash = Pattern.compile(arg); } catch (PatternSyntaxException e) { throw new BadArgs("err.badpattern", arg).showUsage(true); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java --- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Thu May 05 19:11:09 2016 +0000 @@ -26,21 +26,25 @@ package sun.tools.jar; import java.io.*; +import java.lang.module.Configuration; import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleDescriptor.Exports; import java.lang.module.ModuleDescriptor.Provides; import java.lang.module.ModuleDescriptor.Requires; import java.lang.module.ModuleDescriptor.Version; import java.lang.module.ModuleFinder; +import java.lang.module.ModuleReader; import java.lang.module.ModuleReference; -import java.lang.reflect.Method; +import java.lang.module.ResolutionException; +import java.lang.module.ResolvedModule; import java.net.URI; import java.nio.file.Path; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; import java.util.function.Consumer; -import java.util.regex.Matcher; +import java.util.function.Function; +import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.zip.*; @@ -49,9 +53,12 @@ import java.util.jar.Manifest; import java.text.MessageFormat; -import jdk.internal.module.Hasher; +import jdk.internal.misc.JavaLangModuleAccess; +import jdk.internal.misc.SharedSecrets; +import jdk.internal.module.ModuleHashes; import jdk.internal.module.ModuleInfoExtender; import jdk.internal.util.jar.JarIndex; + import static jdk.internal.util.jar.JarIndex.INDEX_NAME; import static java.util.jar.JarFile.MANIFEST_NAME; import static java.util.stream.Collectors.joining; @@ -117,7 +124,7 @@ /* Modular jar related options */ boolean printModuleDescriptor; Version moduleVersion; - Pattern dependenciesToHash; + Pattern modulesToHash; ModuleFinder moduleFinder = ModuleFinder.empty(); private static final String MODULE_INFO = "module-info.class"; @@ -241,7 +248,7 @@ if (isModularJar()) { moduleInfoBytes = addExtendedModuleAttributes( readModuleInfo(moduleInfo)); - } else if (moduleVersion != null || dependenciesToHash != null) { + } else if (moduleVersion != null || modulesToHash != null) { error(getMsg("error.module.options.without.info")); return false; } @@ -801,7 +808,7 @@ } } else if (isModuleInfoEntry && ((newModuleInfoBytes != null) || (ename != null) - || moduleVersion != null || dependenciesToHash != null)) { + || moduleVersion != null || modulesToHash != null)) { if (newModuleInfoBytes == null) { // Update existing module-info.class newModuleInfoBytes = readModuleInfo(zis); @@ -861,7 +868,7 @@ if (!updateModuleInfo(newModuleInfoBytes, zos)) { updateOk = false; } - } else if (moduleVersion != null || dependenciesToHash != null) { + } else if (moduleVersion != null || modulesToHash != null) { error(getMsg("error.module.options.without.info")); updateOk = false; } @@ -1642,70 +1649,60 @@ return false; } - @SuppressWarnings("unchecked") + static String toString(Set set) { + if (set.isEmpty()) { return ""; } + return set.stream().map(e -> e.toString().toLowerCase(Locale.ROOT)) + .collect(joining(" ")); + } + + private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess(); + private void printModuleDescriptor(InputStream entryInputStream) throws IOException { ModuleDescriptor md = ModuleDescriptor.read(entryInputStream); StringBuilder sb = new StringBuilder(); - sb.append("\nName:\n " + md.toNameAndVersion()); - - Set requires = md.requires(); - if (!requires.isEmpty()) { - sb.append("\nRequires:"); - requires.forEach(r -> - sb.append("\n ").append(r.name()) - .append(toString(r.modifiers(), " [ ", " ]"))); - } + sb.append("\n").append(md.toNameAndVersion()); - Set s = md.uses(); - if (!s.isEmpty()) { - sb.append("\nUses: "); - s.forEach(sv -> sb.append("\n ").append(sv)); - } + md.requires().stream() + .sorted(Comparator.comparing(Requires::name)) + .forEach(r -> { + sb.append("\n requires "); + if (!r.modifiers().isEmpty()) + sb.append(toString(r.modifiers())).append(" "); + sb.append(r.name()); + }); - Set exports = md.exports(); - if (!exports.isEmpty()) { - sb.append("\nExports:"); - exports.forEach(sv -> sb.append("\n ").append(sv)); - } + md.uses().stream().sorted() + .forEach(p -> sb.append("\n uses ").append(p)); + + md.exports().stream() + .sorted(Comparator.comparing(Exports::source)) + .forEach(p -> sb.append("\n exports ").append(p)); + + md.conceals().stream().sorted() + .forEach(p -> sb.append("\n conceals ").append(p)); - Map provides = md.provides(); - if (!provides.isEmpty()) { - sb.append("\nProvides: "); - provides.values().forEach(p -> - sb.append("\n ").append(p.service()) - .append(" with ") - .append(toString(p.providers(), "", ""))); - } + md.provides().values().stream() + .sorted(Comparator.comparing(Provides::service)) + .forEach(p -> sb.append("\n provides ").append(p.service()) + .append(" with ") + .append(toString(p.providers()))); - Optional mc = md.mainClass(); - if (mc.isPresent()) - sb.append("\nMain class:\n " + mc.get()); + md.mainClass().ifPresent(v -> sb.append("\n main-class " + v)); + + md.osName().ifPresent(v -> sb.append("\n operating-system-name " + v)); - s = md.conceals(); - if (!s.isEmpty()) { - sb.append("\nConceals:"); - s.forEach(p -> sb.append("\n ").append(p)); - } + md.osArch().ifPresent(v -> sb.append("\n operating-system-architecture " + v)); - try { - Method m = ModuleDescriptor.class.getDeclaredMethod("hashes"); - m.setAccessible(true); - Optional optHashes = - (Optional) m.invoke(md); + md.osVersion().ifPresent(v -> sb.append("\n operating-system-version " + v)); - if (optHashes.isPresent()) { - Hasher.DependencyHashes hashes = optHashes.get(); - sb.append("\nHashes:"); - sb.append("\n Algorithm: " + hashes.algorithm()); - hashes.names().stream().forEach(mod -> - sb.append("\n ").append(mod) - .append(": ").append(hashes.hashFor(mod))); - } - } catch (ReflectiveOperationException x) { - throw new InternalError(x); - } + JLMA.hashes(md).ifPresent(hashes -> + hashes.names().stream().sorted().forEach( + mod -> sb.append("\n hashes ").append(mod).append(" ") + .append(hashes.algorithm()).append(" ") + .append(hashes.hashFor(mod)))); + output(sb.toString()); } @@ -1751,7 +1748,6 @@ md = ModuleDescriptor.read(in); } String name = md.name(); - Set dependences = md.requires(); Set exported = md.exports() .stream() .map(ModuleDescriptor.Exports::source) @@ -1778,9 +1774,17 @@ if (moduleVersion != null) extender.version(moduleVersion); - // --hash-dependencies - if (dependenciesToHash != null) - extender.hashes(hashDependences(name, dependences)); + // --hash-modules + if (modulesToHash != null) { + Hasher hasher = new Hasher(md, fname); + ModuleHashes moduleHashes = hasher.computeHashes(name); + if (moduleHashes != null) { + extender.hashes(moduleHashes); + } else { + // should it issue warning or silent? + System.out.println("warning: no module is recorded in hash in " + name); + } + } extender.write(baos); return baos.toByteArray(); @@ -1788,36 +1792,156 @@ } /** - * Examines the module dependences of the given module and computes the - * hash of any module that matches the pattern {@code dependenciesToHash}. + * Compute and record hashes */ - private Hasher.DependencyHashes - hashDependences(String name, - Set moduleDependences) - throws IOException - { - Map map = new HashMap<>(); - Matcher matcher = dependenciesToHash.matcher(""); - for (ModuleDescriptor.Requires md: moduleDependences) { - String dn = md.name(); - if (matcher.reset(dn).find()) { - Optional omref = moduleFinder.find(dn); - if (!omref.isPresent()) { - throw new IOException(formatMsg2("error.hash.dep", name , dn)); - } - map.put(dn, modRefToPath(omref.get())); + private class Hasher { + final ModuleFinder finder; + final Map moduleNameToPath; + final Set modules; + final Configuration configuration; + Hasher(ModuleDescriptor descriptor, String fname) throws IOException { + // Create a module finder that finds the modular JAR + // being created/updated + URI uri = Paths.get(fname).toUri(); + ModuleReference mref = new ModuleReference(descriptor, uri, + new Supplier<>() { + @Override + public ModuleReader get() { + throw new UnsupportedOperationException("should not reach here"); + } + }); + + // Compose a module finder with the module path and + // the modular JAR being created or updated + this.finder = ModuleFinder.compose(moduleFinder, + new ModuleFinder() { + @Override + public Optional find(String name) { + if (descriptor.name().equals(name)) + return Optional.of(mref); + else + return Optional.empty(); + } + + @Override + public Set findAll() { + return Collections.singleton(mref); + } + }); + + // Determine the modules that matches the modulesToHash pattern + this.modules = moduleFinder.findAll().stream() + .map(moduleReference -> moduleReference.descriptor().name()) + .filter(mn -> modulesToHash.matcher(mn).find()) + .collect(Collectors.toSet()); + + // a map from a module name to Path of the modular JAR + this.moduleNameToPath = moduleFinder.findAll().stream() + .map(ModuleReference::descriptor) + .map(ModuleDescriptor::name) + .collect(Collectors.toMap(Function.identity(), mn -> moduleToPath(mn))); + + Configuration config = null; + try { + config = Configuration.empty() + .resolveRequires(ModuleFinder.ofSystem(), finder, modules); + } catch (ResolutionException e) { + // should it throw an error? or emit a warning + System.out.println("warning: " + e.getMessage()); } + this.configuration = config; } - if (map.size() == 0) { - return null; - } else { - return Hasher.generate(map, "SHA-256"); + /** + * Compute hashes of the modules that depend upon the specified + * module directly or indirectly. + */ + ModuleHashes computeHashes(String name) { + // the transposed graph includes all modules in the resolved graph + Map> graph = transpose(); + + // find the modules that transitively depend upon the specified name + Deque deque = new ArrayDeque<>(); + deque.add(name); + Set mods = visitNodes(graph, deque); + + // filter modules matching the pattern specified --hash-modules + // as well as itself as the jmod file is being generated + Map modulesForHash = mods.stream() + .filter(mn -> !mn.equals(name) && modules.contains(mn)) + .collect(Collectors.toMap(Function.identity(), moduleNameToPath::get)); + + if (modulesForHash.isEmpty()) + return null; + + return ModuleHashes.generate(modulesForHash, "SHA-256"); + } + + /** + * Returns all nodes traversed from the given roots. + */ + private Set visitNodes(Map> graph, + Deque roots) { + Set visited = new HashSet<>(); + while (!roots.isEmpty()) { + String mn = roots.pop(); + if (!visited.contains(mn)) { + visited.add(mn); + + // the given roots may not be part of the graph + if (graph.containsKey(mn)) { + for (String dm : graph.get(mn)) { + if (!visited.contains(dm)) + roots.push(dm); + } + } + } + } + return visited; + } + + /** + * Returns a transposed graph from the resolved module graph. + */ + private Map> transpose() { + Map> transposedGraph = new HashMap<>(); + Deque deque = new ArrayDeque<>(modules); + + Set visited = new HashSet<>(); + while (!deque.isEmpty()) { + String mn = deque.pop(); + if (!visited.contains(mn)) { + visited.add(mn); + + // add an empty set + transposedGraph.computeIfAbsent(mn, _k -> new HashSet<>()); + + ResolvedModule resolvedModule = configuration.findModule(mn).get(); + for (ResolvedModule dm : resolvedModule.reads()) { + String name = dm.name(); + if (!visited.contains(name)) { + deque.push(name); + } + // reverse edge + transposedGraph.computeIfAbsent(name, _k -> new HashSet<>()) + .add(mn); + } + } + } + return transposedGraph; + } + + private Path moduleToPath(String name) { + ModuleReference mref = moduleFinder.find(name).orElseThrow( + () -> new InternalError(formatMsg2("error.hash.dep",name , name))); + + URI uri = mref.location().get(); + Path path = Paths.get(uri); + String fn = path.getFileName().toString(); + if (!fn.endsWith(".jar")) { + throw new UnsupportedOperationException(path + " is not a modular JAR"); + } + return path; } } - - private static Path modRefToPath(ModuleReference mref) { - URI location = mref.location().get(); - return Paths.get(location); - } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties --- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties Thu May 05 19:11:09 2016 +0000 @@ -57,7 +57,7 @@ error.hash.dep=\ Hashing module {0} dependences, unable to find module {1} on module path error.module.options.without.info=\ - One of --module-version or --hash-dependencies without module-info.class + One of --module-version or --hash-modules without module-info.class error.unexpected.module-info=\ Unexpected module descriptor {0} error.module.descriptor.not.found=\ @@ -178,11 +178,11 @@ main.help.opt.create.update.module-version=\ \ --module-version=VERSION The module version, when creating a modular\n\ \ jar, or updating a non-modular jar -main.help.opt.create.update.hash-dependencies=\ -\ --hash-dependencies=PATTERN Compute and record the hashes of module\n\ -\ dependencies matched by the given pattern, when\n\ -\ creating a modular jar, or updating a non-modular\n\ -\ jar +main.help.opt.create.update.hash-modules=\ +\ --hash-modules=PATTERN Compute and record the hashes of modules \n\ +\ matched by the given pattern and that depend upon\n\ +\ directly or indirectly on a modular jar being\n\ +\ created or a non-modular jar being updated main.help.opt.create.update.modulepath=\ \ --modulepath Location of module dependence for generating \ the hash @@ -201,7 +201,7 @@ \ located in the root of the given directories, or the root of the jar archive\n\ \ itself. The following operations are only valid when creating a modular jar,\n\ \ or updating an existing non-modular jar: '--module-version',\n\ -\ '--hash-dependencies', and '--modulepath'.\n\ +\ '--hash-modules', and '--modulepath'.\n\ \n\ \ Mandatory or optional arguments to long options are also mandatory or optional\n\ \ for any corresponding short options. \ No newline at end of file diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ProcessAttachingConnector.java --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ProcessAttachingConnector.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ProcessAttachingConnector.java Thu May 05 19:11:09 2016 +0000 @@ -128,7 +128,9 @@ if (lib.equals("dt_shmem")) { try { Class c = Class.forName("com.sun.tools.jdi.SharedMemoryTransportService"); - ts = (TransportService)c.newInstance(); + @SuppressWarnings("deprecation") + Object tmp = c.newInstance(); + ts = (TransportService)tmp; } catch (Exception x) { } } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/RawCommandLineLauncher.java --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/RawCommandLineLauncher.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/RawCommandLineLauncher.java Thu May 05 19:11:09 2016 +0000 @@ -53,17 +53,19 @@ super(); try { - Class c = Class.forName("com.sun.tools.jdi.SharedMemoryTransportService"); - transportService = (TransportService)c.newInstance(); + @SuppressWarnings("deprecation") + Object o = + Class.forName("com.sun.tools.jdi.SharedMemoryTransportService").newInstance(); + transportService = (TransportService)o; transport = new Transport() { public String name() { return "dt_shmem"; } }; - } catch (ClassNotFoundException x) { - } catch (UnsatisfiedLinkError x) { - } catch (InstantiationException x) { - } catch (IllegalAccessException x) { + } catch (ClassNotFoundException | + UnsatisfiedLinkError | + InstantiationException | + IllegalAccessException x) { }; if (transportService == null) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java Thu May 05 19:11:09 2016 +0000 @@ -64,18 +64,20 @@ * transport or the socket transport */ try { - Class c = Class.forName("com.sun.tools.jdi.SharedMemoryTransportService"); - transportService = (TransportService)c.newInstance(); + @SuppressWarnings("deprecation") + Object o = + Class.forName("com.sun.tools.jdi.SharedMemoryTransportService").newInstance(); + transportService = (TransportService)o; transport = new Transport() { public String name() { return "dt_shmem"; } }; usingSharedMemory = true; - } catch (ClassNotFoundException x) { - } catch (UnsatisfiedLinkError x) { - } catch (InstantiationException x) { - } catch (IllegalAccessException x) { + } catch (ClassNotFoundException | + UnsatisfiedLinkError | + InstantiationException | + IllegalAccessException x) { }; if (transportService == null) { transportService = new SocketTransportService(); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Thu May 05 19:11:09 2016 +0000 @@ -95,27 +95,23 @@ private final Path root; private final Path mdir; - private final boolean genBom; private final Set modules = new HashSet<>(); /** * Default image builder constructor. * - * @param genBom true, generates a bom file. * @param root The image root directory. * @throws IOException */ - public DefaultImageBuilder(boolean genBom, Path root) throws IOException { + public DefaultImageBuilder(Path root) throws IOException { Objects.requireNonNull(root); - this.genBom = genBom; - this.root = root; this.mdir = root.resolve("lib"); Files.createDirectories(mdir); } - private void storeFiles(Set modules, String bom, Properties release) throws IOException { + private void storeFiles(Set modules, Properties release) throws IOException { if (release != null) { addModules(release, modules); File r = new File(root.toFile(), "release"); @@ -123,11 +119,6 @@ release.store(fo, null); } } - // Generate bom - if (genBom) { - File bomFile = new File(root.toFile(), "bom"); - createUtf8File(bomFile, bom); - } } private void addModules(Properties release, Set modules) throws IOException { @@ -144,7 +135,7 @@ } @Override - public void storeFiles(Pool files, String bom, Properties release) { + public void storeFiles(Pool files, Properties release) { try { for (ModuleData f : files.getContent()) { if (!f.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)) { @@ -161,7 +152,7 @@ modules.add(m.getName()); } } - storeFiles(modules, bom, release); + storeFiles(modules, release); if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) { // launchers in the bin directory need execute permission @@ -190,8 +181,8 @@ } @Override - public void storeFiles(Pool files, String bom) { - storeFiles(files, bom, new Properties()); + public void storeFiles(Pool files) { + storeFiles(files, new Properties()); } /** @@ -213,28 +204,48 @@ mainClass = ModuleDescriptor.read(stream).mainClass(); if (mainClass.isPresent()) { Path cmd = root.resolve("bin").resolve(module); - if (!Files.exists(cmd)) { - StringBuilder sb = new StringBuilder(); - sb.append("#!/bin/sh") - .append("\n"); - sb.append("JLINK_VM_OPTIONS=") - .append("\n"); - sb.append("DIR=`dirname $0`") - .append("\n"); - sb.append("$DIR/java $JLINK_VM_OPTIONS -m ") + // generate shell script for Unix platforms + StringBuilder sb = new StringBuilder(); + sb.append("#!/bin/sh") + .append("\n"); + sb.append("JLINK_VM_OPTIONS=") + .append("\n"); + sb.append("DIR=`dirname $0`") + .append("\n"); + sb.append("$DIR/java $JLINK_VM_OPTIONS -m ") + .append(module).append('/') + .append(mainClass.get()) + .append(" $@\n"); + + try (BufferedWriter writer = Files.newBufferedWriter(cmd, + StandardCharsets.ISO_8859_1, + StandardOpenOption.CREATE_NEW)) { + writer.write(sb.toString()); + } + if (Files.getFileStore(root.resolve("bin")) + .supportsFileAttributeView(PosixFileAttributeView.class)) { + setExecutable(cmd); + } + // generate .bat file for Windows + if (isWindows()) { + Path bat = root.resolve("bin").resolve(module + ".bat"); + sb = new StringBuilder(); + sb.append("@echo off") + .append("\r\n"); + sb.append("set JLINK_VM_OPTIONS=") + .append("\r\n"); + sb.append("set DIR=%~dp0") + .append("\r\n"); + sb.append("\"%DIR%\\java\" %JLINK_VM_OPTIONS% -m ") .append(module).append('/') .append(mainClass.get()) - .append(" $@\n"); + .append(" %*\r\n"); - try (BufferedWriter writer = Files.newBufferedWriter(cmd, + try (BufferedWriter writer = Files.newBufferedWriter(bat, StandardCharsets.ISO_8859_1, StandardOpenOption.CREATE_NEW)) { writer.write(sb.toString()); } - if (Files.getFileStore(root.resolve("bin")) - .supportsFileAttributeView(PosixFileAttributeView.class)) { - setExecutable(cmd); - } } } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java Thu May 05 19:11:09 2016 +0000 @@ -42,22 +42,20 @@ * Store the external files. * * @param content Pool of module content. - * @param bom The options used to build the image file. * @param release the release properties * @throws PluginException */ - public default void storeFiles(Pool content, String bom, Properties release) { - storeFiles(content, bom); + public default void storeFiles(Pool content, Properties release) { + storeFiles(content); } /** * Store the external files. * * @param content Pool of module content. - * @param bom The options used to build the image file. * @throws PluginException */ - public default void storeFiles(Pool content, String bom) { + public default void storeFiles(Pool content) { throw new UnsupportedOperationException("storeFiles"); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java Thu May 05 19:11:09 2016 +0000 @@ -88,7 +88,7 @@ ByteOrder byteOrder) throws IOException { return ImageFileCreator.create(archives, byteOrder, - new ImagePluginStack(null)); + new ImagePluginStack()); } public static ExecutableImage create(Set archives, diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Thu May 05 19:11:09 2016 +0000 @@ -68,20 +68,13 @@ private ImagePluginConfiguration() { } - public static ImagePluginStack parseConfiguration(Jlink.PluginsConfiguration plugins) - throws Exception { - return parseConfiguration(plugins, null); - } - /* * Create a stack of plugins from a a configuration. - * */ - public static ImagePluginStack parseConfiguration(Jlink.PluginsConfiguration pluginsConfiguration, - String bom) + public static ImagePluginStack parseConfiguration(Jlink.PluginsConfiguration pluginsConfiguration) throws Exception { if (pluginsConfiguration == null) { - return new ImagePluginStack(bom); + return new ImagePluginStack(); } Map> plugins = new LinkedHashMap<>(); for (Plugin.CATEGORY cat : CATEGORIES_ORDER) { @@ -150,7 +143,7 @@ } @Override - public void storeFiles(Pool files, String bom) { + public void storeFiles(Pool files) { throw new PluginException("No directory setup to store files"); } }; @@ -158,6 +151,6 @@ PluginContext ctxt = pluginsConfiguration.getPluginContext(); return new ImagePluginStack(builder, transformerPlugins, - lastSorter, postProcessingPlugins, ctxt, bom); + lastSorter, postProcessingPlugins, ctxt); } } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java Thu May 05 19:11:09 2016 +0000 @@ -167,28 +167,25 @@ private final ImageBuilder imageBuilder; private final Properties release; - private final String bom; + + public ImagePluginStack() { + this(null, Collections.emptyList(), null, + Collections.emptyList(), null); + } - public ImagePluginStack(String bom) { - this(null, Collections.emptyList(), null, - Collections.emptyList(), null, bom); + public ImagePluginStack(ImageBuilder imageBuilder, + List contentPlugins, + Plugin lastSorter, + List postprocessingPlugins) { + this(imageBuilder, contentPlugins, lastSorter, + postprocessingPlugins, null); } public ImagePluginStack(ImageBuilder imageBuilder, List contentPlugins, Plugin lastSorter, List postprocessingPlugins, - String bom) { - this(imageBuilder, contentPlugins, lastSorter, - postprocessingPlugins, null, bom); - } - - public ImagePluginStack(ImageBuilder imageBuilder, - List contentPlugins, - Plugin lastSorter, - List postprocessingPlugins, - PluginContext ctxt, - String bom) { + PluginContext ctxt) { Objects.requireNonNull(contentPlugins); this.lastSorter = lastSorter; for (TransformerPlugin p : contentPlugins) { @@ -204,7 +201,6 @@ } this.imageBuilder = imageBuilder; this.release = ctxt != null? ctxt.getReleaseProperties() : new Properties(); - this.bom = bom; } public void operate(ImageProvider provider) throws Exception { @@ -479,7 +475,7 @@ } catch (Exception ignored) { } - imageBuilder.storeFiles(new LastPool(transformed), bom, release); + imageBuilder.storeFiles(new LastPool(transformed), release); } public ExecutableImage getExecutableImage() throws IOException { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Thu May 05 19:11:09 2016 +0000 @@ -70,6 +70,7 @@ * ## Should use jdk.joptsimple some day. */ public class JlinkTask { + private static final boolean DEBUG = Boolean.getBoolean("jlink.debug"); private static void fail(Class type, String format, @@ -142,9 +143,6 @@ } task.options.packagedModulesPath = path; }, true, "--keep-packaged-modules"), - new Option(false, (task, opt, arg) -> { - task.options.genbom = true; - }, true, "--genbom"), new Option(true, (task, opt, arg) -> { task.options.saveoptsfile = arg; }, "--saveopts"), @@ -175,7 +173,6 @@ static class OptionsValues { boolean help; - boolean genbom; String saveoptsfile; boolean version; boolean fullVersion; @@ -219,18 +216,24 @@ } return EXIT_OK; - } catch (UncheckedIOException | PluginException | IOException | ResolutionException e) { + } catch (UncheckedIOException | PluginException | IllegalArgumentException | + IOException | ResolutionException e) { log.println(taskHelper.getMessage("error.prefix") + " " + e.getMessage()); - log.println(taskHelper.getMessage("main.usage.summary", PROGNAME)); + if (DEBUG) { + e.printStackTrace(log); + } return EXIT_ERROR; } catch (BadArgs e) { taskHelper.reportError(e.key, e.args); if (e.showUsage) { log.println(taskHelper.getMessage("main.usage.summary", PROGNAME)); } + if (DEBUG) { + e.printStackTrace(log); + } return EXIT_CMDERR; } catch (Throwable x) { - log.println(taskHelper.getMessage("main.msg.bug")); + log.println(taskHelper.getMessage("error.prefix") + " " + x.getMessage()); x.printStackTrace(log); return EXIT_ABNORMAL; } finally { @@ -238,16 +241,6 @@ } } - private static Map modulesToPath(Configuration cf) { - Map modPaths = new HashMap<>(); - for (ResolvedModule resolvedModule : cf.modules()) { - ModuleReference mref = resolvedModule.reference(); - URI uri = mref.location().get(); - modPaths.put(mref.descriptor().name(), Paths.get(uri)); - } - return modPaths; - } - /* * Jlink API entry point. */ @@ -275,8 +268,7 @@ null); // Then create the Plugin Stack - ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(plugins, - genBOMContent(config, plugins)); + ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(plugins); //Ask the stack to proceed; stack.operate(imageProvider); @@ -297,7 +289,7 @@ } private void postProcessOnly(Path existingImage) throws Exception { - PluginsConfiguration config = taskHelper.getPluginsConfig(null, false); + PluginsConfiguration config = taskHelper.getPluginsConfig(null); ExecutableImage img = DefaultImageBuilder.getExecutableImage(existingImage); if (img == null) { throw taskHelper.newBadArgs("err.existing.image.invalid"); @@ -327,8 +319,7 @@ // Then create the Plugin Stack ImagePluginStack stack = ImagePluginConfiguration. - parseConfiguration(taskHelper.getPluginsConfig(options.output, options.genbom), - genBOMContent()); + parseConfiguration(taskHelper.getPluginsConfig(options.output)); //Ask the stack to proceed stack.operate(imageProvider); @@ -358,6 +349,15 @@ return finder; } + + private static Path toPathLocation(ResolvedModule m) { + Optional ouri = m.reference().location(); + if (!ouri.isPresent()) + throw new InternalError(m + " does not have a location"); + URI uri = ouri.get(); + return Paths.get(uri); + } + private static ImageProvider createImageProvider(ModuleFinder finder, Set addMods, Set limitMods, @@ -374,7 +374,8 @@ ModuleFinder.empty(), addMods); - Map mods = modulesToPath(cf); + Map mods = cf.modules().stream() + .collect(Collectors.toMap(ResolvedModule::name, JlinkTask::toPathLocation)); return new ImageHelper(cf, mods, order, retainModulesPath); } @@ -399,21 +400,15 @@ map.put(mref.descriptor().name(), mref); }); + // add the other modules + otherMods.stream() + .map(finder::find) + .flatMap(Optional::stream) + .forEach(mref -> map.putIfAbsent(mref.descriptor().name(), mref)); + // set of modules that are observable Set mrefs = new HashSet<>(map.values()); - // add the other modules - for (String mod : otherMods) { - Optional omref = finder.find(mod); - if (omref.isPresent()) { - ModuleReference mref = omref.get(); - map.putIfAbsent(mod, mref); - mrefs.add(mref); - } else { - // no need to fail - } - } - return new ModuleFinder() { @Override public Optional find(String name) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Thu May 05 19:11:09 2016 +0000 @@ -337,8 +337,8 @@ return null; } - private PluginsConfiguration getPluginsConfig(Path output, - boolean genbom) throws IOException, BadArgs { + private PluginsConfiguration getPluginsConfig(Path output + ) throws IOException, BadArgs { if (output != null) { if (Files.exists(output)) { throw new PluginException(PluginsResourceBundle. @@ -367,7 +367,7 @@ // recreate or postprocessing don't require an output directory. ImageBuilder builder = null; if (output != null) { - builder = new DefaultImageBuilder(genbom, output); + builder = new DefaultImageBuilder(output); } return new Jlink.PluginsConfiguration(pluginsList, @@ -676,9 +676,9 @@ + bundleHelper.getMessage(key, args)); } - public PluginsConfiguration getPluginsConfig(Path output, boolean genbom) + public PluginsConfiguration getPluginsConfig(Path output) throws IOException, BadArgs { - return pluginOptions.getPluginsConfig(output, genbom); + return pluginOptions.getPluginsConfig(output); } public Path getExistingImage() { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Thu May 05 19:11:09 2016 +0000 @@ -139,7 +139,7 @@ // build the image Jlink.PluginsConfiguration pluginConfig = new Jlink.PluginsConfiguration( - plugins, new DefaultImageBuilder(true, outputDir), null); + plugins, new DefaultImageBuilder(outputDir), null); Jlink jlink = new Jlink(); jlink.build(jlinkConfig, pluginConfig); } diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java Thu May 05 19:11:09 2016 +0000 @@ -125,7 +125,7 @@ zip = new ZipPlugin(resFilter); break; default: - throw new PluginException("Invalid level " + level); + throw new IllegalArgumentException("Invalid compression level " + level); } } else { ss = new StringSharingPlugin(resFilter); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java Thu May 05 19:11:09 2016 +0000 @@ -208,7 +208,7 @@ break; } default: { - throw new PluginException("Unknown option " + value); + throw new IllegalArgumentException("Unknown exclude VM option: " + value); } } predicate = new ResourceFilter(Utils.listParser.apply(exclude), true); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java Thu May 05 19:11:09 2016 +0000 @@ -164,7 +164,7 @@ try { return new Locale.LanguageRange(s); } catch (IllegalArgumentException iae) { - throw new PluginException(String.format( + throw new IllegalArgumentException(String.format( PluginsResourceBundle.getMessage(NAME + ".invalidtag"), s)); } }) @@ -177,24 +177,28 @@ Pool.Module module = resources.getModule(MODULENAME); // jdk.localedata module validation - Set packages = module.getAllPackages(); - if (!packages.containsAll(LOCALEDATA_PACKAGES)) { - throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".missingpackages") + - LOCALEDATA_PACKAGES.stream() - .filter(pn -> !packages.contains(pn)) - .collect(Collectors.joining(",\n\t"))); - } + if (module != null) { + Set packages = module.getAllPackages(); + if (!packages.containsAll(LOCALEDATA_PACKAGES)) { + throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".missingpackages") + + LOCALEDATA_PACKAGES.stream() + .filter(pn -> !packages.contains(pn)) + .collect(Collectors.joining(",\n\t"))); + } - available = Stream.concat(module.getContent().stream() - .map(md -> p.matcher(md.getPath())) - .filter(m -> m.matches()) - .map(m -> m.group("tag").replaceAll("_", "-")), - Stream.concat(Stream.of(jaJPJPTag), Stream.of(thTHTHTag))) - .distinct() - .sorted() - .map(IncludeLocalesPlugin::tagToLocale) - .collect(Collectors.toList()); - + available = Stream.concat(module.getContent().stream() + .map(md -> p.matcher(md.getPath())) + .filter(m -> m.matches()) + .map(m -> m.group("tag").replaceAll("_", "-")), + Stream.concat(Stream.of(jaJPJPTag), Stream.of(thTHTHTag))) + .distinct() + .sorted() + .map(IncludeLocalesPlugin::tagToLocale) + .collect(Collectors.toList()); + } else { + // jdk.localedata is not added. + throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".localedatanotfound")); + } filtered = filterLocales(available); if (filtered.isEmpty()) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java Thu May 05 19:11:09 2016 +0000 @@ -273,7 +273,7 @@ } else if (s.equals(FORNAME_REMOVAL)) { optimizers.add(new ForNameFolding()); } else { - throw new PluginException("Unknown optimization"); + throw new IllegalArgumentException("Unknown optimization: " + s); } } String f = config.get(LOG); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModuleDescriptorPlugin.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModuleDescriptorPlugin.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModuleDescriptorPlugin.java Thu May 05 19:11:09 2016 +0000 @@ -39,6 +39,8 @@ import java.util.Set; import java.util.stream.Collectors; +import jdk.internal.misc.JavaLangModuleAccess; +import jdk.internal.misc.SharedSecrets; import jdk.internal.module.Checks; import jdk.internal.module.ModuleInfoExtender; import jdk.internal.module.SystemModules; @@ -50,6 +52,7 @@ import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.Pool; import jdk.tools.jlink.plugin.TransformerPlugin; +import jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin.Builder.*; /** * Jlink plugin to reconstitute module descriptors for installed modules. @@ -63,6 +66,8 @@ * @see SystemModules */ public final class SystemModuleDescriptorPlugin implements TransformerPlugin { + private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess(); + // TODO: packager has the dependency on the plugin name // Keep it as "--installed-modules" until packager removes such // dependency (should not need to specify this plugin since it @@ -118,7 +123,8 @@ Pool.ModuleData data = module.get("module-info.class"); if (data == null) { // automatic module not supported yet - throw new PluginException("module-info.class not found for " + module.getName() + " module"); + throw new PluginException("module-info.class not found for " + + module.getName() + " module"); } assert module.getName().equals(data.getModule()); try { @@ -126,15 +132,20 @@ ModuleDescriptor md = ModuleDescriptor.read(bain); validateNames(md); - Builder.ModuleDescriptorBuilder mbuilder = builder.module(md, module.getAllPackages()); + ModuleDescriptorBuilder mbuilder = builder.module(md, module.getAllPackages()); + int packages = md.exports().size() + md.conceals().size(); if (md.conceals().isEmpty() && - (md.exports().size() + md.conceals().size()) != module.getAllPackages().size()) { + packages != module.getAllPackages().size()) { // add ConcealedPackages attribute if not exist bain.reset(); - ModuleInfoRewriter minfoWriter = new ModuleInfoRewriter(bain, mbuilder.conceals()); + ModuleInfoRewriter minfoWriter = + new ModuleInfoRewriter(bain, mbuilder.conceals()); // replace with the overridden version - data = new Pool.ModuleData(data.getModule(), data.getPath(), data.getType(), - minfoWriter.stream(), minfoWriter.size()); + data = new Pool.ModuleData(data.getModule(), + data.getPath(), + data.getType(), + minfoWriter.stream(), + minfoWriter.size()); } out.add(data); } catch (IOException e) { @@ -151,8 +162,12 @@ if (builder.isOverriddenClass(data.getPath())) { byte[] bytes = cwriter.toByteArray(); - Pool.ModuleData ndata = new Pool.ModuleData(data.getModule(), data.getPath(), data.getType(), - new ByteArrayInputStream(bytes), bytes.length); + Pool.ModuleData ndata = + new Pool.ModuleData(data.getModule(), + data.getPath(), + data.getType(), + new ByteArrayInputStream(bytes), + bytes.length); out.add(ndata); } else { out.add(data); @@ -230,6 +245,7 @@ // static variables in SystemModules class private static final String MODULE_NAMES = "MODULE_NAMES"; + private static final String MODULES_TO_HASH = "MODULES_TO_HASH"; private static final String PACKAGE_COUNT = "PACKAGES_IN_BOOT_LAYER"; private static final int BUILDER_VAR = 0; @@ -246,6 +262,9 @@ // list of all ModuleDescriptorBuilders, invoked in turn when building. private final List builders = new ArrayList<>(); + // module name to hash + private final Map modulesToHash = new HashMap<>(); + // map Set to a specialized builder to allow them to be // deduplicated as they are requested private final Map, StringSetBuilder> stringSets = new HashMap<>(); @@ -268,6 +287,11 @@ "[Ljava/lang/String;", null, null) .visitEnd(); + // public static String[] MODULES_TO_HASH = new String[] {....}; + cw.visitField(ACC_PUBLIC+ACC_FINAL+ACC_STATIC, MODULES_TO_HASH, + "[Ljava/lang/String;", null, null) + .visitEnd(); + // public static int PACKAGES_IN_BOOT_LAYER; cw.visitField(ACC_PUBLIC+ACC_FINAL+ACC_STATIC, PACKAGE_COUNT, "I", null, numPackages) @@ -283,15 +307,35 @@ int index = 0; for (ModuleDescriptorBuilder builder : builders) { - mv.visitInsn(DUP); // arrayref + mv.visitInsn(DUP); // arrayref pushInt(index++); - mv.visitLdcInsn(builder.md.name()); // value + mv.visitLdcInsn(builder.md.name()); // value mv.visitInsn(AASTORE); } mv.visitFieldInsn(PUTSTATIC, CLASSNAME, MODULE_NAMES, "[Ljava/lang/String;"); + // create the MODULES_TO_HASH array + pushInt(numModules); + mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); + + index = 0; + for (ModuleDescriptorBuilder builder : builders) { + String mn = builder.md.name(); + String recordedHash = modulesToHash.get(mn); + if (recordedHash != null) { + mv.visitInsn(DUP); // arrayref + pushInt(index); + mv.visitLdcInsn(recordedHash); // value + mv.visitInsn(AASTORE); + } + index++; + } + + mv.visitFieldInsn(PUTSTATIC, CLASSNAME, MODULES_TO_HASH, + "[Ljava/lang/String;"); + mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); @@ -315,15 +359,19 @@ } } - // provides + // provides (preserve iteration order) for (ModuleDescriptor.Provides p : md.provides().values()) { - stringSets.computeIfAbsent(p.providers(), s -> new StringSetBuilder(s)) + stringSets.computeIfAbsent(p.providers(), s -> new StringSetBuilder(s, true)) .increment(); } // uses stringSets.computeIfAbsent(md.uses(), s -> new StringSetBuilder(s)) .increment(); + + // hashes + JLMA.hashes(md).ifPresent(mh -> modulesToHash.putAll(mh.hashes())); + return builder; } @@ -484,13 +532,17 @@ conceals(pn); } - if (md.version().isPresent()) { - version(md.version().get()); - } + // version + md.version().ifPresent(this::version); + + // main class + md.mainClass().ifPresent(this::mainClass); - if (md.mainClass().isPresent()) { - mainClass(md.mainClass().get()); - } + // hashes + JLMA.hashes(md).ifPresent(mh -> { + algorithm(mh.algorithm()); + mh.names().forEach(mn -> moduleHash(mn, mh.hashFor(mn))); + }); putModuleDescriptor(); } @@ -603,7 +655,7 @@ /* * Invoke Builder.provides(String service, Set providers) * - * Set providers = new HashSet<>(); + * Set providers = new LinkedHashSet<>(); * providers.add(impl); * : * : @@ -652,6 +704,22 @@ mv.visitInsn(POP); } + void algorithm(String alg) { + mv.visitVarInsn(ALOAD, BUILDER_VAR); + mv.visitLdcInsn(alg); + mv.visitMethodInsn(INVOKEVIRTUAL, MODULE_DESCRIPTOR_BUILDER, + "algorithm", STRING_SIG, false); + mv.visitInsn(POP); + } + + void moduleHash(String name, String hashString) { + mv.visitVarInsn(ALOAD, BUILDER_VAR); + mv.visitLdcInsn(name); + mv.visitLdcInsn(hashString); + mv.visitMethodInsn(INVOKEVIRTUAL, MODULE_DESCRIPTOR_BUILDER, + "moduleHash", STRING_STRING_SIG, false); + mv.visitInsn(POP); + } } /* @@ -663,10 +731,17 @@ */ class StringSetBuilder { final Set names; + final boolean linked; int refCount; int localVarIndex; + + StringSetBuilder(Set names, boolean linked) { + this.names = names; + this.linked = linked; + } + StringSetBuilder(Set names) { - this.names = names; + this(names, false); } void increment() { @@ -704,11 +779,11 @@ "singleton", "(Ljava/lang/Object;)Ljava/util/Set;", false); mv.visitVarInsn(ASTORE, index); } else { - mv.visitTypeInsn(NEW, "java/util/HashSet"); + String cn = linked ? "java/util/LinkedHashSet" : "java/util/HashSet"; + mv.visitTypeInsn(NEW, cn); mv.visitInsn(DUP); pushInt(initialCapacity(names.size())); - mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashSet", - "", "(I)V", false); + mv.visitMethodInsn(INVOKESPECIAL, cn, "", "(I)V", false); mv.visitVarInsn(ASTORE, index); for (String t : names) { diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java Thu May 05 19:11:09 2016 +0000 @@ -201,6 +201,8 @@ * This method is called prior to invoke the plugin. * * @param config The plugin configuration. + * @throws IllegalArgumentException if a mandatory argument is missing or + * if an argument has invalid value. */ public default void configure(Map config) { } @@ -211,6 +213,9 @@ * * @param config The plugin configuration. * @param ctx The plugin context + * @throws IllegalArgumentException if a mandatory argument is missing or + * if an argument has invalid value. + * */ public default void configure(Map config, PluginContext ctx) { configure(config); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties Thu May 05 19:11:09 2016 +0000 @@ -33,9 +33,6 @@ main.opt.endian=\ \ --endian Byte order of generated jimage (default:native) -main.opt.genbom=\ -\ --genbom Generate a bom file containing jlink info - main.opt.saveopts=\ \ --saveopts Save jlink options in the given file diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Thu May 05 19:11:09 2016 +0000 @@ -89,6 +89,9 @@ include-locales.invalidtag=\ Invalid language tag: %s +include-locales.localedatanotfound=\ +jdk.localedata module was not specified with --addmods option + main.status.ok=Functional. main.status.not.ok= Not functional. diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu May 05 19:11:09 2016 +0000 @@ -26,6 +26,7 @@ package jdk.tools.jmod; import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -34,14 +35,17 @@ import java.io.OutputStream; import java.io.PrintStream; import java.io.UncheckedIOException; -import java.lang.module.FindException; +import java.lang.module.Configuration; +import java.lang.module.ModuleReader; import java.lang.module.ModuleReference; import java.lang.module.ModuleFinder; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleDescriptor.Exports; +import java.lang.module.ModuleDescriptor.Provides; import java.lang.module.ModuleDescriptor.Requires; -import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleDescriptor.Version; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; +import java.lang.module.ResolutionException; +import java.lang.module.ResolvedModule; import java.net.URI; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; @@ -51,13 +55,16 @@ import java.nio.file.PathMatcher; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.text.MessageFormat; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Formatter; +import java.util.Comparator; +import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -68,6 +75,7 @@ import java.util.ResourceBundle; import java.util.Set; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.jar.JarEntry; @@ -89,16 +97,14 @@ import jdk.internal.joptsimple.OptionSet; import jdk.internal.joptsimple.OptionSpec; import jdk.internal.joptsimple.ValueConverter; +import jdk.internal.misc.JavaLangModuleAccess; +import jdk.internal.misc.SharedSecrets; import jdk.internal.module.ConfigurableModuleFinder; import jdk.internal.module.ConfigurableModuleFinder.Phase; -import jdk.internal.module.Hasher; -import jdk.internal.module.Hasher.DependencyHashes; +import jdk.internal.module.ModuleHashes; import jdk.internal.module.ModuleInfoExtender; -import static java.util.function.Function.identity; import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; /** * Implementation for the jmod tool. @@ -127,21 +133,6 @@ } } - static void fail(Class type, - String format, - Object... args) throws T { - String msg = new Formatter().format(format, args).toString(); - try { - T t = type.getConstructor(String.class).newInstance(msg); - throw t; - } catch (InstantiationException | - InvocationTargetException | - NoSuchMethodException | - IllegalAccessException e) { - throw new InternalError("Unable to create an instance of " + type, e); - } - } - private static final String PROGNAME = "jmod"; private static final String MODULE_INFO = "module-info.class"; @@ -161,7 +152,8 @@ enum Mode { CREATE, LIST, - DESCRIBE + DESCRIBE, + HASH }; static class Options { @@ -179,7 +171,8 @@ String osName; String osArch; String osVersion; - Pattern dependenciesToHash; + Pattern modulesToHash; + boolean dryrun; List excludes; } @@ -211,6 +204,9 @@ case DESCRIBE: ok = describe(); break; + case HASH: + ok = hashModules(); + break; default: throw new AssertionError("Unknown mode: " + options.mode.name()); } @@ -248,26 +244,8 @@ } } - private Map modulesToPath(Set modules) { - ModuleFinder finder = options.moduleFinder; - - Map modPaths = new HashMap<>(); - for (ModuleDescriptor m : modules) { - String name = m.name(); - - Optional omref = finder.find(name); - if (!omref.isPresent()) { - // this should not happen, module path bug? - fail(InternalError.class, - "Selected module %s not on module path", - name); - } - - URI uri = omref.get().location().get(); - modPaths.put(name, Paths.get(uri)); - - } - return modPaths; + private boolean hashModules() { + return new Hasher(options.moduleFinder).run(); } private boolean describe() throws IOException { @@ -297,6 +275,8 @@ .collect(joining(" ")); } + private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess(); + private boolean printModuleDescriptor(InputStream in) throws IOException { @@ -311,74 +291,45 @@ StringBuilder sb = new StringBuilder(); sb.append("\n").append(md.toNameAndVersion()); - List requires = md.requires().stream().sorted().collect(toList()); - if (!requires.isEmpty()) { - requires.forEach(r -> { - sb.append("\n requires "); - if (!r.modifiers().isEmpty()) - sb.append(toString(r.modifiers())).append(" "); - sb.append(r.name()); - }); - } - - List l = md.uses().stream().sorted().collect(toList()); - if (!l.isEmpty()) { - l.forEach(sv -> sb.append("\n uses ").append(sv)); - } + md.requires().stream() + .sorted(Comparator.comparing(Requires::name)) + .forEach(r -> { + sb.append("\n requires "); + if (!r.modifiers().isEmpty()) + sb.append(toString(r.modifiers())).append(" "); + sb.append(r.name()); + }); - List exports = sortExports(md.exports()); - if (!exports.isEmpty()) { - exports.forEach(ex -> sb.append("\n exports ").append(ex)); - } + md.uses().stream().sorted() + .forEach(s -> sb.append("\n uses ").append(s)); - l = md.conceals().stream().sorted().collect(toList()); - if (!l.isEmpty()) { - l.forEach(p -> sb.append("\n conceals ").append(p)); - } + md.exports().stream() + .sorted(Comparator.comparing(Exports::source)) + .forEach(p -> sb.append("\n exports ").append(p)); - Map provides = md.provides(); - if (!provides.isEmpty()) { - provides.values().forEach(p -> - sb.append("\n provides ").append(p.service()) - .append(" with ") - .append(toString(p.providers()))); - } + md.conceals().stream().sorted() + .forEach(p -> sb.append("\n conceals ").append(p)); - Optional mc = md.mainClass(); - if (mc.isPresent()) - sb.append("\n main-class " + mc.get()); - - + md.provides().values().stream() + .sorted(Comparator.comparing(Provides::service)) + .forEach(p -> sb.append("\n provides ").append(p.service()) + .append(" with ") + .append(toString(p.providers()))); - Optional osname = md.osName(); - if (osname.isPresent()) - sb.append("\n operating-system-name " + osname.get()); + md.mainClass().ifPresent(v -> sb.append("\n main-class " + v)); - Optional osarch = md.osArch(); - if (osarch.isPresent()) - sb.append("\n operating-system-architecture " + osarch.get()); - - Optional osversion = md.osVersion(); - if (osversion.isPresent()) - sb.append("\n operating-system-version " + osversion.get()); + md.osName().ifPresent(v -> sb.append("\n operating-system-name " + v)); - try { - Method m = ModuleDescriptor.class.getDeclaredMethod("hashes"); - m.setAccessible(true); - @SuppressWarnings("unchecked") - Optional optHashes = - (Optional) m.invoke(md); + md.osArch().ifPresent(v -> sb.append("\n operating-system-architecture " + v)); + + md.osVersion().ifPresent(v -> sb.append("\n operating-system-version " + v)); - if (optHashes.isPresent()) { - Hasher.DependencyHashes hashes = optHashes.get(); - hashes.names().stream().forEach(mod -> - sb.append("\n hashes ").append(mod).append(" ") - .append(hashes.algorithm()).append(" ") - .append(hashes.hashFor(mod))); - } - } catch (ReflectiveOperationException x) { - throw new InternalError(x); - } + JLMA.hashes(md).ifPresent( + hashes -> hashes.names().stream().sorted().forEach( + mod -> sb.append("\n hashes ").append(mod).append(" ") + .append(hashes.algorithm()).append(" ") + .append(hashes.hashFor(mod)))); + out.println(sb.toString()); return true; } @@ -387,21 +338,6 @@ return false; } - static List sortExports(Set exports) { - Map map = - exports.stream() - .collect(toMap(ModuleDescriptor.Exports::source, - identity())); - List sources = exports.stream() - .map(ModuleDescriptor.Exports::source) - .sorted() - .collect(toList()); - - List l = new ArrayList<>(); - sources.forEach(e -> l.add(map.get(e))); - return l; - } - private boolean create() throws IOException { JmodFileWriter jmod = new JmodFileWriter(); @@ -410,8 +346,9 @@ Path target = options.jmodFile; Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp"); try { - try (OutputStream out = Files.newOutputStream(tempTarget)) { - jmod.write(out); + try (OutputStream out = Files.newOutputStream(tempTarget); + BufferedOutputStream bos = new BufferedOutputStream(out)) { + jmod.write(bos); } Files.move(tempTarget, target); } catch (Exception e) { @@ -428,7 +365,6 @@ } private class JmodFileWriter { - final ModuleFinder moduleFinder = options.moduleFinder; final List cmds = options.cmds; final List libs = options.libs; final List configs = options.configs; @@ -438,8 +374,8 @@ final String osName = options.osName; final String osArch = options.osArch; final String osVersion = options.osVersion; - final Pattern dependenciesToHash = options.dependenciesToHash; final List excludes = options.excludes; + final Hasher hasher = hasher(); JmodFileWriter() { } @@ -545,11 +481,13 @@ if (moduleVersion != null) extender.version(moduleVersion); - // --hash-dependencies - if (dependenciesToHash != null) { - String name = descriptor.name(); - Set dependences = descriptor.requires(); - extender.hashes(hashDependences(name, dependences)); + if (hasher != null) { + ModuleHashes moduleHashes = hasher.computeHashes(descriptor.name()); + if (moduleHashes != null) { + extender.hashes(moduleHashes); + } else { + warning("warn.no.module.hashes", descriptor.name()); + } } // write the (possibly extended or modified) module-info.class @@ -561,38 +499,56 @@ } } - /** - * Examines the module dependences of the given module - * and computes the hash of any module that matches the - * pattern {@code dependenciesToHash}. + /* + * Hasher resolves a module graph using the --hash-modules PATTERN + * as the roots. + * + * The jmod file is being created and does not exist in the + * given modulepath. */ - DependencyHashes hashDependences(String name, Set moduleDependences) - throws IOException - { - Set descriptors = new HashSet<>(); - for (Requires md: moduleDependences) { - String dn = md.name(); - if (dependenciesToHash.matcher(dn).find()) { - try { - Optional omref = moduleFinder.find(dn); - if (!omref.isPresent()) { - throw new RuntimeException("Hashing module " + name - + " dependencies, unable to find module " + dn - + " on module path"); + private Hasher hasher() { + if (options.modulesToHash == null) + return null; + + try { + Supplier miSupplier = newModuleInfoSupplier(); + if (miSupplier == null) { + throw new IOException(MODULE_INFO + " not found"); + } + + ModuleDescriptor descriptor; + try (InputStream in = miSupplier.get()) { + descriptor = ModuleDescriptor.read(in); + } + + URI uri = options.jmodFile.toUri(); + ModuleReference mref = new ModuleReference(descriptor, uri, new Supplier<>() { + @Override + public ModuleReader get() { + throw new UnsupportedOperationException(); + } + }); + + // compose a module finder with the module path and also + // a module finder that can find the jmod file being created + ModuleFinder finder = ModuleFinder.compose(options.moduleFinder, + new ModuleFinder() { + @Override + public Optional find(String name) { + if (descriptor.name().equals(name)) + return Optional.of(mref); + else return Optional.empty(); } - descriptors.add(omref.get().descriptor()); - } catch (FindException x) { - throw new IOException("error reading module path", x); - } - } - } - Map map = modulesToPath(descriptors); - if (map.size() == 0) { - return null; - } else { - // use SHA-256 for now, easy to make this configurable if needed - return Hasher.generate(map, "SHA-256"); + @Override + public Set findAll() { + return Collections.singleton(mref); + } + }); + + return new Hasher(finder); + } catch (IOException e) { + throw new UncheckedIOException(e); } } @@ -765,6 +721,273 @@ } } + /** + * Compute and record hashes + */ + private class Hasher { + final ModuleFinder moduleFinder; + final Map moduleNameToPath; + final Set modules; + final Configuration configuration; + final boolean dryrun = options.dryrun; + Hasher(ModuleFinder finder) { + this.moduleFinder = finder; + // Determine the modules that matches the pattern {@code modulesToHash} + this.modules = moduleFinder.findAll().stream() + .map(mref -> mref.descriptor().name()) + .filter(mn -> options.modulesToHash.matcher(mn).find()) + .collect(Collectors.toSet()); + + // a map from a module name to Path of the packaged module + this.moduleNameToPath = moduleFinder.findAll().stream() + .map(mref -> mref.descriptor().name()) + .collect(Collectors.toMap(Function.identity(), mn -> moduleToPath(mn))); + + // get a resolved module graph + Configuration config = null; + try { + config = Configuration.empty() + .resolveRequires(ModuleFinder.ofSystem(), moduleFinder, modules); + } catch (ResolutionException e) { + warning("warn.module.resolution.fail", e.getMessage()); + } + this.configuration = config; + } + + /** + * This method is for jmod hash command. + * + * Identify the base modules in the module graph, i.e. no outgoing edge + * to any of the modules to be hashed. + * + * For each base module M, compute the hashes of all modules that depend + * upon M directly or indirectly. Then update M's module-info.class + * to record the hashes. + */ + boolean run() { + if (configuration == null) + return false; + + // transposed graph containing the the packaged modules and + // its transitive dependences matching --hash-modules + Map> graph = new HashMap<>(); + for (String root : modules) { + Deque deque = new ArrayDeque<>(); + deque.add(root); + Set visited = new HashSet<>(); + while (!deque.isEmpty()) { + String mn = deque.pop(); + if (!visited.contains(mn)) { + visited.add(mn); + + if (modules.contains(mn)) + graph.computeIfAbsent(mn, _k -> new HashSet<>()); + + ResolvedModule resolvedModule = configuration.findModule(mn).get(); + for (ResolvedModule dm : resolvedModule.reads()) { + String name = dm.name(); + if (!visited.contains(name)) { + deque.push(name); + } + + // reverse edge + if (modules.contains(name) && modules.contains(mn)) { + graph.computeIfAbsent(name, _k -> new HashSet<>()).add(mn); + } + } + } + } + } + + if (dryrun) + out.println("Dry run:"); + + // each node in a transposed graph is a matching packaged module + // in which the hash of the modules that depend upon it is recorded + graph.entrySet().stream() + .filter(e -> !e.getValue().isEmpty()) + .forEach(e -> { + String mn = e.getKey(); + Map modulesForHash = e.getValue().stream() + .collect(Collectors.toMap(Function.identity(), + moduleNameToPath::get)); + ModuleHashes hashes = ModuleHashes.generate(modulesForHash, "SHA-256"); + if (dryrun) { + out.format("%s%n", mn); + hashes.names().stream() + .sorted() + .forEach(name -> out.format(" hashes %s %s %s%n", + name, hashes.algorithm(), hashes.hashFor(name))); + } else { + try { + updateModuleInfo(mn, hashes); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + }); + return true; + } + + /** + * Compute hashes of the specified module. + * + * It records the hashing modules that depend upon the specified + * module directly or indirectly. + */ + ModuleHashes computeHashes(String name) { + if (configuration == null) + return null; + + // the transposed graph includes all modules in the resolved graph + Map> graph = transpose(); + + // find the modules that transitively depend upon the specified name + Deque deque = new ArrayDeque<>(); + deque.add(name); + Set mods = visitNodes(graph, deque); + + // filter modules matching the pattern specified --hash-modules + // as well as itself as the jmod file is being generated + Map modulesForHash = mods.stream() + .filter(mn -> !mn.equals(name) && modules.contains(mn)) + .collect(Collectors.toMap(Function.identity(), moduleNameToPath::get)); + + if (modulesForHash.isEmpty()) + return null; + + return ModuleHashes.generate(modulesForHash, "SHA-256"); + } + + /** + * Returns all nodes traversed from the given roots. + */ + private Set visitNodes(Map> graph, + Deque roots) { + Set visited = new HashSet<>(); + while (!roots.isEmpty()) { + String mn = roots.pop(); + if (!visited.contains(mn)) { + visited.add(mn); + // the given roots may not be part of the graph + if (graph.containsKey(mn)) { + for (String dm : graph.get(mn)) { + if (!visited.contains(dm)) { + roots.push(dm); + } + } + } + } + } + return visited; + } + + /** + * Returns a transposed graph from the resolved module graph. + */ + private Map> transpose() { + Map> transposedGraph = new HashMap<>(); + Deque deque = new ArrayDeque<>(modules); + + Set visited = new HashSet<>(); + while (!deque.isEmpty()) { + String mn = deque.pop(); + if (!visited.contains(mn)) { + visited.add(mn); + + transposedGraph.computeIfAbsent(mn, _k -> new HashSet<>()); + + ResolvedModule resolvedModule = configuration.findModule(mn).get(); + for (ResolvedModule dm : resolvedModule.reads()) { + String name = dm.name(); + if (!visited.contains(name)) { + deque.push(name); + } + + // reverse edge + transposedGraph.computeIfAbsent(name, _k -> new HashSet<>()) + .add(mn); + } + } + } + return transposedGraph; + } + + /** + * Reads the given input stream of module-info.class and write + * the extended module-info.class with the given ModuleHashes + * + * @param in InputStream of module-info.class + * @param out OutputStream to write the extended module-info.class + * @param hashes ModuleHashes + */ + private void recordHashes(InputStream in, OutputStream out, ModuleHashes hashes) + throws IOException + { + ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in); + extender.hashes(hashes); + extender.write(out); + } + + private void updateModuleInfo(String name, ModuleHashes moduleHashes) + throws IOException + { + Path target = moduleNameToPath.get(name); + Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp"); + ZipFile zip = new ZipFile(target.toFile()); + try { + try (OutputStream out = Files.newOutputStream(tempTarget); + ZipOutputStream zos = new ZipOutputStream(out)) { + zip.stream().forEach(e -> { + try { + InputStream in = zip.getInputStream(e); + if (e.getName().equals(MODULE_INFO) || + e.getName().equals(Section.CLASSES.jmodDir() + "/" + MODULE_INFO)) { + ZipEntry ze = new ZipEntry(e.getName()); + ze.setTime(System.currentTimeMillis()); + zos.putNextEntry(ze); + recordHashes(in, zos, moduleHashes); + zos.closeEntry(); + } else { + zos.putNextEntry(e); + zos.write(in.readAllBytes()); + zos.closeEntry(); + } + } catch (IOException x) { + throw new UncheckedIOException(x); + } + }); + } + } catch (IOException|RuntimeException e) { + if (Files.exists(tempTarget)) { + try { + Files.delete(tempTarget); + } catch (IOException ioe) { + e.addSuppressed(ioe); + } + } + throw e; + } finally { + zip.close(); + } + out.println(getMessage("module.hashes.recorded", name)); + Files.move(tempTarget, target, StandardCopyOption.REPLACE_EXISTING); + } + + private Path moduleToPath(String name) { + ModuleReference mref = moduleFinder.find(name).orElseThrow( + () -> new InternalError("Selected module " + name + " not on module path")); + + URI uri = mref.location().get(); + Path path = Paths.get(uri); + String fn = path.getFileName().toString(); + if (!fn.endsWith(".jar") && !fn.endsWith(".jmod")) { + throw new InternalError(path + " is not a modular JAR or jmod file"); + } + return path; + } + } + enum Section { NATIVE_LIBS("native"), NATIVE_CMDS("bin"), @@ -921,7 +1144,8 @@ builder.append("\n").append(" Main operation modes:\n "); builder.append(getMessage("main.opt.mode.create")).append("\n "); builder.append(getMessage("main.opt.mode.list")).append("\n "); - builder.append(getMessage("main.opt.mode.describe")).append("\n\n"); + builder.append(getMessage("main.opt.mode.describe")).append("\n "); + builder.append(getMessage("main.opt.mode.hash")).append("\n\n"); String cmdfile = null; String[] lines = content.split("\n"); @@ -964,13 +1188,16 @@ .withValuesSeparatedBy(File.pathSeparatorChar) .withValuesConvertedBy(DirPathConverter.INSTANCE); + OptionSpec dryrun + = parser.accepts("dry-run", getMessage("main.opt.dry-run")); + OptionSpec excludes = parser.accepts("exclude", getMessage("main.opt.exclude")) .withRequiredArg() .withValuesConvertedBy(new GlobConverter()); - OptionSpec hashDependencies - = parser.accepts("hash-dependencies", getMessage("main.opt.hash-dependencies")) + OptionSpec hashModules + = parser.accepts("hash-modules", getMessage("main.opt.hash-modules")) .withRequiredArg() .withValuesConvertedBy(new PatternConverter()); @@ -1049,6 +1276,8 @@ options.cmds = opts.valuesOf(cmds); if (opts.has(config)) options.configs = opts.valuesOf(config); + if (opts.has(dryrun)) + options.dryrun = true; if (opts.has(excludes)) options.excludes = opts.valuesOf(excludes); if (opts.has(libs)) @@ -1069,27 +1298,39 @@ options.osArch = opts.valueOf(osArch); if (opts.has(osVersion)) options.osVersion = opts.valueOf(osVersion); - if (opts.has(hashDependencies)) { - options.dependenciesToHash = opts.valueOf(hashDependencies); - // if storing hashes of dependencies then the module path is required + if (opts.has(hashModules)) { + options.modulesToHash = opts.valueOf(hashModules); + // if storing hashes then the module path is required if (options.moduleFinder == null) - throw new CommandException("err.modulepath.must.be.specified").showUsage(true); + throw new CommandException("err.modulepath.must.be.specified") + .showUsage(true); } - if (words.size() <= 1) - throw new CommandException("err.jmod.must.be.specified").showUsage(true); - Path path = Paths.get(words.get(1)); - if (options.mode.equals(Mode.CREATE) && Files.exists(path)) - throw new CommandException("err.file.already.exists", path); - else if ((options.mode.equals(Mode.LIST) || - options.mode.equals(Mode.DESCRIBE)) - && Files.notExists(path)) - throw new CommandException("err.jmod.not.found", path); - options.jmodFile = path; + if (options.mode.equals(Mode.HASH)) { + if (options.moduleFinder == null || options.modulesToHash == null) + throw new CommandException("err.modulepath.must.be.specified") + .showUsage(true); + } else { + if (words.size() <= 1) + throw new CommandException("err.jmod.must.be.specified").showUsage(true); + Path path = Paths.get(words.get(1)); - if (words.size() > 2) - throw new CommandException("err.unknown.option", - words.subList(2, words.size())).showUsage(true); + if (options.mode.equals(Mode.CREATE) && Files.exists(path)) + throw new CommandException("err.file.already.exists", path); + else if ((options.mode.equals(Mode.LIST) || + options.mode.equals(Mode.DESCRIBE)) + && Files.notExists(path)) + throw new CommandException("err.jmod.not.found", path); + + if (options.dryrun) { + throw new CommandException("err.invalid.dryrun.option"); + } + options.jmodFile = path; + + if (words.size() > 2) + throw new CommandException("err.unknown.option", + words.subList(2, words.size())).showUsage(true); + } if (options.mode.equals(Mode.CREATE) && options.classpath == null) throw new CommandException("err.classpath.must.be.specified").showUsage(true); diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Thu May 05 19:11:09 2016 +0000 @@ -1,9 +1,9 @@ main.usage.summary=\ -Usage: {0} (create|list|describe) \n\ +Usage: {0} (create|list|describe|hash) \n\ use --help for a list of possible options main.usage=\ -Usage: {0} (create|list|describe) +Usage: {0} (create|list|describe|hash) error.prefix=Error: warn.prefix=Warning: @@ -14,6 +14,8 @@ \list - Prints the names of all the entries main.opt.mode.describe=\ \describe - Prints the module details +main.opt.mode.hash=\ +\hash - Records hashes of tied modules. main.opt.help=Print this usage message main.opt.version=Version information @@ -21,9 +23,9 @@ main.opt.libs=Location of native libraries main.opt.cmds=Location of native commands main.opt.config=Location of user-editable config files +main.opt.dry-run=Dry run of hash mode main.opt.exclude=Exclude files, given as a PATTERN main.opt.module-version= Module version -main.opt.modulepath=Module path main.opt.main-class=Main class main.opt.main-class.arg=class-name main.opt.os-name=Operating system name @@ -32,18 +34,25 @@ main.opt.os-arch.arg=os-arch main.opt.os-version=Operating system version main.opt.os-version.arg=os-version -main.opt.hash-dependencies=Compute and record hashes of dependencies matched by the pattern +main.opt.modulepath=Module path +main.opt.hash-modules=Compute and record hashes to tie a packaged module\ +\ with modules matching the given pattern and depending upon it directly\ +\ or indirectly. The hashes are recorded in the JMOD file being created, or\ +\ a JMOD file or modular JAR on the module path specified the jmod hash command. + main.opt.cmdfile=Read options from the specified file -err.missing.mode=one of create, list, or describe must be specified -err.invalid.mode=mode must be one of create, list, or describe: {0} +module.hashes.recorded=Hashes are recorded in module {0} + +err.missing.mode=one of create, list, describe, or hash must be specified +err.invalid.mode=mode must be one of create, list, describe, or hash: {0} err.classpath.must.be.specified=--class-path must be specified err.jmod.must.be.specified=jmod-file must be specified err.invalid.version=invalid module version {0} -err.output.must.be.specified:--output must be specified -err.mods.must.be.specified:--mods must be specified -err.modulepath.must.be.specified:--module-path must be specified when hashing dependencies -err.invalid.main-class:invalid main-class name: {0} +err.output.must.be.specified=--output must be specified +err.mods.must.be.specified=--mods must be specified +err.modulepath.must.be.specified=--module-path must be specified when hashing modules +err.invalid.main-class=invalid main-class name: {0} err.path.not.found=path not found: {0} err.path.not.valid=invalid path: {0} err.path.not.a.dir=path must be a directory: {0} @@ -54,5 +63,9 @@ err.unknown.option=unknown option(s): {0} err.missing.arg=no value given for {0} err.internal.error=internal error: {0} {1} {2} +err.invalid.dryrun.option=--dry-run can only be used with hash mode err.module.descriptor.not.found=Module descriptor not found warn.invalid.arg=Invalid classname or pathname not exist: {0} +warn.no.module.hashes=No hashes recorded: no module specified for hashing depends on {0} +warn.module.resolution.fail=No hashes recorded: {0} + diff -r 5c95f3324916 -r 41844efbbcce jdk/src/jdk.localedata/share/classes/sun/util/resources/provider/LocaleDataProvider.java --- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/provider/LocaleDataProvider.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/provider/LocaleDataProvider.java Thu May 05 19:11:09 2016 +0000 @@ -46,7 +46,7 @@ Class c = Class.forName(LocaleDataProvider.class.getModule(), bundleName); if (c != null && ResourceBundle.class.isAssignableFrom(c)) { try { - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "deprecation"}) ResourceBundle rb = ((Class) c).newInstance(); return rb; } catch (InstantiationException | IllegalAccessException e) { diff -r 5c95f3324916 -r 41844efbbcce jdk/test/TEST.ROOT --- a/jdk/test/TEST.ROOT Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/TEST.ROOT Thu May 05 19:11:09 2016 +0000 @@ -26,9 +26,12 @@ # Allow querying of sun.arch.data.model in @requires clauses requires.properties=sun.arch.data.model -# Tests using jtreg 4.2 b01 features -requiredVersion=4.2 b01 +# Tests using jtreg 4.2 b02 features +requiredVersion=4.2 b02 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them external.lib.roots = ../../ + +# Use new form of -Xpatch +useNewXpatch=true diff -r 5c95f3324916 -r 41844efbbcce jdk/test/TEST.groups --- a/jdk/test/TEST.groups Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/TEST.groups Thu May 05 19:11:09 2016 +0000 @@ -29,7 +29,6 @@ :jdk_lang \ -java/lang/ProcessHandle/TreeTest.java \ :jdk_util \ - -java/util/WeakHashMap/GCDuringIteration.java \ -java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \ -java/util/concurrent/forkjoin/FJExceptionTableLeak.java \ sun/nio/cs/ISO8859x.java \ @@ -39,7 +38,6 @@ tier2 = \ java/lang/ProcessHandle/TreeTest.java \ - java/util/WeakHashMap/GCDuringIteration.java \ java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \ java/util/concurrent/forkjoin/FJExceptionTableLeak.java \ :jdk_io \ diff -r 5c95f3324916 -r 41844efbbcce jdk/test/com/sun/corba/5036554/TestCorbaBug.sh --- a/jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Thu May 05 19:11:09 2016 +0000 @@ -81,9 +81,9 @@ chmod -fR 777 bug -${COMPILEJAVA}${FS}bin${FS}javac -d . bug${FS}*.java +${COMPILEJAVA}${FS}bin${FS}javac -addmods java.corba -d . bug${FS}*.java -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -cp . bug/JavaBug > test.out 2>&1 +${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -addmods java.corba -cp . bug/JavaBug > test.out 2>&1 grep "NullPointerException" test.out diff -r 5c95f3324916 -r 41844efbbcce jdk/test/com/sun/corba/7130985/CorbaExceptionsCompileTest.java --- a/jdk/test/com/sun/corba/7130985/CorbaExceptionsCompileTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/com/sun/corba/7130985/CorbaExceptionsCompileTest.java Thu May 05 19:11:09 2016 +0000 @@ -27,7 +27,8 @@ * @summary Four helper classes missing in Sun JDK * @library /lib/testlibrary * @build jdk.testlibrary.* - * @run main CorbaExceptionsCompileTest + * @compile -addmods java.corba CorbaExceptionsCompileTest.java + * @run main/othervm -addmods java.corba CorbaExceptionsCompileTest */ import java.io.*; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/com/sun/corba/se/impl/io/HookPutFieldsTest.java --- a/jdk/test/com/sun/corba/se/impl/io/HookPutFieldsTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/com/sun/corba/se/impl/io/HookPutFieldsTest.java Thu May 05 19:11:09 2016 +0000 @@ -25,6 +25,8 @@ * @test * @bug 7095856 * @summary OutputStreamHook doesn't handle null values + * @compile -addmods java.corba HookPutFieldsTest.java + * @run main/othervm -addmods java.corba HookPutFieldsTest */ import java.net.InetAddress; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/com/sun/corba/se/impl/orb/SetDefaultORBTest.java --- a/jdk/test/com/sun/corba/se/impl/orb/SetDefaultORBTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/com/sun/corba/se/impl/orb/SetDefaultORBTest.java Thu May 05 19:11:09 2016 +0000 @@ -25,7 +25,8 @@ * @test * @bug 8028215 * @summary SetDefaultORBTest setting ORB impl via properties test - * @run main/othervm SetDefaultORBTest + * @compile -addmods java.corba SetDefaultORBTest.java + * @run main/othervm -addmods java.corba SetDefaultORBTest * */ diff -r 5c95f3324916 -r 41844efbbcce jdk/test/com/sun/net/httpserver/bugs/B6373555.java --- a/jdk/test/com/sun/net/httpserver/bugs/B6373555.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/com/sun/net/httpserver/bugs/B6373555.java Thu May 05 19:11:09 2016 +0000 @@ -29,7 +29,6 @@ import java.net.*; import java.io.*; -import javax.xml.soap.*; import java.util.*; import com.sun.net.httpserver.*; import java.util.concurrent.*; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/lang/invoke/VarargsArrayTest.java --- a/jdk/test/java/lang/invoke/VarargsArrayTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/lang/invoke/VarargsArrayTest.java Thu May 05 19:11:09 2016 +0000 @@ -37,7 +37,7 @@ * @library /lib/testlibrary /lib/testlibrary/jsr292 * @compile/module=java.base java/lang/invoke/MethodHandleHelper.java * @run main/bootclasspath VarargsArrayTest - * @run main/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.START_ARITY=250 + * @run main/bootclasspath/othervm -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.START_ARITY=250 * VarargsArrayTest */ diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/lang/module/ModuleFinderTest.java --- a/jdk/test/java/lang/module/ModuleFinderTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/lang/module/ModuleFinderTest.java Thu May 05 19:11:09 2016 +0000 @@ -340,7 +340,7 @@ */ public void testOfWithUnrecognizedEntry() throws Exception { Path dir = Files.createTempDirectory(USER_DIR, "mods"); - Path mod = Files.createTempFile(dir, "m", "mod"); + Path mod = Files.createTempFile(dir, "m", ".junk"); ModuleFinder finder = ModuleFinder.of(mod); try { @@ -361,6 +361,48 @@ /** + * Test ModuleFinder.of with a file path to a directory containing a file + * that will not be recognized as a module. + */ + public void testOfWithUnrecognizedEntryInDirectory() throws Exception { + Path dir = Files.createTempDirectory(USER_DIR, "mods"); + Files.createTempFile(dir, "m", ".junk"); + + ModuleFinder finder = ModuleFinder.of(dir); + try { + finder.find("java.rhubarb"); + assertTrue(false); + } catch (FindException e) { + // expected + } + + finder = ModuleFinder.of(dir); + try { + finder.findAll(); + assertTrue(false); + } catch (FindException e) { + // expected + } + } + + + /** + * Test ModuleFinder.of with a file path to a directory containing a file + * starting with ".", the file should be ignored. + */ + public void testOfWithHiddenEntryInDirectory() throws Exception { + Path dir = Files.createTempDirectory(USER_DIR, "mods"); + Files.createTempFile(dir, ".marker", ""); + + ModuleFinder finder = ModuleFinder.of(dir); + assertFalse(finder.find("java.rhubarb").isPresent()); + + finder = ModuleFinder.of(dir); + assertTrue(finder.findAll().isEmpty()); + } + + + /** * Test ModuleFinder.of with a directory that contains two * versions of the same module */ diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/lang/reflect/WeakPairMap/Driver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/reflect/WeakPairMap/Driver.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8888888 + * @summary Functional test for WeakPairMap + * @build java.base/java.lang.reflect.WeakPairMapTest + * @run main Driver + */ +public class Driver { + public static void main(String[] args) { + java.lang.reflect.WeakPairMapTest.main(args); + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/lang/reflect/WeakPairMap/java.base/java/lang/reflect/WeakPairMapTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/reflect/WeakPairMap/java.base/java/lang/reflect/WeakPairMapTest.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,175 @@ +/* + * 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.reflect; + +import java.lang.ref.Reference; +import java.util.Objects; + +/** + * Functional test for WeakPairMap + * + * @author Peter Levart + */ +public class WeakPairMapTest { + public static void main(String[] args) { + WeakPairMap pm = new WeakPairMap<>(); + Object key1 = new Object(); + Object key2 = new Object(); + + // check for emptiness + assertEquals(pm.containsKeyPair(key1, key2), false); + assertEquals(pm.get(key1, key2), null); + + // check for NPE(s) + for (Object k1 : new Object[]{null, key1}) { + for (Object k2 : new Object[]{null, key2}) { + for (String v : new String[]{null, "abc"}) { + + if (k1 != null && k2 != null && v != null) { + // skip non-null args + continue; + } + + try { + pm.put(k1, k2, v); + throw new AssertionError("Unexpected code path, k1=" + + k1 + ", k2=" + k2 + ", v=" + v); + } catch (NullPointerException e) { + // expected + } + + try { + pm.putIfAbsent(k1, k2, v); + throw new AssertionError("Unexpected code path, k1=" + + k1 + ", k2=" + k2 + ", v=" + v); + } catch (NullPointerException e) { + // expected + } + + if (k1 != null && k2 != null) { + // skip non-null args + continue; + } + + try { + pm.computeIfAbsent(k1, k2, (_k1, _k2) -> v); + throw new AssertionError("Unexpected code path, k1=" + + k1 + ", k2=" + k2 + ", v=" + v); + } catch (NullPointerException e) { + // expected + } + + try { + pm.containsKeyPair(k1, k2); + throw new AssertionError("Unexpected code path, k1=" + + k1 + ", k2=" + k2); + } catch (NullPointerException e) { + // expected + } + + try { + pm.get(k1, k2); + throw new AssertionError("Unexpected code path, k1=" + + k1 + ", k2=" + k2); + } catch (NullPointerException e) { + // expected + } + } + } + } + + // how much to wait when it is expected for entry to be retained + final long retentionTimeout = 500L; + // how much to wait when it is expected for entry to be removed + final long cleanupTimeout = 30_000L; + + // check insertion + assertEquals(pm.putIfAbsent(key1, key2, "abc"), null); + assertEquals(pm.get(key1, key2), "abc"); + + // check retention while both keys are still reachable + assertEquals(gcAndWaitRemoved(pm, "abc", retentionTimeout), false); + assertEquals(pm.get(key1, key2), "abc"); + + // check cleanup when both keys are unreachable + key1 = null; + key2 = null; + assertEquals(gcAndWaitRemoved(pm, "abc", cleanupTimeout), true); + + // new insertion + key1 = new Object(); + key2 = new Object(); + assertEquals(pm.putIfAbsent(key1, key2, "abc"), null); + assertEquals(pm.get(key1, key2), "abc"); + + // check retention while both keys are still reachable + assertEquals(gcAndWaitRemoved(pm, "abc", retentionTimeout), false); + assertEquals(pm.get(key1, key2), "abc"); + + // check cleanup when 1st key is unreachable + key1 = null; + assertEquals(gcAndWaitRemoved(pm, "abc", cleanupTimeout), true); + Reference.reachabilityFence(key2); + + // new insertion + key1 = new Object(); + key2 = new Object(); + assertEquals(pm.putIfAbsent(key1, key2, "abc"), null); + assertEquals(pm.get(key1, key2), "abc"); + + // check retention while both keys are still reachable + assertEquals(gcAndWaitRemoved(pm, "abc", retentionTimeout), false); + assertEquals(pm.get(key1, key2), "abc"); + + // check cleanup when 2nd key is unreachable + key2 = null; + assertEquals(gcAndWaitRemoved(pm, "abc", cleanupTimeout), true); + Reference.reachabilityFence(key1); + } + + /** + * Trigger GC and wait for at most {@code millis} ms for given value to + * be removed from given WeakPairMap. + * + * @return true if element has been removed or false if not + */ + static boolean gcAndWaitRemoved(WeakPairMap pm, V value, + long millis) { + System.gc(); + for (int i = 0; i < (millis + 99) / 100 && pm.values().contains(value); i++) { + try { + Thread.sleep(100L); + } catch (InterruptedException e) { + throw new AssertionError("Interrupted"); + } + } + return !pm.values().contains(value); + } + + static void assertEquals(Object actual, Object expected) { + if (!Objects.equals(actual, expected)) { + throw new AssertionError("Expected: " + expected + ", actual: " + actual); + } + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/0.policy --- a/jdk/test/java/net/httpclient/security/0.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/0.policy Thu May 05 19:11:09 2016 +0000 @@ -2,8 +2,7 @@ grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/1.policy --- a/jdk/test/java/net/httpclient/security/1.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/1.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 1 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; @@ -13,7 +12,7 @@ // permissions specific to this test - permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET"; }; // For proxy only. Not being tested diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/10.policy --- a/jdk/test/java/net/httpclient/security/10.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/10.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 10 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; @@ -12,7 +11,7 @@ permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:*"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:*"; }; // For proxy only. Not being tested diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/11.policy --- a/jdk/test/java/net/httpclient/security/11.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/11.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 11 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; @@ -12,8 +11,8 @@ permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:*"; - permission java.net.URLPermission "socket://127.0.0.1:27301", "CONNECT"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "socket://127.0.0.1:${port.number1}", "CONNECT"; }; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/12.policy --- a/jdk/test/java/net/httpclient/security/12.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/12.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 11 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; @@ -12,8 +11,8 @@ permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:*"; - permission java.net.URLPermission "socket://127.0.0.1:27301", "CONNECT"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "socket://127.0.0.1:${port.number1}", "CONNECT"; }; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/14.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/httpclient/security/14.policy Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,23 @@ +// Policy 14 +grant { + // permissions common to all tests + permission java.util.PropertyPermission "*", "read"; + permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; + permission java.net.NetPermission "getDefaultHttpClient"; + permission java.lang.RuntimePermission "modifyThread"; + permission java.util.logging.LoggingPermission "control", ""; + permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; + permission java.lang.RuntimePermission "createClassLoader"; + + + // permissions specific to this test + permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET"; +}; + +// For proxy only. Not being tested +grant codebase "file:${test.classes}/proxydir/-" { + permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; + permission java.net.SocketPermission "127.0.0.1:1024-", "connect,resolve"; +}; + diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/15.policy --- a/jdk/test/java/net/httpclient/security/15.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/15.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 11 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; @@ -13,7 +12,6 @@ // permissions specific to this test permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:*"; - permission java.net.URLPermission "socket://127.0.0.1:27301", "CONNECT"; // Test checks for this explicitly permission java.net.RuntimePermission "foobar"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/2.policy --- a/jdk/test/java/net/httpclient/security/2.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/2.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 2 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/3.policy --- a/jdk/test/java/net/httpclient/security/3.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/3.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 3 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/4.policy --- a/jdk/test/java/net/httpclient/security/4.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/4.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 4 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/5.policy --- a/jdk/test/java/net/httpclient/security/5.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/5.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 5 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/6.policy --- a/jdk/test/java/net/httpclient/security/6.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/6.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 6 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/7.policy --- a/jdk/test/java/net/httpclient/security/7.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/7.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 7 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/8.policy --- a/jdk/test/java/net/httpclient/security/8.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/8.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 8 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/9.policy --- a/jdk/test/java/net/httpclient/security/9.policy Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/9.policy Thu May 05 19:11:09 2016 +0000 @@ -1,8 +1,7 @@ // Policy 9 grant { // permissions common to all tests - permission java.util.PropertyPermission "test.src", "read"; - permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "*", "read"; permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.net.NetPermission "getDefaultHttpClient"; permission java.lang.RuntimePermission "modifyThread"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/Driver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/httpclient/security/Driver.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,139 @@ +/* + * 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 + */ + +/** + * @test + * @bug 8087112 + * @library /lib/testlibrary/ + * @build jdk.testlibrary.SimpleSSLContext jdk.testlibrary.Utils + * @compile ../../../../com/sun/net/httpserver/LogFilter.java + * @compile ../../../../com/sun/net/httpserver/FileServerHandler.java + * @compile ../ProxyServer.java + * @build Security + * + * @run driver/timeout=60 Driver + */ + +/** + * driver required for allocating free portnumbers and putting this number + * into security policy file used in some tests. + * + * The tests are in Security.java and port number supplied in -Dport.number + * and -Dport.number1 for tests that require a second free port + */ +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.io.*; +import java.net.*; + +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.Utils; + +/** + * Driver for tests + */ +public class Driver { + + public static void main(String[] args) throws Throwable { + System.out.println("Starting Driver"); + runtest("1.policy", "1"); + runtest("10.policy", "10"); + runtest("11.policy", "11"); + runtest("12.policy", "12"); + System.out.println("DONE"); + } + + static class Logger extends Thread { + private final OutputStream ps; + private final InputStream stdout; + + Logger(String cmdLine, Process p, String dir) throws IOException { + super(); + setDaemon(true); + cmdLine = "Command line = [" + cmdLine + "]"; + stdout = p.getInputStream(); + File f = File.createTempFile("debug", ".txt", new File(dir)); + ps = new FileOutputStream(f); + ps.write(cmdLine.getBytes()); + ps.flush(); + } + + public void run() { + try { + byte[] buf = new byte[128]; + int c; + while ((c = stdout.read(buf)) != -1) { + ps.write(buf, 0, c); + ps.flush(); + } + ps.close(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + public static void runtest(String policy, String testnum) throws Throwable { + + String testJdk = System.getProperty("test.jdk", "?"); + String testSrc = System.getProperty("test.src", "?"); + String testClassPath = System.getProperty("test.class.path", "?"); + String testClasses = System.getProperty("test.classes", "?"); + String sep = System.getProperty("file.separator", "?"); + String javaCmd = testJdk + sep + "bin" + sep + "java"; + int retval = 10; // 10 is special exit code denoting a bind error + // in which case, we retry + while (retval == 10) { + List cmd = new ArrayList<>(); + cmd.add(javaCmd); + cmd.add("-Dtest.jdk=" + testJdk); + cmd.add("-Dtest.src=" + testSrc); + cmd.add("-Dtest.classes=" + testClasses); + cmd.add("-Djava.security.manager"); + cmd.add("-Djava.security.policy=" + testSrc + sep + policy); + cmd.add("-Dport.number=" + Integer.toString(Utils.getFreePort())); + cmd.add("-Dport.number1=" + Integer.toString(Utils.getFreePort())); + cmd.add("-cp"); + cmd.add(testClassPath); + cmd.add("Security"); + cmd.add(testnum); + + ProcessBuilder processBuilder = new ProcessBuilder(cmd) + .redirectOutput(ProcessBuilder.Redirect.PIPE) + .redirectErrorStream(true); + + String cmdLine = cmd.stream().collect(Collectors.joining(" ")); + Process child = processBuilder.start(); + Logger log = new Logger(cmdLine, child, testClasses); + log.start(); + retval = child.waitFor(); + System.out.println("retval = " + retval); + } + if (retval != 0) { + Thread.sleep(2000); + throw new RuntimeException("Non zero return value"); + } + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/net/httpclient/security/Security.java --- a/jdk/test/java/net/httpclient/security/Security.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/net/httpclient/security/Security.java Thu May 05 19:11:09 2016 +0000 @@ -32,7 +32,6 @@ * @compile ../ProxyServer.java * * @run main/othervm/secure=java.lang.SecurityManager/policy=0.policy Security 0 - * @run main/othervm/secure=java.lang.SecurityManager/policy=1.policy Security 1 * @run main/othervm/secure=java.lang.SecurityManager/policy=2.policy Security 2 * @run main/othervm/secure=java.lang.SecurityManager/policy=3.policy Security 3 * @run main/othervm/secure=java.lang.SecurityManager/policy=4.policy Security 4 @@ -41,14 +40,13 @@ * @run main/othervm/secure=java.lang.SecurityManager/policy=7.policy Security 7 * @run main/othervm/secure=java.lang.SecurityManager/policy=8.policy Security 8 * @run main/othervm/secure=java.lang.SecurityManager/policy=9.policy Security 9 - * @run main/othervm/secure=java.lang.SecurityManager/policy=10.policy Security 10 - * @run main/othervm/secure=java.lang.SecurityManager/policy=11.policy Security 11 - * @run main/othervm/secure=java.lang.SecurityManager/policy=12.policy Security 12 * @run main/othervm/secure=java.lang.SecurityManager/policy=0.policy Security 13 - * @run main/othervm/secure=java.lang.SecurityManager/policy=1.policy Security 14 + * @run main/othervm/secure=java.lang.SecurityManager/policy=14.policy Security 14 * @run main/othervm/secure=java.lang.SecurityManager/policy=15.policy Security 15 */ +// Tests 1, 10, 11 and 12 executed from Driver + import com.sun.net.httpserver.*; import java.io.IOException; import java.io.InputStream; @@ -78,7 +76,7 @@ static HttpServer s1 = null; static ExecutorService executor=null; - static int port; + static int port, proxyPort; static HttpClient client; static String httproot, fileuri, fileroot, redirectroot; static List clients = new LinkedList<>(); @@ -136,6 +134,9 @@ if (!dest.toFile().exists()) { System.out.printf("moving %s to %s\n", src.toString(), dest.toString()); Files.move(src, dest, StandardCopyOption.REPLACE_EXISTING); + } else if (src.toFile().exists()) { + System.out.printf("%s exists, deleting %s\n", dest.toString(), src.toString()); + Files.delete(src); } else { System.out.printf("NOT moving %s to %s\n", src.toString(), dest.toString()); } @@ -225,15 +226,15 @@ }), // (10) policy has permission for destination URL but not for proxy test(false, () -> { //Policy 10 - directProxyTest(27208, true); + directProxyTest(proxyPort, true); }), // (11) policy has permission for both destination URL and proxy test(true, () -> { //Policy 11 - directProxyTest(27301, true); + directProxyTest(proxyPort, true); }), // (12) policy has permission for both destination URL and proxy test(false, () -> { //Policy 11 - directProxyTest(28301, false); + directProxyTest(proxyPort, false); }), // (13) async version of test 0 test(false, () -> { // Policy 0 @@ -350,6 +351,8 @@ throw new RuntimeException("Failed"); } System.out.println (policy + " succeeded as expected"); + } catch (BindException e) { + System.exit(10); } catch (SecurityException e) { if (succeeds) { System.out.println("FAILED"); @@ -362,8 +365,12 @@ } public static void main(String[] args) throws Exception { - initServer(); - setupProxy(); + try { + initServer(); + setupProxy(); + } catch (BindException e) { + System.exit(10); + } fileroot = System.getProperty ("test.src")+ "/docs"; int testnum = Integer.parseInt(args[0]); String policy = args[0]; @@ -382,33 +389,25 @@ runtest(tr.test, policy, tr.result); } finally { s1.stop(0); - //executor.shutdownNow(); + executor.shutdownNow(); for (HttpClient client : clients) client.executorService().shutdownNow(); } } - // create Http Server on port range below. So, we can - HttpServer createServer() { - HttpServer server; - for (int i=25800; i<26800; i++) { - InetSocketAddress a = new InetSocketAddress(i); - try { - server = HttpServer.create(a, 0); - return server; - } catch (IOException e) {} - } - return null; - } + public static void initServer() throws Exception { + String portstring = System.getProperty("port.number"); + port = portstring != null ? Integer.parseInt(portstring) : 0; + portstring = System.getProperty("port.number1"); + proxyPort = portstring != null ? Integer.parseInt(portstring) : 0; - public static void initServer() throws Exception { Logger logger = Logger.getLogger("com.sun.net.httpserver"); ConsoleHandler ch = new ConsoleHandler(); logger.setLevel(Level.ALL); ch.setLevel(Level.ALL); logger.addHandler(ch); String root = System.getProperty ("test.src")+ "/docs"; - InetSocketAddress addr = new InetSocketAddress (0); + InetSocketAddress addr = new InetSocketAddress (port); s1 = HttpServer.create (addr, 0); if (s1 instanceof HttpsServer) { throw new RuntimeException ("should not be httpsserver"); @@ -423,7 +422,13 @@ s1.setExecutor (executor); s1.start(); - port = s1.getAddress().getPort(); + if (port == 0) + port = s1.getAddress().getPort(); + else { + if (s1.getAddress().getPort() != port) + throw new RuntimeException("Error wrong port"); + System.out.println("Port was assigned by Driver"); + } System.out.println("HTTP server port = " + port); httproot = "http://127.0.0.1:" + port + "/files/"; redirectroot = "http://127.0.0.1:" + port + "/redirect/"; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/util/ResourceBundle/Bug6299235Test.sh --- a/jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Thu May 05 19:11:09 2016 +0000 @@ -68,7 +68,7 @@ ${TESTJAVA}/bin/jar xf ${TESTSRC}/awtres.jar echo -${TESTJAVA}/bin/java ${TESTVMOPTS} -Xpatch:${PATCHDIR} \ +${TESTJAVA}/bin/java ${TESTVMOPTS} -Xpatch:java.desktop=${PATCHDIR}/java.desktop \ -cp ${TESTCLASSES} Bug6299235Test if [ $? -ne 0 ] diff -r 5c95f3324916 -r 41844efbbcce jdk/test/java/util/jar/JarFile/MultiReleaseJarHttpProperties.java --- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarHttpProperties.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/java/util/jar/JarFile/MultiReleaseJarHttpProperties.java Thu May 05 19:11:09 2016 +0000 @@ -26,7 +26,7 @@ * @bug 8132734 * @summary Test the System properties for JarFile that support multi-release jar files * @library /lib/testlibrary/java/util/jar - * @build Compiler JarBuilder CreateMultiReleaseTestJars + * @build Compiler JarBuilder CreateMultiReleaseTestJars SimpleHttpServer * @run testng MultiReleaseJarHttpProperties * @run testng/othervm -Djdk.util.jar.version=0 MultiReleaseJarHttpProperties * @run testng/othervm -Djdk.util.jar.version=8 MultiReleaseJarHttpProperties @@ -43,8 +43,6 @@ * @run testng/othervm -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties */ -import com.sun.net.httpserver.*; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -73,7 +71,7 @@ @Override protected void initializeClassLoader() throws Exception { URL[] urls = new URL[]{ - new URL("http://localhost:" + server.getPort() + "/multi-release-jar") + new URL("http://localhost:" + server.getPort() + "/multi-release.jar") }; cldr = new URLClassLoader(urls); // load any class, Main is convenient and in the root entries @@ -112,45 +110,3 @@ getResource(rootClass, resource); } } - -/** - * Extremely simple server that only performs one task. The server listens for - * requests on the ephemeral port. If it sees a request that begins with - * "/multi-release-jar", it consumes the request and returns a stream of bytes - * representing the jar file multi-release.jar found in "userdir". - */ -class SimpleHttpServer { - private static final String userdir = System.getProperty("user.dir", "."); - private static final Path multirelease = Paths.get(userdir, "multi-release.jar"); - - private final HttpServer server; - - public SimpleHttpServer() throws IOException { - server = HttpServer.create(); - } - - public void start() throws IOException { - server.bind(new InetSocketAddress(0), 0); - server.createContext("/multi-release-jar", t -> { - try (InputStream is = t.getRequestBody()) { - is.readAllBytes(); // probably not necessary to consume request - byte[] bytes = Files.readAllBytes(multirelease); - t.sendResponseHeaders(200, bytes.length); - try (OutputStream os = t.getResponseBody()) { - os.write(bytes); - } - } - }); - server.setExecutor(null); // creates a default executor - server.start(); - } - - public void stop() { - server.stop(0); - } - - int getPort() { - return server.getAddress().getPort(); - } -} - diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/crypto/Cipher/CipherStreamClose.java --- a/jdk/test/javax/crypto/Cipher/CipherStreamClose.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/crypto/Cipher/CipherStreamClose.java Thu May 05 19:11:09 2016 +0000 @@ -27,6 +27,8 @@ * @summary Make sure Cipher IO streams doesn't call extra doFinal if close() * is called multiple times. Additionally, verify the input and output streams * match with encryption and decryption with non-stream crypto. + * @compile -addmods java.xml.bind CipherStreamClose.java + * @run main/othervm -addmods java.xml.bind CipherStreamClose */ import java.io.*; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java --- a/jdk/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java Thu May 05 19:11:09 2016 +0000 @@ -27,8 +27,10 @@ * @summary test RMI-IIOP call with ConcurrentHashMap as an argument * @library /lib/testlibrary * @build jdk.testlibrary.* - * @build Test HelloInterface HelloServer HelloClient HelloImpl _HelloImpl_Tie _HelloInterface_Stub ConcurrentHashMapTest - * @run main/othervm -Djava.naming.provider.url=iiop://localhost:1050 -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory ConcurrentHashMapTest + * @compile -addmods java.corba Test.java HelloInterface.java HelloServer.java HelloClient.java + * HelloImpl.java _HelloImpl_Tie.java _HelloInterface_Stub.java ConcurrentHashMapTest.java + * @run main/othervm -addmods java.corba -Djava.naming.provider.url=iiop://localhost:1050 + * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory ConcurrentHashMapTest * @key intermittent */ @@ -101,6 +103,8 @@ // -Djava.naming.provider.url=iiop://localhost:1050 HelloServer List commands = new ArrayList<>(); commands.add(ConcurrentHashMapTest.JAVA); + commands.add("-addmods"); + commands.add("java.corba"); commands.add("-Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory"); commands.add("-Djava.naming.provider.url=iiop://localhost:1050"); commands.add("-cp"); diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/smartcardio/CommandAPDUTest.java --- a/jdk/test/javax/smartcardio/CommandAPDUTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/smartcardio/CommandAPDUTest.java Thu May 05 19:11:09 2016 +0000 @@ -26,7 +26,8 @@ * @bug 8049021 * @summary Test different constructors for CommandAPDU and check CLA,INS,NC,NE, * P1,and P2 - * @run testng CommandAPDUTest + * @compile -addmods java.smartcardio CommandAPDUTest.java + * @run testng/othervm -addmods java.smartcardio CommandAPDUTest */ import java.nio.ByteBuffer; import javax.smartcardio.CommandAPDU; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/smartcardio/HistoricalBytes.java --- a/jdk/test/javax/smartcardio/HistoricalBytes.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/smartcardio/HistoricalBytes.java Thu May 05 19:11:09 2016 +0000 @@ -26,7 +26,9 @@ * @bug 6445367 * @summary Verify that ATR.getHistoricalBytes() works * @author Andreas Sterbenz -**/ + * @compile -addmods java.smartcardio HistoricalBytes.java + * @run main/othervm -addmods java.smartcardio HistoricalBytes + */ import java.util.Arrays; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/smartcardio/ResponseAPDUTest.java --- a/jdk/test/javax/smartcardio/ResponseAPDUTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/smartcardio/ResponseAPDUTest.java Thu May 05 19:11:09 2016 +0000 @@ -25,7 +25,8 @@ * @test * @bug 8049021 * @summary Construct ResponseAPDU from byte array and check NR< SW, SW1 and SW2 - * @run testng ResponseAPDUTest + * @compile -addmods java.smartcardio ResponseAPDUTest.java + * @run testng/othervm -addmods java.smartcardio ResponseAPDUTest */ import javax.smartcardio.ResponseAPDU; import static org.testng.Assert.*; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/smartcardio/Serialize.java --- a/jdk/test/javax/smartcardio/Serialize.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/smartcardio/Serialize.java Thu May 05 19:11:09 2016 +0000 @@ -26,6 +26,8 @@ * @bug 6445367 * @summary make sure serialization works * @author Andreas Sterbenz + * @compile -addmods java.smartcardio Serialize.java + * @run main/othervm -addmods java.smartcardio Serialize */ import java.io.*; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/smartcardio/TerminalFactorySpiTest.java --- a/jdk/test/javax/smartcardio/TerminalFactorySpiTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/smartcardio/TerminalFactorySpiTest.java Thu May 05 19:11:09 2016 +0000 @@ -25,7 +25,8 @@ * @test * @bug 8049021 * @summary Test if we can write new provider for smart card - * @run main/othervm/policy=policy TerminalFactorySpiTest + * @compile -addmods java.smartcardio TerminalFactorySpiTest.java + * @run main/othervm/policy=policy -addmods java.smartcardio TerminalFactorySpiTest */ import java.security.Provider; import java.security.Security; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/smartcardio/TestCardPermission.java --- a/jdk/test/javax/smartcardio/TestCardPermission.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/smartcardio/TestCardPermission.java Thu May 05 19:11:09 2016 +0000 @@ -26,6 +26,8 @@ * @bug 6293767 * @summary Test for the CardPermission class * @author Andreas Sterbenz + * @compile -addmods java.smartcardio TestCardPermission.java + * @run main/othervm -addmods java.smartcardio TestCardPermission */ import javax.smartcardio.*; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/smartcardio/TestCommandAPDU.java --- a/jdk/test/javax/smartcardio/TestCommandAPDU.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/smartcardio/TestCommandAPDU.java Thu May 05 19:11:09 2016 +0000 @@ -27,6 +27,8 @@ * @summary Test for the CommandAPDU class * @author Andreas Sterbenz * @key randomness + * @compile -addmods java.smartcardio TestCommandAPDU.java + * @run main/othervm -addmods java.smartcardio TestCommandAPDU */ import java.util.*; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/transaction/testng/Driver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/transaction/testng/Driver.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @compile -addmods java.transaction + * test/transaction/InvalidTransactionExceptionTests.java + * test/transaction/TransactionRequiredExceptionTests.java + * test/transaction/TransactionRolledbackExceptionTests.java + * test/transaction/XAExceptionTests.java + * util/SerializedTransactionExceptions.java + * @run testng/othervm -addmods java.transaction test.transaction.InvalidTransactionExceptionTests + * @run testng/othervm -addmods java.transaction test.transaction.TransactionRequiredExceptionTests + * @run testng/othervm -addmods java.transaction test.transaction.TransactionRolledbackExceptionTests + * @run testng/othervm -addmods java.transaction util.SerializedTransactionExceptions + */ diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/transaction/testng/TEST.properties --- a/jdk/test/javax/transaction/testng/TEST.properties Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -# JDBC unit tests uses TestNG -TestNG.dirs= . -othervm.dirs= . - diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/xml/bind/xjc/8032884/XjcOptionalPropertyTest.java --- a/jdk/test/javax/xml/bind/xjc/8032884/XjcOptionalPropertyTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/xml/bind/xjc/8032884/XjcOptionalPropertyTest.java Thu May 05 19:11:09 2016 +0000 @@ -26,6 +26,7 @@ * @bug 8032884 * @summary Globalbindings optionalProperty="primitive" does not work when minOccurs=0 * @run shell compile-schema.sh + * @compile -addmods java.xml.bind XjcOptionalPropertyTest.java * @run main/othervm XjcOptionalPropertyTest */ diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/xml/jaxp/common/8035437/run.sh --- a/jdk/test/javax/xml/jaxp/common/8035437/run.sh Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/xml/jaxp/common/8035437/run.sh Thu May 05 19:11:09 2016 +0000 @@ -34,12 +34,12 @@ -d compile/java.xml -Xmodule:java.xml $TESTSRC/Document.java $TESTSRC/Node.java || exit 1 $COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ - -d exec/java.xml -Xpatch:compile -Xmodule:java.xml $TESTSRC/DocumentImpl.java || exit 2 + -d exec/java.xml -Xpatch:java.xml=compile/java.xml -Xmodule:java.xml $TESTSRC/DocumentImpl.java || exit 2 $COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ $TESTSRC/AbstractMethodErrorTest.java -d exec || exit 3 -$TESTJAVA/bin/java ${TESTVMOPTS} -Xpatch:exec -cp exec AbstractMethodErrorTest || exit 4 +$TESTJAVA/bin/java ${TESTVMOPTS} -Xpatch:java.xml=exec -cp exec AbstractMethodErrorTest || exit 4 exit 0 diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/xml/soap/XmlTest.java --- a/jdk/test/javax/xml/soap/XmlTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/xml/soap/XmlTest.java Thu May 05 19:11:09 2016 +0000 @@ -38,6 +38,8 @@ /* * @test + * @compile -addmods java.xml.ws XmlTest.java + * @run main/othervm -addmods java.xml.ws XmlTest * @summary tests JAF DataHandler can be instantiated; test serialize and * deserialize SOAP message containing xml attachment */ diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/xml/soap/spi/SAAJFactoryTest.java --- a/jdk/test/javax/xml/soap/spi/SAAJFactoryTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/xml/soap/spi/SAAJFactoryTest.java Thu May 05 19:11:09 2016 +0000 @@ -49,29 +49,29 @@ * run main/othervm SAAJFactoryTest saaj.factory.Valid - * scenario14 javax.xml.soap.MessageFactory=saaj.factory.Valid saaj.factory.Valid2 - * - * @build saaj.factory.* + * @compile -addmods java.xml.ws saaj/factory/Invalid.java saaj/factory/Valid.java + * saaj/factory/Valid2.java saaj/factory/Valid3.java SAAJFactoryTest.java * - * @run main/othervm SAAJFactoryTest com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl - - * scenario2 - - - * @run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.Valid SAAJFactoryTest saaj.factory.Valid - - * scenario5 - - - * @run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.NonExisting SAAJFactoryTest - * - javax.xml.soap.SOAPException - * scenario6 - - - * @run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.Invalid SAAJFactoryTest - javax.xml.soap.SOAPException - * scenario7 - - - * @run main/othervm SAAJFactoryTest saaj.factory.Valid - - * scenario8 - saaj.factory.Valid - * @run main/othervm SAAJFactoryTest saaj.factory.Valid - - * scenario9 - saaj.factory.Valid - * @run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException - * scenario10 - saaj.factory.NonExisting - * @run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException - * scenario11 - saaj.factory.Invalid - * @run main/othervm SAAJFactoryTest com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl - - * scenario12 - - - * @run main/othervm SAAJFactoryTest saaj.factory.Valid - - * scenario15 - saaj.factory.Valid + * @run main/othervm -addmods java.xml.ws + * SAAJFactoryTest com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl - scenario2 - - + * @run main/othervm -addmods java.xml.ws -Djavax.xml.soap.MessageFactory=saaj.factory.Valid + * SAAJFactoryTest saaj.factory.Valid - scenario5 - - + * @run main/othervm -addmods java.xml.ws -Djavax.xml.soap.MessageFactory=saaj.factory.NonExisting + * SAAJFactoryTest - javax.xml.soap.SOAPException scenario6 - - + * @run main/othervm -addmods java.xml.ws -Djavax.xml.soap.MessageFactory=saaj.factory.Invalid + * SAAJFactoryTest - javax.xml.soap.SOAPException scenario7 - - + * @run main/othervm -addmods java.xml.ws + * SAAJFactoryTest saaj.factory.Valid - scenario8 - saaj.factory.Valid + * @run main/othervm -addmods java.xml.ws + * SAAJFactoryTest saaj.factory.Valid - scenario9 - saaj.factory.Valid + * @run main/othervm -addmods java.xml.ws + * SAAJFactoryTest - javax.xml.soap.SOAPException scenario10 - saaj.factory.NonExisting + * @run main/othervm -addmods java.xml.ws + * SAAJFactoryTest - javax.xml.soap.SOAPException scenario11 - saaj.factory.Invalid scenario11 - saaj.factory.Invalid + * @run main/othervm -addmods java.xml.ws + * SAAJFactoryTest com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl - scenario12 - - + * @run main/othervm -addmods java.xml.ws + * SAAJFactoryTest saaj.factory.Valid - scenario15 - saaj.factory.Valid */ public class SAAJFactoryTest { diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/xml/ws/8043129/MailTest.java --- a/jdk/test/javax/xml/ws/8043129/MailTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/xml/ws/8043129/MailTest.java Thu May 05 19:11:09 2016 +0000 @@ -27,8 +27,8 @@ * @summary JAF initialisation in SAAJ clashing with the one in javax.mail * @author mkos * @library javax.mail.jar - * @build MailTest - * @run main MailTest + * @compile -addmods java.xml.ws MailTest.java + * @run main/othervm -addmods java.xml.ws MailTest */ import javax.activation.CommandMap; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/xml/ws/clientjar/TestWsImport.java --- a/jdk/test/javax/xml/ws/clientjar/TestWsImport.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/xml/ws/clientjar/TestWsImport.java Thu May 05 19:11:09 2016 +0000 @@ -25,7 +25,8 @@ * @test * @bug 8016271 8026405 * @summary wsimport -clientjar does not create portable jar on windows due to hardcoded '\' - * @run main/othervm TestWsImport + * @compile -addmods java.xml.ws TestWsImport.java + * @run main/othervm -addmods java.xml.ws TestWsImport */ import javax.xml.namespace.QName; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/xml/ws/publish/WSTest.java --- a/jdk/test/javax/xml/ws/publish/WSTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/xml/ws/publish/WSTest.java Thu May 05 19:11:09 2016 +0000 @@ -25,7 +25,8 @@ * @test * @bug 8146086 * @summary Publishing two webservices on same port fails with "java.net.BindException: Address already in use" - * @run main/othervm WSTest + * @compile -addmods java.xml.ws WSTest.java + * @run main/othervm -addmods java.xml.ws WSTest */ import javax.jws.WebMethod; import javax.jws.WebService; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/javax/xml/ws/xsanymixed/Test.java --- a/jdk/test/javax/xml/ws/xsanymixed/Test.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/javax/xml/ws/xsanymixed/Test.java Thu May 05 19:11:09 2016 +0000 @@ -27,7 +27,8 @@ * @summary the content of xs:any content:mixed should remain as is, * no white space changes and no changes to namespace prefixes * @run shell compile-wsdl.sh - * @run main/othervm Test + * @compile -addmods java.xml.ws Test.java + * @run main/othervm -addmods java.xml.ws Test */ import com.sun.net.httpserver.HttpServer; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/lib/testlibrary/java/util/jar/SimpleHttpServer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/lib/testlibrary/java/util/jar/SimpleHttpServer.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.net.httpserver.*; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Extremely simple server that only performs one task. The server listens for + * requests on the ephemeral port. If it sees a request that begins with + * "/multi-release.jar", it consumes the request and returns a stream of bytes + * representing the jar file multi-release.jar found in "userdir". + */ +class SimpleHttpServer { + private static final String userdir = System.getProperty("user.dir", "."); + private static final Path multirelease = Paths.get(userdir, "multi-release.jar"); + + private final HttpServer server; + + public SimpleHttpServer() throws IOException { + server = HttpServer.create(); + } + + public void start() throws IOException { + server.bind(new InetSocketAddress(0), 0); + server.createContext("/multi-release.jar", t -> { + try (InputStream is = t.getRequestBody()) { + is.readAllBytes(); // probably not necessary to consume request + byte[] bytes = Files.readAllBytes(multirelease); + t.sendResponseHeaders(200, bytes.length); + try (OutputStream os = t.getResponseBody()) { + os.write(bytes); + } + } + }); + server.setExecutor(null); // creates a default executor + server.start(); + } + + public void stop() { + server.stop(0); + } + + int getPort() { + return server.getAddress().getPort(); + } +} + diff -r 5c95f3324916 -r 41844efbbcce jdk/test/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java --- a/jdk/test/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java Thu May 05 19:11:09 2016 +0000 @@ -26,19 +26,25 @@ * @bug 8132734 * @summary Test that URL connections to multi-release jars can be runtime versioned * @library /lib/testlibrary/java/util/jar - * @build Compiler JarBuilder CreateMultiReleaseTestJars + * @build Compiler JarBuilder CreateMultiReleaseTestJars SimpleHttpServer * @run testng MultiReleaseJarURLConnection */ import java.io.IOException; import java.io.InputStream; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.net.JarURLConnection; import java.net.URL; +import java.net.URLClassLoader; import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Paths; import java.util.jar.JarFile; +import jdk.Version; + import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -47,46 +53,78 @@ public class MultiReleaseJarURLConnection { String userdir = System.getProperty("user.dir","."); - String file = userdir + "/signed-multi-release.jar"; + String unversioned = userdir + "/unversioned.jar"; + String unsigned = userdir + "/multi-release.jar"; + String signed = userdir + "/signed-multi-release.jar"; + SimpleHttpServer server; @BeforeClass public void initialize() throws Exception { CreateMultiReleaseTestJars creator = new CreateMultiReleaseTestJars(); creator.compileEntries(); + creator.buildUnversionedJar(); creator.buildMultiReleaseJar(); creator.buildSignedMultiReleaseJar(); + + server = new SimpleHttpServer(); + server.start(); + } @AfterClass public void close() throws IOException { - Files.delete(Paths.get(userdir, "multi-release.jar")); - Files.delete(Paths.get(userdir, "signed-multi-release.jar")); + // Windows requires server to stop before file is deleted + if (server != null) + server.stop(); + Files.delete(Paths.get(unversioned)); + Files.delete(Paths.get(unsigned)); + Files.delete(Paths.get(signed)); } @DataProvider(name = "data") public Object[][] createData() { return new Object[][]{ - {"unsigned file", userdir + "/multi-release.jar"}, - {"signed file", userdir + "/signed-multi-release.jar"}, + {"unversioned", unversioned}, + {"unsigned", unsigned}, + {"signed", signed} }; } @Test(dataProvider = "data") - public void testRuntimeVersioning(String ignore, String file) throws Exception { + public void testRuntimeVersioning(String style, String file) throws Exception { String urlFile = "jar:file:" + file + "!/"; - String urlEntry = urlFile + "version/Version.java"; + String baseUrlEntry = urlFile + "version/Version.java"; + String rtreturn = "return " + Version.current().major(); + + Assert.assertTrue(readAndCompare(new URL(baseUrlEntry), "return 8")); + // #runtime is "magic" for a multi-release jar, but not for unversioned jar + Assert.assertTrue(readAndCompare(new URL(baseUrlEntry + "#runtime"), + style.equals("unversioned") ? "return 8" : rtreturn)); + // #fragment or any other fragment is not magic + Assert.assertTrue(readAndCompare(new URL(baseUrlEntry + "#fragment"), "return 8")); + // cached entities not affected + Assert.assertTrue(readAndCompare(new URL(baseUrlEntry), "return 8")); - Assert.assertTrue(readAndCompare(new URL(urlEntry), "return 8")); - // #runtime is "magic" - Assert.assertTrue(readAndCompare(new URL(urlEntry + "#runtime"), "return 9")); - // #fragment or any other fragment is not magic - Assert.assertTrue(readAndCompare(new URL(urlEntry + "#fragment"), "return 8")); - // cached entities not affected - Assert.assertTrue(readAndCompare(new URL(urlEntry), "return 8")); + // the following tests will not work with unversioned jars + if (style.equals("unversioned")) return; + + // direct access to versioned entry + String versUrlEntry = urlFile + "META-INF/versions/" + Version.current().major() + + "/version/Version.java"; + Assert.assertTrue(readAndCompare(new URL(versUrlEntry), rtreturn)); + // adding any fragment does not change things + Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#runtime"), rtreturn)); + Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#fragment"), rtreturn)); + + // it really doesn't change things + versUrlEntry = urlFile + "META-INF/versions/10/version/Version.java"; + Assert.assertTrue(readAndCompare(new URL(versUrlEntry), "return 10")); + Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#runtime"), "return 10")); + Assert.assertTrue(readAndCompare(new URL(versUrlEntry + "#fragment"), "return 10")); } @Test(dataProvider = "data") - public void testCachedJars(String ignore, String file) throws Exception { + public void testCachedJars(String style, String file) throws Exception { String urlFile = "jar:file:" + file + "!/"; URL rootUrl = new URL(urlFile); @@ -98,7 +136,11 @@ juc = (JarURLConnection)runtimeUrl.openConnection(); JarFile runtimeJar = juc.getJarFile(); JarFile.Release runtime = runtimeJar.getVersion(); - Assert.assertNotEquals(root, runtime); + if (style.equals("unversioned")) { + Assert.assertEquals(root, runtime); + } else { + Assert.assertNotEquals(root, runtime); + } juc = (JarURLConnection)rootUrl.openConnection(); JarFile jar = juc.getJarFile(); @@ -115,6 +157,63 @@ jar.close(); // probably not needed } + @DataProvider(name = "resourcedata") + public Object[][] createResourceData() throws Exception { + return new Object[][]{ + {"unversioned", Paths.get(unversioned).toUri().toURL()}, + {"unsigned", Paths.get(unsigned).toUri().toURL()}, + {"signed", Paths.get(signed).toUri().toURL()}, + {"unversioned", new URL("file:" + unversioned)}, + {"unsigned", new URL("file:" + unsigned)}, + {"signed", new URL("file:" + signed)}, + {"unversioned", new URL("jar:file:" + unversioned + "!/")}, + {"unsigned", new URL("jar:file:" + unsigned + "!/")}, + {"signed", new URL("jar:file:" + signed + "!/")}, + // external jar received via http protocol + {"http", new URL("jar:http://localhost:" + server.getPort() + "/multi-release.jar!/")}, + {"http", new URL("http://localhost:" + server.getPort() + "/multi-release.jar")}, + + }; + } + + @Test(dataProvider = "resourcedata") + public void testResources(String style, URL url) throws Throwable { + //System.out.println(" testing " + style + " url: " + url); + URL[] urls = {url}; + URLClassLoader cldr = new URLClassLoader(urls); + Class vcls = cldr.loadClass("version.Version"); + + // verify we are loading a runtime versioned class + MethodType mt = MethodType.methodType(int.class); + MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt); + Assert.assertEquals((int)mh.invoke(vcls.newInstance()), + style.equals("unversioned") ? 8 : Version.current().major()); + + // now get a resource and verify that we don't have a fragment attached + URL vclsUrl = vcls.getResource("/version/Version.class"); + String fragment = vclsUrl.getRef(); + Assert.assertNull(fragment); + + // and verify that the the url is a reified pointer to the runtime entry + String rep = vclsUrl.toString(); + //System.out.println(" getResource(\"/version/Version.class\") returned: " + rep); + if (style.equals("http")) { + Assert.assertTrue(rep.startsWith("jar:http:")); + } else { + Assert.assertTrue(rep.startsWith("jar:file:")); + } + String suffix; + if (style.equals("unversioned")) { + suffix = ".jar!/version/Version.class"; + } else { + suffix = ".jar!/META-INF/versions/" + Version.current().major() + + "/version/Version.class"; + } + Assert.assertTrue(rep.endsWith(suffix)); + cldr.close(); + } + + private boolean readAndCompare(URL url, String match) throws Exception { boolean result; // necessary to do it this way, instead of openStream(), so we can diff -r 5c95f3324916 -r 41844efbbcce jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.java --- a/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.java Thu May 05 19:11:09 2016 +0000 @@ -26,7 +26,6 @@ import java.security.*; import javax.crypto.*; import javax.crypto.spec.*; -import javax.xml.bind.DatatypeConverter; public class SecretKeysBasic extends PKCS11Test { @@ -131,8 +130,11 @@ System.out.println(info + "> " + key); System.out.println("\tALGO=" + key.getAlgorithm()); if (key.getFormat() != null) { - System.out.println("\t[" + key.getFormat() + "] VALUE=" + - DatatypeConverter.printHexBinary(key.getEncoded())); + StringBuilder sb = new StringBuilder(); + for (byte b : key.getEncoded()) { + sb.append(String.format("%02x", b & 0xff)); + } + System.out.println("\t[" + key.getFormat() + "] VALUE=" + sb); } else { System.out.println("\tVALUE=n/a"); } diff -r 5c95f3324916 -r 41844efbbcce jdk/test/sun/security/provider/PolicyFile/Modules.java --- a/jdk/test/sun/security/provider/PolicyFile/Modules.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/sun/security/provider/PolicyFile/Modules.java Thu May 05 19:11:09 2016 +0000 @@ -25,7 +25,9 @@ * @test * @bug 8047771 * @summary check permissions and principals from various modules - * @run main/othervm/java.security.policy==modules.policy Modules + * @compile -addmods java.xml.ws,java.smartcardio Modules.java + * @run main/othervm/java.security.policy==modules.policy + * -addmods java.xml.ws,java.smartcardio Modules */ import java.security.AccessController; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jar/modularJar/Basic.java --- a/jdk/test/tools/jar/modularJar/Basic.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/jar/modularJar/Basic.java Thu May 05 19:11:09 2016 +0000 @@ -340,43 +340,43 @@ "--file=" + modularJar.toString()) .assertSuccess() .resultChecker(r -> { - // Expect similar output: "Name:bar, Requires: foo,... - // Conceals: jdk.test.foo, jdk.test.foo.internal" - Pattern p = Pattern.compile("\\s+Name:\\s+bar\\s+Requires:\\s+foo"); + // Expect similar output: "bar, requires mandated foo, ... + // conceals jdk.test.foo, conceals jdk.test.foo.internal" + Pattern p = Pattern.compile("\\s+bar\\s+requires\\s++foo"); assertTrue(p.matcher(r.output).find(), - "Expecting to find \"Name: bar, Requires: foo,...\"", + "Expecting to find \"bar, requires foo,...\"", "in output, but did not: [" + r.output + "]"); p = Pattern.compile( - "Conceals:\\s+jdk.test.foo\\s+jdk.test.foo.internal"); + "conceals\\s+jdk.test.foo\\s+conceals\\s+jdk.test.foo.internal"); assertTrue(p.matcher(r.output).find(), - "Expecting to find \"Conceals: jdk.test.foo,...\"", + "Expecting to find \"conceals jdk.test.foo,...\"", "in output, but did not: [" + r.output + "]"); }); } @Test - public void dependencesFooBar() throws IOException { + public void hashBarInFooModule() throws IOException { Path mp = Paths.get("dependencesFooBar"); createTestDir(mp); - Path modClasses = MODULE_CLASSES.resolve(FOO.moduleName); - Path modularJar = mp.resolve(FOO.moduleName + ".jar"); + Path modClasses = MODULE_CLASSES.resolve(BAR.moduleName); + Path modularJar = mp.resolve(BAR.moduleName + ".jar"); + jar("--create", + "--file=" + modularJar.toString(), + "--main-class=" + BAR.mainClass, + "--module-version=" + BAR.version, + "--no-manifest", + "-C", modClasses.toString(), ".") + .assertSuccess(); + + modClasses = MODULE_CLASSES.resolve(FOO.moduleName); + modularJar = mp.resolve(FOO.moduleName + ".jar"); jar("--create", "--file=" + modularJar.toString(), "--main-class=" + FOO.mainClass, "--module-version=" + FOO.version, - "--no-manifest", - "-C", modClasses.toString(), ".") - .assertSuccess(); - - modClasses = MODULE_CLASSES.resolve(BAR.moduleName); - modularJar = mp.resolve(BAR.moduleName + ".jar"); - jar("--create", - "--file=" + modularJar.toString(), - "--main-class=" + BAR.mainClass, - "--module-version=" + BAR.version, "--modulepath=" + mp.toString(), - "--hash-dependencies=" + "foo", // dependency on foo + "--hash-modules=" + "bar", "--no-manifest", "-C", modClasses.toString(), ".") .assertSuccess(); @@ -392,49 +392,49 @@ } @Test - public void badDependencyFooBar() throws IOException { + public void invalidHashInFooModule() throws IOException { Path mp = Paths.get("badDependencyFooBar"); createTestDir(mp); - Path fooClasses = MODULE_CLASSES.resolve(FOO.moduleName); - Path fooJar = mp.resolve(FOO.moduleName + ".jar"); - jar("--create", - "--file=" + fooJar.toString(), - "--main-class=" + FOO.mainClass, - "--module-version=" + FOO.version, - "--no-manifest", - "-C", fooClasses.toString(), ".").assertSuccess(); - Path barClasses = MODULE_CLASSES.resolve(BAR.moduleName); Path barJar = mp.resolve(BAR.moduleName + ".jar"); jar("--create", "--file=" + barJar.toString(), "--main-class=" + BAR.mainClass, "--module-version=" + BAR.version, - "--modulepath=" + mp.toString(), - "--hash-dependencies=" + "foo", // dependency on foo "--no-manifest", "-C", barClasses.toString(), ".").assertSuccess(); - // Rebuild foo.jar with a change that will cause its hash to be different - FileUtils.deleteFileWithRetry(fooJar); + Path fooClasses = MODULE_CLASSES.resolve(FOO.moduleName); + Path fooJar = mp.resolve(FOO.moduleName + ".jar"); jar("--create", "--file=" + fooJar.toString(), "--main-class=" + FOO.mainClass, - "--module-version=" + FOO.version + ".1", // a newer version + "--module-version=" + FOO.version, + "--modulepath=" + mp.toString(), + "--hash-modules=" + "bar", "--no-manifest", "-C", fooClasses.toString(), ".").assertSuccess(); + // Rebuild bar.jar with a change that will cause its hash to be different + FileUtils.deleteFileWithRetry(barJar); + jar("--create", + "--file=" + barJar.toString(), + "--main-class=" + BAR.mainClass, + "--module-version=" + BAR.version + ".1", // a newer version + "--no-manifest", + "-C", barClasses.toString(), ".").assertSuccess(); + java(mp, BAR.moduleName + "/" + BAR.mainClass, "-XaddExports:java.base/jdk.internal.module=bar") .assertFailure() .resultChecker(r -> { // Expect similar output: "java.lang.module.ResolutionException: Hash - // of foo (WdktSIQSkd4+CEacpOZoeDrCosMATNrIuNub9b5yBeo=) differs to + // of bar (WdktSIQSkd4+CEacpOZoeDrCosMATNrIuNub9b5yBeo=) differs to // expected hash (iepvdv8xTeVrFgMtUhcFnmetSub6qQHCHc92lSaSEg0=)" - Pattern p = Pattern.compile(".*Hash of foo.*differs to expected hash.*"); + Pattern p = Pattern.compile(".*Hash of bar.*differs to expected hash.*"); assertTrue(p.matcher(r.output).find(), - "Expecting error message containing \"Hash of foo ... differs to" + "Expecting error message containing \"Hash of bar ... differs to" + " expected hash...\" but got: [", r.output + "]"); }); } @@ -454,7 +454,7 @@ jar("--create", "--file=" + modularJar.toString(), - "--hash-dependencies=" + ".*", // no module-info.class + "--hash-modules=" + ".*", // no module-info.class "-C", modClasses.toString(), "jdk") .assertFailure(); // TODO: expected failure message } diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jar/modularJar/src/bar/jdk/test/bar/Bar.java --- a/jdk/test/tools/jar/modularJar/src/bar/jdk/test/bar/Bar.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/jar/modularJar/src/bar/jdk/test/bar/Bar.java Thu May 05 19:11:09 2016 +0000 @@ -30,7 +30,7 @@ import java.util.Optional; import java.util.StringJoiner; -import jdk.internal.module.Hasher; +import jdk.internal.module.ModuleHashes; import jdk.test.bar.internal.Message; public class Bar { @@ -43,10 +43,11 @@ Method m = ModuleDescriptor.class.getDeclaredMethod("hashes"); m.setAccessible(true); - Optional optHashes = - (Optional) m.invoke(md); + ModuleDescriptor foo = jdk.test.foo.Foo.class.getModule().getDescriptor(); + Optional oHashes = + (Optional) m.invoke(foo); - System.out.println("hashes:" + optHashes.get().hashFor("foo")); + System.out.println("hashes:" + oHashes.get().hashFor("bar")); StringJoiner sj = new StringJoiner(","); md.conceals().forEach(sj::add); diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/ImageFileCreatorTest.java --- a/jdk/test/tools/jlink/ImageFileCreatorTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/jlink/ImageFileCreatorTest.java Thu May 05 19:11:09 2016 +0000 @@ -214,14 +214,12 @@ } @Override - public void storeFiles(Pool content, String bom) { - + public void storeFiles(Pool content) { } - }; ImagePluginStack stack = new ImagePluginStack(noopBuilder, Collections.emptyList(), - null, Collections.emptyList(), ""); + null, Collections.emptyList()); ImageFileCreator.create(archives, ByteOrder.nativeOrder(), stack); } diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/IntegrationTest.java --- a/jdk/test/tools/jlink/IntegrationTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/jlink/IntegrationTest.java Thu May 05 19:11:09 2016 +0000 @@ -241,7 +241,7 @@ lst.add(new MyPostProcessor()); } // Image builder - DefaultImageBuilder builder = new DefaultImageBuilder(true, output); + DefaultImageBuilder builder = new DefaultImageBuilder(output); PluginsConfiguration plugins = new Jlink.PluginsConfiguration(lst, builder, null); @@ -254,10 +254,6 @@ if (!jimage.exists()) { throw new AssertionError("jimage not generated"); } - File bom = new File(output.toString(), "bom"); - if (!bom.exists()) { - throw new AssertionError("bom not generated"); - } File release = new File(output.toString(), "release"); if (!release.exists()) { throw new AssertionError("release not generated"); @@ -311,7 +307,7 @@ } // Image builder - DefaultImageBuilder builder = new DefaultImageBuilder(false, output); + DefaultImageBuilder builder = new DefaultImageBuilder(output); PluginsConfiguration plugins = new Jlink.PluginsConfiguration(lst, builder, null); @@ -359,7 +355,7 @@ } // Image builder - DefaultImageBuilder builder = new DefaultImageBuilder(false, output); + DefaultImageBuilder builder = new DefaultImageBuilder(output); PluginsConfiguration plugins = new Jlink.PluginsConfiguration(lst, builder, null); boolean failed = false; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/JLink2Test.java --- a/jdk/test/tools/jlink/JLink2Test.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/jlink/JLink2Test.java Thu May 05 19:11:09 2016 +0000 @@ -66,8 +66,6 @@ // This test case must be first one, the JlinkTask is clean // and reveals possible bug related to plugin options in defaults - // e. g.: --genbom - testBomFile(helper); testSameNames(helper); testModulePath(helper); testOptions(); @@ -136,35 +134,6 @@ validator.validate(); } - private static void testBomFile(Helper helper) throws Exception { - String[] userOptions = { - "--compress", - "2", - "--addmods", - "bomzip", - "--strip-debug", - "--genbom", - "--exclude-resources", - "*.jcov,*/META-INF/*"}; - String moduleName = "bomzip"; - helper.generateDefaultJModule(moduleName, "composite2"); - Path imgDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); - helper.checkImage(imgDir, moduleName, userOptions, null, null); - File bom = new File(imgDir.toFile(), "bom"); - if (!bom.exists()) { - throw new RuntimeException(bom.getAbsolutePath() + " not generated"); - } - String bomcontent = new String(Files.readAllBytes(bom.toPath())); - if (!bomcontent.contains("--strip-debug") - || !bomcontent.contains("--compress") - || !bomcontent.contains("--genbom") - || !bomcontent.contains("--exclude-resources *.jcov," - + "*/META-INF/*") - || !bomcontent.contains("--addmods bomzip")) { - throw new Exception("Not expected content in " + bom); - } - } - private static void testOptions() throws Exception { List builtInPlugins = new ArrayList<>(); builtInPlugins.addAll(PluginRepository.getPlugins(Layer.boot())); diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/JLinkTest.java --- a/jdk/test/tools/jlink/JLinkTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/jlink/JLinkTest.java Thu May 05 19:11:09 2016 +0000 @@ -204,7 +204,7 @@ String[] userOptions = {"--compress", "invalid"}; String moduleName = "invalidCompressLevel"; helper.generateDefaultJModule(moduleName, "composite2"); - helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: Invalid level invalid"); + helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: Invalid compression level invalid"); } // @file diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/HashesTest.java --- a/jdk/test/tools/jlink/hashes/HashesTest.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -/** - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @summary Test the recording and checking of dependency hashes - * @author Andrei Eremeev - * @library /lib/testlibrary - * @modules java.base/jdk.internal.module - * jdk.jlink/jdk.tools.jlink - * jdk.jlink/jdk.tools.jmod - * jdk.compiler - * @ignore - * @build jdk.testlibrary.ProcessTools jdk.testlibrary.OutputAnalyzer CompilerUtils - * @run main HashesTest - */ - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import jdk.testlibrary.OutputAnalyzer; -import jdk.testlibrary.ProcessTools; - -public class HashesTest { - - private final Path jdkHome = Paths.get(System.getProperty("test.jdk")); - private final Path stdJmods = jdkHome.resolve("jmods"); - private final Path testSrc = Paths.get(System.getProperty("test.src")); - private final Path modSrc = testSrc.resolve("src"); - private final Path newModSrc = testSrc.resolve("newsrc"); - private final Path classes = Paths.get("classes"); - private final Path jmods = Paths.get("jmods"); - - public static void main(String[] args) throws Exception { - new HashesTest().run(); - } - - private void run() throws Exception { - if (!Files.exists(stdJmods)) { - return; - } - Files.createDirectories(jmods); - Path m1Classes = classes.resolve("m1"); - Path m2Classes = classes.resolve("m2"); - Path m3Classes = classes.resolve("not_matched"); - // build the second module - compileClasses(modSrc, m2Classes); - runJmod(m2Classes.toString(), m2Classes.getFileName().toString()); - - // build the third module - compileClasses(modSrc, m3Classes); - runJmod(m3Classes.toString(), m3Classes.getFileName().toString()); - - compileClasses(modSrc, m1Classes, "-mp", jmods.toString()); - runJmod(m1Classes.toString(), m1Classes.getFileName().toString(), - "--modulepath", jmods.toString(), "--hash-dependencies", "m2"); - runJava(0, "-mp", jmods.toString(), "-m", "m1/org.m1.Main"); - - deleteDirectory(m3Classes); - Files.delete(jmods.resolve("not_matched.jmod")); - - // build the new third module - compileClasses(newModSrc, m3Classes); - runJmod(m3Classes.toString(), m3Classes.getFileName().toString()); - runJava(0, "-mp", jmods.toString(), "-m", "m1/org.m1.Main"); - - deleteDirectory(m2Classes); - Files.delete(jmods.resolve("m2.jmod")); - - compileClasses(newModSrc, m2Classes); - runJmod(m2Classes.toString(), m2Classes.getFileName().toString()); - - runJava(1, "-mp", jmods.toString(), "-m", "m1/org.m1.Main"); - - if (jdk.tools.jlink.internal.Main.run(new String[]{ - "--modulepath", stdJmods.toString() + File.pathSeparator + jmods.toString(), - "--addmods", "m1", "--output", "myimage"}, new PrintWriter(System.out)) == 0) { - throw new AssertionError("Expected failure. rc = 0"); - } - } - - private void deleteDirectory(Path dir) throws IOException { - Files.walkFileTree(dir, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); - } - - private void runJava(int expectedExitCode, String... args) throws Exception { - OutputAnalyzer analyzer = ProcessTools.executeTestJava(args); - if (analyzer.getExitValue() != expectedExitCode) { - throw new AssertionError("Expected exit code: " + expectedExitCode + - ", got: " + analyzer.getExitValue()); - } - } - - private void compileClasses(Path src, Path output, String... options) throws IOException { - List args = new ArrayList<>(); - Collections.addAll(args, options); - Collections.addAll(args, "-d", output.toString()); - args.add(src.toString()); - System.out.println("javac options: " + args.stream().collect(Collectors.joining(" "))); - if (!CompilerUtils.compile(src.resolve(output.getFileName()), output, options)) { - throw new AssertionError("Compilation failure. See log."); - } - } - - private void runJmod(String cp, String modName, String... options) { - List args = new ArrayList<>(); - args.add("create"); - Collections.addAll(args, options); - Collections.addAll(args, "--class-path", cp, - jmods + File.separator + modName + ".jmod"); - int rc = jdk.tools.jmod.Main.run(args.toArray(new String[args.size()]), System.out); - System.out.println("jmod options: " + args.stream().collect(Collectors.joining(" "))); - if (rc != 0) { - throw new AssertionError("Jmod failed: rc = " + rc); - } - } -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/newsrc/m2/module-info.java --- a/jdk/test/tools/jlink/hashes/newsrc/m2/module-info.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -module m2 { - exports org.m2; -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/newsrc/m2/org/m2/Util.java --- a/jdk/test/tools/jlink/hashes/newsrc/m2/org/m2/Util.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.m2; - -public class Util { - private Util() { } - - public static String timeOfDay() { - return "Time for a beer"; - } -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/newsrc/not_matched/module-info.java --- a/jdk/test/tools/jlink/hashes/newsrc/not_matched/module-info.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -module not_matched { - exports org.not_matched; -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/newsrc/not_matched/org/not_matched/Name.java --- a/jdk/test/tools/jlink/hashes/newsrc/not_matched/org/not_matched/Name.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.not_matched; - -public class Name { - private Name() { } - - public static String name() { - return "new_module"; - } -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/src/m1/module-info.java --- a/jdk/test/tools/jlink/hashes/src/m1/module-info.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -module m1 { - requires m2; - requires not_matched; -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/src/m1/org/m1/Main.java --- a/jdk/test/tools/jlink/hashes/src/m1/org/m1/Main.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.m1; - -import org.m2.Util; -import org.not_matched.Name; - -public class Main { - public static void main(String[] args) { - System.out.println(Util.timeOfDay()); - System.out.println(Name.name()); - } -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/src/m2/module-info.java --- a/jdk/test/tools/jlink/hashes/src/m2/module-info.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -module m2 { - exports org.m2; -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/src/m2/org/m2/Util.java --- a/jdk/test/tools/jlink/hashes/src/m2/org/m2/Util.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.m2; - -public class Util { - private Util() { } - - public static String timeOfDay() { - return "Time for lunch"; - } -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/src/not_matched/module-info.java --- a/jdk/test/tools/jlink/hashes/src/not_matched/module-info.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -module not_matched { - exports org.not_matched; -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/hashes/src/not_matched/org/not_matched/Name.java --- a/jdk/test/tools/jlink/hashes/src/not_matched/org/not_matched/Name.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.not_matched; - -public class Name { - private Name() { } - - public static String name() { - return "old_module"; - } -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/plugins/FileCopierPluginTest.java --- a/jdk/test/tools/jlink/plugins/FileCopierPluginTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/jlink/plugins/FileCopierPluginTest.java Thu May 05 19:11:09 2016 +0000 @@ -101,9 +101,8 @@ } Path root = new File(".").toPath(); - DefaultImageBuilder imgbuilder = new DefaultImageBuilder(false, - root); - imgbuilder.storeFiles(pool, ""); + DefaultImageBuilder imgbuilder = new DefaultImageBuilder(root); + imgbuilder.storeFiles(pool); if (lic.exists()) { File license = new File(root.toFile(), "LICENSE"); diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jlink/plugins/IncludeLocalesPluginTest.java --- a/jdk/test/tools/jlink/plugins/IncludeLocalesPluginTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/jlink/plugins/IncludeLocalesPluginTest.java Thu May 05 19:11:09 2016 +0000 @@ -36,6 +36,7 @@ /* * @test + * @bug 8152143 8152704 8155649 * @summary IncludeLocalesPlugin tests * @author Naoto Sato * @library ../../lib @@ -55,15 +56,17 @@ private final static String moduleName = "IncludeLocalesTest"; private static Helper helper; private final static int INCLUDE_LOCALES_OPTION = 0; - private final static int EXPECTED_LOCATIONS = 1; - private final static int UNEXPECTED_PATHS = 2; - private final static int AVAILABLE_LOCALES = 3; - private final static int ERROR_MESSAGE = 4; + private final static int ADDMODS_OPTION = 1; + private final static int EXPECTED_LOCATIONS = 2; + private final static int UNEXPECTED_PATHS = 3; + private final static int AVAILABLE_LOCALES = 4; + private final static int ERROR_MESSAGE = 5; private final static Object[][] testData = { // without --include-locales option: should include all locales { "", + "jdk.localedata", List.of( "/jdk.localedata/sun/text/resources/ext/FormatData_en_GB.class", "/jdk.localedata/sun/text/resources/ext/FormatData_ja.class", @@ -144,6 +147,7 @@ // All English/Japanese locales { "--include-locales=en,ja", + "jdk.localedata", List.of( "/jdk.localedata/sun/text/resources/ext/FormatData_en_GB.class", "/jdk.localedata/sun/text/resources/ext/FormatData_ja.class", @@ -174,6 +178,7 @@ // All locales in India { "--include-locales=*-IN", + "jdk.localedata", List.of( "/jdk.localedata/sun/text/resources/ext/FormatData_en_IN.class", "/jdk.localedata/sun/text/resources/ext/FormatData_hi_IN.class", @@ -201,7 +206,9 @@ }, // Thai - {"--include-locales=th", + { + "--include-locales=th", + "jdk.localedata", List.of( "/jdk.localedata/sun/text/resources/LineBreakIteratorData_th", "/jdk.localedata/sun/text/resources/thai_dict", @@ -221,7 +228,9 @@ }, // Hong Kong - {"--include-locales=zh-HK", + { + "--include-locales=zh-HK", + "jdk.localedata", List.of( "/jdk.localedata/sun/text/resources/ext/FormatData_zh.class", "/jdk.localedata/sun/text/resources/ext/FormatData_zh_HK.class", @@ -244,7 +253,9 @@ }, // Norwegian - {"--include-locales=nb,nn,no", + { + "--include-locales=nb,nn,no", + "jdk.localedata", List.of( "/jdk.localedata/sun/text/resources/ext/FormatData_no.class", "/jdk.localedata/sun/text/resources/ext/FormatData_no_NO.class", @@ -268,7 +279,9 @@ }, // Hebrew/Indonesian/Yiddish - {"--include-locales=he,id,yi", + { + "--include-locales=he,id,yi", + "jdk.localedata", List.of( "/jdk.localedata/sun/text/resources/ext/FormatData_in.class", "/jdk.localedata/sun/text/resources/ext/FormatData_in_ID.class", @@ -294,7 +307,9 @@ }, // Error case: No matching locales - {"--include-locales=xyz", + { + "--include-locales=xyz", + "jdk.localedata", null, null, null, @@ -304,7 +319,9 @@ }, // Error case: Invalid argument - {"--include-locales=en,zh_HK", + { + "--include-locales=en,zh_HK", + "jdk.localedata", null, null, null, @@ -312,6 +329,18 @@ PluginsResourceBundle.getMessage("include-locales.invalidtag"), "zh_HK")) .getMessage(), }, + + // Error case: jdk.localedata is not added + { + "--include-locales=en-US", + "java.base", + null, + null, + null, + new PluginException( + PluginsResourceBundle.getMessage("include-locales.localedatanotfound")) + .getMessage(), + }, }; public static void main(String[] args) throws Exception { @@ -328,7 +357,7 @@ Result result = JImageGenerator.getJLinkTask() .modulePath(helper.defaultModulePath()) .output(helper.createNewImageDir(moduleName)) - .addMods("jdk.localedata") + .addMods((String)data[ADDMODS_OPTION]) .option((String)data[INCLUDE_LOCALES_OPTION]) .call(); diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/JmodNegativeTest.java --- a/jdk/test/tools/jmod/JmodNegativeTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/jmod/JmodNegativeTest.java Thu May 05 19:11:09 2016 +0000 @@ -76,7 +76,7 @@ jmod() .assertFailure() .resultChecker(r -> - assertContains(r.output, "Error: one of create, list, or describe must be specified") + assertContains(r.output, "Error: one of create, list, describe, or hash must be specified") ); } @@ -85,7 +85,7 @@ jmod("badAction") .assertFailure() .resultChecker(r -> - assertContains(r.output, "Error: mode must be one of create, list, or describe") + assertContains(r.output, "Error: mode must be one of create, list, describe, or hash") ); jmod("--badOption") @@ -170,14 +170,14 @@ } @Test - public void testHashDependenciesModulePathNotSpecified() { + public void testHashModulesModulePathNotSpecified() { jmod("create", - "--hash-dependencies", "anyPattern.*", + "--hash-modules", "anyPattern.*", "output.jmod") .assertFailure() .resultChecker(r -> assertContains(r.output, "Error: --module-path must be " - +"specified when hashing dependencies") + +"specified when hashing modules") ); } @@ -317,7 +317,7 @@ } @Test - public void testDependencyNotFound() throws IOException { + public void testNoModuleHash() throws IOException { Path jmod = MODS_DIR.resolve("output.jmod"); FileUtils.deleteFileIfExistsWithRetry(jmod); Path emptyDir = Paths.get("empty"); @@ -328,13 +328,12 @@ jmod("create", "--class-path", cp, - "--hash-dependencies", ".*", + "--hash-modules", ".*", "--modulepath", emptyDir.toString(), jmod.toString()) - .assertFailure() .resultChecker(r -> - assertContains(r.output, "Hashing module foo dependencies, " - + "unable to find module java.base on module path") + assertContains(r.output, "No hashes recorded: " + + "no module specified for hashing depends on foo") ); } @@ -350,13 +349,10 @@ jmod("create", "--class-path", cp, - "--hash-dependencies", ".*", + "--hash-modules", ".*", "--modulepath", MODS_DIR.toString(), jmod.toString()) - .assertFailure() - .resultChecker(r -> - assertContains(r.output, "Error: error reading module path") - ); + .assertFailure(); } finally { FileUtils.deleteFileWithRetry(empty); } @@ -371,7 +367,7 @@ Files.createFile(file); jmod("create", - "--hash-dependencies", ".*", + "--hash-modules", ".*", "--modulepath", file.toString(), jmod.toString()) .assertFailure() @@ -388,7 +384,7 @@ List> tasks = Arrays.asList( () -> jmod("create", - "--hash-dependencies", "anyPattern", + "--hash-modules", "anyPattern", "--modulepath", "doesNotExist", "output.jmod"), () -> jmod("create", @@ -436,7 +432,7 @@ List> tasks = Arrays.asList( () -> jmod("create", - "--hash-dependencies", "anyPattern", + "--hash-modules", "anyPattern", "--modulepath","empty" + pathSeparator + "doesNotExist", "output.jmod"), () -> jmod("create", diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/hashes/HashesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jmod/hashes/HashesTest.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Test the recording and checking of module hashes + * @author Andrei Eremeev + * @library /lib/testlibrary + * @modules java.base/jdk.internal.module + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jmod + * jdk.compiler + * @build CompilerUtils + * @run testng HashesTest + */ + +import java.io.IOException; +import java.io.InputStream; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleFinder; +import java.lang.module.ModuleReader; +import java.lang.module.ModuleReference; +import java.lang.reflect.Method; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import jdk.internal.module.ConfigurableModuleFinder; +import jdk.internal.module.ModuleHashes; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class HashesTest { + + private final Path testSrc = Paths.get(System.getProperty("test.src")); + private final Path modSrc = testSrc.resolve("src"); + private final Path mods = Paths.get("mods"); + private final Path jmods = Paths.get("jmods"); + private final String[] modules = new String[] { "m1", "m2", "m3"}; + + private static Method hashesMethod; + @BeforeTest + private void setup() throws Exception { + if (Files.exists(jmods)) { + deleteDirectory(jmods); + } + Files.createDirectories(jmods); + + // build m2, m3 required by m1 + compileModule("m2", modSrc); + jmod("m2"); + + compileModule("m3", modSrc); + jmod("m3"); + + // build m1 + compileModule("m1", modSrc); + // no hash is recorded since m1 has outgoing edges + jmod("m1", "--modulepath", jmods.toString(), "--hash-modules", ".*"); + + // compile org.bar and org.foo + compileModule("org.bar", modSrc); + compileModule("org.foo", modSrc); + + try { + hashesMethod = ModuleDescriptor.class.getDeclaredMethod("hashes"); + hashesMethod.setAccessible(true); + } catch (ReflectiveOperationException x) { + throw new InternalError(x); + } + } + + @Test + public void test() throws Exception { + for (String mn : modules) { + assertFalse(hashes(mn).isPresent()); + } + + // hash m1 in m2 + jmod("m2", "--modulepath", jmods.toString(), "--hash-modules", "m1"); + checkHashes(hashes("m2").get(), "m1"); + + // hash m1 in m2 + jmod("m2", "--modulepath", jmods.toString(), "--hash-modules", ".*"); + checkHashes(hashes("m2").get(), "m1"); + + // create m2.jmod with no hash + jmod("m2"); + // run jmod hash command to hash m1 in m2 and m3 + runJmod(Arrays.asList("hash", "--modulepath", jmods.toString(), + "--hash-modules", ".*")); + checkHashes(hashes("m2").get(), "m1"); + checkHashes(hashes("m3").get(), "m1"); + + jmod("org.bar"); + jmod("org.foo"); + + jmod("org.bar", "--modulepath", jmods.toString(), "--hash-modules", "org.*"); + checkHashes(hashes("org.bar").get(), "org.foo"); + + jmod("m3", "--modulepath", jmods.toString(), "--hash-modules", ".*"); + checkHashes(hashes("m3").get(), "org.foo", "org.bar", "m1"); + } + + private void checkHashes(ModuleHashes hashes, String... hashModules) { + assertTrue(hashes.names().equals(Set.of(hashModules))); + } + + private Optional hashes(String name) throws Exception { + ModuleFinder finder = ModuleFinder.of(jmods.resolve(name + ".jmod")); + if (finder instanceof ConfigurableModuleFinder) { + ((ConfigurableModuleFinder) finder) + .configurePhase(ConfigurableModuleFinder.Phase.LINK_TIME); + } + ModuleReference mref = finder.find(name).orElseThrow(RuntimeException::new); + ModuleReader reader = mref.open(); + try (InputStream in = reader.open("module-info.class").get()) { + ModuleDescriptor md = ModuleDescriptor.read(in); + Optional hashes = + (Optional) hashesMethod.invoke(md); + System.out.format("hashes in module %s %s%n", name, + hashes.isPresent() ? "present" : "absent"); + if (hashes.isPresent()) { + hashes.get().names().stream() + .sorted() + .forEach(n -> System.out.format(" %s %s%n", n, hashes.get().hashFor(n))); + } + return hashes; + } finally { + reader.close(); + } + } + + private void deleteDirectory(Path dir) throws IOException { + Files.walkFileTree(dir, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException + { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) + throws IOException + { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } + + private void compileModule(String moduleName, Path src) throws IOException { + Path msrc = src.resolve(moduleName); + assertTrue(CompilerUtils.compile(msrc, mods, "-modulesourcepath", src.toString())); + } + + private void jmod(String moduleName, String... options) throws IOException { + Path mclasses = mods.resolve(moduleName); + Path outfile = jmods.resolve(moduleName + ".jmod"); + List args = new ArrayList<>(); + args.add("create"); + Collections.addAll(args, options); + Collections.addAll(args, "--class-path", mclasses.toString(), + outfile.toString()); + + if (Files.exists(outfile)) + Files.delete(outfile); + + runJmod(args); + } + + private void runJmod(List args) { + int rc = jdk.tools.jmod.Main.run(args.toArray(new String[args.size()]), System.out); + System.out.println("jmod options: " + args.stream().collect(Collectors.joining(" "))); + if (rc != 0) { + throw new AssertionError("Jmod failed: rc = " + rc); + } + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/hashes/src/m1/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jmod/hashes/src/m1/module-info.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +module m1 { + requires m2; + requires m3; +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/hashes/src/m1/org/m1/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jmod/hashes/src/m1/org/m1/Main.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.m1; + +import org.m2.Util; +import org.m3.Name; + +public class Main { + public static void main(String[] args) { + System.out.println(Util.timeOfDay()); + System.out.println(Name.name()); + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/hashes/src/m2/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jmod/hashes/src/m2/module-info.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +module m2 { + exports org.m2; +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/hashes/src/m2/org/m2/Util.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jmod/hashes/src/m2/org/m2/Util.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.m2; + +public class Util { + private Util() { } + + public static String timeOfDay() { + return "Time for lunch"; + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/hashes/src/m3/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jmod/hashes/src/m3/module-info.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +module m3 { + exports org.m3; +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/hashes/src/m3/org/m3/Name.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jmod/hashes/src/m3/org/m3/Name.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.m3; + +public class Name { + private Name() { } + + public static String name() { + return "m3"; + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/hashes/src/org.bar/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jmod/hashes/src/org.bar/module-info.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,26 @@ +/* + * 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. + */ + +module org.bar { + requires public m1; +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/jmod/hashes/src/org.foo/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/jmod/hashes/src/org.foo/module-info.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,26 @@ +/* + * 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. + */ + +module org.foo { + requires public org.bar; +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/ToolsOpts.java --- a/jdk/test/tools/launcher/ToolsOpts.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/launcher/ToolsOpts.java Thu May 05 19:11:09 2016 +0000 @@ -151,29 +151,26 @@ init(); TestResult tr; int jpos = -1; + String xPatch = "-J-Xpatch:jdk.compiler=jdk.compiler"; for (String arg[] : optionPatterns) { jpos = indexOfJoption(arg); //Build a cmd string for output in results reporting. - String cmdString = javacCmd + " -J-Xpatch:."; + String cmdString = javacCmd + " " + xPatch; for (String opt : arg) { cmdString = cmdString.concat(" " + opt); } switch (arg.length) { case 1: - tr = doExec(javacCmd, "-J-Xpatch:.", - arg[0]); + tr = doExec(javacCmd, xPatch, arg[0]); break; case 2: - tr = doExec(javacCmd, "-J-Xpatch:.", - arg[0], arg[1]); + tr = doExec(javacCmd, xPatch, arg[0], arg[1]); break; case 3: - tr = doExec(javacCmd, "-J-Xpatch:.", - arg[0], arg[1], arg[2]); + tr = doExec(javacCmd, xPatch, arg[0], arg[1], arg[2]); break; case 4: - tr = doExec(javacCmd, "-J-Xpatch:.", - arg[0], arg[1], arg[2], arg[3]); + tr = doExec(javacCmd, xPatch, arg[0], arg[1], arg[2], arg[3]); break; default: tr = null; diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/addmods/AddModsTest.java --- a/jdk/test/tools/launcher/modules/addmods/AddModsTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/launcher/modules/addmods/AddModsTest.java Thu May 05 19:11:09 2016 +0000 @@ -47,120 +47,179 @@ private static final String TEST_SRC = System.getProperty("test.src"); private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); - private static final Path MODS_DIR = Paths.get("mods"); - - // the module name of the library module - private static final String LIB_MODULE = "lib"; + private static final Path MODS1_DIR = Paths.get("mods1"); + private static final Path MODS2_DIR = Paths.get("mods2"); - // application source directory - private static final String APP_SRC = "app"; + // test module / main class + private static final String TEST_MODULE = "test"; + private static final String TEST_MAIN_CLASS = "test.Main"; + private static final String TEST_MID = TEST_MODULE + "/" + TEST_MAIN_CLASS; - // application is compiled to classes - private static final Path CLASSES_DIR = Paths.get("classes"); - - // application main class - private static final String MAIN_CLASS = "app.Main"; + // logger module + private static final String LOGGER_MODULE = "logger"; @BeforeTest public void compile() throws Exception { - - // javac -d mods/$LIB_MODULE src/$LIB_MODULE/** + // javac -d mods1/test src/test/** boolean compiled = CompilerUtils.compile( - SRC_DIR.resolve(LIB_MODULE), - MODS_DIR.resolve(LIB_MODULE) + SRC_DIR.resolve(TEST_MODULE), + MODS1_DIR.resolve(TEST_MODULE) ); - assertTrue(compiled, "library module did not compile"); + assertTrue(compiled, "test did not compile"); - // javac -d classes -mp mods src/$APP_DIR/** - compiled = CompilerUtils.compile( - SRC_DIR.resolve(APP_SRC), - CLASSES_DIR, - "-mp", MODS_DIR.toString(), - "-addmods", LIB_MODULE + // javac -d mods1/logger src/logger/** + compiled= CompilerUtils.compile( + SRC_DIR.resolve(LOGGER_MODULE), + MODS2_DIR.resolve(LOGGER_MODULE) ); - assertTrue(compiled, "app did not compile"); + assertTrue(compiled, "test did not compile"); } /** - * Basic test of -addmods ALL-SYSTEM, using the output of -listmods to - * check that the a sample of the system modules are resolved. + * Basic test of -addmods ALL-DEFAULT. Module java.sql should be + * resolved and the types in that module should be visible. */ - public void testAddSystemModules() throws Exception { - - executeTestJava("-addmods", "ALL-SYSTEM", - "-listmods", - "-m", "java.base") - .outputTo(System.out) - .errorTo(System.out) - .shouldContain("java.sql") - .shouldContain("java.corba"); + public void testAddDefaultModules1() throws Exception { - // no exit value to check as -m java.base will likely fail - } - - - /** - * Run application on class path that makes use of module on the - * application module path. Uses {@code -addmods lib} - */ - public void testRunWithAddMods() throws Exception { - - // java -mp mods -addmods lib -cp classes app.Main + // java -addmods ALL-DEFAULT -mp mods1 -m test ... int exitValue - = executeTestJava("-mp", MODS_DIR.toString(), - "-addmods", LIB_MODULE, - "-cp", CLASSES_DIR.toString(), - MAIN_CLASS) + = executeTestJava("-mp", MODS1_DIR.toString(), + "-addmods", "ALL-DEFAULT", + "-m", TEST_MID, + "java.sql.Connection") .outputTo(System.out) .errorTo(System.out) .getExitValue(); assertTrue(exitValue == 0); - } /** - * Run application on class path that makes use of module on the - * application module path. Uses {@code -addmods ALL-MODULE-PATH}. + * Basic test of -addmods ALL-DEFAULT. Module java.annotations.common + * should not resolved and so the types in that module should not be + * visible. */ - public void testAddAllModulePath() throws Exception { + public void testAddDefaultModules2() throws Exception { + + // java -addmods ALL-DEFAULT -mp mods1 -m test ... + int exitValue + = executeTestJava("-mp", MODS1_DIR.toString(), + "-addmods", "ALL-DEFAULT", + "-m", TEST_MID, + "javax.annotation.Generated") + .outputTo(System.out) + .errorTo(System.out) + .shouldContain("ClassNotFoundException") + .getExitValue(); - // java -mp mods -addmods lib -cp classes app.Main + assertTrue(exitValue != 0); + } + + /** + * Basic test of -addmods ALL-SYSTEM. All system modules should be resolved + * and thus all types in those modules should be visible. + */ + public void testAddSystemModules() throws Exception { + + // java -addmods ALL-SYSTEM -mp mods1 -m test ... int exitValue - = executeTestJava("-mp", MODS_DIR.toString(), - "-addmods", "ALL-MODULE-PATH", - "-cp", CLASSES_DIR.toString(), - MAIN_CLASS) + = executeTestJava("-mp", MODS1_DIR.toString(), + "-addmods", "ALL-SYSTEM", + "-m", TEST_MID, + "java.sql.Connection", + "javax.annotation.Generated") .outputTo(System.out) .errorTo(System.out) .getExitValue(); assertTrue(exitValue == 0); - } /** - * Run application on class path that makes use of module on the - * application module path. Does not use -addmods and so will - * fail at run-time. + * Run test on class path to load a type in a module on the application + * module path, uses {@code -addmods logger}. */ - public void testRunMissingAddMods() throws Exception { + public void testRunWithAddMods() throws Exception { - // java -mp mods -cp classes app.Main + // java -mp mods -addmods logger -cp classes test.Main + String classpath = MODS1_DIR.resolve(TEST_MODULE).toString(); + String modulepath = MODS2_DIR.toString(); int exitValue - = executeTestJava("-mp", MODS_DIR.toString(), - "-cp", CLASSES_DIR.toString(), - MAIN_CLASS) + = executeTestJava("-mp", modulepath, + "-addmods", LOGGER_MODULE, + "-cp", classpath, + TEST_MAIN_CLASS, + "logger.Logger") .outputTo(System.out) .errorTo(System.out) .getExitValue(); - // CNFE or other error/exception - assertTrue(exitValue != 0); + assertTrue(exitValue == 0); + } + + /** + * Run application on class path that makes use of module on the + * application module path. Does not use -addmods and so should + * fail at run-time. + */ + public void testRunMissingAddMods() throws Exception { + + // java -mp mods -cp classes test.Main + String classpath = MODS1_DIR.resolve(TEST_MODULE).toString(); + String modulepath = MODS1_DIR.toString(); + int exitValue + = executeTestJava("-mp", modulepath, + "-cp", classpath, + TEST_MAIN_CLASS, + "logger.Logger") + .outputTo(System.out) + .errorTo(System.out) + .shouldContain("ClassNotFoundException") + .getExitValue(); + + assertTrue(exitValue != 0); + } + + /** + * Run test on class path to load a type in a module on the application + * module path, uses {@code -addmods ALL-MODULE-PATH}. + */ + public void testAddAllModulePath() throws Exception { + + // java -mp mods -addmods ALL-MODULE-PATH -cp classes test.Main + String classpath = MODS1_DIR.resolve(TEST_MODULE).toString(); + String modulepath = MODS1_DIR.toString(); + int exitValue + = executeTestJava("-mp", modulepath, + "-addmods", "ALL-MODULE-PATH", + "-cp", classpath, + TEST_MAIN_CLASS) + .outputTo(System.out) + .errorTo(System.out) + .getExitValue(); + + assertTrue(exitValue == 0); + } + + + /** + * Test {@code -addmods ALL-MODULE-PATH} without {@code -modulepath}. + */ + public void testAddAllModulePathWithNoModulePath() throws Exception { + + // java -addmods ALL-MODULE-PATH -version + int exitValue + = executeTestJava("-addmods", "ALL-MODULE-PATH", + "-version") + .outputTo(System.out) + .errorTo(System.out) + .getExitValue(); + + assertTrue(exitValue == 0); } @@ -169,18 +228,17 @@ */ public void testRunWithBadAddMods() throws Exception { - // java -mp mods -addmods,DoesNotExist lib -cp classes app.Main + // java -mp mods -addmods DoesNotExist -m test ... int exitValue - = executeTestJava("-mp", MODS_DIR.toString(), - "-addmods", LIB_MODULE + ",DoesNotExist", - "-cp", CLASSES_DIR.toString(), - MAIN_CLASS) + = executeTestJava("-mp", MODS1_DIR.toString(), + "-addmods", "DoesNotExist", + "-m", TEST_MID) .outputTo(System.out) .errorTo(System.out) + .shouldContain("DoesNotExist") .getExitValue(); assertTrue(exitValue != 0); - } } diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/addmods/src/app/Main.java --- a/jdk/test/tools/launcher/modules/addmods/src/app/Main.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2014, 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 app; - -import jdk.lib.Util; - -public class Main { - public static void main(String[] args) { - Object obj = Util.makeObject(); - } -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/addmods/src/lib/jdk/lib/Util.java --- a/jdk/test/tools/launcher/modules/addmods/src/lib/jdk/lib/Util.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2014, 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 jdk.lib; - -public class Util { - private Util() { } - - public static Object makeObject() { - return new Object(); - } -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/addmods/src/lib/module-info.java --- a/jdk/test/tools/launcher/modules/addmods/src/lib/module-info.java Thu May 05 17:35:48 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ - -module lib { - exports jdk.lib; -} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/addmods/src/logger/logger/Logger.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/launcher/modules/addmods/src/logger/logger/Logger.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,30 @@ +/* + * 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 logger; + +/** + * No-op user module for use by the {@code java -addmods} tests. + */ +public class Logger { +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/addmods/src/logger/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/launcher/modules/addmods/src/logger/module-info.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,24 @@ +/** + * 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. + */ + +module logger { } diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/addmods/src/test/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/launcher/modules/addmods/src/test/module-info.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,24 @@ +/** + * 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. + */ + +module test { } diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/addmods/src/test/test/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/launcher/modules/addmods/src/test/test/Main.java Thu May 05 19:11:09 2016 +0000 @@ -0,0 +1,37 @@ +/* + * 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 test; + +/** + * Invoked by tests for the {@code java -addmods} option to check that types + * are visible. + */ +public class Main { + public static void main(String[] args) throws Exception { + for (String cn : args) { + Class c = Class.forName(cn); + System.out.println("Loaded: " + c); + } + } +} diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/addreads/AddReadsTest.java --- a/jdk/test/tools/launcher/modules/addreads/AddReadsTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/launcher/modules/addreads/AddReadsTest.java Thu May 05 19:11:09 2016 +0000 @@ -25,7 +25,7 @@ * @test * @library /lib/testlibrary * @modules jdk.compiler - * @build AddReadsTest CompilerUtils jdk.testlibrary.* + * @build AddReadsTest CompilerUtils JarUtils jdk.testlibrary.* * @run testng AddReadsTest * @summary Basic tests for java -XaddReads */ diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/launcher/modules/patch/PatchTest.java --- a/jdk/test/tools/launcher/modules/patch/PatchTest.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/launcher/modules/patch/PatchTest.java Thu May 05 19:11:09 2016 +0000 @@ -25,7 +25,7 @@ * @test * @library /lib/testlibrary * @modules jdk.compiler - * @build PatchTest CompilerUtils jdk.testlibrary.* + * @build PatchTest CompilerUtils JarUtils jdk.testlibrary.* * @run testng PatchTest * @summary Basic test for -Xpatch */ @@ -72,6 +72,9 @@ private static final Path SRC2_DIR = Paths.get(TEST_SRC, "src2"); private static final Path PATCHES2_DIR = Paths.get("patches2"); + // destination directory for patches packaged as JAR files + private static final Path PATCHES_DIR = Paths.get("patches"); + // the classes overridden or added with -Xpatch private static final String[] CLASSES = { @@ -95,7 +98,7 @@ @BeforeTest - public void compile() throws Exception { + public void setup() throws Exception { // javac -d mods/test src/test/** boolean compiled= CompilerUtils.compile(SRC_DIR.resolve("test"), @@ -103,36 +106,40 @@ assertTrue(compiled, "classes did not compile"); // javac -Xmodule:$MODULE -d patches1/$MODULE patches1/$MODULE/** + // jar cf patches/$MODULE-1.jar -C patches1/$MODULE . for (Path src : Files.newDirectoryStream(SRC1_DIR)) { Path output = PATCHES1_DIR.resolve(src.getFileName()); String mn = src.getFileName().toString(); compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn); assertTrue(compiled, "classes did not compile"); + JarUtils.createJarFile(PATCHES_DIR.resolve(mn + "-1.jar"), output); } // javac -Xmodule:$MODULE -d patches2/$MODULE patches2/$MODULE/** + // jar cf patches/$MODULE-2.jar -C patches2/$MODULE . for (Path src : Files.newDirectoryStream(SRC2_DIR)) { Path output = PATCHES2_DIR.resolve(src.getFileName()); String mn = src.getFileName().toString(); compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn); assertTrue(compiled, "classes did not compile"); + JarUtils.createJarFile(PATCHES_DIR.resolve(mn + "-2.jar"), output); } } /** - * Run the test with -Xpatch + * Run test with patches to java.base, jdk.naming.dns and jdk.compiler */ - public void testRunWithXPatch() throws Exception { - - // value for -Xpatch - String patchPath = PATCHES1_DIR + File.pathSeparator + PATCHES2_DIR; - + void runTest(String basePatches, String dnsPatches, String compilerPatches) + throws Exception + { // the argument to the test is the list of classes overridden or added String arg = Stream.of(CLASSES).collect(Collectors.joining(",")); int exitValue - = executeTestJava("-Xpatch:" + patchPath, + = executeTestJava("-Xpatch:java.base=" + basePatches, + "-Xpatch:jdk.naming.dns=" + dnsPatches, + "-Xpatch:jdk.compiler=" + compilerPatches, "-XaddExports:java.base/java.lang2=test", "-XaddExports:jdk.naming.dns/com.sun.jndi.dns=test", "-XaddExports:jdk.naming.dns/com.sun.jndi.dns2=test", @@ -145,6 +152,44 @@ .getExitValue(); assertTrue(exitValue == 0); + } + + + /** + * Run test with -Xpatch and exploded patches + */ + public void testWithExplodedPatches() throws Exception { + + // patches1/java.base:patches2/java.base + String basePatches = PATCHES1_DIR.resolve("java.base") + + File.pathSeparator + PATCHES2_DIR.resolve("java.base"); + + String dnsPatches = PATCHES1_DIR.resolve("jdk.naming.dns") + + File.pathSeparator + PATCHES2_DIR.resolve("jdk.naming.dns"); + + String compilerPatches = PATCHES1_DIR.resolve("jdk.compiler") + + File.pathSeparator + PATCHES2_DIR.resolve("jdk.compiler"); + + runTest(basePatches, dnsPatches, compilerPatches); + } + + + /** + * Run test with -Xpatch and patches in JAR files + */ + public void testWitJarPatches() throws Exception { + + // patches/java.base-1.jar:patches/java-base-2.jar + String basePatches = PATCHES_DIR.resolve("java.base-1.jar") + + File.pathSeparator + PATCHES_DIR.resolve("java.base-2.jar"); + + String dnsPatches = PATCHES_DIR.resolve("jdk.naming.dns-1.jar") + + File.pathSeparator + PATCHES_DIR.resolve("jdk.naming.dns-2.jar"); + + String compilerPatches = PATCHES_DIR.resolve("jdk.compiler-1.jar") + + File.pathSeparator + PATCHES_DIR.resolve("jdk.compiler-2.jar"); + + runTest(basePatches, dnsPatches, compilerPatches); } diff -r 5c95f3324916 -r 41844efbbcce jdk/test/tools/lib/tests/JImageGenerator.java --- a/jdk/test/tools/lib/tests/JImageGenerator.java Thu May 05 17:35:48 2016 +0000 +++ b/jdk/test/tools/lib/tests/JImageGenerator.java Thu May 05 19:11:09 2016 +0000 @@ -113,7 +113,7 @@ private static final String CMDS_OPTION = "--cmds"; private static final String CONFIG_OPTION = "--config"; - private static final String HASH_DEPENDENCIES_OPTION = "--hash-dependencies"; + private static final String HASH_MODULES_OPTION = "--hash-modules"; private static final String LIBS_OPTION = "--libs"; private static final String MODULE_VERSION_OPTION = "--module-version"; @@ -347,7 +347,7 @@ private final List jmods = new ArrayList<>(); private final List options = new ArrayList<>(); private Path output; - private String hashDependencies; + private String hashModules; private String mainClass; private String moduleVersion; @@ -356,8 +356,8 @@ return this; } - public JModTask hashDependencies(String hash) { - this.hashDependencies = hash; + public JModTask hashModules(String hash) { + this.hashModules = hash; return this; } @@ -430,9 +430,9 @@ options.add(CONFIG_OPTION); options.add(toPath(config)); } - if (hashDependencies != null) { - options.add(HASH_DEPENDENCIES_OPTION); - options.add(hashDependencies); + if (hashModules != null) { + options.add(HASH_MODULES_OPTION); + options.add(hashModules); } if (mainClass != null) { options.add(MAIN_CLASS_OPTION);