This commit is contained in:
Phil Race 2017-11-14 12:07:55 -08:00
commit 60c7c6052d
26 changed files with 405 additions and 71 deletions
make
src
java.base/share/classes
jdk.jartool/share/classes/sun/security/tools/jarsigner
jdk.jlink/share/classes/jdk/tools/jlink/internal
jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime
test
jdk
nashorn/script/nosecurity/es6

@ -36,15 +36,18 @@ help:
$(info =====================)
$(info )
$(info Common make targets)
$(info $(_) make [default] # Compile all modules in langtools, hotspot, jdk, jaxws,)
$(info $(_) # jaxp and corba, and create a runnable "exploded" image)
$(info $(_) make all # Compile everything, all repos, docs and images)
$(info $(_) make images # Create complete jdk and jre images (alias for product-images))
$(info $(_) make <name>-image # Build just the image (jdk, jre, test, docs etc))
$(info $(_) make [default] # Compile all modules and create a runnable "exploded")
$(info $(_) # image (alias for jdk or exploded-image))
$(info $(_) make all # Create all images: product, test, docs)
$(info $(_) # (alias for all-images))
$(info $(_) make images # Create complete jdk and jre images)
$(info $(_) # (alias for product-images))
$(info $(_) make <name>-image # Build just the image for any of: )
$(info $(_) # jdk, jre, test, docs, symbols, profiles)
$(info $(_) make <phase> # Build the specified phase and everything it depends on)
$(info $(_) # (gensrc, java, copy, libs, launchers, gendata, rmic))
$(info $(_) make *-only # Applies to most targets and disables compling the)
$(info $(_) # dependencies for the target. This is faster but may)
$(info $(_) make *-only # Applies to most targets and disables building the)
$(info $(_) # dependencies for that target. This is faster but may)
$(info $(_) # result in incorrect build results!)
$(info $(_) make docs # Create all docs)
$(info $(_) make docs-jdk-api # Create just JDK javadocs)
@ -74,7 +77,7 @@ help:
$(info $(_) make hotspot # Build all of hotspot)
$(info $(_) make hotspot-<variant> # Build just the specified jvm variant)
$(info $(_) make hotspot-gensrc # Only build the gensrc part of hotspot)
$(info $(_) make hotspot-<variant>-<phase> # Build the specified phase for the specified module)
$(info $(_) make hotspot-<variant>-<phase> # Build the specified phase for the variant)
$(info )
$(info Targets for specific modules)
$(info $(_) make <module> # Build <module> and everything it depends on)

@ -830,8 +830,8 @@ grant codeBase "file:/${basedir}/${test.script.dir}/basic/JDK-8158467.js" {
<!-- underscorejs -->
<mkdir dir="${test.external.dir}/underscore"/>
<get src="http://underscorejs.org/underscore.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true"/>
<get src="http://underscorejs.org/underscore-min.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true"/>
<get src="http://underscorejs.org/underscore.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true" tryGzipEncoding="true"/>
<get src="http://underscorejs.org/underscore-min.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true" tryGzipEncoding="true"/>
<!-- yui -->
<mkdir dir="${test.external.dir}/yui"/>

@ -57,13 +57,12 @@ import java.util.Date;
*
* @author Benjamin Renaud
* @since 1.1
* @deprecated A new certificate handling package is created in the Java platform.
* This Certificate interface is entirely deprecated and
* is here to allow for a smooth transition to the new
* package.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by
* {@code java.security.cert.Certificate} and related classes.
* @see java.security.cert.Certificate
*/
@Deprecated(since="1.2")
@Deprecated(since="1.2", forRemoval=true)
public interface Certificate {
/**

@ -52,12 +52,13 @@ import java.util.*;
*
* @author Benjamin Renaud
* @since 1.1
* @deprecated This class is no longer used. Its functionality has been
* replaced by {@code java.security.KeyStore}, the
* {@code java.security.cert} package, and
* {@code java.security.Principal}.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by
* {@code java.security.KeyStore}, the {@code java.security.cert} package,
* and {@code java.security.Principal}.
*/
@Deprecated(since="1.2")
@Deprecated(since="1.2", forRemoval=true)
@SuppressWarnings("removal")
public abstract class Identity implements Principal, Serializable {
/** use serialVersionUID from JDK 1.1.x for interoperability */

@ -57,12 +57,13 @@ import java.util.Properties;
* @author Benjamin Renaud
* @since 1.1
*
* @deprecated This class is no longer used. Its functionality has been
* replaced by {@code java.security.KeyStore}, the
* {@code java.security.cert} package, and
* {@code java.security.Principal}.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by
* {@code java.security.KeyStore}, the {@code java.security.cert} package,
* and {@code java.security.Principal}.
*/
@Deprecated(since="1.2")
@Deprecated(since="1.2", forRemoval=true)
@SuppressWarnings("removal")
public abstract
class IdentityScope extends Identity {

@ -40,12 +40,13 @@ import java.io.*;
* @author Benjamin Renaud
* @since 1.1
*
* @deprecated This class is no longer used. Its functionality has been
* replaced by {@code java.security.KeyStore}, the
* {@code java.security.cert} package, and
* {@code java.security.Principal}.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by
* {@code java.security.KeyStore}, the {@code java.security.cert} package,
* and {@code java.security.Principal}.
*/
@Deprecated(since="1.2")
@Deprecated(since="1.2", forRemoval=true)
@SuppressWarnings("removal")
public abstract class Signer extends Identity {
private static final long serialVersionUID = -1763464102261361480L;

@ -84,11 +84,13 @@ import java.security.Principal;
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval=true)
@SuppressWarnings("removal")
public interface Acl extends Owner {
/**

@ -52,10 +52,12 @@ import java.security.Principal;
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval=true)
@SuppressWarnings("removal")
public interface AclEntry extends Cloneable {
/**

@ -32,10 +32,11 @@ package java.security.acl;
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval=true)
public class AclNotFoundException extends Exception {
private static final long serialVersionUID = 5684295034092681791L;

@ -41,10 +41,11 @@ import java.security.Principal;
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval=true)
public interface Group extends Principal {
/**

@ -34,10 +34,11 @@ package java.security.acl;
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval=true)
public class LastOwnerException extends Exception {
private static final long serialVersionUID = -5141997548211140359L;

@ -33,10 +33,11 @@ package java.security.acl;
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval=true)
public class NotOwnerException extends Exception {
private static final long serialVersionUID = -5555597911163362399L;

@ -37,10 +37,12 @@ import java.security.Principal;
* @since 1.1
* @see java.security.acl.Acl
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval=true)
@SuppressWarnings("removal")
public interface Owner {
/**

@ -33,10 +33,11 @@ package java.security.acl;
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
* @deprecated This class is deprecated and subject to removal in a future
* version of Java SE. It has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval=true)
public interface Permission {
/**

@ -27,7 +27,8 @@
* The classes and interfaces in this package have been deprecated. New
* classes should not be added to this package. The {@code java.security}
* package contains suitable replacements. See {@link java.security.Policy}
* and related classes for details.
* and related classes for details. This package is subject to removal in a
* future version of Java SE.
*
* @since 1.1
*/

@ -456,21 +456,21 @@ public class Resources extends java.util.ListResourceBundle {
{"the.tsa.certificate", "The TSA certificate"},
{"the.input", "The input"},
{"reply", "Reply"},
{"one.in.many", "%s #%d of %d"},
{"one.in.many", "%1$s #%2$d of %3$d"},
{"alias.in.cacerts", "Issuer <%s> in cacerts"},
{"alias.in.keystore", "Issuer <%s>"},
{"with.weak", "%s (weak)"},
{"key.bit", "%d-bit %s key"},
{"key.bit.weak", "%d-bit %s key (weak)"},
{"key.bit", "%1$d-bit %2$s key"},
{"key.bit.weak", "%1$d-bit %2$s key (weak)"},
{"unknown.size.1", "unknown size %s key"},
{".PATTERN.printX509Cert.with.weak",
"Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t SHA1: {5}\n\t SHA256: {6}\nSignature algorithm name: {7}\nSubject Public Key Algorithm: {8}\nVersion: {9}"},
{"PKCS.10.with.weak",
"PKCS #10 Certificate Request (Version 1.0)\n" +
"Subject: %s\nFormat: %s\nPublic Key: %s\nSignature algorithm: %s\n"},
{"verified.by.s.in.s.weak", "Verified by %s in %s with a %s"},
{"whose.sigalg.risk", "%s uses the %s signature algorithm which is considered a security risk."},
{"whose.key.risk", "%s uses a %s which is considered a security risk."},
"Subject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignature algorithm: %4$s\n"},
{"verified.by.s.in.s.weak", "Verified by %1$s in %2$s with a %3$s"},
{"whose.sigalg.risk", "%1$s uses the %2$s signature algorithm which is considered a security risk."},
{"whose.key.risk", "%1$s uses a %2$s which is considered a security risk."},
{"jks.storetype.warning", "The %1$s keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using \"keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12\"."},
{"migrate.keystore.warning", "Migrated \"%1$s\" to %4$s. The %2$s keystore is backed up as \"%3$s\"."},
{"backup.keystore.warning", "The original keystore \"%1$s\" is backed up as \"%3$s\"..."},

@ -270,7 +270,7 @@ public class Resources extends java.util.ListResourceBundle {
{"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
"The %1$s algorithm specified for the %2$s option is considered a security risk."},
{"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.",
"The %s signing key has a keysize of %d which is considered a security risk."},
"The %1$s signing key has a keysize of %2$d which is considered a security risk."},
{"This.jar.contains.entries.whose.certificate.chain.is.invalid.reason.1",
"This jar contains entries whose certificate chain is invalid. Reason: %s"},
{"This.jar.contains.entries.whose.tsa.certificate.chain.is.invalid.reason.1",

@ -74,14 +74,16 @@ public abstract class JarArchive implements Archive {
private final Path file;
private final String moduleName;
private final Runtime.Version version;
// currently processed JarFile
private JarFile jarFile;
protected JarArchive(String mn, Path file) {
protected JarArchive(String mn, Path file, Runtime.Version version) {
Objects.requireNonNull(mn);
Objects.requireNonNull(file);
this.moduleName = mn;
this.file = file;
this.version = Objects.requireNonNull(version);
}
@Override
@ -126,7 +128,7 @@ public abstract class JarArchive implements Archive {
if (jarFile != null) {
jarFile.close();
}
jarFile = new JarFile(file.toFile(), true, ZipFile.OPEN_READ, JarFile.runtimeVersion());
jarFile = new JarFile(file.toFile(), true, ZipFile.OPEN_READ, version);
}
protected JarFile getJarFile() {

@ -421,6 +421,9 @@ public class JlinkTask {
* the observable modules to those in the transitive closure of
* the modules specified in {@code limitMods} plus other modules
* specified in the {@code roots} set.
*
* @throws IllegalArgumentException if java.base module is present
* but its descriptor has no version
*/
public static ModuleFinder newModuleFinder(List<Path> paths,
Set<String> limitMods,
@ -429,8 +432,25 @@ public class JlinkTask {
if (Objects.requireNonNull(paths).isEmpty()) {
throw new IllegalArgumentException("Empty module path");
}
Path[] entries = paths.toArray(new Path[0]);
ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries);
Runtime.Version version = Runtime.version();
ModuleFinder finder = ModulePath.of(version, true, entries);
if (finder.find("java.base").isPresent()) {
// use the version of java.base module, if present, as
// the release version for multi-release JAR files
ModuleDescriptor.Version v = finder.find("java.base").get()
.descriptor().version().orElseThrow(() ->
new IllegalArgumentException("No version in java.base descriptor")
);
// java.base version is different than the current runtime version
version = Runtime.Version.parse(v.toString());
if (Runtime.version().major() != version.major()) {
finder = ModulePath.of(version, true, entries);
}
}
// if limitmods is specified then limit the universe
if (limitMods != null && !limitMods.isEmpty()) {
@ -744,6 +764,7 @@ public class JlinkTask {
final ByteOrder order;
final Path packagedModulesPath;
final boolean ignoreSigning;
final Runtime.Version version;
final Set<Archive> archives;
ImageHelper(Configuration cf,
@ -754,6 +775,17 @@ public class JlinkTask {
this.order = order;
this.packagedModulesPath = packagedModulesPath;
this.ignoreSigning = ignoreSigning;
// use the version of java.base module, if present, as
// the release version for multi-release JAR files
this.version = cf.findModule("java.base")
.map(ResolvedModule::reference)
.map(ModuleReference::descriptor)
.flatMap(ModuleDescriptor::version)
.map(ModuleDescriptor.Version::toString)
.map(Runtime.Version::parse)
.orElse(Runtime.version());
this.archives = modsPaths.entrySet().stream()
.map(e -> newArchive(e.getKey(), e.getValue()))
.collect(Collectors.toSet());
@ -763,7 +795,7 @@ public class JlinkTask {
if (path.toString().endsWith(".jmod")) {
return new JmodArchive(module, path);
} else if (path.toString().endsWith(".jar")) {
ModularJarArchive modularJarArchive = new ModularJarArchive(module, path);
ModularJarArchive modularJarArchive = new ModularJarArchive(module, path, version);
Stream<Archive.Entry> signatures = modularJarArchive.entries().filter((entry) -> {
String name = entry.name().toUpperCase(Locale.ENGLISH);

@ -39,8 +39,8 @@ public class ModularJarArchive extends JarArchive {
private static final String JAR_EXT = ".jar";
private static final String MODULE_INFO = "module-info.class";
public ModularJarArchive(String mn, Path jmod) {
super(mn, jmod);
public ModularJarArchive(String mn, Path jmod, Runtime.Version version) {
super(mn, jmod, version);
String filename = Objects.requireNonNull(jmod.getFileName()).toString();
if (!filename.endsWith(JAR_EXT)) {
throw new UnsupportedOperationException("Unsupported format: " + filename);

@ -2050,7 +2050,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
final PropertyMap newMap = oldMap.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
setMap(newMap);
set(key, value, 0);
set(key, value, NashornCallSiteDescriptor.CALLSITE_DECLARE);
}
/**
@ -3071,7 +3071,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
}
if (f != null) {
if (!f.getProperty().isWritable() || !f.getProperty().hasNativeSetter()) {
if ((!f.getProperty().isWritable() && !NashornCallSiteDescriptor.isDeclaration(callSiteFlags)) || !f.getProperty().hasNativeSetter()) {
if (isScopeFlag(callSiteFlags) && f.getProperty().isLexicalBinding()) {
throw typeError("assign.constant", key.toString()); // Overwriting ES6 const should throw also in non-strict mode.
}

@ -504,6 +504,15 @@ public final class NashornCallSiteDescriptor extends CallSiteDescriptor {
return (flags & CALLSITE_SCOPE) != 0;
}
/**
* Returns true if {@code flags} has the {@link #CALLSITE_DECLARE} bit set.
* @param flags the flags
* @return true if the flag is set, false otherwise.
*/
public static boolean isDeclaration(final int flags) {
return (flags & CALLSITE_DECLARE) != 0;
}
/**
* Get a program point from a descriptor (must be optimistic)
* @param desc descriptor

@ -174,6 +174,8 @@ java/net/MulticastSocket/Test.java 7145658 macosx-a
java/net/DatagramSocket/SendDatagramToBadAddress.java 7143960 macosx-all
java/net/httpclient/websocket/ConnectionHandover.java 8188895 windows-all
############################################################################
# jdk_nio

@ -0,0 +1,51 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
public class CheckRuntimeVersion {
public static void main(String... args) {
int version = Integer.parseInt(args[0]);
if (Runtime.version().major() != version) {
throw new RuntimeException(version + " != current runtime version "
+ Runtime.version());
}
Set<String> expected = Arrays.stream(args, 1, args.length)
.collect(Collectors.toSet());
Set<String> modules = ModuleFinder.ofSystem().findAll().stream()
.map(ModuleReference::descriptor)
.map(ModuleDescriptor::name)
.collect(Collectors.toSet());
if (!modules.equals(expected)) {
throw new RuntimeException("Expected: " + expected +
" observable modules: " + modules);
}
}
}

@ -0,0 +1,163 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8177471
* @summary jlink should use the version from java.base.jmod to find modules
* @modules java.base/jdk.internal.module
* @library /test/lib
* @build jdk.test.lib.process.* CheckRuntimeVersion
* @run testng/othervm JLinkMRJavaBaseVersionTest
*/
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.jar.JarFile;
import java.util.spi.ToolProvider;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.module.ModulePath;
import jdk.test.lib.process.ProcessTools;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class JLinkMRJavaBaseVersionTest {
private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
.orElseThrow(() -> new RuntimeException("jar tool not found"));
private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac")
.orElseThrow(() -> new RuntimeException("javac tool not found"));
private static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
.orElseThrow(() -> new RuntimeException("jlink tool not found"));
private static final Path javaHome = Paths.get(System.getProperty("java.home"));
// resource text for version 9
private byte[] resource9 = ("9 resource file").getBytes();
// resource text for current version
private byte[] resource = (Runtime.version().major() + " resource file").getBytes();
static Path getJmods() {
Path jmods = Paths.get(System.getProperty("java9.home", javaHome.toString())).resolve("jmods");
if (Files.notExists(jmods)) {
throw new RuntimeException(jmods + " not found");
}
return jmods;
}
@BeforeClass
public void initialize() throws IOException {
Path srcdir = Paths.get(System.getProperty("test.src"));
// create class files from source
Path base = srcdir.resolve("base");
Path mr9 = Paths.get("mr9");
javac(base, mr9, base.toString());
// current version
Path rt = srcdir.resolve("rt");
Path rtmods = Paths.get("rtmods");
javac(rt, rtmods, rt.toString());
// build multi-release jar file with different module-info.class
String[] args = {
"-cf", "m1.jar",
"-C", rtmods.resolve("m1").toString(), ".",
"--release ", "9",
"-C", mr9.resolve("m1").toString(), "."
};
JAR_TOOL.run(System.out, System.err, args);
}
private void javac(Path source, Path destination, String srcpath) throws IOException {
String[] args = Stream.concat(
Stream.of("-d", destination.toString(), "--release", "9",
"--module-source-path", srcpath),
Files.walk(source)
.map(Path::toString)
.filter(s -> s.endsWith(".java"))
).toArray(String[]::new);
int rc = JAVAC_TOOL.run(System.out, System.err, args);
Assert.assertEquals(rc, 0);
}
@Test
public void basicTest() throws Throwable {
if (Files.notExists(javaHome.resolve("lib").resolve("modules"))) {
// exploded image
return;
}
Runtime.Version version = targetRuntimeVersion();
System.out.println("Testing jlink with " + getJmods() + " of target version " + version);
// use jlink to build image from multi-release jar
jlink("m1.jar", "myimage");
// validate runtime image
Path java = Paths.get("myimage", "bin", "java");
ProcessTools.executeProcess(java.toString(), "-m", "m1/p.Main");
// validate the image linked with the proper MR version
if (version.equalsIgnoreOptional(Runtime.version())) {
ProcessTools.executeProcess(java.toString(), "-cp", System.getProperty("test.classes"),
"CheckRuntimeVersion", String.valueOf(version.major()),
"java.base", "java.logging", "m1")
.shouldHaveExitValue(0);
} else {
ProcessTools.executeProcess(java.toString(), "-cp", System.getProperty("test.classes"),
"CheckRuntimeVersion", String.valueOf(version.major()),
"java.base", "m1")
.shouldHaveExitValue(0);
}
}
private Runtime.Version targetRuntimeVersion() {
ModuleReference mref = ModulePath.of(Runtime.version(), true, getJmods())
.find("java.base")
.orElseThrow(() -> new RuntimeException("java.base not found from " + getJmods()));
return Runtime.Version.parse(mref.descriptor().version().get().toString());
}
private void jlink(String jar, String image) {
List<String> args = List.of("--output", image,
"--add-modules", "m1",
"--module-path",
getJmods().toString() + File.pathSeparator + jar);
System.out.println("jlink " + args.stream().collect(Collectors.joining(" ")));
int exitCode = JLINK_TOOL.run(System.out, System.err, args.toArray(new String[0]));
Assert.assertEquals(exitCode, 0);
}
}

@ -0,0 +1,58 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8185119: Uninitialized const when using multiple threads
*
* @test
* @option --language=es6
* @run
*/
function f() {
let a;
const b = {};
b.crash; // b is sometimes undefined
function c() {
a; b;
}
}
let count = new java.util.concurrent.atomic.AtomicInteger();
let T = Java.extend(Java.type('java.lang.Thread'), {
run: function() {
for (let j = 0; j < 100; j++) {
f();
}
count.getAndIncrement();
}
});
const threads = [new T(), new T(), new T(), new T()];
threads.forEach(t => t.start());
threads.forEach(t => t.join());
Assert.assertEquals(count.intValue(), 4);