8232080: jlink plugins for vendor information and run-time options

Reviewed-by: ihse, alanb, kvn, bobv, mchung
This commit is contained in:
Mark Reinhold 2019-10-29 08:26:55 -07:00
parent 72b3f81dd4
commit d83df45396
33 changed files with 848 additions and 45 deletions

View File

@ -162,7 +162,9 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
AC_MSG_ERROR([--with-vendor-vm-bug-url must have a value])
elif [ ! [[ $with_vendor_vm_bug_url =~ ^[[:print:]]*$ ]] ]; then
AC_MSG_ERROR([--with-vendor-vm-bug-url contains non-printing characters: $with_vendor_vm_bug_url])
else
elif test "x$with_vendor_vm_bug_url" != x; then
# Only set VENDOR_URL_VM_BUG if '--with-vendor-vm-bug-url' was used and is not empty.
# Otherwise we will use the value from "version-numbers" included above.
VENDOR_URL_VM_BUG="$with_vendor_vm_bug_url"
fi
AC_SUBST(VENDOR_URL_VM_BUG)

View File

@ -23,7 +23,8 @@
# questions.
#
# Default version numbers to use unless overridden by configure
# Default version, product, and vendor information to use,
# unless overridden by configure
DEFAULT_VERSION_FEATURE=14
DEFAULT_VERSION_INTERIM=0
@ -47,6 +48,7 @@ COMPANY_NAME=N/A
HOTSPOT_VM_DISTRO="OpenJDK"
VENDOR_URL=https://openjdk.java.net/
VENDOR_URL_BUG=https://bugreport.java.com/bugreport/
VENDOR_URL_VM_BUG=https://bugreport.java.com/bugreport/crash.jsp
# Might need better names for these
MACOSX_BUNDLE_NAME_BASE="OpenJDK"

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2019, 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,8 @@ $(eval $(call SetupTextFileProcessing, BUILD_VERSION_JAVA, \
@@VENDOR_VERSION_STRING@@ => $(VENDOR_VERSION_STRING) ; \
@@VENDOR@@ => $(COMPANY_NAME) ; \
@@VENDOR_URL@@ => $(VENDOR_URL) ; \
@@VENDOR_URL_BUG@@ => $(VENDOR_URL_BUG), \
@@VENDOR_URL_BUG@@ => $(VENDOR_URL_BUG) ; \
@@VENDOR_URL_VM_BUG@@ => $(VENDOR_URL_VM_BUG), \
))
GENSRC_JAVA_BASE += $(BUILD_VERSION_JAVA)

View File

@ -1529,11 +1529,43 @@ void ClassLoader::initialize() {
// lookup zip library entry points
load_zip_library();
// lookup jimage library entry points
load_jimage_library();
// jimage library entry points are loaded below, in lookup_vm_options
setup_bootstrap_search_path();
}
char* lookup_vm_resource(JImageFile *jimage, const char *jimage_version, const char *path) {
jlong size;
JImageLocationRef location = (*JImageFindResource)(jimage, "java.base", jimage_version, path, &size);
if (location == 0)
return NULL;
char *val = NEW_C_HEAP_ARRAY(char, size+1, mtClass);
(*JImageGetResource)(jimage, location, val, size);
val[size] = '\0';
return val;
}
// Lookup VM options embedded in the modules jimage file
char* ClassLoader::lookup_vm_options() {
jint error;
char modules_path[JVM_MAXPATHLEN];
const char* fileSep = os::file_separator();
// Initialize jimage library entry points
load_jimage_library();
jio_snprintf(modules_path, JVM_MAXPATHLEN, "%s%slib%smodules", Arguments::get_java_home(), fileSep, fileSep);
JImageFile* jimage =(*JImageOpen)(modules_path, &error);
if (jimage == NULL) {
return NULL;
}
const char *jimage_version = get_jimage_version_string();
char *options = lookup_vm_resource(jimage, jimage_version, "jdk/internal/vm/options");
(*JImageClose)(jimage);
return options;
}
#if INCLUDE_CDS
void ClassLoader::initialize_shared_path() {
if (Arguments::is_dumping_archive()) {

View File

@ -411,6 +411,9 @@ class ClassLoader: AllStatic {
static char* skip_uri_protocol(char* source);
static void record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS);
#endif
static char* lookup_vm_options();
static JImageLocationRef jimage_find_resource(JImageFile* jf, const char* module_name,
const char* file_name, jlong &size);

View File

@ -135,6 +135,8 @@
template(java_lang_VersionProps, "java/lang/VersionProps") \
template(java_runtime_name_name, "java_runtime_name") \
template(java_runtime_version_name, "java_runtime_version") \
template(java_runtime_vendor_version_name, "VENDOR_VERSION") \
template(java_runtime_vendor_vm_bug_url_name, "VENDOR_URL_VM_BUG") \
\
/* system initialization */ \
template(initPhase1_name, "initPhase1") \

View File

@ -133,6 +133,7 @@ static const char* flag_value_origin_to_string(JVMFlag::Flags origin) {
case JVMFlag::ERGONOMIC: return "Ergonomic";
case JVMFlag::ATTACH_ON_DEMAND: return "Attach on demand";
case JVMFlag::INTERNAL: return "Internal";
case JVMFlag::JIMAGE_RESOURCE: return "JImage resource";
default: ShouldNotReachHere(); return "";
}
}

View File

@ -60,12 +60,6 @@
#include "jfr/jfr.hpp"
#endif
// Note: This is a special bug reporting site for the JVM
#ifdef VENDOR_URL_VM_BUG
# define DEFAULT_VENDOR_URL_BUG VENDOR_URL_VM_BUG
#else
# define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp"
#endif
#define DEFAULT_JAVA_LAUNCHER "generic"
char* Arguments::_jvm_flags_file = NULL;
@ -80,7 +74,7 @@ size_t Arguments::_conservative_max_heap_alignment = 0;
Arguments::Mode Arguments::_mode = _mixed;
bool Arguments::_java_compiler = false;
bool Arguments::_xdebug_mode = false;
const char* Arguments::_java_vendor_url_bug = DEFAULT_VENDOR_URL_BUG;
const char* Arguments::_java_vendor_url_bug = NULL;
const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER;
bool Arguments::_sun_java_launcher_is_altjvm = false;
@ -1422,12 +1416,16 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop
os::free(old_java_command);
}
} else if (strcmp(key, "java.vendor.url.bug") == 0) {
// If this property is set on the command line then its value will be
// displayed in VM error logs as the URL at which to submit such logs.
// Normally the URL displayed in error logs is different from the value
// of this system property, so a different property should have been
// used here, but we leave this as-is in case someone depends upon it.
const char* old_java_vendor_url_bug = _java_vendor_url_bug;
// save it in _java_vendor_url_bug, so JVM fatal error handler can access
// its value without going through the property list or making a Java call.
_java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
if (old_java_vendor_url_bug != NULL) {
os::free((void *)old_java_vendor_url_bug);
}
}
@ -2185,7 +2183,8 @@ Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
// Parse JavaVMInitArgs structure
jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
jint Arguments::parse_vm_init_args(const JavaVMInitArgs *vm_options_args,
const JavaVMInitArgs *java_tool_options_args,
const JavaVMInitArgs *java_options_args,
const JavaVMInitArgs *cmd_line_args) {
bool patch_mod_javabase = false;
@ -2203,9 +2202,15 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
// Setup flags for mixed which is the default
set_mode_flags(_mixed);
// Parse args structure generated from java.base vm options resource
jint result = parse_each_vm_init_arg(vm_options_args, &patch_mod_javabase, JVMFlag::JIMAGE_RESOURCE);
if (result != JNI_OK) {
return result;
}
// Parse args structure generated from JAVA_TOOL_OPTIONS environment
// variable (if present).
jint result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, JVMFlag::ENVIRON_VAR);
result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, JVMFlag::ENVIRON_VAR);
if (result != JNI_OK) {
return result;
}
@ -2711,7 +2716,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
needs_module_property_warning = true;
continue;
}
if (!add_property(tail)) {
return JNI_ENOMEM;
}
@ -3832,16 +3836,19 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
const char* hotspotrc = ".hotspotrc";
bool settings_file_specified = false;
bool needs_hotspotrc_warning = false;
ScopedVMInitArgs initial_vm_options_args("");
ScopedVMInitArgs initial_java_tool_options_args("env_var='JAVA_TOOL_OPTIONS'");
ScopedVMInitArgs initial_java_options_args("env_var='_JAVA_OPTIONS'");
// Pointers to current working set of containers
JavaVMInitArgs* cur_cmd_args;
JavaVMInitArgs* cur_vm_options_args;
JavaVMInitArgs* cur_java_options_args;
JavaVMInitArgs* cur_java_tool_options_args;
// Containers for modified/expanded options
ScopedVMInitArgs mod_cmd_args("cmd_line_args");
ScopedVMInitArgs mod_vm_options_args("vm_options_args");
ScopedVMInitArgs mod_java_tool_options_args("env_var='JAVA_TOOL_OPTIONS'");
ScopedVMInitArgs mod_java_options_args("env_var='_JAVA_OPTIONS'");
@ -3857,6 +3864,16 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
return code;
}
// Parse the options in the /java.base/jdk/internal/vm/options resource, if present
char *vmoptions = ClassLoader::lookup_vm_options();
if (vmoptions != NULL) {
code = parse_options_buffer("vm options resource", vmoptions, strlen(vmoptions), &initial_vm_options_args);
FREE_C_HEAP_ARRAY(char, vmoptions);
if (code != JNI_OK) {
return code;
}
}
code = expand_vm_options_as_needed(initial_java_tool_options_args.get(),
&mod_java_tool_options_args,
&cur_java_tool_options_args);
@ -3878,6 +3895,13 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
return code;
}
code = expand_vm_options_as_needed(initial_vm_options_args.get(),
&mod_vm_options_args,
&cur_vm_options_args);
if (code != JNI_OK) {
return code;
}
const char* flags_file = Arguments::get_jvm_flags_file();
settings_file_specified = (flags_file != NULL);
@ -3915,7 +3939,8 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
}
// Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS
jint result = parse_vm_init_args(cur_java_tool_options_args,
jint result = parse_vm_init_args(cur_vm_options_args,
cur_java_tool_options_args,
cur_java_options_args,
cur_cmd_args);

View File

@ -427,7 +427,8 @@ class Arguments : AllStatic {
static void handle_extra_cms_flags(const char* msg);
static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
static jint parse_vm_init_args(const JavaVMInitArgs *vm_options_args,
const JavaVMInitArgs *java_tool_options_args,
const JavaVMInitArgs *java_options_args,
const JavaVMInitArgs *cmd_line_args);
static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, JVMFlag::Flags origin);

View File

@ -709,6 +709,8 @@ void JVMFlag::print_origin(outputStream* st, unsigned int width) {
st->print("attach"); break;
case INTERNAL:
st->print("internal"); break;
case JIMAGE_RESOURCE:
st->print("jimage"); break;
}
st->print("}");
}

View File

@ -44,8 +44,9 @@ struct JVMFlag {
ERGONOMIC = 5,
ATTACH_ON_DEMAND = 6,
INTERNAL = 7,
JIMAGE_RESOURCE = 8,
LAST_VALUE_ORIGIN = INTERNAL,
LAST_VALUE_ORIGIN = JIMAGE_RESOURCE,
VALUE_ORIGIN_BITS = 4,
VALUE_ORIGIN_MASK = right_n_bits(VALUE_ORIGIN_BITS),

View File

@ -690,6 +690,8 @@ void vm_shutdown_during_initialization(const char* error, const char* message) {
JDK_Version JDK_Version::_current;
const char* JDK_Version::_runtime_name;
const char* JDK_Version::_runtime_version;
const char* JDK_Version::_runtime_vendor_version;
const char* JDK_Version::_runtime_vendor_vm_bug_url;
void JDK_Version::initialize() {
jdk_version_info info;

View File

@ -67,6 +67,8 @@ class JDK_Version {
static JDK_Version _current;
static const char* _runtime_name;
static const char* _runtime_version;
static const char* _runtime_vendor_version;
static const char* _runtime_vendor_vm_bug_url;
uint8_t _major;
uint8_t _minor;
@ -142,6 +144,20 @@ class JDK_Version {
_runtime_version = version;
}
static const char* runtime_vendor_version() {
return _runtime_vendor_version;
}
static void set_runtime_vendor_version(const char* vendor_version) {
_runtime_vendor_version = vendor_version;
}
static const char* runtime_vendor_vm_bug_url() {
return _runtime_vendor_vm_bug_url;
}
static void set_runtime_vendor_vm_bug_url(const char* vendor_vm_bug_url) {
_runtime_vendor_vm_bug_url = vendor_vm_bug_url;
}
};
#endif // SHARE_RUNTIME_JAVA_HPP

View File

@ -1090,6 +1090,8 @@ static oop create_initial_thread(Handle thread_group, JavaThread* thread,
char java_runtime_name[128] = "";
char java_runtime_version[128] = "";
char java_runtime_vendor_version[128] = "";
char java_runtime_vendor_vm_bug_url[128] = "";
// extract the JRE name from java.lang.VersionProps.java_runtime_name
static const char* get_java_runtime_name(TRAPS) {
@ -1135,6 +1137,50 @@ static const char* get_java_runtime_version(TRAPS) {
}
}
// extract the JRE vendor version from java.lang.VersionProps.VENDOR_VERSION
static const char* get_java_runtime_vendor_version(TRAPS) {
Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(),
Handle(), Handle(), CHECK_AND_CLEAR_NULL);
fieldDescriptor fd;
bool found = k != NULL &&
InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_vendor_version_name(),
vmSymbols::string_signature(), &fd);
if (found) {
oop name_oop = k->java_mirror()->obj_field(fd.offset());
if (name_oop == NULL) {
return NULL;
}
const char* name = java_lang_String::as_utf8_string(name_oop,
java_runtime_vendor_version,
sizeof(java_runtime_vendor_version));
return name;
} else {
return NULL;
}
}
// extract the JRE vendor VM bug URL from java.lang.VersionProps.VENDOR_URL_VM_BUG
static const char* get_java_runtime_vendor_vm_bug_url(TRAPS) {
Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(),
Handle(), Handle(), CHECK_AND_CLEAR_NULL);
fieldDescriptor fd;
bool found = k != NULL &&
InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_vendor_vm_bug_url_name(),
vmSymbols::string_signature(), &fd);
if (found) {
oop name_oop = k->java_mirror()->obj_field(fd.offset());
if (name_oop == NULL) {
return NULL;
}
const char* name = java_lang_String::as_utf8_string(name_oop,
java_runtime_vendor_vm_bug_url,
sizeof(java_runtime_vendor_vm_bug_url));
return name;
} else {
return NULL;
}
}
// General purpose hook into Java code, run once when the VM is initialized.
// The Java library method itself may be changed independently from the VM.
static void call_postVMInitHook(TRAPS) {
@ -3656,9 +3702,11 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
// Phase 1 of the system initialization in the library, java.lang.System class initialization
call_initPhase1(CHECK);
// get the Java runtime name after java.lang.System is initialized
// get the Java runtime name, version, and vendor info after java.lang.System is initialized
JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
JDK_Version::set_runtime_vendor_version(get_java_runtime_vendor_version(THREAD));
JDK_Version::set_runtime_vendor_vm_bug_url(get_java_runtime_vendor_vm_bug_url(THREAD));
// an instance of OutOfMemory exception has been allocated earlier
initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK);

View File

@ -2612,6 +2612,7 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
declare_constant(JVMFlag::ERGONOMIC) \
declare_constant(JVMFlag::ATTACH_ON_DEMAND) \
declare_constant(JVMFlag::INTERNAL) \
declare_constant(JVMFlag::JIMAGE_RESOURCE) \
declare_constant(JVMFlag::VALUE_ORIGIN_MASK) \
declare_constant(JVMFlag::ORIG_COMMAND_LINE)

View File

@ -130,7 +130,10 @@ static void print_bug_submit_message(outputStream *out, Thread *thread) {
if (out == NULL) return;
out->print_raw_cr("# If you would like to submit a bug report, please visit:");
out->print_raw ("# ");
out->print_raw_cr(Arguments::java_vendor_url_bug());
const char *url = Arguments::java_vendor_url_bug();
if (url == NULL || *url == '\0')
url = JDK_Version::runtime_vendor_vm_bug_url();
out->print_raw_cr(url);
// If the crash is in native code, encourage user to submit a bug to the
// provider of that code.
if (thread && thread->is_Java_thread() &&
@ -321,15 +324,19 @@ static void report_vm_version(outputStream* st, char* buf, int buflen) {
JDK_Version::runtime_name() : "";
const char* runtime_version = JDK_Version::runtime_version() != NULL ?
JDK_Version::runtime_version() : "";
const char* vendor_version = JDK_Version::runtime_vendor_version() != NULL ?
JDK_Version::runtime_vendor_version() : "";
const char* jdk_debug_level = VM_Version::printable_jdk_debug_level() != NULL ?
VM_Version::printable_jdk_debug_level() : "";
st->print_cr("# JRE version: %s (%s) (%sbuild %s)", runtime_name, buf,
jdk_debug_level, runtime_version);
st->print_cr("# JRE version: %s%s%s (%s) (%sbuild %s)", runtime_name,
(*vendor_version != '\0') ? " " : "", vendor_version,
buf, jdk_debug_level, runtime_version);
// This is the long version with some default settings added
st->print_cr("# Java VM: %s (%s%s, %s%s%s%s%s, %s, %s)",
st->print_cr("# Java VM: %s%s%s (%s%s, %s%s%s%s%s, %s, %s)",
VM_Version::vm_name(),
(*vendor_version != '\0') ? " " : "", vendor_version,
jdk_debug_level,
VM_Version::vm_release(),
VM_Version::vm_info_string(),

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2019, 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
@ -42,9 +42,11 @@ class VersionProps {
private static final String java_version_date =
"@@VERSION_DATE@@";
// This field is read by HotSpot
private static final String java_runtime_name =
"@@RUNTIME_NAME@@";
// This field is read by HotSpot
private static final String java_runtime_version =
"@@VERSION_STRING@@";
@ -69,22 +71,26 @@ class VersionProps {
private static final String CLASSFILE_MAJOR_MINOR =
"@@VERSION_CLASSFILE_MAJOR@@.@@VERSION_CLASSFILE_MINOR@@";
private static final String VENDOR_VERSION_STRING =
"@@VENDOR_VERSION_STRING@@";
private static final String vendor_version =
(!VENDOR_VERSION_STRING.isEmpty()
? " " + VENDOR_VERSION_STRING : "");
private static final String VENDOR =
"@@VENDOR@@";
private static final String VENDOR_URL =
"@@VENDOR_URL@@";
private static final String VENDOR_URL_BUG =
// The remaining VENDOR_* fields must not be final,
// so that they can be redefined by jlink plugins
// This field is read by HotSpot
private static String VENDOR_VERSION =
"@@VENDOR_VERSION_STRING@@";
private static String VENDOR_URL_BUG =
"@@VENDOR_URL_BUG@@";
// This field is read by HotSpot
private static String VENDOR_URL_VM_BUG =
"@@VENDOR_URL_VM_BUG@@";
/**
* Initialize system properties using build provided values.
*
@ -95,8 +101,8 @@ class VersionProps {
props.put("java.version.date", java_version_date);
props.put("java.runtime.version", java_runtime_version);
props.put("java.runtime.name", java_runtime_name);
if (!VENDOR_VERSION_STRING.isEmpty())
props.put("java.vendor.version", VENDOR_VERSION_STRING);
if (!VENDOR_VERSION.isEmpty())
props.put("java.vendor.version", VENDOR_VERSION);
props.put("java.class.version", CLASSFILE_MAJOR_MINOR);
@ -216,6 +222,9 @@ class VersionProps {
jdk_debug_level = jdk_debug_level + " ";
}
String vendor_version = (VENDOR_VERSION.isEmpty()
? "" : " " + VENDOR_VERSION);
ps.println(java_runtime_name + vendor_version
+ " (" + jdk_debug_level + "build " + java_runtime_version + ")");

View File

@ -35,7 +35,8 @@ public enum Flags {
MANAGEMENT ("Management"),
ERGONOMIC ("Ergonomic"),
ATTACH_ON_DEMAND ("Attach on demand"),
INTERNAL ("Internal");
INTERNAL ("Internal"),
JIMAGE_RESOURCE ("JImage");
private final String value;

View File

@ -114,6 +114,7 @@ public class VM {
public static int Flags_ERGONOMIC;
public static int Flags_ATTACH_ON_DEMAND;
public static int Flags_INTERNAL;
public static int Flags_JIMAGE_RESOURCE;
private static int Flags_VALUE_ORIGIN_MASK;
private static int Flags_ORIG_COMMAND_LINE;
/** This is only present in a non-core build */
@ -200,6 +201,8 @@ public class VM {
return "attach";
} else if (origin == Flags_INTERNAL) {
return "internal";
} else if (origin == Flags_JIMAGE_RESOURCE) {
return "jimage";
} else {
throw new IllegalStateException(
"Unknown flag origin " + origin + " is detected in " + name);
@ -484,6 +487,7 @@ public class VM {
Flags_ERGONOMIC = db.lookupIntConstant("JVMFlag::ERGONOMIC").intValue();
Flags_ATTACH_ON_DEMAND = db.lookupIntConstant("JVMFlag::ATTACH_ON_DEMAND").intValue();
Flags_INTERNAL = db.lookupIntConstant("JVMFlag::INTERNAL").intValue();
Flags_JIMAGE_RESOURCE = db.lookupIntConstant("JVMFlag::JIMAGE_RESOURCE").intValue();
Flags_VALUE_ORIGIN_MASK = db.lookupIntConstant("JVMFlag::VALUE_ORIGIN_MASK").intValue();
Flags_ORIG_COMMAND_LINE = db.lookupIntConstant("JVMFlag::ORIG_COMMAND_LINE").intValue();
oopSize = db.lookupIntConstant("oopSize").intValue();

View File

@ -50,6 +50,7 @@ public final class ImagePluginConfiguration {
static {
CATEGORIES_ORDER.add(Category.FILTER);
CATEGORIES_ORDER.add(Category.ADDER);
CATEGORIES_ORDER.add(Category.TRANSFORMER);
CATEGORIES_ORDER.add(Category.MODULEINFO_TRANSFORMER);
CATEGORIES_ORDER.add(Category.SORTER);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, 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
@ -325,7 +325,7 @@ public final class TaskHelper {
Map<String, String> m = addArgumentMap(plugin);
// handle one or more arguments
if (arg.indexOf(':') == -1) {
if (plugin.hasRawArgument() || arg.indexOf(':') == -1) {
// single argument case
m.put(option, arg);
} else {

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2019, 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.tools.jlink.internal.plugins;
import java.io.*;
import java.nio.charset.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import jdk.tools.jlink.plugin.*;
/**
* Plugin to add VM command-line options, by storing them in a resource
* that's read by the VM at startup
*/
public final class AddOptionsPlugin extends AddResourcePlugin {
public AddOptionsPlugin() {
super("add-options", "/java.base/jdk/internal/vm/options");
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2019, 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.tools.jlink.internal.plugins;
import java.io.*;
import java.nio.charset.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import jdk.tools.jlink.plugin.*;
/**
* Base plugin to add a resource
*/
abstract class AddResourcePlugin implements Plugin {
private final String name;
private final String path;
private String value;
protected AddResourcePlugin(String n, String p) {
name = n;
path = p;
}
@Override
public String getName() {
return name;
}
@Override
public String getDescription() {
return PluginsResourceBundle.getDescription(name);
}
@Override
public Category getType() {
return Category.ADDER;
}
@Override
public boolean hasArguments() {
return true;
}
@Override
public boolean hasRawArgument() {
return true;
}
@Override
public String getArgumentsDescription() {
return PluginsResourceBundle.getArgument(name);
}
@Override
public void configure(Map<String, String> config) {
var v = config.get(name);
if (v == null)
throw new AssertionError();
value = v;
}
@Override
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy(Function.identity(), out);
out.add(ResourcePoolEntry.create(path,
value.getBytes(StandardCharsets.UTF_8)));
return out.build();
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2019, 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.tools.jlink.internal.plugins;
/**
* Plugin to set the vendor bug URL, by redefining the static field
* java.lang.VersionProps.VENDOR_URL_BUG
*/
public final class VendorBugURLPlugin extends VersionPropsPlugin {
public VendorBugURLPlugin() {
super("VENDOR_URL_BUG", "vendor-bug-url");
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2019, 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.tools.jlink.internal.plugins;
/**
* Plugin to set the vendor VM bug URL, by redefining the static field
* java.lang.VersionProps.VENDOR_URL_VM_BUG
*/
public final class VendorVMBugURLPlugin extends VersionPropsPlugin {
public VendorVMBugURLPlugin() {
super("VENDOR_URL_VM_BUG", "vendor-vm-bug-url");
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2019, 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.tools.jlink.internal.plugins;
/**
* Plugin to set the vendor version string, by redefining the static field
* java.lang.VersionProps.VENDOR_VERSION
*/
public final class VendorVersionPlugin extends VersionPropsPlugin {
public VendorVersionPlugin() {
super("VENDOR_VERSION");
}
}

View File

@ -0,0 +1,175 @@
/*
* Copyright (c) 2019, 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.tools.jlink.internal.plugins;
import java.io.*;
import java.nio.charset.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import jdk.tools.jlink.plugin.*;
import jdk.internal.org.objectweb.asm.*;
import static java.lang.System.out;
/**
* Base plugin to update a static field in java.lang.VersionProps
*/
abstract class VersionPropsPlugin implements Plugin {
private static final String VERSION_PROPS_CLASS
= "/java.base/java/lang/VersionProps.class";
private final String name;
private final String field;
private String value;
/**
* @param field The name of the java.lang.VersionProps field to be redefined
* @param option The option name
*/
protected VersionPropsPlugin(String field, String option) {
this.field = field;
this.name = option;
}
/**
* Shorthand constructor for when the option name can be derived from the
* name of the field.
*
* @param field The name of the java.lang.VersionProps field to be redefined
*/
protected VersionPropsPlugin(String field) {
this(field, field.toLowerCase().replace('_', '-'));
}
@Override
public String getName() {
return name;
}
@Override
public String getDescription() {
return PluginsResourceBundle.getDescription(name);
}
@Override
public Category getType() {
return Category.TRANSFORMER;
}
@Override
public boolean hasArguments() {
return true;
}
@Override
public boolean hasRawArgument() {
return true;
}
@Override
public String getArgumentsDescription() {
return PluginsResourceBundle.getArgument(name);
}
@Override
public void configure(Map<String, String> config) {
var v = config.get(name);
if (v == null)
throw new AssertionError();
value = v;
}
private boolean redefined = false;
private byte[] redefine(byte[] classFile) {
var cr = new ClassReader(classFile);
var cw = new ClassWriter(0);
cr.accept(new ClassVisitor(Opcodes.ASM7, cw) {
public MethodVisitor visitMethod(int access,
String name,
String desc,
String sig,
String[] xs)
{
if (name.equals("<clinit>"))
return new MethodVisitor(Opcodes.ASM7,
super.visitMethod(access,
name,
desc,
sig,
xs))
{
public void visitFieldInsn(int opcode,
String owner,
String name,
String desc)
{
if (opcode == Opcodes.PUTSTATIC
&& name.equals(field))
{
// Discard the original value
super.visitInsn(Opcodes.POP);
// Load the value that we want
super.visitLdcInsn(value);
redefined = true;
}
super.visitFieldInsn(opcode, owner,
name, desc);
}
};
else
return super.visitMethod(access, name, desc, sig, xs);
}
}, 0);
return cw.toByteArray();
}
@Override
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy(res -> {
if (res.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
if (res.path().equals(VERSION_PROPS_CLASS)) {
return res.copyWithContent(redefine(res.contentBytes()));
}
}
return res;
}, out);
if (!redefined)
throw new AssertionError(field);
return out.build();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, 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
@ -39,6 +39,7 @@ public interface Plugin {
* Order of categories matches the plugin sort order.
* <ol>
* <li>FILTER: Filter in/out resources or files.</li>
* <li>ADDER: Add resources or files.</li>
* <li>TRANSFORMER: Transform resources or files(eg: refactoring, bytecode
* manipulation).</li>
* <li>MODULEINFO_TRANSFORMER: Transform only module-info.class</li>
@ -52,6 +53,7 @@ public interface Plugin {
*/
public enum Category {
FILTER("FILTER"),
ADDER("ADDER"),
TRANSFORMER("TRANSFORMER"),
MODULEINFO_TRANSFORMER("MODULEINFO_TRANSFORMER"),
SORTER("SORTER"),
@ -152,6 +154,10 @@ public interface Plugin {
return false;
}
public default boolean hasRawArgument() {
return false;
}
/**
* The plugin argument(s) description.
* @return The argument(s) description.

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2015, 2019, 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
@ -23,6 +23,13 @@
# questions.
#
add-options.argument=<options>
add-options.description=\
Prepend the specified <options> string, which may include\n\
whitespace, before any other options when invoking the virtual machine\n\
in the resulting image.
release-info.argument=<file>|add:<key1>=<value1>:<key2>=<value2>:...|del:<key list>
release-info.description=\
@ -105,6 +112,24 @@ Strip Java debug attributes from classes in the output image
strip-native-commands.description=\
Exclude native commands (such as java/java.exe) from the image
vendor-version.argument=<vendor-version>
vendor-version.description=\
Override the vendor version string baked into the build, if any.\n\
The value of the system property "java.vendor.version" will be <vendor-version>.
vendor-bug-url.argument=<vendor-bug-url>
vendor-bug-url.description=\
Override the vendor bug URL baked into the build. The value\n\
of the system property "java.vendor.url.bug" will be <vendor-url-bug>.
vendor-vm-bug-url.argument=<vendor-vm-bug-url>
vendor-vm-bug-url.description=\
Override the vendor VM bug URL baked into the build. The URL\n\
displayed in VM error logs will be <vendor-vm-bug-url>.
vm.argument=<client|server|minimal|all>
vm.description=\

View File

@ -72,5 +72,10 @@ module jdk.jlink {
jdk.tools.jlink.internal.plugins.ExcludeVMPlugin,
jdk.tools.jlink.internal.plugins.IncludeLocalesPlugin,
jdk.tools.jlink.internal.plugins.GenerateJLIClassesPlugin,
jdk.tools.jlink.internal.plugins.ReleaseInfoPlugin;
}
jdk.tools.jlink.internal.plugins.ReleaseInfoPlugin,
jdk.tools.jlink.internal.plugins.AddOptionsPlugin,
jdk.tools.jlink.internal.plugins.VendorBugURLPlugin,
jdk.tools.jlink.internal.plugins.VendorVMBugURLPlugin,
jdk.tools.jlink.internal.plugins.VendorVersionPlugin;
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2019, 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 jdk.test.lib.process.*;
import tests.Helper;
/* @test
* @bug 8232080
* @summary Test the --add-options plugin
* @library ../../lib
* @library /test/lib
* @modules java.base/jdk.internal.jimage
* jdk.jdeps/com.sun.tools.classfile
* jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jmod
* jdk.jlink/jdk.tools.jimage
* jdk.compiler
* @build tests.*
* @run main AddOptionsPluginTest
*/
public class AddOptionsPluginTest {
private static final String PROP = "add.options.plugin.test";
private static final String VALUE = "xyzzy";
private static final String OPTS = "-D" + PROP + "=" + VALUE;
public static void main(String[] args) throws Throwable {
Helper helper = Helper.newHelper();
if (helper == null) {
System.err.println("Test not run");
return;
}
var module = "addoptions";
helper.generateDefaultJModule(module);
var image = helper.generateDefaultImage(new String[] { "--add-options", OPTS },
module)
.assertSuccess();
helper.checkImage(image, module, null, null);
var launcher = image.resolve("bin/java"
+ (System.getProperty("os.name").startsWith("Windows")
? ".exe" : ""));
var oa = ProcessTools.executeProcess(launcher.toString(),
"-XshowSettings:properties", "--version");
oa.stderrShouldMatch("^ +" + PROP + " = " + VALUE + "$");
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2019, 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 jdk.test.lib.process.*;
import tests.Helper;
/* @test
* @bug 8232080
* @summary Test the --vendor-version --vendor-url-bug plugins
* @library ../../lib
* @library /test/lib
* @modules java.base/jdk.internal.jimage
* jdk.jdeps/com.sun.tools.classfile
* jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jmod
* jdk.jlink/jdk.tools.jimage
* jdk.compiler
* @build tests.*
* @run main VendorInfoPluginsTest
*/
public class VendorInfoPluginsTest {
public static class Crasher {
public static void main(String ... args) throws Exception {
var uc = Class.forName("sun.misc.Unsafe");
var f = uc.getDeclaredField("theUnsafe");
f.setAccessible(true);
var u = (sun.misc.Unsafe)f.get(null);
for (long a = 0; a < Long.MAX_VALUE; a += 8)
u.putLong(a, -1L);
}
}
private static final String VERSION = "XyzzyVM 3.14.15";
private static final String BUG_URL = "https://bugs.xyzzy.com/";
private static final String VM_BUG_URL = "https://bugs.xyzzy.com/crash/";
public static void main(String[] args) throws Throwable {
Helper helper = Helper.newHelper();
if (helper == null) {
System.err.println("Test not run");
return;
}
var module = "vendorinfo";
helper.generateDefaultJModule(module);
var image = helper.generateDefaultImage(new String[] {
"--add-modules", "jdk.unsupported",
"--vendor-version", VERSION,
"--vendor-bug-url", BUG_URL,
"--vendor-vm-bug-url", VM_BUG_URL },
module).assertSuccess();
helper.checkImage(image, module, null, null);
// Properties and --version
var launcher
= image.resolve("bin/java"
+ (System.getProperty("os.name").startsWith("Windows")
? ".exe" : "")).toString();
var oa = ProcessTools.executeProcess(launcher,
"-XshowSettings:properties",
"--version");
oa.stderrShouldMatch("^ +java.vendor.url.bug = " + BUG_URL + "$");
oa.stderrShouldMatch("^ +java.vendor.version = " + VERSION + "$");
oa.stdoutShouldMatch("^.*Runtime Environment " + VERSION + " \\(build.*$");
oa.stdoutShouldMatch("^.*Server VM " + VERSION + " \\(build.*$");
// VM error log
oa = ProcessTools.executeProcess(launcher,
"--class-path",
System.getProperty("test.classes"),
"VendorInfoPluginsTest$Crasher");
oa.stdoutShouldMatch("^# +" + VM_BUG_URL + "$");
oa.stdoutShouldMatch("^.*Runtime Environment " + VERSION + " \\(.*$");
oa.stdoutShouldMatch("^.*Server VM " + VERSION + " \\(.*$");
}
}

View File

@ -309,7 +309,7 @@ public class CDSTestUtils {
// exceptions match. Pass null if you wish not to re-throw any exception.
public static void checkCommonExecExceptions(OutputAnalyzer output, Exception e)
throws Exception {
if (output.getStdout().contains("http://bugreport.java.com/bugreport/crash.jsp")) {
if (output.getStdout().contains("https://bugreport.java.com/bugreport/crash.jsp")) {
throw new RuntimeException("Hotspot crashed");
}
if (output.getStdout().contains("TEST FAILED")) {