diff --git a/platform/platform-api/src/com/intellij/util/io/HttpRequests.java b/platform/platform-api/src/com/intellij/util/io/HttpRequests.java index dd8624ce5c4f..acc1d8b53fd3 100644 --- a/platform/platform-api/src/com/intellij/util/io/HttpRequests.java +++ b/platform/platform-api/src/com/intellij/util/io/HttpRequests.java @@ -352,15 +352,15 @@ public final class HttpRequests { } private static T process(RequestBuilderImpl builder, RequestProcessor processor) throws IOException { - if (!UrlClassLoader.PARALLEL_CAPABLE) { + ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); + if (!UrlClassLoader.isRegisteredAsParallelCapable(contextLoader)) { // hack-around for class loader lock in sun.net.www.protocol.http.NegotiateAuthentication (IDEA-131621) - ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - try (URLClassLoader cl = new URLClassLoader(new URL[0], oldClassLoader)) { + try (URLClassLoader cl = new URLClassLoader(new URL[0], contextLoader)) { Thread.currentThread().setContextClassLoader(cl); return doProcess(builder, processor); } finally { - Thread.currentThread().setContextClassLoader(oldClassLoader); + Thread.currentThread().setContextClassLoader(contextLoader); } } else { diff --git a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java index cf81a2272034..82de631a11af 100644 --- a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java +++ b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java @@ -29,6 +29,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -45,20 +46,31 @@ import java.util.List; public class UrlClassLoader extends ClassLoader { public static final String CLASS_EXTENSION = ".class"; - public static final boolean PARALLEL_CAPABLE; + private static final boolean HAS_PARALLEL_LOADERS = SystemInfo.isJavaVersionAtLeast("1.7") && !SystemInfo.isIbmJvm; + static { - boolean parallelCapable = false; - if (SystemInfo.isJavaVersionAtLeast("1.7") && !SystemInfo.isIbmJvm) { + if (HAS_PARALLEL_LOADERS) { try { - // todo Patches.USE_REFLECTION_TO_ACCESS_JDK7 + //todo Patches.USE_REFLECTION_TO_ACCESS_JDK7 Method registerAsParallelCapable = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable"); registerAsParallelCapable.setAccessible(true); registerAsParallelCapable.invoke(null); - parallelCapable = true; } catch (Exception ignored) { } } - PARALLEL_CAPABLE = parallelCapable; + } + + public static boolean isRegisteredAsParallelCapable(@NotNull ClassLoader loader) { + if (!HAS_PARALLEL_LOADERS) return false; + try { + //todo Patches.USE_REFLECTION_TO_ACCESS_JDK7 + Field parallelLockMap = ClassLoader.class.getDeclaredField("parallelLockMap"); + parallelLockMap.setAccessible(true); + return parallelLockMap.get(loader) != null; + } + catch (Exception e) { + throw new AssertionError("Internal error: ClassLoader implementation has been altered"); + } } private static final boolean ourClassPathIndexEnabled = Boolean.parseBoolean(System.getProperty("idea.classpath.index.enabled", "true")); @@ -161,7 +173,7 @@ public class UrlClassLoader extends ClassLoader { }); myClassPath = createClassPath(builder); myAllowBootstrapResources = builder.myAllowBootstrapResources; - myClassNameInterner = PARALLEL_CAPABLE ? new WeakStringInterner() : null; + myClassNameInterner = isRegisteredAsParallelCapable(this) ? new WeakStringInterner() : null; } @NotNull @@ -332,6 +344,8 @@ public class UrlClassLoader extends ClassLoader { else return ""; } + // called by a parent class on Java 7+ + @SuppressWarnings("unused") protected Object getClassLoadingLock(String className) { return myClassNameInterner != null ? myClassNameInterner.intern(new String(className)) : this; }