8236075: Minor bootstrap improvements
Reviewed-by: mchung, alanb
This commit is contained in:
parent
3cf8b34d54
commit
c639682887
@ -1564,7 +1564,7 @@ void SystemDictionary::define_instance_class(InstanceKlass* k, TRAPS) {
|
||||
unsigned int d_hash = dictionary->compute_hash(name_h);
|
||||
check_constraints(d_hash, k, class_loader_h, true, CHECK);
|
||||
|
||||
// Register class just loaded with class loader (placed in Vector)
|
||||
// Register class just loaded with class loader (placed in ArrayList)
|
||||
// Note we do this before updating the dictionary, as this can
|
||||
// fail with an OutOfMemoryError (if it does, we will *not* put this
|
||||
// class in the dictionary and will not update the class hierarchy).
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, 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,11 +31,6 @@ class ClassLoaderHelper {
|
||||
|
||||
private ClassLoaderHelper() {}
|
||||
|
||||
/**
|
||||
* Indicates, whether PATH env variable is allowed to contain quoted entries.
|
||||
*/
|
||||
static final boolean allowsQuotedPathElements = false;
|
||||
|
||||
/**
|
||||
* Returns an alternate path name for the given file
|
||||
* such that if the original pathname did not exist, then the
|
||||
@ -50,4 +45,25 @@ class ClassLoaderHelper {
|
||||
}
|
||||
return new File(name.substring(0, index) + ".jnilib");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a PATH env variable.
|
||||
*
|
||||
* Empty elements will be replaced by dot.
|
||||
*/
|
||||
static String[] parsePath(String ldPath) {
|
||||
char ps = File.pathSeparatorChar;
|
||||
ArrayList<String> paths = new ArrayList<>();
|
||||
int pathStart = 0;
|
||||
int pathEnd;
|
||||
while ((pathEnd = ldPath.indexOf(ps, pathStart)) >= 0) {
|
||||
paths.add((pathStart < pathEnd) ?
|
||||
ldPath.substring(pathStart, pathEnd) : ".");
|
||||
pathStart = pathEnd + 1;
|
||||
}
|
||||
int ldLen = ldPath.length();
|
||||
paths.add((pathStart < ldLen) ?
|
||||
ldPath.substring(pathStart, ldLen) : ".");
|
||||
return paths.toArray(new String[paths.size()]);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -40,20 +40,19 @@ import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.Vector;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
@ -69,6 +68,7 @@ import jdk.internal.misc.VM;
|
||||
import jdk.internal.ref.CleanerFactory;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.util.StaticProperty;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
@ -303,14 +303,14 @@ public abstract class ClassLoader {
|
||||
private final ConcurrentHashMap<String, Object> parallelLockMap;
|
||||
|
||||
// Maps packages to certs
|
||||
private final Map <String, Certificate[]> package2certs;
|
||||
private final ConcurrentHashMap<String, Certificate[]> package2certs;
|
||||
|
||||
// Shared among all packages with unsigned classes
|
||||
private static final Certificate[] nocerts = new Certificate[0];
|
||||
|
||||
// The classes loaded by this class loader. The only purpose of this table
|
||||
// is to keep the classes from being GC'ed until the loader is GC'ed.
|
||||
private final Vector<Class<?>> classes = new Vector<>();
|
||||
private final ArrayList<Class<?>> classes = new ArrayList<>();
|
||||
|
||||
// The "default" domain. Set as the default ProtectionDomain on newly
|
||||
// created classes.
|
||||
@ -320,7 +320,9 @@ public abstract class ClassLoader {
|
||||
|
||||
// Invoked by the VM to record every loaded class with this loader.
|
||||
void addClass(Class<?> c) {
|
||||
classes.addElement(c);
|
||||
synchronized (classes) {
|
||||
classes.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
// The packages defined in this class loader. Each package name is
|
||||
@ -378,14 +380,13 @@ public abstract class ClassLoader {
|
||||
this.unnamedModule = new Module(this);
|
||||
if (ParallelLoaders.isRegistered(this.getClass())) {
|
||||
parallelLockMap = new ConcurrentHashMap<>();
|
||||
package2certs = new ConcurrentHashMap<>();
|
||||
assertionLock = new Object();
|
||||
} else {
|
||||
// no finer-grained lock; lock on the classloader instance
|
||||
parallelLockMap = null;
|
||||
package2certs = new Hashtable<>();
|
||||
assertionLock = this;
|
||||
}
|
||||
this.package2certs = new ConcurrentHashMap<>();
|
||||
this.nameAndId = nameAndId(this);
|
||||
}
|
||||
|
||||
@ -1135,18 +1136,8 @@ public abstract class ClassLoader {
|
||||
if (cs != null) {
|
||||
certs = cs.getCertificates();
|
||||
}
|
||||
Certificate[] pcerts = null;
|
||||
if (parallelLockMap == null) {
|
||||
synchronized (this) {
|
||||
pcerts = package2certs.get(pname);
|
||||
if (pcerts == null) {
|
||||
package2certs.put(pname, (certs == null? nocerts:certs));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).
|
||||
putIfAbsent(pname, (certs == null? nocerts:certs));
|
||||
}
|
||||
certs = certs == null ? nocerts : certs;
|
||||
Certificate[] pcerts = package2certs.putIfAbsent(pname, certs);
|
||||
if (pcerts != null && !compareCerts(pcerts, certs)) {
|
||||
throw new SecurityException("class \"" + name
|
||||
+ "\"'s signer information does not match signer information"
|
||||
@ -1158,13 +1149,10 @@ public abstract class ClassLoader {
|
||||
* check to make sure the certs for the new class (certs) are the same as
|
||||
* the certs for the first class inserted in the package (pcerts)
|
||||
*/
|
||||
private boolean compareCerts(Certificate[] pcerts,
|
||||
Certificate[] certs)
|
||||
{
|
||||
// certs can be null, indicating no certs.
|
||||
if ((certs == null) || (certs.length == 0)) {
|
||||
private boolean compareCerts(Certificate[] pcerts, Certificate[] certs) {
|
||||
// empty array fast-path
|
||||
if (certs.length == 0)
|
||||
return pcerts.length == 0;
|
||||
}
|
||||
|
||||
// the length must be the same at this point
|
||||
if (certs.length != pcerts.length)
|
||||
@ -2005,17 +1993,6 @@ public abstract class ClassLoader {
|
||||
return scl;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize default paths for native libraries search.
|
||||
* Must be done early as JDK may load libraries during bootstrap.
|
||||
*
|
||||
* @see java.lang.System#initPhase1
|
||||
*/
|
||||
static void initLibraryPaths() {
|
||||
usr_paths = initializePath("java.library.path");
|
||||
sys_paths = initializePath("sun.boot.library.path");
|
||||
}
|
||||
|
||||
// Returns true if the specified class loader can be found in this class
|
||||
// loader's delegation chain.
|
||||
boolean isAncestor(ClassLoader cl) {
|
||||
@ -2570,59 +2547,17 @@ public abstract class ClassLoader {
|
||||
static native void unload(String name, boolean isBuiltin, long handle);
|
||||
}
|
||||
|
||||
// The paths searched for libraries
|
||||
private static String usr_paths[];
|
||||
private static String sys_paths[];
|
||||
|
||||
private static String[] initializePath(String propName) {
|
||||
String ldPath = System.getProperty(propName, "");
|
||||
int ldLen = ldPath.length();
|
||||
char ps = File.pathSeparatorChar;
|
||||
int psCount = 0;
|
||||
|
||||
if (ClassLoaderHelper.allowsQuotedPathElements &&
|
||||
ldPath.indexOf('\"') >= 0) {
|
||||
// First, remove quotes put around quoted parts of paths.
|
||||
// Second, use a quotation mark as a new path separator.
|
||||
// This will preserve any quoted old path separators.
|
||||
char[] buf = new char[ldLen];
|
||||
int bufLen = 0;
|
||||
for (int i = 0; i < ldLen; ++i) {
|
||||
char ch = ldPath.charAt(i);
|
||||
if (ch == '\"') {
|
||||
while (++i < ldLen &&
|
||||
(ch = ldPath.charAt(i)) != '\"') {
|
||||
buf[bufLen++] = ch;
|
||||
}
|
||||
} else {
|
||||
if (ch == ps) {
|
||||
psCount++;
|
||||
ch = '\"';
|
||||
}
|
||||
buf[bufLen++] = ch;
|
||||
}
|
||||
}
|
||||
ldPath = new String(buf, 0, bufLen);
|
||||
ldLen = bufLen;
|
||||
ps = '\"';
|
||||
} else {
|
||||
for (int i = ldPath.indexOf(ps); i >= 0;
|
||||
i = ldPath.indexOf(ps, i + 1)) {
|
||||
psCount++;
|
||||
}
|
||||
}
|
||||
|
||||
String[] paths = new String[psCount + 1];
|
||||
int pathStart = 0;
|
||||
for (int j = 0; j < psCount; ++j) {
|
||||
int pathEnd = ldPath.indexOf(ps, pathStart);
|
||||
paths[j] = (pathStart < pathEnd) ?
|
||||
ldPath.substring(pathStart, pathEnd) : ".";
|
||||
pathStart = pathEnd + 1;
|
||||
}
|
||||
paths[psCount] = (pathStart < ldLen) ?
|
||||
ldPath.substring(pathStart, ldLen) : ".";
|
||||
return paths;
|
||||
/**
|
||||
* Holds system and user library paths derived from the
|
||||
* {@code java.library.path} and {@code sun.boot.library.path} system
|
||||
* properties. The system properties are eagerly read at bootstrap, then
|
||||
* lazily parsed on first use to avoid initialization ordering issues.
|
||||
*/
|
||||
private static class LibraryPaths {
|
||||
static final String[] USER =
|
||||
ClassLoaderHelper.parsePath(StaticProperty.javaLibraryPath());
|
||||
static final String[] SYS =
|
||||
ClassLoaderHelper.parsePath(StaticProperty.sunBootLibraryPath());
|
||||
}
|
||||
|
||||
// Invoked in the java.lang.Runtime class to implement load and loadLibrary.
|
||||
@ -2630,8 +2565,6 @@ public abstract class ClassLoader {
|
||||
boolean isAbsolute) {
|
||||
ClassLoader loader =
|
||||
(fromClass == null) ? null : fromClass.getClassLoader();
|
||||
assert sys_paths != null : "should be initialized at this point";
|
||||
assert usr_paths != null : "should be initialized at this point";
|
||||
|
||||
if (isAbsolute) {
|
||||
if (loadLibrary0(fromClass, new File(name))) {
|
||||
@ -2653,8 +2586,8 @@ public abstract class ClassLoader {
|
||||
throw new UnsatisfiedLinkError("Can't load " + libfilename);
|
||||
}
|
||||
}
|
||||
for (String sys_path : sys_paths) {
|
||||
File libfile = new File(sys_path, System.mapLibraryName(name));
|
||||
for (String sysPath : LibraryPaths.SYS) {
|
||||
File libfile = new File(sysPath, System.mapLibraryName(name));
|
||||
if (loadLibrary0(fromClass, libfile)) {
|
||||
return;
|
||||
}
|
||||
@ -2664,8 +2597,8 @@ public abstract class ClassLoader {
|
||||
}
|
||||
}
|
||||
if (loader != null) {
|
||||
for (String usr_path : usr_paths) {
|
||||
File libfile = new File(usr_path, System.mapLibraryName(name));
|
||||
for (String userPath : LibraryPaths.USER) {
|
||||
File libfile = new File(userPath, System.mapLibraryName(name));
|
||||
if (loadLibrary0(fromClass, libfile)) {
|
||||
return;
|
||||
}
|
||||
@ -2677,7 +2610,7 @@ public abstract class ClassLoader {
|
||||
}
|
||||
// Oops, it failed
|
||||
throw new UnsatisfiedLinkError("no " + name +
|
||||
" in java.library.path: " + Arrays.toString(usr_paths));
|
||||
" in java.library.path: " + Arrays.toString(LibraryPaths.USER));
|
||||
}
|
||||
|
||||
private static native String findBuiltinLib(String name);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2020, 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
|
||||
@ -2043,8 +2043,6 @@ public final class System {
|
||||
// register shared secrets
|
||||
setJavaLangAccess();
|
||||
|
||||
ClassLoader.initLibraryPaths();
|
||||
|
||||
// Subsystems that are invoked during initialization can invoke
|
||||
// VM.isBooted() in order to avoid doing things that should
|
||||
// wait until the VM is fully initialized. The initialization level
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, 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
|
||||
@ -198,22 +198,23 @@ public class BuiltinClassLoader
|
||||
* types in the module visible.
|
||||
*/
|
||||
public void loadModule(ModuleReference mref) {
|
||||
String mn = mref.descriptor().name();
|
||||
ModuleDescriptor descriptor = mref.descriptor();
|
||||
String mn = descriptor.name();
|
||||
if (nameToModule.putIfAbsent(mn, mref) != null) {
|
||||
throw new InternalError(mn + " already defined to this loader");
|
||||
}
|
||||
|
||||
LoadedModule loadedModule = new LoadedModule(this, mref);
|
||||
for (String pn : mref.descriptor().packages()) {
|
||||
for (String pn : descriptor.packages()) {
|
||||
LoadedModule other = packageToModule.putIfAbsent(pn, loadedModule);
|
||||
if (other != null) {
|
||||
throw new InternalError(pn + " in modules " + mn + " and "
|
||||
+ other.mref().descriptor().name());
|
||||
+ other.name());
|
||||
}
|
||||
}
|
||||
|
||||
// clear resources cache if VM is already initialized
|
||||
if (VM.isModuleSystemInited() && resourceCache != null) {
|
||||
if (resourceCache != null && VM.isModuleSystemInited()) {
|
||||
resourceCache = null;
|
||||
}
|
||||
}
|
||||
@ -408,8 +409,11 @@ public class BuiltinClassLoader
|
||||
SoftReference<Map<String, List<URL>>> ref = this.resourceCache;
|
||||
Map<String, List<URL>> map = (ref != null) ? ref.get() : null;
|
||||
if (map == null) {
|
||||
map = new ConcurrentHashMap<>();
|
||||
this.resourceCache = new SoftReference<>(map);
|
||||
// only cache resources after VM is fully initialized
|
||||
if (VM.isModuleSystemInited()) {
|
||||
map = new ConcurrentHashMap<>();
|
||||
this.resourceCache = new SoftReference<>(map);
|
||||
}
|
||||
} else {
|
||||
List<URL> urls = map.get(name);
|
||||
if (urls != null)
|
||||
@ -444,7 +448,7 @@ public class BuiltinClassLoader
|
||||
}
|
||||
|
||||
// only cache resources after VM is fully initialized
|
||||
if (VM.isModuleSystemInited()) {
|
||||
if (map != null) {
|
||||
map.putIfAbsent(name, urls);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2020, 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,6 +25,8 @@
|
||||
|
||||
package jdk.internal.util;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* System Property access for internal use only.
|
||||
* Read-only access to System property values initialized during Phase 1
|
||||
@ -38,22 +40,41 @@ public final class StaticProperty {
|
||||
|
||||
// The class static initialization is triggered to initialize these final
|
||||
// fields during init Phase 1 and before a security manager is set.
|
||||
private static final String JAVA_HOME = initProperty("java.home");
|
||||
private static final String USER_HOME = initProperty("user.home");
|
||||
private static final String USER_DIR = initProperty("user.dir");
|
||||
private static final String USER_NAME = initProperty("user.name");
|
||||
private static final String JDK_SERIAL_FILTER = System.getProperty("jdk.serialFilter");
|
||||
private static final String JAVA_HOME;
|
||||
private static final String USER_HOME;
|
||||
private static final String USER_DIR;
|
||||
private static final String USER_NAME;
|
||||
private static final String JAVA_LIBRARY_PATH;
|
||||
private static final String SUN_BOOT_LIBRARY_PATH;
|
||||
private static final String JDK_SERIAL_FILTER;
|
||||
|
||||
private StaticProperty() {}
|
||||
|
||||
private static String initProperty(String key) {
|
||||
String v = System.getProperty(key);
|
||||
static {
|
||||
Properties props = System.getProperties();
|
||||
JAVA_HOME = getProperty(props, "java.home");
|
||||
USER_HOME = getProperty(props, "user.home");
|
||||
USER_DIR = getProperty(props, "user.dir");
|
||||
USER_NAME = getProperty(props, "user.name");
|
||||
JAVA_LIBRARY_PATH = getProperty(props, "java.library.path", "");
|
||||
SUN_BOOT_LIBRARY_PATH = getProperty(props, "sun.boot.library.path", "");
|
||||
JDK_SERIAL_FILTER = getProperty(props, "jdk.serialFilter", null);
|
||||
}
|
||||
|
||||
private static String getProperty(Properties props, String key) {
|
||||
String v = props.getProperty(key);
|
||||
if (v == null) {
|
||||
throw new InternalError("null property: " + key);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
private static String getProperty(Properties props, String key,
|
||||
String defaultVal) {
|
||||
String v = props.getProperty(key);
|
||||
return (v == null) ? defaultVal : v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@code java.home} system property.
|
||||
*
|
||||
@ -106,6 +127,33 @@ public final class StaticProperty {
|
||||
return USER_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@code java.library.path} system property.
|
||||
*
|
||||
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
|
||||
* in this method. The caller of this method should take care to ensure
|
||||
* that the returned property is not made accessible to untrusted code.</strong>
|
||||
*
|
||||
* @return the {@code java.library.path} system property
|
||||
*/
|
||||
public static String javaLibraryPath() {
|
||||
return JAVA_LIBRARY_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@code sun.boot.library.path} system property.
|
||||
*
|
||||
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
|
||||
* in this method. The caller of this method should take care to ensure
|
||||
* that the returned property is not made accessible to untrusted code.</strong>
|
||||
*
|
||||
* @return the {@code sun.boot.library.path} system property
|
||||
*/
|
||||
public static String sunBootLibraryPath() {
|
||||
return SUN_BOOT_LIBRARY_PATH;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the {@code jdk.serialFilter} system property.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, 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,16 +26,12 @@
|
||||
package java.lang;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class ClassLoaderHelper {
|
||||
|
||||
private ClassLoaderHelper() {}
|
||||
|
||||
/**
|
||||
* Indicates, whether PATH env variable is allowed to contain quoted entries.
|
||||
*/
|
||||
static final boolean allowsQuotedPathElements = false;
|
||||
|
||||
/**
|
||||
* Returns an alternate path name for the given file
|
||||
* such that if the original pathname did not exist, then the
|
||||
@ -45,4 +41,25 @@ class ClassLoaderHelper {
|
||||
static File mapAlternativeName(File lib) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a PATH env variable.
|
||||
*
|
||||
* Empty elements will be replaced by dot.
|
||||
*/
|
||||
static String[] parsePath(String ldPath) {
|
||||
char ps = File.pathSeparatorChar;
|
||||
ArrayList<String> paths = new ArrayList<>();
|
||||
int pathStart = 0;
|
||||
int pathEnd;
|
||||
while ((pathEnd = ldPath.indexOf(ps, pathStart)) >= 0) {
|
||||
paths.add((pathStart < pathEnd) ?
|
||||
ldPath.substring(pathStart, pathEnd) : ".");
|
||||
pathStart = pathEnd + 1;
|
||||
}
|
||||
int ldLen = ldPath.length();
|
||||
paths.add((pathStart < ldLen) ?
|
||||
ldPath.substring(pathStart, ldLen) : ".");
|
||||
return paths.toArray(new String[paths.size()]);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, 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,11 +31,6 @@ class ClassLoaderHelper {
|
||||
|
||||
private ClassLoaderHelper() {}
|
||||
|
||||
/**
|
||||
* Indicates, whether PATH env variable is allowed to contain quoted entries.
|
||||
*/
|
||||
static final boolean allowsQuotedPathElements = true;
|
||||
|
||||
/**
|
||||
* Returns an alternate path name for the given file
|
||||
* such that if the original pathname did not exist, then the
|
||||
@ -45,4 +40,59 @@ class ClassLoaderHelper {
|
||||
static File mapAlternativeName(File lib) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a PATH env variable. Windows allows quoted elements in a PATH,
|
||||
* so special care needs to be taken.
|
||||
*
|
||||
* Empty elements will be replaced by dot.
|
||||
*/
|
||||
static String[] parsePath(String ldPath) {
|
||||
int ldLen = ldPath.length();
|
||||
char ps = File.pathSeparatorChar;
|
||||
int psCount = 0;
|
||||
|
||||
if (ldPath.indexOf('\"') >= 0) {
|
||||
// First, remove quotes put around quoted parts of paths.
|
||||
// Second, use a quotation mark as a new path separator.
|
||||
// This will preserve any quoted old path separators.
|
||||
char[] buf = new char[ldLen];
|
||||
int bufLen = 0;
|
||||
for (int i = 0; i < ldLen; ++i) {
|
||||
char ch = ldPath.charAt(i);
|
||||
if (ch == '\"') {
|
||||
while (++i < ldLen &&
|
||||
(ch = ldPath.charAt(i)) != '\"') {
|
||||
buf[bufLen++] = ch;
|
||||
}
|
||||
} else {
|
||||
if (ch == ps) {
|
||||
psCount++;
|
||||
ch = '\"';
|
||||
}
|
||||
buf[bufLen++] = ch;
|
||||
}
|
||||
}
|
||||
ldPath = new String(buf, 0, bufLen);
|
||||
ldLen = bufLen;
|
||||
ps = '\"';
|
||||
} else {
|
||||
for (int i = ldPath.indexOf(ps); i >= 0;
|
||||
i = ldPath.indexOf(ps, i + 1)) {
|
||||
psCount++;
|
||||
}
|
||||
}
|
||||
|
||||
String[] paths = new String[psCount + 1];
|
||||
int pathStart = 0;
|
||||
for (int j = 0; j < psCount; ++j) {
|
||||
int pathEnd = ldPath.indexOf(ps, pathStart);
|
||||
paths[j] = (pathStart < pathEnd) ?
|
||||
ldPath.substring(pathStart, pathEnd) : ".";
|
||||
pathStart = pathEnd + 1;
|
||||
}
|
||||
paths[psCount] = (pathStart < ldLen) ?
|
||||
ldPath.substring(pathStart, ldLen) : ".";
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public class TestInstanceKlassSize {
|
||||
public static WhiteBox wb = WhiteBox.getWhiteBox();
|
||||
private static String[] SAInstanceKlassNames = new String[] {
|
||||
"java.lang.Object",
|
||||
"java.util.Vector",
|
||||
"java.util.ArrayList",
|
||||
"java.lang.String",
|
||||
"java.lang.Thread",
|
||||
"java.lang.Byte"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, 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,8 +23,8 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8067951
|
||||
* @summary Unit test for internal ClassLoader#initializePath().
|
||||
* @bug 8067951 8236075
|
||||
* @summary Unit test for internal ClassLoaderHelper#parsePath().
|
||||
* Quoted entries should get unquoted on Windows.
|
||||
* Empty entries should be replaced with dot.
|
||||
* @library /test/lib
|
||||
@ -40,14 +40,12 @@ import jdk.test.lib.Platform;
|
||||
|
||||
public class LibraryPathProperty {
|
||||
|
||||
static final String propName = "test.property.name";
|
||||
static final String SP = File.pathSeparator;
|
||||
static Method method;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
method = ClassLoader.class
|
||||
.getDeclaredMethod("initializePath",
|
||||
String.class);
|
||||
Class<?> klass = Class.forName("java.lang.ClassLoaderHelper");
|
||||
method = klass.getDeclaredMethod("parsePath", String.class);
|
||||
method.setAccessible(true);
|
||||
|
||||
test("", ".");
|
||||
@ -74,8 +72,7 @@ public class LibraryPathProperty {
|
||||
}
|
||||
|
||||
static void test(String s, String... expected) throws Throwable {
|
||||
System.setProperty(propName, s);
|
||||
String[] res = (String[])method.invoke(null, propName);
|
||||
String[] res = (String[])method.invoke(null, s);
|
||||
if (!Arrays.asList(res).equals(Arrays.asList(expected))) {
|
||||
throw new RuntimeException("Parsing [" + s + "] " +
|
||||
" result " + Arrays.asList(res) +
|
||||
|
Loading…
Reference in New Issue
Block a user