mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
IJPL-159596 loading com.intellij.util.lang classes via PluginClassLoader must also use app classloader instead of core
GitOrigin-RevId: 7b698220a575816d62dfcfec1fb919ed5749a3a4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
616b007827
commit
442e513e33
@@ -223,7 +223,7 @@ class PluginClassLoader(
|
||||
}
|
||||
continue
|
||||
}
|
||||
c = classloader.loadClassInsideSelf(name, fileName, packageNameHash, false)
|
||||
c = classloader.loadClassWithPrecomputedMeta(name, fileName, fileNameWithoutExtension, packageNameHash)
|
||||
}
|
||||
catch (e: IOException) {
|
||||
throw ClassNotFoundException(name, e)
|
||||
@@ -314,7 +314,7 @@ class PluginClassLoader(
|
||||
return loadClassInsideSelf(name, fileName, packageNameHash, false)
|
||||
}
|
||||
|
||||
override fun loadClassInsideSelf(name: String, fileName: String, packageNameHash: Long, forceLoadFromSubPluginClassloader: Boolean): Class<*>? {
|
||||
private fun loadClassInsideSelf(name: String, fileName: String, packageNameHash: Long, forceLoadFromSubPluginClassloader: Boolean): Class<*>? {
|
||||
synchronized(getClassLoadingLock(name)) {
|
||||
var c = findLoadedClass(name)
|
||||
if (c?.classLoader === this) {
|
||||
|
||||
@@ -27,7 +27,6 @@ c:com.intellij.util.lang.UrlClassLoader
|
||||
- hasLoadedClass(java.lang.String):Z
|
||||
- isByteBufferSupported(java.lang.String):Z
|
||||
- p:isPackageDefined(java.lang.String):Z
|
||||
- loadClassInsideSelf(java.lang.String,java.lang.String,J,Z):java.lang.Class
|
||||
- f:processResources(java.lang.String,java.util.function.Predicate,java.util.function.BiConsumer):V
|
||||
- ps:registerInClassLoaderValueMap(java.lang.ClassLoader,java.lang.ClassLoader):V
|
||||
- ps:toCanonicalPath(java.lang.String):java.lang.String
|
||||
|
||||
@@ -63,7 +63,7 @@ public class UrlClassLoader extends ClassLoader implements ClassPath.ClassDataCo
|
||||
}
|
||||
|
||||
/**
|
||||
* There are two definitions of the `ClassPath` class: one from the app class loader that is used by bootstrap,
|
||||
* There are two definitions of the `ClassPath` class: one from the app class loader that bootstrap uses,
|
||||
* and another one from the core class loader produced as a result of creating a plugin class loader.
|
||||
* The core class loader doesn't use bootstrap class loader as a parent - instead, only platform classloader is used (only JRE classes).
|
||||
*/
|
||||
@@ -215,24 +215,51 @@ public class UrlClassLoader extends ClassLoader implements ClassPath.ClassDataCo
|
||||
//
|
||||
// com.intellij.util.lang
|
||||
// see XxHash3Test.packages
|
||||
if (isSystemClassLoader && packageNameHash == -9217824570049207139L) {
|
||||
// these two classes from com.intellij.util.lang are located in intellij.platform.util module, which shouldn't be loaded by appClassLoader (IDEA-331043)
|
||||
if (!fileNameWithoutExtension.endsWith("/CompoundRuntimeException") && !fileNameWithoutExtension.endsWith("/JavaVersion")) {
|
||||
return appClassLoader.loadClass(name);
|
||||
}
|
||||
if (isSystemClassLoader && packageNameHash == -9217824570049207139L && isNotExcludedLangClasses(fileNameWithoutExtension)) {
|
||||
return appClassLoader.loadClass(name);
|
||||
}
|
||||
|
||||
Class<?> clazz;
|
||||
Class<?> aClass;
|
||||
try {
|
||||
clazz = classPath.findClass(name, fileName, packageNameHash, classDataConsumer);
|
||||
aClass = classPath.findClass(name, fileName, packageNameHash, classDataConsumer);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ClassNotFoundException(name, e);
|
||||
}
|
||||
if (clazz == null) {
|
||||
if (aClass == null) {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
return clazz;
|
||||
return aClass;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public @Nullable Class<?> loadClassWithPrecomputedMeta(String name,
|
||||
String fileName,
|
||||
String fileNameWithoutExtension,
|
||||
long packageNameHash) throws IOException, ClassNotFoundException {
|
||||
synchronized (getClassLoadingLock(name)) {
|
||||
Class<?> c = findLoadedClass(name);
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
|
||||
ClassLoader parent = getParent();
|
||||
if (parent != null) {
|
||||
try {
|
||||
c = parent.loadClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
if (isSystemClassLoader && packageNameHash == -9217824570049207139L && isNotExcludedLangClasses(fileNameWithoutExtension)) {
|
||||
return appClassLoader.loadClass(name);
|
||||
}
|
||||
return classPath.findClass(name, fileName, packageNameHash, classDataConsumer);
|
||||
}
|
||||
}
|
||||
|
||||
private void definePackageIfNeeded(String name) {
|
||||
@@ -353,32 +380,10 @@ public class UrlClassLoader extends ClassLoader implements ClassPath.ClassDataCo
|
||||
@ApiStatus.Internal
|
||||
public @Nullable BiFunction<String, Boolean, String> resolveScopeManager;
|
||||
|
||||
public @Nullable Class<?> loadClassInsideSelf(String name,
|
||||
String fileName,
|
||||
long packageNameHash,
|
||||
boolean forceLoadFromSubPluginClassloader) throws IOException {
|
||||
synchronized (getClassLoadingLock(name)) {
|
||||
Class<?> c = findLoadedClass(name);
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
|
||||
if (!forceLoadFromSubPluginClassloader) {
|
||||
// "self" makes sense for PluginClassLoader, but not for UrlClassLoader - our parent it is implementation detail
|
||||
ClassLoader parent = getParent();
|
||||
if (parent != null) {
|
||||
try {
|
||||
c = parent.loadClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException ignore) { }
|
||||
}
|
||||
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return classPath.findClass(name, fileName, packageNameHash, classDataConsumer);
|
||||
}
|
||||
private static boolean isNotExcludedLangClasses(String fileNameWithoutExtension) {
|
||||
// these two classes from com.intellij.util.lang are located in intellij.platform.util module,
|
||||
// which shouldn't be loaded by appClassLoader (IDEA-331043)
|
||||
return !fileNameWithoutExtension.endsWith("/CompoundRuntimeException") && !fileNameWithoutExtension.endsWith("/JavaVersion");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -610,7 +615,7 @@ public class UrlClassLoader extends ClassLoader implements ClassPath.ClassDataCo
|
||||
/**
|
||||
* `ZipFile` handles opened in `JarLoader` will be kept in as soft references.
|
||||
* Depending on OS, the option significantly speeds up classloading from libraries.
|
||||
* Caveat: on Windows, an unclosed handle locks a file, preventing its modification.
|
||||
* Warning: on Windows, an unclosed handle locks a file, preventing its modification.
|
||||
* Thus, the option is recommended when .jar files are not modified or a process that uses this option is transient.
|
||||
*/
|
||||
public @NotNull UrlClassLoader.Builder allowLock(boolean lockJars) {
|
||||
@@ -635,10 +640,11 @@ public class UrlClassLoader extends ClassLoader implements ClassPath.ClassDataCo
|
||||
* `FileLoader` will save a list of files/packages under its root and use this information instead of walking files.
|
||||
* Should be used only when the caches can be properly invalidated (when e.g., a new file appears under `FileLoader`'s root).
|
||||
* Currently, the flag is used for faster unit tests / debug IDE instance, because IDEA's build process (as of 14.1) ensures deletion of
|
||||
* such information upon appearing new file for output root.
|
||||
* such information upon appearing a new file for output root.
|
||||
* <p>
|
||||
* IDEA's building process does not ensure deletion of cached information upon deletion of some file under a local root,
|
||||
* but false positives are not a logical error, since code is prepared for that and disk access is performed upon class/resource loading.
|
||||
* IDEA's building process does not ensure deletion of cached information upon deletion of some file under a local root.
|
||||
* However, false positives are not a logical error,
|
||||
* since code is prepared for that and disk access is performed upon class/resource loading.
|
||||
*/
|
||||
public @NotNull UrlClassLoader.Builder usePersistentClasspathIndexForLocalClassDirectories() {
|
||||
this.isClassPathIndexEnabled = true;
|
||||
|
||||
Reference in New Issue
Block a user