ATLAS-4642: replace use of static volatile member from plugin classloader
This commit is contained in:
parent
2949b11627
commit
218dd81db9
|
|
@ -30,6 +30,8 @@ import java.security.PrivilegedAction;
|
||||||
import java.security.PrivilegedActionException;
|
import java.security.PrivilegedActionException;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AtlasPluginClassLoader to use plugin classpath first, before component classpath.
|
* AtlasPluginClassLoader to use plugin classpath first, before component classpath.
|
||||||
|
|
@ -37,39 +39,43 @@ import java.util.Enumeration;
|
||||||
public final class AtlasPluginClassLoader extends URLClassLoader {
|
public final class AtlasPluginClassLoader extends URLClassLoader {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AtlasPluginClassLoader.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AtlasPluginClassLoader.class);
|
||||||
|
|
||||||
private static volatile AtlasPluginClassLoader me = null;
|
private static final Map<String, AtlasPluginClassLoader> pluginClassLoaders = new HashMap<>();
|
||||||
|
|
||||||
private final ThreadLocal<ClassLoader> preActivateClassLoader = new ThreadLocal<>();
|
private final ThreadLocal<ClassLoader> preActivateClassLoader = new ThreadLocal<>();
|
||||||
|
private final MyClassLoader componentClassLoader;
|
||||||
private final MyClassLoader componentClassLoader;
|
|
||||||
|
|
||||||
private AtlasPluginClassLoader(String pluginType, Class<?> pluginClass) throws URISyntaxException {
|
private AtlasPluginClassLoader(String pluginType, Class<?> pluginClass) throws URISyntaxException {
|
||||||
this(AtlasPluginClassLoaderUtil.getPluginImplLibPath(pluginType, pluginClass));
|
this(AtlasPluginClassLoaderUtil.getPluginImplLibPath(pluginType, pluginClass), pluginClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
//visible for testing
|
//visible for testing
|
||||||
AtlasPluginClassLoader(String libraryPath) {
|
AtlasPluginClassLoader(String[] libraryPath, Class<?> pluginShimClass) {
|
||||||
super(AtlasPluginClassLoaderUtil.getFilesInDirectories(new String[]{libraryPath}), null);
|
super(AtlasPluginClassLoaderUtil.getFilesInDirectories(libraryPath), null);
|
||||||
|
|
||||||
componentClassLoader = AccessController.doPrivileged(new PrivilegedAction<MyClassLoader>() {
|
componentClassLoader = AccessController.doPrivileged(new PrivilegedAction<MyClassLoader>() {
|
||||||
public MyClassLoader run() {
|
public MyClassLoader run() {
|
||||||
return new MyClassLoader(Thread.currentThread().getContextClassLoader());
|
return new MyClassLoader(pluginShimClass);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AtlasPluginClassLoader getInstance(final String pluginType, final Class<?> pluginClass) throws PrivilegedActionException {
|
public static AtlasPluginClassLoader getInstance(final String pluginType, final Class<?> pluginClass) throws PrivilegedActionException {
|
||||||
AtlasPluginClassLoader ret = me;
|
AtlasPluginClassLoader ret = pluginClassLoaders.get(pluginType);
|
||||||
|
|
||||||
if (ret == null) {
|
if (ret == null) {
|
||||||
synchronized (AtlasPluginClassLoader.class) {
|
synchronized (AtlasPluginClassLoader.class) {
|
||||||
ret = me;
|
ret = pluginClassLoaders.get(pluginType);
|
||||||
|
|
||||||
if (ret == null) {
|
if (ret == null) {
|
||||||
me = AccessController.doPrivileged(new PrivilegedExceptionAction<AtlasPluginClassLoader>() {
|
ret = AccessController.doPrivileged(new PrivilegedExceptionAction<AtlasPluginClassLoader>() {
|
||||||
public AtlasPluginClassLoader run() throws URISyntaxException {
|
public AtlasPluginClassLoader run() throws URISyntaxException {
|
||||||
return new AtlasPluginClassLoader(pluginType, pluginClass);
|
return new AtlasPluginClassLoader(pluginType, pluginClass);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ret = me;
|
|
||||||
|
if (ret != null) {
|
||||||
|
pluginClassLoaders.put(pluginType, ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -332,13 +338,17 @@ public final class AtlasPluginClassLoader extends URLClassLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
static class MyClassLoader extends ClassLoader {
|
static class MyClassLoader extends ClassLoader {
|
||||||
public MyClassLoader(ClassLoader realClassLoader) {
|
public MyClassLoader(Class<?> pluginShimClass) {
|
||||||
super(realClassLoader);
|
super(getParentClassLoaderToUse(pluginShimClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> findClass(String name) throws ClassNotFoundException { //NOPMD
|
public Class<?> findClass(String name) throws ClassNotFoundException { //NOPMD
|
||||||
return super.findClass(name);
|
return super.findClass(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ClassLoader getParentClassLoaderToUse(Class<?> pluginShimClass) {
|
||||||
|
return pluginShimClass != null ? pluginShimClass.getClassLoader() : Thread.currentThread().getContextClassLoader();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,19 +96,19 @@ final class AtlasPluginClassLoaderUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPluginImplLibPath(String pluginType, Class<?> pluginClass) throws URISyntaxException {
|
public static String[] getPluginImplLibPath(String pluginType, Class<?> pluginClass) throws URISyntaxException {
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("==> AtlasPluginClassLoaderUtil.getPluginImplLibPath for Class ({})", pluginClass.getName());
|
LOG.debug("==> AtlasPluginClassLoaderUtil.getPluginImplLibPath for Class ({})", pluginClass.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
URI uri = pluginClass.getProtectionDomain().getCodeSource().getLocation().toURI();
|
URI uri = pluginClass.getProtectionDomain().getCodeSource().getLocation().toURI();
|
||||||
Path path = Paths.get(URI.create(uri.toString()));
|
Path path = Paths.get(URI.create(uri.toString()));
|
||||||
String ret = path.getParent().toString() + File.separatorChar + ATLAS_PLUGIN_LIBDIR.replaceAll("%", pluginType);
|
String ret = path.getParent().toString() + File.separatorChar + ATLAS_PLUGIN_LIBDIR.replaceAll("%", pluginType);
|
||||||
|
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("<== AtlasPluginClassLoaderUtil.getPluginImplLibPath for Class {}): {})", pluginClass.getName(), ret);
|
LOG.debug("<== AtlasPluginClassLoaderUtil.getPluginImplLibPath for Class {}): {})", pluginClass.getName(), ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return new String[] { ret };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ public class AtlasPluginClassLoaderTest {
|
||||||
//expected
|
//expected
|
||||||
}
|
}
|
||||||
|
|
||||||
AtlasPluginClassLoader classLoader = new AtlasPluginClassLoader("../common/target");
|
AtlasPluginClassLoader classLoader = new AtlasPluginClassLoader(new String[]{ "../common/target" }, this.getClass());
|
||||||
|
|
||||||
classLoader.activate();
|
classLoader.activate();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue