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

View File

@ -113,7 +113,8 @@ public class InitializationTest
@Test
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);
@ -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
{
@Override