Make extension classloader caching keyed on directory (#3165)

* Make extension classloaders keyed by extension directory
* Fixes #3163

* Add in same-directory-name unit test
This commit is contained in:
Charles Allen 2016-06-23 17:13:19 -07:00 committed by Jonathan Wei
parent 66d8ad36d7
commit 15f833a861
2 changed files with 31 additions and 5 deletions

View File

@ -78,13 +78,15 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/** /**
*/ */
public class Initialization public class Initialization
{ {
private static final Logger log = new Logger(Initialization.class); private static final Logger log = new Logger(Initialization.class);
private static final Map<String, URLClassLoader> loadersMap = Maps.newHashMap(); private static final ConcurrentMap<File, URLClassLoader> loadersMap = new ConcurrentHashMap<>();
private final static Map<Class, Set> extensionsMap = Maps.<Class, Set>newHashMap(); private final static Map<Class, Set> extensionsMap = Maps.<Class, Set>newHashMap();
@ -114,7 +116,7 @@ public class Initialization
/** /**
* Used for testing only * Used for testing only
*/ */
static Map<String, URLClassLoader> getLoadersMap() static Map<File, URLClassLoader> getLoadersMap()
{ {
return loadersMap; return loadersMap;
} }
@ -274,8 +276,8 @@ public class Initialization
log.info("added URL[%s]", url); log.info("added URL[%s]", url);
urls[i++] = url; urls[i++] = url;
} }
loader = new URLClassLoader(urls, Initialization.class.getClassLoader()); loadersMap.putIfAbsent(extension, new URLClassLoader(urls, Initialization.class.getClassLoader()));
loadersMap.put(extension.getName(), loader); loader = loadersMap.get(extension);
} }
return loader; return loader;
} }

View File

@ -113,7 +113,8 @@ public class InitializationTest
@Test @Test
public void test04DuplicateClassLoaderExtensions() throws Exception public void test04DuplicateClassLoaderExtensions() throws Exception
{ {
Initialization.getLoadersMap().put("xyz", (URLClassLoader) Initialization.class.getClassLoader()); final File extensionDir = temporaryFolder.newFolder();
Initialization.getLoadersMap().put(extensionDir, (URLClassLoader) Initialization.class.getClassLoader());
Collection<DruidModule> modules = Initialization.getFromExtensions(new ExtensionsConfig(), DruidModule.class); Collection<DruidModule> modules = Initialization.getFromExtensions(new ExtensionsConfig(), DruidModule.class);
@ -426,6 +427,29 @@ public class InitializationTest
} }
@Test
public void testExtensionsWithSameDirName() throws Exception
{
final String extensionName = "some_extension";
final File tmpDir1 = temporaryFolder.newFolder();
final File tmpDir2 = temporaryFolder.newFolder();
final File extension1 = new File(tmpDir1, extensionName);
final File extension2 = new File(tmpDir2, extensionName);
Assert.assertTrue(extension1.mkdir());
Assert.assertTrue(extension2.mkdir());
final File jar1 = new File(extension1, "jar1.jar");
final File jar2 = new File(extension2, "jar2.jar");
Assert.assertTrue(jar1.createNewFile());
Assert.assertTrue(jar2.createNewFile());
final ClassLoader classLoader1 = Initialization.getClassLoaderForExtension(extension1);
final ClassLoader classLoader2 = Initialization.getClassLoaderForExtension(extension2);
Assert.assertArrayEquals(new URL[]{jar1.toURL()}, ((URLClassLoader) classLoader1).getURLs());
Assert.assertArrayEquals(new URL[]{jar2.toURL()}, ((URLClassLoader) classLoader2).getURLs());
}
public static class TestDruidModule implements DruidModule public static class TestDruidModule implements DruidModule
{ {
@Override @Override