Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/java.base/share/classes/java/lang/System.java
Original file line number Diff line number Diff line change
Expand Up @@ -2631,6 +2631,16 @@ public StackWalker newStackWalkerInstance(Set<StackWalker.Option> 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);
}
}
});
}
}
15 changes: 9 additions & 6 deletions src/java.base/share/classes/java/lang/VersionProps.java.template
Original file line number Diff line number Diff line change
Expand Up @@ -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@@";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,4 +537,8 @@ public interface JavaLangAccess {
StackWalker newStackWalkerInstance(Set<StackWalker.Option> options,
ContinuationScope contScope,
Continuation continuation);
/**
* Gets the value of the field named {@code name} in {@code java.lang.VersionProps}.
*/
String getVendorPropertyFieldValue(String name);
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<State> 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<String, String> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;

Expand All @@ -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);
Expand All @@ -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<String, String> config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -46,19 +50,28 @@
*/
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
*/
protected VersionPropsPlugin(String field, String option) {
super(option);
this.field = field;
this.jrtValue = getJRTValue();
}

/**
Expand All @@ -76,6 +89,15 @@ public Category getType() {
return Category.TRANSFORMER;
}

@Override
public Set<State> 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;
Expand All @@ -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<String, String> config) {
var v = config.get(getName());
if (v == null && !jrtValue.isEmpty())
v = jrtValue;
if (v == null)
throw new AssertionError();
value = v;
Expand Down