forked from jboss-modules/jboss-modules
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
From now on, alias modules are handled as regular modules with a single dependency on the alias target
- Loading branch information
Showing
22 changed files
with
504 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
164 changes: 164 additions & 0 deletions
164
src/test/java/org/jboss/modules/ModuleClassLoaderAliasReloadTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package org.jboss.modules; | ||
|
||
import static org.junit.Assert.assertNotNull; | ||
import static org.junit.Assert.fail; | ||
|
||
import java.io.IOException; | ||
import java.util.Collection; | ||
|
||
import org.jboss.modules.test.TestClass; | ||
import org.jboss.modules.util.TestModuleLoader; | ||
import org.jboss.modules.util.TestResourceLoader; | ||
import org.junit.Test; | ||
|
||
/** | ||
* Verifies the functionality of alias modules in unload/reload scenarios. | ||
* | ||
* @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a> | ||
* @author <a href="https://github.com/ppalaga">Peter Palaga</a> | ||
*/ | ||
public class ModuleClassLoaderAliasReloadTest extends AbstractModuleTestCase { | ||
|
||
private static final ModuleIdentifier MODULE_ONE_ID = ModuleIdentifier.fromString("test-module-1"); | ||
private static final ModuleIdentifier MODULE_TWO_ID = ModuleIdentifier.fromString("test-module-2"); | ||
private static final ModuleIdentifier MODULE_TWO_AL = ModuleIdentifier.fromString("test-module-2-alias"); | ||
private TestModuleLoader moduleLoader = new TestModuleLoader(); | ||
|
||
private static final class CloseAwareResourceLoader implements ResourceLoader { | ||
|
||
private final ResourceLoader delegate; | ||
private volatile boolean closed; | ||
|
||
private CloseAwareResourceLoader(final ResourceLoader delegate) { | ||
this.delegate = delegate; | ||
} | ||
|
||
@Override | ||
public String getRootName() { | ||
if (closed) throw new IllegalStateException(); | ||
return delegate.getRootName(); | ||
} | ||
|
||
@Override | ||
public ClassSpec getClassSpec(String fileName) throws IOException { | ||
if (closed) throw new IllegalStateException(); | ||
return delegate.getClassSpec(fileName); | ||
} | ||
|
||
@Override | ||
public PackageSpec getPackageSpec(String name) throws IOException { | ||
if (closed) throw new IllegalStateException(); | ||
return delegate.getPackageSpec(name); | ||
} | ||
|
||
@Override | ||
public Resource getResource(String name) { | ||
if (closed) throw new IllegalStateException(); | ||
return delegate.getResource(name); | ||
} | ||
|
||
@Override | ||
public String getLibrary(String name) { | ||
if (closed) throw new IllegalStateException(); | ||
return delegate.getLibrary(name); | ||
} | ||
|
||
@Override | ||
public Collection<String> getPaths() { | ||
if (closed) throw new IllegalStateException(); | ||
return delegate.getPaths(); | ||
} | ||
|
||
public void close() { | ||
closed = true; | ||
} | ||
} | ||
|
||
public void configureModules() throws Exception { | ||
// first module | ||
final ModuleSpec.Builder moduleOneBuilder = ModuleSpec.build(MODULE_ONE_ID); | ||
moduleOneBuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec( | ||
new CloseAwareResourceLoader( | ||
TestResourceLoader.build() | ||
.addClass(TestClass.class) | ||
.addResources(getResource("test/aliasmodule/rootOne")) | ||
.create()) | ||
)); | ||
moduleOneBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_TWO_AL)); | ||
moduleOneBuilder.addDependency(DependencySpec.createLocalDependencySpec()); | ||
moduleLoader.addModuleSpec(moduleOneBuilder.create()); | ||
// second module | ||
final ModuleSpec.Builder moduleTwoBuilder = ModuleSpec.build(MODULE_TWO_ID); | ||
moduleTwoBuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec( | ||
new CloseAwareResourceLoader( | ||
TestResourceLoader.build() | ||
.addClass(TestClass.class) | ||
.addResources(getResource("test/aliasmodule/rootTwo")) | ||
.create() | ||
) | ||
)); | ||
moduleTwoBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_ONE_ID)); | ||
moduleTwoBuilder.addDependency(DependencySpec.createLocalDependencySpec()); | ||
moduleLoader.addModuleSpec(moduleTwoBuilder.create()); | ||
// second alias module | ||
final ModuleSpec.AliasBuilder moduleTwoAliasBuilder = ModuleSpec.buildAlias(MODULE_TWO_AL, MODULE_TWO_ID); | ||
moduleLoader.addModuleSpec(moduleTwoAliasBuilder.create()); | ||
} | ||
|
||
/** | ||
* Ensure the Alias modules do not leak during unload/reload, see https://issues.jboss.org/browse/MODULES-241 | ||
* | ||
* @throws Exception | ||
*/ | ||
@Test | ||
public void testAliasModuleReload() throws Exception { | ||
// FIRST PHASE | ||
configureModules(); | ||
Module testModule1 = moduleLoader.loadModule(MODULE_ONE_ID); | ||
Module testModule2 = moduleLoader.loadModule(MODULE_TWO_ID); | ||
ModuleClassLoader classLoader1 = testModule1.getClassLoader(); | ||
ModuleClassLoader classLoader2 = testModule2.getClassLoader(); | ||
|
||
try { | ||
Class<?> testClass1 = classLoader1.loadClass("org.jboss.modules.test.TestClass"); | ||
assertNotNull(testClass1); | ||
Class<?> testClass2 = classLoader2.loadClass("org.jboss.modules.test.TestClass"); | ||
assertNotNull(testClass2); | ||
assertNotNull(testClass1.getResource("/test.txt")); | ||
assertNotNull(testClass2.getResource("/test.txt")); | ||
} catch (ClassNotFoundException e) { | ||
fail(); | ||
} | ||
// cleanup | ||
for (final ResourceLoader rl : classLoader1.getResourceLoaders()) { ((CloseAwareResourceLoader)rl).close(); } | ||
for (final ResourceLoader rl : classLoader2.getResourceLoaders()) { ((CloseAwareResourceLoader)rl).close(); } | ||
moduleLoader.unloadModuleLocal(testModule1); | ||
moduleLoader.unloadModuleLocal(testModule2); | ||
|
||
// SECOND PHASE | ||
configureModules(); | ||
testModule1 = moduleLoader.loadModule(MODULE_ONE_ID); | ||
moduleLoader.relink(testModule1); | ||
testModule2 = moduleLoader.loadModule(MODULE_TWO_ID); | ||
moduleLoader.relink(testModule2); | ||
classLoader1 = testModule1.getClassLoader(); | ||
classLoader2 = testModule2.getClassLoader(); | ||
|
||
try { | ||
Class<?> testClass1 = classLoader1.loadClass("org.jboss.modules.test.TestClass"); | ||
assertNotNull(testClass1); | ||
Class<?> testClass2 = classLoader2.loadClass("org.jboss.modules.test.TestClass"); | ||
assertNotNull(testClass2); | ||
assertNotNull(testClass1.getResource("/test.txt")); | ||
assertNotNull(testClass2.getResource("/test.txt")); | ||
} catch (ClassNotFoundException e) { | ||
fail(); | ||
} | ||
// cleanup | ||
for (final ResourceLoader rl : classLoader1.getResourceLoaders()) { ((CloseAwareResourceLoader)rl).close(); } | ||
for (final ResourceLoader rl : classLoader2.getResourceLoaders()) { ((CloseAwareResourceLoader)rl).close(); } | ||
moduleLoader.unloadModuleLocal(testModule1); | ||
moduleLoader.unloadModuleLocal(testModule2); | ||
} | ||
|
||
} |
103 changes: 103 additions & 0 deletions
103
src/test/java/org/jboss/modules/ModuleClassLoaderAliasTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package org.jboss.modules; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotNull; | ||
import static org.junit.Assert.assertSame; | ||
import static org.junit.Assert.fail; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.net.URL; | ||
import java.nio.charset.Charset; | ||
|
||
import org.jboss.modules.util.Util; | ||
import org.junit.Test; | ||
|
||
/** | ||
* Tests the basic functionality of alias modules. | ||
* | ||
* @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a> | ||
* @author <a href="https://github.com/ppalaga">Peter Palaga</a> | ||
*/ | ||
public class ModuleClassLoaderAliasTest extends AbstractModuleTestCase { | ||
|
||
@Test | ||
public void testAliasCyclic() throws Exception { | ||
final File repoRoot = getResource("test/repo"); | ||
final ModuleLoader moduleLoader = new LocalModuleLoader(new File[] { repoRoot }); | ||
|
||
Module testModule1 = moduleLoader.loadModule(ModuleIdentifier.fromString("test.alias-cyclic.module-one")); | ||
Module testModule2 = moduleLoader.loadModule(ModuleIdentifier.fromString("test.alias-cyclic.module-two")); | ||
ModuleClassLoader classLoader1 = testModule1.getClassLoader(); | ||
ModuleClassLoader classLoader2 = testModule2.getClassLoader(); | ||
|
||
try { | ||
Class<?> testClass1 = classLoader1.loadClass("org.jboss.modules.test.ClassA"); | ||
assertNotNull(testClass1); | ||
Class<?> testClass2 = classLoader2.loadClass("org.jboss.modules.test.ClassB"); | ||
assertNotNull(testClass2); | ||
|
||
Class<?> testClass1ViaLoader2 = classLoader2.loadClass("org.jboss.modules.test.ClassA"); | ||
assertNotNull(testClass1ViaLoader2); | ||
assertSame(testClass1, testClass1ViaLoader2); | ||
|
||
Class<?> testClass2ViaLoader1 = classLoader1.loadClass("org.jboss.modules.test.ClassB"); | ||
assertNotNull(testClass2ViaLoader1); | ||
assertSame(testClass2, testClass2ViaLoader1); | ||
|
||
assertResourceString(testClass1.getResource("/test.txt"), "Test file 1"); | ||
assertResourceString(testClass2.getResource("/test.txt"), "Test file 2"); | ||
|
||
assertResourceString(classLoader1.getResource("/test.txt"), "Test file 1"); | ||
assertResourceString(classLoader2.getResource("/test.txt"), "Test file 2"); | ||
|
||
} catch (ClassNotFoundException e) { | ||
fail(); | ||
} | ||
moduleLoader.unloadModuleLocal(testModule1); | ||
moduleLoader.unloadModuleLocal(testModule2); | ||
|
||
} | ||
|
||
@Test | ||
public void testAliasSimple() throws Exception { | ||
final File repoRoot = getResource("test/repo"); | ||
final ModuleLoader moduleLoader = new LocalModuleLoader(new File[] { repoRoot }); | ||
|
||
Module testModule1 = moduleLoader.loadModule(ModuleIdentifier.fromString("test.alias-simple.module-one")); | ||
Module testModule2 = moduleLoader.loadModule(ModuleIdentifier.fromString("test.alias-simple.module-two")); | ||
ModuleClassLoader classLoader1 = testModule1.getClassLoader(); | ||
ModuleClassLoader classLoader2 = testModule2.getClassLoader(); | ||
|
||
Class<?> testClass1 = classLoader1.loadClass("org.jboss.modules.test.ClassA"); | ||
assertNotNull(testClass1); | ||
Class<?> testClass2 = classLoader2.loadClass("org.jboss.modules.test.ClassB"); | ||
assertNotNull(testClass2); | ||
|
||
Class<?> testClass2ViaLoader1 = classLoader1.loadClass("org.jboss.modules.test.ClassB"); | ||
assertNotNull(testClass2ViaLoader1); | ||
assertSame(testClass2, testClass2ViaLoader1); | ||
|
||
try { | ||
classLoader2.loadClass("org.jboss.modules.test.ClassA"); | ||
fail("ClassNotFoundException expected"); | ||
} catch (ClassNotFoundException expected) { | ||
} | ||
|
||
assertResourceString(testClass1.getResource("/test.txt"), "Test file 1"); | ||
assertResourceString(testClass2.getResource("/test.txt"), "Test file 2"); | ||
|
||
assertResourceString(classLoader1.getResource("/test.txt"), "Test file 1"); | ||
assertResourceString(classLoader2.getResource("/test.txt"), "Test file 2"); | ||
|
||
moduleLoader.unloadModuleLocal(testModule1); | ||
moduleLoader.unloadModuleLocal(testModule2); | ||
|
||
} | ||
|
||
private static void assertResourceString(URL resource, String expected) throws IOException { | ||
assertNotNull(resource); | ||
byte[] bytes = Util.readBytes(resource.openStream()); | ||
assertEquals(expected, new String(bytes, Charset.forName("utf-8"))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Test file 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Test file 2 |
Binary file added
BIN
+302 Bytes
...urces/test/repo/test/alias-cyclic/module-one/main/dir/org/jboss/modules/test/ClassA.class
Binary file not shown.
1 change: 1 addition & 0 deletions
1
src/test/resources/test/repo/test/alias-cyclic/module-one/main/dir/test.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Test file 1 |
Oops, something went wrong.