From 60d49e8eaf6b64c33ddd46406c4441f3d409ac55 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 22 Aug 2022 12:26:29 +0200 Subject: [PATCH] made --add-options and --vendor-* jlink plugins persistent --- .../share/classes/java/lang/System.java | 10 +++++ .../java/lang/VersionProps.java.template | 15 +++++--- .../jdk/internal/access/JavaLangAccess.java | 4 ++ .../internal/plugins/AddOptionsPlugin.java | 38 ++++++++++++++++++- .../internal/plugins/AddResourcePlugin.java | 31 ++++++++++++++- .../internal/plugins/VersionPropsPlugin.java | 31 +++++++++++++++ 6 files changed, 119 insertions(+), 10 deletions(-) diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 0f12d2a1f44eb..0aa1c61bba99e 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -2631,6 +2631,16 @@ public StackWalker newStackWalkerInstance(Set options, Continuation continuation) { return StackWalker.newInstance(options, null, contScope, continuation); } + + @Override + public String getVendorPropertyFieldValue(String name) { + switch (name) { + case "VENDOR_VERSION": return VersionProps.VENDOR_VERSION; + case "VENDOR_URL_BUG": return VersionProps.VENDOR_URL_BUG; + case "VENDOR_URL_VM_BUG": return VersionProps.VENDOR_URL_VM_BUG; + default: throw new InternalError("Unknown VersionProps field: " + name); + } + } }); } } diff --git a/src/java.base/share/classes/java/lang/VersionProps.java.template b/src/java.base/share/classes/java/lang/VersionProps.java.template index d58be681f554d..20232d666a6b7 100644 --- a/src/java.base/share/classes/java/lang/VersionProps.java.template +++ b/src/java.base/share/classes/java/lang/VersionProps.java.template @@ -79,18 +79,21 @@ class VersionProps { "@@VENDOR_URL@@"; // The remaining VENDOR_* fields must not be final, - // so that they can be redefined by jlink plugins + // so that they can be redefined by jlink plugins. + // They must also not be private so that they can + // be read by JavaLangAccess. - // This field is read by HotSpot - private static String VENDOR_VERSION = + // This field is read by HotSpot and JavaLangAccess. + static String VENDOR_VERSION = "@@VENDOR_VERSION_STRING@@"; - private static String VENDOR_URL_BUG = + // This field is read by JavaLangAccess. + static String VENDOR_URL_BUG = "@@VENDOR_URL_BUG@@"; - // This field is read by HotSpot + // This field is read by HotSpot and JavaLangAccess. @SuppressWarnings("unused") - private static String VENDOR_URL_VM_BUG = + static String VENDOR_URL_VM_BUG = "@@VENDOR_URL_VM_BUG@@"; /** diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index bc1aeedc7af43..4d442ad846b60 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -537,4 +537,8 @@ public interface JavaLangAccess { StackWalker newStackWalkerInstance(Set options, ContinuationScope contScope, Continuation continuation); + /** + * Gets the value of the field named {@code name} in {@code java.lang.VersionProps}. + */ + String getVendorPropertyFieldValue(String name); } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java index 26c70f3f61712..0b395cea17b67 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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,14 +25,48 @@ package jdk.tools.jlink.internal.plugins; +import java.util.EnumSet; +import java.util.Map; +import java.util.Set; + /** * Plugin to add VM command-line options, by storing them in a resource - * that's read by the VM at startup + * that's read by the VM at startup. The plugin prepend options from + * the resource if it exists in the current Java runtime. */ public final class AddOptionsPlugin extends AddResourcePlugin { + /** + * Value of the options resource in the current Java runtime. + */ + private final String jrtValue; + public AddOptionsPlugin() { super("add-options", "/java.base/jdk/internal/vm/options"); + this.jrtValue = readResource(); } + @Override + public Set getState() { + if (jrtValue == null) { + return super.getState(); + } + // Auto-enable if the current Java runtime has an options resource. + return EnumSet.of(State.AUTO_ENABLED, State.FUNCTIONAL); + } + + @Override + public void configure(Map config) { + var v = config.get(getName()); + if (v == null && jrtValue == null) + throw new AssertionError(); + if (jrtValue != null) { + if (v == null) { + v = jrtValue; + } else { + v = jrtValue + " " + v; + } + } + value = v; + } } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java index f7de6151826a0..91d8b28071f61 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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,7 +25,14 @@ package jdk.tools.jlink.internal.plugins; +import java.io.IOException; +import java.net.URI; import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; import java.util.Map; import java.util.function.Function; @@ -39,7 +46,7 @@ abstract class AddResourcePlugin extends AbstractPlugin { private final String path; - private String value; + protected String value; protected AddResourcePlugin(String name, String p) { super(name); @@ -61,6 +68,26 @@ public boolean hasRawArgument() { return true; } + /** + * Gets the contents of the resource denoted by {@link #path} in the current + * Java runtime if it exists. + * + * @return the contents of the resource as a String or {@code null} if the + * resource does not exist + */ + protected String readResource() throws AssertionError { + try { + FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap()); + Path optionsPath = fs.getPath("/modules" + path); + if (Files.exists(optionsPath)) { + var optionsBytes = Files.readAllBytes(optionsPath); + return new String(optionsBytes, StandardCharsets.UTF_8); + } + } catch (IOException e) { + throw new AssertionError(e); + } + return null; + } @Override public void configure(Map config) { diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java index af241efcea7b8..358067fd6689f 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java @@ -25,8 +25,12 @@ package jdk.tools.jlink.internal.plugins; +import java.util.EnumSet; import java.util.Map; +import java.util.Set; +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassVisitor; import jdk.internal.org.objectweb.asm.ClassWriter; @@ -46,12 +50,20 @@ */ abstract class VersionPropsPlugin extends AbstractPlugin { + private static final JavaLangAccess JLA + = SharedSecrets.getJavaLangAccess(); + private static final String VERSION_PROPS_CLASS = "/java.base/java/lang/VersionProps.class"; private final String field; private String value; + /** + * Value of the java.lang.VersionProps field in the current Java runtime. + */ + protected final String jrtValue; + /** * @param field The name of the java.lang.VersionProps field to be redefined * @param option The option name @@ -59,6 +71,7 @@ abstract class VersionPropsPlugin extends AbstractPlugin { protected VersionPropsPlugin(String field, String option) { super(option); this.field = field; + this.jrtValue = getJRTValue(); } /** @@ -76,6 +89,15 @@ public Category getType() { return Category.TRANSFORMER; } + @Override + public Set getState() { + if (jrtValue.isEmpty()) { + return super.getState(); + } + // Auto-enable if the props field has a non-empty value in the current Java runtime. + return EnumSet.of(State.AUTO_ENABLED, State.FUNCTIONAL); + } + @Override public boolean hasArguments() { return true; @@ -86,9 +108,18 @@ public boolean hasRawArgument() { return true; } + /** + * Gets the value of the props field in the current Java runtime. + */ + private String getJRTValue() { + return JLA.getVendorPropertyFieldValue(field); + } + @Override public void configure(Map config) { var v = config.get(getName()); + if (v == null && !jrtValue.isEmpty()) + v = jrtValue; if (v == null) throw new AssertionError(); value = v;