提交 9c1aaa8c 编写于 作者: V valeriep

6832540: IllegalArgumentException in ClassLoader.definePackage when classes are loaded in parallel

Summary: Modified to handle race condition for parallel-capable classloaders by re-trying/re-verifying package
Reviewed-by: alanb
上级 48068e07
...@@ -305,6 +305,35 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { ...@@ -305,6 +305,35 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
} }
} }
/*
* Retrieve the package using the specified package name.
* If non-null, verify the package using the specified code
* source and manifest.
*/
private Package getAndVerifyPackage(String pkgname,
Manifest man, URL url) {
Package pkg = getPackage(pkgname);
if (pkg != null) {
// Package found, so check package sealing.
if (pkg.isSealed()) {
// Verify that code source URL is the same.
if (!pkg.isSealed(url)) {
throw new SecurityException(
"sealing violation: package " + pkgname + " is sealed");
}
} else {
// Make sure we are not attempting to seal the package
// at this code source URL.
if ((man != null) && isSealed(pkgname, man)) {
throw new SecurityException(
"sealing violation: can't seal package " + pkgname +
": already loaded");
}
}
}
return pkg;
}
/* /*
* Defines a Class using the class bytes obtained from the specified * Defines a Class using the class bytes obtained from the specified
* Resource. The resulting Class must be resolved before it can be * Resource. The resulting Class must be resolved before it can be
...@@ -316,32 +345,23 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { ...@@ -316,32 +345,23 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
if (i != -1) { if (i != -1) {
String pkgname = name.substring(0, i); String pkgname = name.substring(0, i);
// Check if package already loaded. // Check if package already loaded.
Package pkg = getPackage(pkgname);
Manifest man = res.getManifest(); Manifest man = res.getManifest();
if (pkg != null) { if (getAndVerifyPackage(pkgname, man, url) == null) {
// Package found, so check package sealing. try {
if (pkg.isSealed()) { if (man != null) {
// Verify that code source URL is the same. definePackage(pkgname, man, url);
if (!pkg.isSealed(url)) { } else {
throw new SecurityException( definePackage(pkgname, null, null, null, null, null, null, null);
"sealing violation: package " + pkgname + " is sealed");
} }
} catch (IllegalArgumentException iae) {
} else { // parallel-capable class loaders: re-verify in case of a
// Make sure we are not attempting to seal the package // race condition
// at this code source URL. if (getAndVerifyPackage(pkgname, man, url) == null) {
if ((man != null) && isSealed(pkgname, man)) { // Should never happen
throw new SecurityException( throw new AssertionError("Cannot find package " +
"sealing violation: can't seal package " + pkgname + pkgname);
": already loaded");
} }
} }
} else {
if (man != null) {
definePackage(pkgname, man, url);
} else {
definePackage(pkgname, null, null, null, null, null, null, null);
}
} }
} }
// Now read the class bytes and define the class // Now read the class bytes and define the class
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册