From a3f6ede9550f6793c902abc793d3aedfee1aa05c Mon Sep 17 00:00:00 2001 From: Dmitry Kandalov Date: Sat, 10 Dec 2022 22:55:59 +0000 Subject: [PATCH] updated PluginClassLoader_Fork --- .../pluginrunner/PluginClassLoader_Fork.java | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/main/liveplugin/implementation/pluginrunner/PluginClassLoader_Fork.java b/src/main/liveplugin/implementation/pluginrunner/PluginClassLoader_Fork.java index 28b2b268..11933a9e 100644 --- a/src/main/liveplugin/implementation/pluginrunner/PluginClassLoader_Fork.java +++ b/src/main/liveplugin/implementation/pluginrunner/PluginClassLoader_Fork.java @@ -14,16 +14,16 @@ import com.intellij.util.lang.Resource; import com.intellij.util.lang.UrlClassLoader; import com.intellij.util.ui.EDT; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.*; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.CodeSource; -import java.security.ProtectionDomain; -import java.security.cert.Certificate; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -31,7 +31,7 @@ import java.util.function.Function; /** - * Fork of PluginClassLoader_Fork + * Fork of com.intellij.ide.plugins.cl.PluginClassLoader * because its an internal IJ API and it has been changing in IJ 2020.2 causing LivePlugin to break. * The assumption is that using fork will make LivePlugin forward-compatible with more IJ versions * given that PluginClassLoader_Fork implementation compatibility is more stable than PluginClassLoader API. @@ -52,9 +52,6 @@ public final class PluginClassLoader_Fork extends UrlClassLoader implements Plug private static final Set KOTLIN_STDLIB_CLASSES_USED_IN_SIGNATURES; - // avoid capturing reference to classloader in AccessControlContext - private static final ProtectionDomain PROTECTION_DOMAIN = new ProtectionDomain(new CodeSource(null, (Certificate[]) null), null); - static { @SuppressWarnings("SSBasedInspection") Set kotlinStdlibClassesUsedInSignatures = new HashSet<>(Arrays.asList( @@ -80,11 +77,17 @@ public final class PluginClassLoader_Fork extends UrlClassLoader implements Plug "kotlin.coroutines.CoroutineContext", "kotlin.coroutines.CoroutineContext$Element", "kotlin.coroutines.CoroutineContext$Key", + "kotlin.Result", + "kotlin.Result$Failure", + "kotlin.Result$Companion", // Even though it's internal class, it can leak (and it does) into API surface because it's exposed by public // `kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED` property "kotlin.coroutines.intrinsics.CoroutineSingletons", "kotlin.coroutines.AbstractCoroutineContextElement", - "kotlin.coroutines.AbstractCoroutineContextKey" + "kotlin.coroutines.AbstractCoroutineContextKey", + "kotlin.coroutines.jvm.internal.ContinuationImpl", // IDEA-295189 + "kotlin.coroutines.jvm.internal.BaseContinuationImpl", // IDEA-295189 + "kotlin.coroutines.jvm.internal.CoroutineStackFrame" // IDEA-295189 )); String classes = System.getProperty("idea.kotlin.classes.used.in.signatures"); if (classes != null) { @@ -225,7 +228,7 @@ public Class loadClass(@NotNull String name, boolean resolve) throws ClassNot } /** - * See https://stackoverflow.com/a/5428795 about resolve flag. + * See https://stackoverflow.com/a/5428795 about resolve flag. */ @Override public @Nullable Class tryLoadingClass(@NotNull String name, boolean forceLoadFromSubPluginClassloader) @@ -382,9 +385,23 @@ private static boolean mustBeLoadedByPlatform(@NonNls String className) { // some commonly used classes from kotlin-runtime must be loaded by the platform classloader. Otherwise, if a plugin bundles its own version // of kotlin-runtime.jar it won't be possible to call platform's methods with these types in signatures from such a plugin. // We assume that these classes don't change between Kotlin versions, so it's safe to always load them from platform's kotlin-runtime. - return className.startsWith("kotlin.") && (className.startsWith("kotlin.jvm.functions.") || - (className.startsWith("kotlin.reflect.") && - className.indexOf('.', 15 /* "kotlin.reflect".length */) < 0) || + return className.startsWith("kotlin.") && + (className.startsWith("kotlin.jvm.functions.") || + // Those are kotlin-reflect related classes but unfortunately, they are placed in kotlin-stdlib. Since we always + // want to load reflect from platform, we should force those classes with platform classloader as well + className.startsWith("kotlin.reflect.") || + className.startsWith("kotlin.jvm.internal.CallableReference") || + className.startsWith("kotlin.jvm.internal.ClassReference") || + className.startsWith("kotlin.jvm.internal.FunInterfaceConstructorReference") || + className.startsWith("kotlin.jvm.internal.FunctionReference") || + className.startsWith("kotlin.jvm.internal.MutablePropertyReference") || + className.startsWith("kotlin.jvm.internal.PropertyReference") || + className.startsWith("kotlin.jvm.internal.TypeReference") || + className.equals("kotlin.jvm.internal.Lambda") || + className.startsWith("kotlin.jvm.internal.LocalVariableReference") || + className.startsWith("kotlin.jvm.internal.MutableLocalVariableReference") || + className.equals("kotlin.jvm.internal.ReflectionFactory") || + className.equals("kotlin.jvm.internal.Reflection") || KOTLIN_STDLIB_CLASSES_USED_IN_SIGNATURES.contains(className)); } @@ -510,7 +527,7 @@ private void logClass(@NotNull String name, @NotNull Writer logStream, @Nullable return doFindResource(name, f1, f2); } - private @Nullable T doFindResource(String name, Function f1, BiFunction f2) { + private @Nullable T doFindResource(String name, Function f1, BiFunction f2) { String canonicalPath = toCanonicalPath(name); Resource resource = classPath.findResource(canonicalPath); @@ -601,10 +618,10 @@ public String toString() { } private static final class DeepEnumeration implements Enumeration { - private final @NotNull List> list; + private final @NotNull List> list; private int myIndex; - DeepEnumeration(@NotNull List> enumerations) { + private DeepEnumeration(@NotNull List> enumerations) { list = enumerations; } @@ -629,10 +646,6 @@ public URL nextElement() { } } - protected ProtectionDomain getProtectionDomain() { - return PROTECTION_DOMAIN; - } - private static void flushDebugLog() { if (logStream != null) { try {