ATLAS-4642: replace use of static volatile member from plugin classloader
diff --git a/plugin-classloader/src/main/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoader.java b/plugin-classloader/src/main/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoader.java
index fc75a7e..0a71bf1 100644
--- a/plugin-classloader/src/main/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoader.java
+++ b/plugin-classloader/src/main/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoader.java
@@ -30,6 +30,8 @@
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * AtlasPluginClassLoader to use plugin classpath first, before component classpath.
@@ -37,39 +39,43 @@
 public final class AtlasPluginClassLoader extends URLClassLoader {
     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 MyClassLoader componentClassLoader;
+    private final MyClassLoader            componentClassLoader;
 
     private AtlasPluginClassLoader(String pluginType, Class<?> pluginClass) throws URISyntaxException {
-        this(AtlasPluginClassLoaderUtil.getPluginImplLibPath(pluginType, pluginClass));
+        this(AtlasPluginClassLoaderUtil.getPluginImplLibPath(pluginType, pluginClass), pluginClass);
     }
 
     //visible for testing
-    AtlasPluginClassLoader(String libraryPath) {
-        super(AtlasPluginClassLoaderUtil.getFilesInDirectories(new String[]{libraryPath}), null);
+    AtlasPluginClassLoader(String[] libraryPath, Class<?> pluginShimClass) {
+        super(AtlasPluginClassLoaderUtil.getFilesInDirectories(libraryPath), null);
 
         componentClassLoader = AccessController.doPrivileged(new PrivilegedAction<MyClassLoader>() {
             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 {
-        AtlasPluginClassLoader ret = me;
+        AtlasPluginClassLoader ret = pluginClassLoaders.get(pluginType);
+
         if (ret == null) {
             synchronized (AtlasPluginClassLoader.class) {
-                ret = me;
+                ret = pluginClassLoaders.get(pluginType);
+
                 if (ret == null) {
-					me = AccessController.doPrivileged(new PrivilegedExceptionAction<AtlasPluginClassLoader>() {
+					ret = AccessController.doPrivileged(new PrivilegedExceptionAction<AtlasPluginClassLoader>() {
 					    public AtlasPluginClassLoader run() throws URISyntaxException {
 					        return new AtlasPluginClassLoader(pluginType, pluginClass);
 					    }
 					});
-                    ret = me;
+
+                    if (ret != null) {
+                        pluginClassLoaders.put(pluginType, ret);
+                    }
                 }
             }
         }
@@ -332,13 +338,17 @@
     }
 
     static class MyClassLoader extends ClassLoader {
-        public MyClassLoader(ClassLoader realClassLoader) {
-            super(realClassLoader);
+        public MyClassLoader(Class<?> pluginShimClass) {
+            super(getParentClassLoaderToUse(pluginShimClass));
         }
 
         @Override
         public Class<?> findClass(String name) throws ClassNotFoundException { //NOPMD
             return super.findClass(name);
         }
+
+        private static ClassLoader getParentClassLoaderToUse(Class<?> pluginShimClass) {
+            return pluginShimClass != null ? pluginShimClass.getClassLoader() : Thread.currentThread().getContextClassLoader();
+        }
     }
 }
diff --git a/plugin-classloader/src/main/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoaderUtil.java b/plugin-classloader/src/main/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoaderUtil.java
index f44603b..e6f868b 100644
--- a/plugin-classloader/src/main/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoaderUtil.java
+++ b/plugin-classloader/src/main/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoaderUtil.java
@@ -96,19 +96,19 @@
         }
     }
 
-    public static String getPluginImplLibPath(String pluginType, Class<?> pluginClass) throws URISyntaxException {
+    public static String[] getPluginImplLibPath(String pluginType, Class<?> pluginClass) throws URISyntaxException {
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> AtlasPluginClassLoaderUtil.getPluginImplLibPath for Class ({})", pluginClass.getName());
         }
 
-        URI uri = pluginClass.getProtectionDomain().getCodeSource().getLocation().toURI();
-        Path path = Paths.get(URI.create(uri.toString()));
-        String ret = path.getParent().toString() + File.separatorChar + ATLAS_PLUGIN_LIBDIR.replaceAll("%", pluginType);
+        URI    uri  = pluginClass.getProtectionDomain().getCodeSource().getLocation().toURI();
+        Path   path = Paths.get(URI.create(uri.toString()));
+        String ret  = path.getParent().toString() + File.separatorChar + ATLAS_PLUGIN_LIBDIR.replaceAll("%", pluginType);
 
         if (LOG.isDebugEnabled()) {
             LOG.debug("<== AtlasPluginClassLoaderUtil.getPluginImplLibPath for Class {}): {})", pluginClass.getName(), ret);
         }
 
-        return ret;
+        return new String[] { ret };
     }
 }
diff --git a/plugin-classloader/src/test/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoaderTest.java b/plugin-classloader/src/test/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoaderTest.java
index 6139a00..e12584f 100644
--- a/plugin-classloader/src/test/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoaderTest.java
+++ b/plugin-classloader/src/test/java/org/apache/atlas/plugin/classloader/AtlasPluginClassLoaderTest.java
@@ -34,7 +34,7 @@
             //expected
         }
 
-        AtlasPluginClassLoader classLoader = new AtlasPluginClassLoader("../common/target");
+        AtlasPluginClassLoader classLoader = new AtlasPluginClassLoader(new String[]{ "../common/target" }, this.getClass());
 
         classLoader.activate();