From 9c1aaa8cd55a613a4a4bcdee20daa465537d1e18 Mon Sep 17 00:00:00 2001 From: valeriep Date: Mon, 13 Jul 2009 15:14:17 -0700 Subject: [PATCH] 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 --- .../classes/java/net/URLClassLoader.java | 64 ++++++++++++------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/src/share/classes/java/net/URLClassLoader.java b/src/share/classes/java/net/URLClassLoader.java index 601601a56..22be20b7e 100644 --- a/src/share/classes/java/net/URLClassLoader.java +++ b/src/share/classes/java/net/URLClassLoader.java @@ -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 * Resource. The resulting Class must be resolved before it can be @@ -316,32 +345,23 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { if (i != -1) { String pkgname = name.substring(0, i); // Check if package already loaded. - Package pkg = getPackage(pkgname); Manifest man = res.getManifest(); - 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"); + if (getAndVerifyPackage(pkgname, man, url) == null) { + try { + if (man != null) { + definePackage(pkgname, man, url); + } else { + definePackage(pkgname, null, null, null, null, null, null, null); } - - } 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"); + } catch (IllegalArgumentException iae) { + // parallel-capable class loaders: re-verify in case of a + // race condition + if (getAndVerifyPackage(pkgname, man, url) == null) { + // Should never happen + throw new AssertionError("Cannot find package " + + pkgname); } } - } 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 -- GitLab