IDEA-CR-48035 follow-up: make BootstrapClassLoader private

GitOrigin-RevId: 32a99f39e95bc2a3dbb6bdf293a615a100a49ba6
This commit is contained in:
Eugene Zhuravlev
2019-06-11 18:15:21 +03:00
committed by intellij-monorepo-bot
parent 3dd8a5a26d
commit ab7e22bda2
3 changed files with 63 additions and 63 deletions
@@ -1,52 +0,0 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide;
import com.intellij.util.lang.UrlClassLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.security.ProtectionDomain;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class BootstrapClassLoader extends UrlClassLoader {
public interface Transformer {
byte[] transform(ClassLoader loader, String className, @Nullable ProtectionDomain protectionDomain, byte[] classBytes);
}
private final List<Transformer> myTransformers = new CopyOnWriteArrayList<>();
public BootstrapClassLoader(@NotNull Builder<BootstrapClassLoader> builder) {
super(builder);
}
public void addTransformer(Transformer transformer) {
myTransformers.add(transformer);
}
public boolean removeTransformer(Transformer transformer) {
return myTransformers.remove(transformer);
}
@Override
protected Class _defineClass(String name, byte[] b) {
return super._defineClass(name, doTransform(name, null, b));
}
@Override
protected Class _defineClass(String name, byte[] b, @Nullable ProtectionDomain protectionDomain) {
return super._defineClass(name, doTransform(name, protectionDomain, b), protectionDomain);
}
private byte[] doTransform(String name, ProtectionDomain protectionDomain, byte[] bytes) {
byte[] b = bytes;
for (Transformer transformer : myTransformers) {
final byte[] result = transformer.transform(this, name, protectionDomain, b);
if (result != null) {
b = result;
}
}
return b;
}
}
@@ -1,14 +1,17 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide;
import com.intellij.idea.Main;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.ClassLoaderUtil;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.util.SmartList;
import com.intellij.util.lang.UrlClassLoader;
import com.intellij.util.text.StringTokenizer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
@@ -20,6 +23,7 @@ import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.regex.Pattern;
@@ -27,11 +31,11 @@ import java.util.regex.Pattern;
* @author max
*/
public class BootstrapClassLoaderUtil extends ClassUtilCore {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.BootstrapClassLoaderUtil");
private static final String PROPERTY_IGNORE_CLASSPATH = "ignore.classpath";
private static final String PROPERTY_ALLOW_BOOTSTRAP_RESOURCES = "idea.allow.bootstrap.resources";
private static final String PROPERTY_ADDITIONAL_CLASSPATH = "idea.additional.classpath";
public static final String CLASSPATH_ORDER_FILE = "classpath-order.txt";
private static final String MARKETPLACE_PLUGIN_NAME = "marketplace";
private BootstrapClassLoaderUtil() { }
@@ -49,13 +53,16 @@ public class BootstrapClassLoaderUtil extends ClassUtilCore {
addAdditionalClassPath(classpath);
addParentClasspath(classpath, true);
final File mpBoot = new File(PathManager.getPluginsPath(), "marketplace/lib/boot/marketplace-bootstrap.jar");
final File mpBoot = new File(PathManager.getPluginsPath(), MARKETPLACE_PLUGIN_NAME + "/lib/boot/marketplace-bootstrap.jar");
final boolean installMarketplace = mpBoot.exists();
if (installMarketplace) {
classpath.add(new File(PathManager.getPluginsPath(), "marketplace/lib/boot/marketplace-impl.jar").toURI().toURL());
final File marketplaceImpl = new File(PathManager.getPluginsPath(), MARKETPLACE_PLUGIN_NAME + "/lib/boot/marketplace-impl.jar");
if (marketplaceImpl.exists()) {
classpath.add(marketplaceImpl.toURI().toURL());
}
}
UrlClassLoader.Builder<BootstrapClassLoader> builder = UrlClassLoader.build(BootstrapClassLoader.class)
UrlClassLoader.Builder<?> builder = UrlClassLoader.build()
.urls(filterClassPath(new ArrayList<>(classpath)))
.allowLock()
.usePersistentClasspathIndexForLocalClassDirectories()
@@ -67,21 +74,26 @@ public class BootstrapClassLoaderUtil extends ClassUtilCore {
ClassLoaderUtil.addPlatformLoaderParentIfOnJdk9(builder);
final BootstrapClassLoader loader = builder.get();
if (installMarketplace) {
try {
final UrlClassLoader mpBootloader = UrlClassLoader.build().urls(mpBoot.toURI().toURL()).parent(BootstrapClassLoaderUtil.class.getClassLoader()).get();
for (BootstrapClassLoader.Transformer transformer : ServiceLoader.load(BootstrapClassLoader.Transformer.class, mpBootloader)) {
loader.addTransformer(transformer);
List<BytecodeTransformer> transformers = new SmartList<>();
UrlClassLoader mpBootloader = UrlClassLoader.build().urls(mpBoot.toURI().toURL()).parent(BootstrapClassLoaderUtil.class.getClassLoader()).get();
for (BytecodeTransformer transformer : ServiceLoader.load(BytecodeTransformer.class, mpBootloader)) {
transformers.add(transformer);
}
if (!transformers.isEmpty()) {
return new TransformingLoader(builder, transformers);
}
}
catch (Throwable e) {
LOG.info("Marketplace boot error: ", e);
// at this point logging is not initialized yet, so reporting the error directly
final String message = "As a workaround you may uninstall or update JetBrains Marketplace Support plugin at " +
new File(PathManager.getPluginsPath(), MARKETPLACE_PLUGIN_NAME).getAbsolutePath();
Main.showMessage("JetBrains Marketplace boot failure", new Exception(message, e));
}
}
return loader;
return builder.get();
}
/**
@@ -243,4 +255,34 @@ public class BootstrapClassLoaderUtil extends ClassUtilCore {
}
return classpath;
}
private static class TransformingLoader extends UrlClassLoader {
private final List<BytecodeTransformer> myTransformers;
TransformingLoader(@NotNull Builder<?> builder, List<BytecodeTransformer> transformers) {
super(builder);
myTransformers = Collections.unmodifiableList(transformers);
}
@Override
protected Class _defineClass(String name, byte[] b) {
return super._defineClass(name, doTransform(name, null, b));
}
@Override
protected Class _defineClass(String name, byte[] b, @Nullable ProtectionDomain protectionDomain) {
return super._defineClass(name, doTransform(name, protectionDomain, b), protectionDomain);
}
private byte[] doTransform(String name, ProtectionDomain protectionDomain, byte[] bytes) {
byte[] b = bytes;
for (BytecodeTransformer transformer : myTransformers) {
final byte[] result = transformer.transform(this, name, protectionDomain, b);
if (result != null) {
b = result;
}
}
return b;
}
}
}
@@ -0,0 +1,10 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide;
import org.jetbrains.annotations.Nullable;
import java.security.ProtectionDomain;
public interface BytecodeTransformer {
byte[] transform(ClassLoader loader, String className, @Nullable ProtectionDomain protectionDomain, byte[] classBytes);
}