[jboss-cvs] JBossAS SVN: r101714 - in projects/jboss-cl/trunk/classloading/src: main/java/org/jboss/classloading/spi/dependency/policy and 8 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Mar 2 08:11:15 EST 2010
Author: adrian at jboss.org
Date: 2010-03-02 08:11:14 -0500 (Tue, 02 Mar 2010)
New Revision: 101714
Added:
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ClassLoadingAdmin.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ExportPackage.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ImportModule.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/ClassLoadingAdminLazyShutdownUnitTestCase.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/ClassLoadingAdminUnitTestCase.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/RefreshModulesUnitTestCase.java
Modified:
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ClassLoading.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Domain.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/LifeCycle.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Module.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/ClassLoaderPolicyModule.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/mock/MockClassLoaderPolicyModule.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/version/Version.java
projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/version/VersionRange.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/DependencyTestSuite.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/AbstractMockClassLoaderUnitTest.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/LifeCycleTestSuite.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/support/a/MockLifeCycle.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/support/a/MockLifeCycleClassLoaderPolicyModule.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/AbstractMockLifeCycleUnitTest.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/LifeCycleUnitTestCase.java
projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/version/test/VersionRangeUnitTestCase.java
Log:
[JBCL-129][JBCL-131][JBCL-154][JBCL-155] - Complete LifeCycle handling and Implement ClassLoadingAdmin. Also add String parsing for VersionRanges.
Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ClassLoading.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ClassLoading.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ClassLoading.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -21,6 +21,7 @@
*/
package org.jboss.classloading.spi.dependency;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -30,6 +31,7 @@
import org.jboss.classloader.spi.ClassLoaderSystem;
import org.jboss.classloading.spi.metadata.Capability;
+import org.jboss.classloading.spi.version.VersionRange;
import org.jboss.logging.Logger;
import org.jboss.util.collection.ConcurrentSet;
@@ -40,7 +42,7 @@
* @author <a href="ales.justin at jboss.org">Ales Justin</a>
* @version $Revision: 1.1 $
*/
-public class ClassLoading implements Resolver
+public class ClassLoading implements Resolver, ClassLoadingAdmin
{
/** The log */
private static final Logger log = Logger.getLogger(ClassLoading.class);
@@ -223,7 +225,7 @@
// FINDBUGS: This synchronization is correct - more than addIfNotPresent behaviour
synchronized (domains)
{
- domain = getDomain(domainName);
+ domain = domains.get(domainName);
if (domain == null)
{
domain = createDomain(domainName, parentDomainName, parentFirst);
@@ -268,6 +270,58 @@
return new Domain(this, domainName, parentDomainName, parentFirst);
}
+ public Module getModuleForClass(Class<?> clazz)
+ {
+ return Module.getModuleForClass(clazz);
+ }
+
+ public Collection<Module> getModules(String name, VersionRange range)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ Collection<Module> result = new HashSet<Module>();
+ for (Domain domain : domains.values())
+ domain.getModulesInternal(name, range, result);
+ return result;
+ }
+
+ public Collection<ImportModule> getImportedModules(String name, VersionRange range)
+ {
+ Collection<ImportModule> result = new HashSet<ImportModule>();
+ for (Domain domain : domains.values())
+ domain.getImportingModulesInternal(name, range, result);
+ return result;
+ }
+
+ public Collection<ExportPackage> getExportedPackages(Module module)
+ {
+ if (module == null)
+ throw new IllegalArgumentException("Null modules");
+ return module.getExportedPackages();
+ }
+
+ public Collection<ExportPackage> getExportedPackages(String name, VersionRange range)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ Collection<ExportPackage> result = new HashSet<ExportPackage>();
+ for (Domain domain : domains.values())
+ domain.getExportedPackagesInternal(name, range, result);
+ return result;
+ }
+
+ public void refreshModules(Module... modules) throws Exception
+ {
+ Module.refreshModules(modules);
+ }
+
+ public boolean resolveModules(Module... modules) throws Exception
+ {
+ return Module.resolveModules(modules);
+ }
+
/**
* Find the module for a classloader
*
Added: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ClassLoadingAdmin.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ClassLoadingAdmin.java (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ClassLoadingAdmin.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -0,0 +1,73 @@
+package org.jboss.classloading.spi.dependency;
+
+import java.util.Collection;
+
+import org.jboss.classloading.spi.version.VersionRange;
+
+/**
+ * ClassLoading admin
+ *
+ * @author adrian at jboss.org
+ */
+public interface ClassLoadingAdmin
+{
+ /**
+ * Get the module for a class
+ *
+ * @param clazz the class
+ * @return the module or null if there is no such module
+ */
+ Module getModuleForClass(Class<?> clazz);
+
+ /**
+ * Get the modules matching the name and version range
+ *
+ * @param name the name
+ * @param range the version range or null if all are required
+ * @return the modules
+ */
+ Collection<Module> getModules(String name, VersionRange range);
+
+ /**
+ * Get the exported packages for a module
+ *
+ * @param module the module
+ * @return the exported packages
+ */
+ Collection<ExportPackage> getExportedPackages(Module module);
+
+ /**
+ * Get the exported packages by name and version
+ *
+ * @param name the name of the package
+ * @param range the version range or null if all are required
+ * @return the exported packages
+ */
+ Collection<ExportPackage> getExportedPackages(String name, VersionRange range);
+
+ /**
+ * Get the imported modules for a module
+ *
+ * @param name the name of the module or null for all
+ * @param range the version range or null if all are required
+ * @return the imported modules
+ */
+ Collection<ImportModule> getImportedModules(String name, VersionRange range);
+
+ /**
+ * Resolve the specified modules
+ *
+ * @param modules the modules
+ * @return the true if all the modules are resolved
+ * @throws Exception for any error
+ */
+ boolean resolveModules(Module... modules) throws Exception;
+
+ /**
+ * Refresh stale modules
+ *
+ * @param modules the modules
+ * @throws Exception for any error
+ */
+ void refreshModules(Module... modules) throws Exception;
+}
Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Domain.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Domain.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Domain.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -21,13 +21,19 @@
*/
package org.jboss.classloading.spi.dependency;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import org.jboss.classloading.plugins.metadata.ModuleRequirement;
+import org.jboss.classloading.plugins.metadata.PackageCapability;
+import org.jboss.classloading.plugins.metadata.PackageRequirement;
import org.jboss.classloading.spi.metadata.Capability;
import org.jboss.classloading.spi.metadata.Requirement;
+import org.jboss.classloading.spi.version.VersionRange;
import org.jboss.logging.Logger;
/**
@@ -38,7 +44,7 @@
* @author Thomas.Diesler at jboss.com
* @version $Revision: 1.1 $
*/
-public class Domain
+public class Domain implements ClassLoadingAdmin
{
/** The log */
private static final Logger log = Logger.getLogger(Domain.class);
@@ -242,7 +248,16 @@
{
LifeCycle lifeCycle = result.getLifeCycle();
if (lifeCycle != null && lifeCycle.isLazyResolve() && lifeCycle.isResolved() == false)
- lifeCycle.doResolve();
+ {
+ try
+ {
+ lifeCycle.resolve();
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error in resolve for " + result, t);
+ }
+ }
}
return result;
@@ -307,6 +322,162 @@
return null;
}
+ public Module getModuleForClass(Class<?> clazz)
+ {
+ return Module.getModuleForClass(clazz);
+ }
+
+ public Collection<Module> getModules(String name, VersionRange range)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ Collection<Module> result = new HashSet<Module>();
+ getModulesInternal(name, range, result);
+ return result;
+ }
+
+ /**
+ * Get the modules matching the name and range
+ *
+ * @param name the name
+ * @param range the range
+ * @param result the matching modules
+ */
+ void getModulesInternal(String name, VersionRange range, Collection<Module> result)
+ {
+ if (range == null)
+ range = VersionRange.ALL_VERSIONS;
+
+ for (Module module : modules)
+ {
+ List<Capability> capabilities = module.getCapabilitiesRaw();
+ if (capabilities != null && capabilities.isEmpty() == false)
+ {
+ ModuleRequirement requirement = new ModuleRequirement(name, range);
+ for (Capability capability : capabilities)
+ {
+ if (capability.resolves(module, requirement))
+ {
+ result.add(module);
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (name.equals(module.getName()) && range.isInRange(module.getVersion()))
+ {
+ result.add(module);
+ return;
+ }
+ }
+ }
+ }
+
+ public Collection<ImportModule> getImportedModules(String name, VersionRange range)
+ {
+ Collection<ImportModule> result = new HashSet<ImportModule>();
+ getImportingModulesInternal(name, range, result);
+ return result;
+ }
+
+ /**
+ * Get the importing modules matching the name and range
+ *
+ * @param name the name
+ * @param range the range
+ * @param result the matching modules
+ */
+ void getImportingModulesInternal(String name, VersionRange range, Collection<ImportModule> result)
+ {
+ if (range == null)
+ range = VersionRange.ALL_VERSIONS;
+
+ for (Module module : modules)
+ {
+ List<RequirementDependencyItem> requirementDependencyItems = module.getDependencies();
+ if (requirementDependencyItems != null && requirementDependencyItems.isEmpty() == false)
+ {
+ for (RequirementDependencyItem dependencyItem : requirementDependencyItems)
+ {
+ Requirement requirement = dependencyItem.getRequirement();
+ if (requirement instanceof ModuleRequirement && dependencyItem.isResolved())
+ {
+ ModuleRequirement moduleRequirement = (ModuleRequirement) requirement;
+ if (name == null || name.equals(moduleRequirement.getName()))
+ {
+ if (range.isConsistent(moduleRequirement.getVersionRange()))
+ {
+ Module other = module.resolveModule(dependencyItem, true);
+ ImportModule importModule = new ImportModule(other);
+ result.add(importModule);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public Collection<ExportPackage> getExportedPackages(Module module)
+ {
+ if (module == null)
+ throw new IllegalArgumentException("Null module");
+ return module.getExportedPackages();
+ }
+
+ public Collection<ExportPackage> getExportedPackages(String name, VersionRange range)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+
+ Collection<ExportPackage> result = new HashSet<ExportPackage>();
+ getExportedPackagesInternal(name, range, result);
+ return result;
+ }
+
+ /**
+ * Get the exported packages matching the name and range
+ *
+ * @param name the name
+ * @param range the range
+ * @param result the matching modules
+ */
+ void getExportedPackagesInternal(String name, VersionRange range, Collection<ExportPackage> result)
+ {
+ if (range == null)
+ range = VersionRange.ALL_VERSIONS;
+
+ for (Module module : modules)
+ {
+ List<Capability> capabilities = module.getCapabilitiesRaw();
+ if (capabilities != null && capabilities.isEmpty() == false)
+ {
+ PackageRequirement requirement = new PackageRequirement(name, range);
+ for (Capability capability : capabilities)
+ {
+ if (capability instanceof PackageCapability && capability.resolves(module, requirement))
+ {
+ ExportPackage exportPackage = new ExportPackage(module, (PackageCapability) capability);
+ result.add(exportPackage);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public void refreshModules(Module... modules) throws Exception
+ {
+ Module.refreshModules(modules);
+ }
+
+ public boolean resolveModules(Module... modules) throws Exception
+ {
+ return Module.resolveModules(modules);
+ }
+
@Override
public String toString()
{
Added: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ExportPackage.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ExportPackage.java (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ExportPackage.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -0,0 +1,105 @@
+package org.jboss.classloading.spi.dependency;
+
+import java.util.Collection;
+
+import org.jboss.classloading.plugins.metadata.PackageCapability;
+import org.jboss.classloading.plugins.metadata.PackageRequirement;
+
+/**
+ * An exported package
+ *
+ * @author adrian at jboss.org
+ */
+public class ExportPackage
+{
+ /** The module exporting the package */
+ private Module module;
+
+ /** The package capability */
+ private PackageCapability capability;
+
+ /**
+ * Create a new ExportPackage
+ *
+ * @param module the module
+ * @param capability the capability
+ */
+ ExportPackage(Module module, PackageCapability capability)
+ {
+ this.module = module;
+ this.capability = capability;
+ }
+
+ /**
+ * Get the module
+ *
+ * @return the module
+ */
+ public Module getModule()
+ {
+ return module;
+ }
+
+ /**
+ * Get the name
+ *
+ * @return the name
+ */
+ public String getName()
+ {
+ return capability.getName();
+ }
+
+ /**
+ * Get the version
+ *
+ * @return the version
+ */
+ public Object getVersion()
+ {
+ return capability.getVersion();
+ }
+
+ /**
+ * Get the importing modules
+ *
+ * @return the importing modules
+ */
+ public Collection<Module> getImportingModules()
+ {
+ return module.getImportingModules(PackageRequirement.class);
+ }
+
+ /**
+ * Whether the package is unregistered
+ *
+ * @return true when unregistered
+ */
+ public boolean isUnregistered()
+ {
+ return module.getClassLoader() == null;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ return true;
+ if (obj == null || obj instanceof ExportPackage == false)
+ return false;
+
+ ExportPackage other = (ExportPackage) obj;
+ if (module.equals(other.getModule()) == false)
+ return false;
+ return capability.equals(other.capability);
+ }
+
+ public int hashCode()
+ {
+ return capability.hashCode();
+ }
+
+ public String toString()
+ {
+ return module + "/" + capability;
+ }
+}
Added: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ImportModule.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ImportModule.java (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/ImportModule.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -0,0 +1,102 @@
+package org.jboss.classloading.spi.dependency;
+
+import java.util.Collection;
+
+import org.jboss.classloading.plugins.metadata.ModuleRequirement;
+
+
+/**
+ * An imported module
+ *
+ * @author adrian at jboss.org
+ */
+public class ImportModule
+{
+ /** The module */
+ private Module module;
+
+ /**
+ * Create a new ExportPackage
+ *
+ * @param module the module
+ */
+ ImportModule(Module module)
+ {
+ this.module = module;
+ }
+
+ /**
+ * Get the module
+ *
+ * @return the module
+ */
+ public Module getModule()
+ {
+ return module;
+ }
+
+ /**
+ * Get the name
+ *
+ * @return the name
+ */
+ public String getName()
+ {
+ return module.getName();
+ }
+
+ /**
+ * Get the version
+ *
+ * @return the version
+ */
+ public Object getVersion()
+ {
+ return module.getVersion();
+ }
+
+ /**
+ * Get the importing modules
+ *
+ * @return the importing modules
+ */
+ public Collection<Module> getImportingModules()
+ {
+ return module.getImportingModules(ModuleRequirement.class);
+ }
+
+ /**
+ * Whether the module is unregistered
+ *
+ * @return true when unregistered
+ */
+ public boolean isUnregistered()
+ {
+ return module.getClassLoader() == null;
+ }
+
+ @Override
+ public String toString()
+ {
+ return module.toString();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return module.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null || obj instanceof ImportModule == false)
+
+ return false;
+
+ ImportModule other = (ImportModule) obj;
+ return module.equals(other.module);
+ }
+}
Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/LifeCycle.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/LifeCycle.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/LifeCycle.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -24,6 +24,8 @@
import org.jboss.classloader.spi.ClassFoundEvent;
import org.jboss.classloader.spi.ClassFoundHandler;
import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.filter.ClassFilter;
+import org.jboss.classloader.spi.filter.ClassFilterUtils;
import org.jboss.classloading.spi.dependency.policy.ClassLoaderPolicyModule;
import org.jboss.dependency.spi.Controller;
import org.jboss.dependency.spi.ControllerContext;
@@ -45,12 +47,17 @@
/** The module associated with this lifecycle */
private Module module;
+ /** Whether to lazy start */
+ private boolean lazyStart = false;
+
+ /** Whether to lazy resolve */
+ private boolean lazyResolve = false;
+
/** Any lazy start handler */
- private LazyStartHandler lazyStart;
+ private LazyStartHandler lazyStartHandler;
- /** Whether we are already in the lifecycle */
- // TODO FIX THIS IN THE MC?
- private boolean lifeCycle = false;
+ /** The lazy start filter */
+ private ClassFilter lazyStartFilter = ClassFilterUtils.EVERYTHING;
/**
* Create a new LifeCycle.
@@ -73,8 +80,53 @@
{
return module;
}
+
+ /**
+ * Whether the context associated with the classloader is lazy start,
+ * i.e. the start method will be invoked on first class load
+ *
+ * @return true if it is lazy start
+ */
+ public boolean isLazyStart()
+ {
+ return lazyStart;
+ }
/**
+ * Set the lazyStart
+ *
+ * @param lazyStart the lazyStart to set
+ */
+ public void setLazyStart(boolean lazyStart)
+ {
+ this.lazyStart = lazyStart;
+ if (lazyStart)
+ setUpLazyStart();
+ }
+
+ /**
+ * Get the lazyStartFilter
+ *
+ * @return the lazyStartFilter
+ */
+ public ClassFilter getLazyStartFilter()
+ {
+ return lazyStartFilter;
+ }
+
+ /**
+ * Set the lazyStartFilter
+ *
+ * @param lazyStartFilter the lazyStartFilter to set
+ */
+ public void setLazyStartFilter(ClassFilter lazyStartFilter)
+ {
+ if (lazyStartFilter == null)
+ lazyStartFilter = ClassFilterUtils.EVERYTHING;
+ this.lazyStartFilter = lazyStartFilter;
+ }
+
+ /**
* Whether the module is resolved
*
* @return true when resolved
@@ -92,44 +144,69 @@
*/
public boolean isLazyResolve()
{
- return false;
+ return lazyResolve;
}
/**
+ * Set the lazyResolve
+ *
+ * @param lazyResolve the lazyResolve to set
+ */
+ public void setLazyResolve(boolean lazyResolve)
+ {
+ this.lazyResolve = lazyResolve;
+ }
+
+ /**
* Resolve the classloader
+ *
+ * @throws Exception for any error
*/
- void doResolve()
+ public void resolve() throws Exception
{
- if (lifeCycle == false)
+ }
+
+ /**
+ * Resolve lots of lifecycles
+ *
+ * @param lifecycles the lifecycles to resolve
+ * @throws Exception for any error
+ */
+ public void resolve(LifeCycle... lifecycles) throws Exception
+ {
+ if (lifecycles == null || lifecycles.length == 0)
+ return;
+ for (LifeCycle lifecycle : lifecycles)
{
- lifeCycle = true;
- try
- {
- resolve();
- }
- catch (Throwable t)
- {
- log.warn("Error in resolve: " + this, t);
- }
- finally
- {
- lifeCycle = false;
- }
+ if (lifecycle.isResolved() == false)
+ lifecycle.resolve();
}
}
/**
- * Resolve the classloader
+ * Unresolve the classloader
+ *
+ * @throws Exception for any error
*/
- public void resolve()
+ public void unresolve() throws Exception
{
}
/**
- * Unresolve the classloader
+ * Unresolve lots of lifecycles
+ *
+ * @param lifecycles the lifecycles to unresolve
+ * @throws Exception for any error
*/
- public void unresolve()
+ public void unresolve(LifeCycle... lifecycles) throws Exception
{
+ if (lifecycles == null || lifecycles.length == 0)
+ return;
+ for (LifeCycle lifecycle : lifecycles)
+ {
+ if (lifecycle.isResolved())
+ lifecycle.unresolve();
+ }
}
/**
@@ -147,6 +224,29 @@
}
/**
+ * Bounce the classloader
+ *
+ * @throws Exception for any error
+ */
+ public void bounce() throws Exception
+ {
+ }
+
+ /**
+ * Bounce lots of lifecycles
+ *
+ * @param lifecycles the lifecycles to bounce
+ * @throws Exception for any error
+ */
+ public void bounce(LifeCycle... lifecycles) throws Exception
+ {
+ if (lifecycles == null || lifecycles.length == 0)
+ return;
+ for (LifeCycle lifecycle : lifecycles)
+ lifecycle.bounce();
+ }
+
+ /**
* Whether the module is started
*
* @return true when started
@@ -164,73 +264,54 @@
/**
* Start the context associated with the classloader
+ *
+ * @throws Exception for any error
*/
- void doStart()
+ public void start() throws Exception
{
- if (lifeCycle == false)
- {
- lifeCycle = true;
- try
- {
- start();
- }
- catch (Throwable t)
- {
- log.warn("Error in start: " + this, t);
- }
- finally
- {
- lifeCycle = false;
- }
- }
}
/**
- * Start the context associated with the classloader
+ * Start lots of lifecycles
+ *
+ * @param lifecycles the lifecycles to start
+ * @throws Exception for any error
*/
- public void start()
+ public void start(LifeCycle... lifecycles) throws Exception
{
- }
-
- /**
- * Stop the context associated with the classloader
- */
- void doStop()
- {
- if (lifeCycle == false)
+ if (lifecycles == null || lifecycles.length == 0)
+ return;
+ for (LifeCycle lifecycle : lifecycles)
{
- lifeCycle = true;
- try
- {
- start();
- }
- catch (Throwable t)
- {
- log.warn("Error in stop: " + this, t);
- }
- finally
- {
- lifeCycle = false;
- }
+ if (lifecycle.isStarted() == false)
+ lifecycle.start();
}
}
/**
* Stop the context associated with the classloader
+ *
+ * @throws Exception for any error
*/
- public void stop()
+ public void stop() throws Exception
{
}
/**
- * Whether the context associated with the classloader is lazy start,
- * i.e. the start method will be invoked on first class load
+ * Stop lots of lifecycles
*
- * @return true if it is lazy start
+ * @param lifecycles the lifecycles to stop
+ * @throws Exception for any error
*/
- public boolean isLazyStart()
+ public void stop(LifeCycle... lifecycles) throws Exception
{
- return false;
+ if (lifecycles == null || lifecycles.length == 0)
+ return;
+ for (LifeCycle lifecycle : lifecycles)
+ {
+ if (lifecycle.isResolved())
+ lifecycle.stop();
+ }
}
/**
@@ -238,12 +319,14 @@
*/
protected void setUpLazyStart()
{
- if (isStarted())
+ if (isResolved() == false || isStarted())
return;
+ if (lazyStartHandler != null)
+ return;
if (module instanceof ClassLoaderPolicyModule)
{
ClassLoaderPolicy policy = ((ClassLoaderPolicyModule) module).getPolicy();
- lazyStart = new LazyStartHandler(policy);
+ lazyStartHandler = new LazyStartHandler(policy);
}
else
{
@@ -256,11 +339,11 @@
*/
protected void removeLazyStart()
{
- if (lazyStart == null)
+ if (lazyStartHandler == null)
return;
- lazyStart.cleanup();
- lazyStart = null;
+ lazyStartHandler.cleanup();
+ lazyStartHandler = null;
}
void fireResolved()
@@ -297,9 +380,21 @@
public void classFound(ClassFoundEvent event)
{
+ if (getLazyStartFilter().matchesClassName(event.getClassName()) == false)
+ return;
+
removeLazyStart();
if (isStarted() == false)
- start();
+ {
+ try
+ {
+ start();
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error in lazy start for " + this, t);
+ }
+ }
}
public void cleanup()
Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Module.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Module.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Module.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -26,6 +26,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
@@ -36,6 +37,7 @@
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
import org.jboss.classloader.spi.ClassLoaderPolicy;
import org.jboss.classloader.spi.ClassLoaderSystem;
@@ -57,10 +59,12 @@
import org.jboss.classloading.spi.metadata.Requirement;
import org.jboss.classloading.spi.visitor.ResourceFilter;
import org.jboss.classloading.spi.visitor.ResourceVisitor;
+import org.jboss.dependency.spi.Controller;
import org.jboss.dependency.spi.ControllerContext;
import org.jboss.dependency.spi.ControllerState;
import org.jboss.dependency.spi.DependencyInfo;
import org.jboss.dependency.spi.DependencyItem;
+import org.jboss.logging.Logger;
/**
* Module.
@@ -73,9 +77,15 @@
/** The serialVersionUID */
private static final long serialVersionUID = 1L;
+ /** The log */
+ private static final Logger log = Logger.getLogger(Module.class);
+
/** The modules by classloader */
private static Map<ClassLoader, Module> modulesByClassLoader = new ConcurrentHashMap<ClassLoader, Module>();
+ /** The lazily shutdown modules */
+ private static Set<Module> lazyShutdownModules = new CopyOnWriteArraySet<Module>();
+
/** The context name */
private String contextName;
@@ -100,6 +110,12 @@
/** Any lifecycle associated with the classloader */
private LifeCycle lifeCycle;
+ /** The remembered policy for cascade shutdown */
+ private Boolean cascadeShutdown;
+
+ /** Requirements resolved to us */
+ private Set<RequirementDependencyItem> depends = new CopyOnWriteArraySet<RequirementDependencyItem>();
+
/**
* Register a classloader for a module
*
@@ -118,7 +134,8 @@
// This is hack - we might not know until the classloader gets constructed whether
// it is in a domain that specifies lazy shutdown of the classloader
- if (module.isCascadeShutdown() == false)
+ module.cascadeShutdown = module.isCascadeShutdown();
+ if (module.cascadeShutdown == false)
module.enableLazyShutdown();
LifeCycle lifeCycle = module.getLifeCycle();
@@ -141,10 +158,15 @@
throw new IllegalArgumentException("Null classloader");
modulesByClassLoader.remove(classLoader);
-
+
+ module.unresolveDependencies();
+
LifeCycle lifeCycle = module.getLifeCycle();
if (lifeCycle != null)
lifeCycle.fireUnresolved();
+
+ if (module.isCascadeShutdown() == false && module.depends.isEmpty() == false)
+ lazyShutdownModules.add(module);
}
/**
@@ -211,7 +233,7 @@
this.domain = domain;
}
- Domain checkDomain()
+ protected Domain checkDomain()
{
Domain result = domain;
if (result == null)
@@ -325,6 +347,10 @@
*/
public boolean isCascadeShutdown()
{
+ // Has it been determined?
+ if (cascadeShutdown != null)
+ return cascadeShutdown;
+
// This is ugly
ClassLoader cl = getClassLoader();
if (cl != null && cl instanceof BaseClassLoader)
@@ -458,6 +484,28 @@
/**
* Find the module that loads a class
*
+ * @param clazz the class
+ * @return the module or null if the class is not loaded by a registered module classloader
+ * @throws IllegalStateException when the module is not associated with a classloader
+ */
+ public static Module getModuleForClass(Class<?> clazz)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+
+ ClassLoader cl = getClassLoaderForClass(clazz);
+
+ // Determine the module (if any) for the classloader
+ if (cl != null)
+ return modulesByClassLoader.get(cl);
+ // Unknown
+ return null;
+ }
+
+ /**
+ * Find the module that loads a class
+ *
* @param className the class name
* @return the module or null if the class is not loaded by a registered module classloader
* @throws ClassNotFoundException when the class is not found
@@ -479,6 +527,32 @@
}
/**
+ * Get the classloader for a class
+ *
+ * @param clazz the class
+ * @return the classloader
+ */
+ protected static ClassLoader getClassLoaderForClass(final Class<?> clazz)
+ {
+ if (clazz == null)
+ throw new IllegalArgumentException("Null class");
+
+ // Determine the classloader for this class
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return clazz.getClassLoader();
+ }
+ });
+ }
+ return clazz.getClassLoader();
+ }
+
+ /**
* Get the classloader for a class name
*
* @param className the class name
@@ -751,6 +825,116 @@
public abstract DelegateLoader getDelegateLoader(Module requiringModule, Requirement requirement);
/**
+ * Get the exported packages
+ *
+ * @return the exported packages
+ */
+ public Collection<ExportPackage> getExportedPackages()
+ {
+ Collection<ExportPackage> result = new HashSet<ExportPackage>();
+ List<Capability> capabilities = getCapabilitiesRaw();
+ if (capabilities != null && capabilities.isEmpty() == false)
+ {
+ for (Capability capability : capabilities)
+ {
+ if (capability instanceof PackageCapability)
+ {
+ ExportPackage exportPackage = new ExportPackage(this, (PackageCapability) capability);
+ result.add(exportPackage);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Refresh the specified modules<p>
+ *
+ * Pass null to refresh any undeployed lazy shutdown modules dependencies
+ *
+ * @param modules the modules
+ * @throws Exception for any error
+ */
+ public static void refreshModules(Module... modules) throws Exception
+ {
+ if (modules == null || modules.length == 0)
+ {
+ Set<Module> snapshot = new HashSet<Module>(lazyShutdownModules);
+ modules = snapshot.toArray(new Module[snapshot.size()]);
+ }
+
+ if (modules.length == 0)
+ return;
+
+ Set<LifeCycle> lifecycles = new HashSet<LifeCycle>();
+ Set<Module> processed = new HashSet<Module>();
+ for (Module module : modules)
+ {
+ if (module == null)
+ throw new IllegalArgumentException("Null module");
+ module.addRefreshModule(lifecycles, processed);
+ }
+
+ if (lifecycles.isEmpty() == false)
+ {
+ LifeCycle[] result = lifecycles.toArray(new LifeCycle[lifecycles.size()]);
+ result[0].bounce(result);
+ }
+ }
+
+ private void addRefreshModule(Set<LifeCycle> lifecycles, Set<Module> processed)
+ {
+ // Avoid recursion
+ if (processed.contains(this))
+ return;
+ processed.add(this);
+
+ // Add our lifecycle - if we have a classloader
+ if (getClassLoader() != null)
+ {
+ LifeCycle lifeCycle = getLifeCycle();
+ if (lifeCycle != null)
+ lifecycles.add(lifeCycle);
+ else
+ log.warn(this + " has no lifecycle, don't know how to refresh it.");
+ }
+
+ // Add dependencies that are not already managed
+ if (isCascadeShutdown() == false && depends.isEmpty() == false)
+ {
+ for (RequirementDependencyItem item : depends)
+ item.getModule().addRefreshModule(lifecycles, processed);
+ }
+ }
+
+ public static boolean resolveModules(Module... modules) throws Exception
+ {
+ if (modules == null || modules.length == 0)
+ return true;
+
+ LifeCycle[] lifeCycles = new LifeCycle[modules.length];
+ for (int i = 0; i < modules.length; ++i)
+ {
+ Module module = modules[i];
+ if (module == null)
+ throw new IllegalArgumentException("Null module");
+ LifeCycle lifeCycle = module.getLifeCycle();
+ if (lifeCycle == null)
+ log.warn(module + " has no lifecycle, don't know how to resolve it.");
+ lifeCycles[i] = lifeCycle;
+ }
+
+ lifeCycles[0].resolve(lifeCycles);
+
+ for (LifeCycle lifeCycle : lifeCycles)
+ {
+ if (lifeCycle.isResolved() == false)
+ return false;
+ }
+ return true;
+ }
+
+ /**
* Get the capabilities.
*
* @return the capabilities.
@@ -802,6 +986,11 @@
return capabilities;
}
+ List<Capability> getCapabilitiesRaw()
+ {
+ return capabilities;
+ }
+
/**
* Get the package names
*
@@ -927,6 +1116,16 @@
}
/**
+ * Get the requirements as they are now.
+ *
+ * @return the requirements.
+ */
+ List<Requirement> getRequirementsRaw()
+ {
+ return requirements;
+ }
+
+ /**
* Return a URL where dynamic classes can be stored
*
* @return the url or null if there isn't one
@@ -976,6 +1175,19 @@
}
/**
+ * Unresolve dependencies
+ */
+ protected void unresolveDependencies()
+ {
+ Controller controller = context.getController();
+ if (requirementDependencies != null && requirementDependencies.isEmpty() == false)
+ {
+ for (RequirementDependencyItem item : requirementDependencies)
+ item.unresolved(controller);
+ }
+ }
+
+ /**
* Get the controller context.
*
* @return the controller context.
@@ -1018,14 +1230,7 @@
throw new IllegalStateException("No controller context");
// Remove the DependsOnMe part of this item
- Object iDependOn = item.getIDependOn();
- if (iDependOn != null)
- {
- // TODO - we need a better way to cleanup
- Module otherModule = domain.getModule(iDependOn.toString());
- if (otherModule != null)
- otherModule.removeDependsOnMe(item);
- }
+ item.setResolved(false);
// Remove the IDependOn part of this item
DependencyInfo dependencyInfo = context.getDependencyInfo();
@@ -1041,12 +1246,55 @@
{
if (context == null)
return;
-
+
DependencyInfo dependencyInfo = context.getDependencyInfo();
dependencyInfo.removeDependsOnMe(item);
}
/**
+ * Add a dependency resolved against us
+ *
+ * @param item the dependency
+ */
+ void addDepends(RequirementDependencyItem item)
+ {
+ depends.add(item);
+ }
+
+ /**
+ * Remove a dependency resolved against us
+ *
+ * @param item the dependency
+ */
+ void removeDepends(RequirementDependencyItem item)
+ {
+ depends.remove(item);
+ if (depends.isEmpty())
+ lazyShutdownModules.remove(this);
+ }
+
+ /**
+ * Get the importing modules
+ *
+ * @param type the requirement type to filter on or null for all
+ * @return the importing modules
+ */
+ public Collection<Module> getImportingModules(Class<? extends Requirement> type)
+ {
+ Set<Module> result = new HashSet<Module>();
+ if (depends.isEmpty() == false)
+ {
+ for (RequirementDependencyItem item : depends)
+ {
+ Requirement requirement = item.getRequirement();
+ if (type == null || type.isInstance(requirement))
+ result.add(item.getModule());
+ }
+ }
+ return result;
+ }
+
+ /**
* Resolve a requirement
*
* @param dependency the dependency the dependency
Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -47,6 +47,9 @@
/** The requirement */
private Requirement requirement;
+ /** The module we resolved to */
+ private Module resolvedModule;
+
/**
* Create a new RequirementDependencyItem.
*
@@ -100,6 +103,16 @@
return requirement;
}
+ /**
+ * Get the resolvedModule
+ *
+ * @return the resolvedModule
+ */
+ public Module getResolvedModule()
+ {
+ return resolvedModule;
+ }
+
public boolean resolve(Controller controller)
{
Requirement requirement = getRequirement();
@@ -128,6 +141,8 @@
if (context != null)
{
setIDependOn(context.getName());
+ resolvedModule = module;
+ module.addDepends(this);
if (module.isCascadeShutdown())
addDependsOnMe(controller, context);
setResolved(true);
@@ -148,6 +163,18 @@
return true;
}
+ @Override
+ protected void setResolved(boolean resolved)
+ {
+ if (resolved == false && resolvedModule != null)
+ {
+ resolvedModule.removeDepends(this);
+ resolvedModule.removeDependsOnMe(this);
+ resolvedModule = null;
+ }
+ super.setResolved(resolved);
+ }
+
public void toString(JBossStringBuilder buffer)
{
super.toString(buffer);
Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/ClassLoaderPolicyModule.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/ClassLoaderPolicyModule.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/ClassLoaderPolicyModule.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -290,6 +290,7 @@
public void reset()
{
super.reset();
+ classLoader = null;
system = null;
policy = null;
}
Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/mock/MockClassLoaderPolicyModule.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/mock/MockClassLoaderPolicyModule.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/mock/MockClassLoaderPolicyModule.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -34,6 +34,7 @@
import org.jboss.classloader.test.support.MockClassLoaderHelper;
import org.jboss.classloader.test.support.MockClassLoaderPolicy;
import org.jboss.classloading.plugins.visitor.DefaultResourceContext;
+import org.jboss.classloading.spi.dependency.Domain;
import org.jboss.classloading.spi.dependency.policy.ClassLoaderPolicyModule;
import org.jboss.classloading.spi.metadata.Capability;
import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
@@ -65,6 +66,12 @@
super(classLoadingMetaData, contextName);
}
+ @Override
+ public Domain checkDomain()
+ {
+ return super.checkDomain();
+ }
+
/**
* Get collection from string array.
*
@@ -278,4 +285,10 @@
policy.setDelegates(getDelegates());
return policy;
}
+
+ @Override
+ public ClassLoader getClassLoader()
+ {
+ return super.getClassLoader();
+ }
}
Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/version/Version.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/version/Version.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/version/Version.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -65,6 +65,17 @@
/** The qualifier part of the version */
private String qualifier;
+
+ /**
+ * Get the version from a string
+ *
+ * @param string the string
+ * @return the version
+ */
+ public static Version valueOf(String string)
+ {
+ return parseVersion(string);
+ }
/**
* Create a new Version.
@@ -147,7 +158,7 @@
}
catch (NumberFormatException e)
{
- throw new IllegalArgumentException("Invalid version format: " + version);
+ throw new IllegalArgumentException("Invalid version format: " + version, e);
}
this.major = major;
Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/version/VersionRange.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/version/VersionRange.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/version/VersionRange.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -22,6 +22,7 @@
package org.jboss.classloading.spi.version;
import java.io.Serializable;
+import java.util.StringTokenizer;
/**
* VersionRange.
@@ -50,6 +51,95 @@
public static final VersionRange ALL_VERSIONS = new VersionRange(Version.DEFAULT_VERSION);
/**
+ * Get the version range from a string
+ *
+ * @param rangeSpec the range spec
+ * @return the version range
+ */
+ public static VersionRange valueOf(String rangeSpec)
+ {
+ return parseRangeSpec(rangeSpec);
+ }
+
+ /**
+ * Parse a range spec
+ *
+ * @param rangeSpec
+ * @return the version range
+ */
+ public static VersionRange parseRangeSpec(String rangeSpec)
+ {
+ if (rangeSpec == null)
+ throw new IllegalArgumentException("Null rangeSpec");
+
+ rangeSpec = rangeSpec.trim();
+
+ int length = rangeSpec.length();
+ if (length == 0)
+ return ALL_VERSIONS;
+
+ char start = rangeSpec.charAt(0);
+ // Single version?
+ if (start != '[' && start != '(')
+ {
+ Version version = Version.parseVersion(rangeSpec);
+ return new VersionRange(version, true, version, true);
+ }
+
+ if (length < 2)
+ throw new IllegalArgumentException("Expected a closing ] or ) for version range: " + rangeSpec);
+
+ boolean floorIsInclusive = true;
+ boolean ceilingIsInclusive = true;
+
+ if (start == '(')
+ floorIsInclusive = false;
+
+ char end = rangeSpec.charAt(length-1);
+ if (end == ')')
+ ceilingIsInclusive = false;
+ else if (end != ']')
+ throw new IllegalArgumentException("Expected a closing ] or ) for version range: " + rangeSpec);
+
+ Version floor = null;
+ Version ceiling = null;
+ StringTokenizer st = new StringTokenizer(rangeSpec.substring(1, length-1), ",", true);
+ boolean mid = false;
+ while (st.hasMoreTokens())
+ {
+ String token = st.nextToken();
+ if (token.equals(","))
+ {
+ if (mid == true)
+ throw new IllegalArgumentException("Expected only one , in version range: " + rangeSpec);
+ mid = true;
+ }
+ else
+ {
+ try
+ {
+ // A version token
+ if (mid == false)
+ floor = Version.parseVersion(token);
+ else
+ ceiling = Version.parseVersion(token);
+ }
+ catch (RuntimeException e)
+ {
+ throw new IllegalArgumentException("Error parsing version '" + token + "' in " + rangeSpec, e);
+ }
+ }
+
+ }
+
+ // This is a hack to support [1.0.0] as a specified version
+ if (ceiling == null && ceilingIsInclusive)
+ ceiling = floor;
+
+ return new VersionRange(floor, floorIsInclusive, ceiling, ceilingIsInclusive);
+ }
+
+ /**
* Create a new VersionRange with just a low inclusive check
*
* @param low the low range (null for no lower bound)
Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/DependencyTestSuite.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/DependencyTestSuite.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/DependencyTestSuite.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -25,6 +25,8 @@
import junit.framework.TestSuite;
import junit.textui.TestRunner;
+import org.jboss.test.classloading.dependency.test.ClassLoadingAdminLazyShutdownUnitTestCase;
+import org.jboss.test.classloading.dependency.test.ClassLoadingAdminUnitTestCase;
import org.jboss.test.classloading.dependency.test.ConflictingPackageUnitTestCase;
import org.jboss.test.classloading.dependency.test.ConflictingRequirementUnitTestCase;
import org.jboss.test.classloading.dependency.test.DependencyUnitTestCase;
@@ -42,7 +44,7 @@
import org.jboss.test.classloading.dependency.test.MockResourceVisitorUnitTestCase;
/**
- * Version Test Suite.
+ * Dependency Test Suite.
*
* @author <a href="adrian at jboss.com">Adrian Brock</a>
* @version $Revision: 37459 $
@@ -83,6 +85,8 @@
suite.addTest(ConflictingRequirementUnitTestCase.suite());
suite.addTest(SplitPackageDependencyUnitTestCase.suite());
suite.addTest(SelfImportPackageDependencyUnitTestCase.suite());
+ suite.addTest(ClassLoadingAdminUnitTestCase.suite());
+ suite.addTest(ClassLoadingAdminLazyShutdownUnitTestCase.suite());
return suite;
}
Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/AbstractMockClassLoaderUnitTest.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/AbstractMockClassLoaderUnitTest.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/AbstractMockClassLoaderUnitTest.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -53,6 +53,8 @@
protected ClassLoaderSystem system;
+ protected ClassLoading classLoading;
+
public static Test suite()
{
return suite(AbstractMockClassLoaderUnitTest.class);
@@ -89,10 +91,16 @@
protected void assertNoClassLoader(KernelControllerContext context) throws Exception
{
- assertNoModule(context);
+ MockClassLoaderPolicyModule module = assertNoModule(context);
+ if (module != null)
+ {
+ ClassLoader cl = module.getClassLoader();
+ if (cl != null)
+ fail("Should not have classloader: " + cl);
+ }
}
- protected void assertNoModule(KernelControllerContext context) throws Exception
+ protected MockClassLoaderPolicyModule assertNoModule(KernelControllerContext context) throws Exception
{
boolean test = ControllerState.INSTALLED.equals(context.getState());
if (test)
@@ -107,7 +115,9 @@
catch (IllegalStateException expected)
{
}
+ return module;
}
+ return null;
}
protected KernelControllerContext install(MockClassLoadingMetaData metaData) throws Exception
@@ -170,6 +180,9 @@
builder.addMethodUninstallCallback("removeModule", null, null, ControllerState.CONFIGURED, null);
install(builder.getBeanMetaData());
+
+ ControllerContext ctx = controller.getInstalledContext("ClassLoading");
+ classLoading = (ClassLoading) ctx.getTarget();
}
protected void tearDown() throws Exception
Added: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/ClassLoadingAdminLazyShutdownUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/ClassLoadingAdminLazyShutdownUnitTestCase.java (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/ClassLoadingAdminLazyShutdownUnitTestCase.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloading.dependency.test;
+
+import junit.framework.Test;
+
+/**
+ * ClassLoadingAdmin unit tests
+ *
+ * @author adrian at jboss.org
+ */
+public class ClassLoadingAdminLazyShutdownUnitTestCase extends ClassLoadingAdminUnitTestCase
+{
+ public static Test suite()
+ {
+ return suite(ClassLoadingAdminLazyShutdownUnitTestCase.class);
+ }
+
+ public ClassLoadingAdminLazyShutdownUnitTestCase(String name)
+ {
+ super(name, true);
+ }
+}
Added: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/ClassLoadingAdminUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/ClassLoadingAdminUnitTestCase.java (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/ClassLoadingAdminUnitTestCase.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -0,0 +1,577 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloading.dependency.test;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ShutdownPolicy;
+import org.jboss.classloading.spi.dependency.Domain;
+import org.jboss.classloading.spi.dependency.ExportPackage;
+import org.jboss.classloading.spi.dependency.ImportModule;
+import org.jboss.classloading.spi.dependency.Module;
+import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoaderPolicyModule;
+import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoadingMetaData;
+import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
+import org.jboss.classloading.spi.version.VersionRange;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.test.classloading.dependency.support.a.A;
+import org.jboss.test.classloading.dependency.support.b.B;
+
+/**
+ * ClassLoadingAdmin unit tests
+ *
+ * @author adrian at jboss.org
+ */
+public class ClassLoadingAdminUnitTestCase extends AbstractMockClassLoaderUnitTest
+{
+ static String PACKAGEA = ClassLoaderUtils.getClassPackageName(A.class.getName());
+ static String PACKAGEB = ClassLoaderUtils.getClassPackageName(B.class.getName());
+
+ boolean lazyShutdown;
+
+ public static Test suite()
+ {
+ return suite(ClassLoadingAdminUnitTestCase.class);
+ }
+
+ public ClassLoadingAdminUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public ClassLoadingAdminUnitTestCase(String name, boolean lazyShutdown)
+ {
+ super(name);
+ this.lazyShutdown = lazyShutdown;
+ }
+
+ ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+
+ MockClassLoaderPolicyModule moduleA;
+ Class<?> classA;
+ Domain domainA;
+ KernelControllerContext contextA;
+
+ MockClassLoaderPolicyModule moduleA2;
+ Class<?> classA2;
+ Domain domainA2;
+ KernelControllerContext contextA2;
+
+ MockClassLoaderPolicyModule moduleB;
+ Class<?> classB;
+ Domain domainB;
+ KernelControllerContext contextB;
+
+ MockClassLoaderPolicyModule moduleC;
+ KernelControllerContext contextC;
+
+ MockClassLoaderPolicyModule moduleD;
+ MockClassLoaderPolicyModule moduleE;
+
+ @Override
+ protected KernelControllerContext install(MockClassLoadingMetaData metaData) throws Exception
+ {
+ if (lazyShutdown)
+ metaData.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+ return super.install(metaData);
+ }
+
+ protected void setUpAB() throws Exception
+ {
+ MockClassLoadingMetaData a = new MockClassLoadingMetaData("a", "1.0.0");
+ a.getCapabilities().addCapability(factory.createModule("ModuleA", "1.0.0"));
+ a.getCapabilities().addCapability(factory.createPackage(PACKAGEA, "1.0.0"));
+ a.setPathsAndPackageNames(A.class);
+ a.setDomain("main");
+ contextA = install(a);
+ moduleA = assertModule(contextA);
+ ClassLoader clA = assertClassLoader(contextA);
+ classA = clA.loadClass(A.class.getName());
+ domainA = moduleA.checkDomain();
+
+ MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a", "2.0.0");
+ a2.getCapabilities().addCapability(factory.createModule("ModuleA", "2.0.0"));
+ a2.getCapabilities().addCapability(factory.createPackage(PACKAGEA, "2.0.0"));
+ a2.getCapabilities().addCapability(factory.createPackage(PACKAGEB, "2.0.0"));
+ a2.setPathsAndPackageNames(A.class);
+ a2.setDomain("main");
+ contextA2 = install(a2);
+ moduleA2 = assertModule(contextA2);
+ ClassLoader clA2 = assertClassLoader(contextA2);
+ classA2 = clA2.loadClass(A.class.getName());
+ domainA2 = moduleA2.checkDomain();
+
+ MockClassLoadingMetaData b = new MockClassLoadingMetaData("b", "2.0.0");
+ b.setDomain("other");
+ b.getCapabilities().addCapability(factory.createModule("ModuleBAlias", "3.0.0"));
+ b.getCapabilities().addCapability(factory.createModule("ModuleB", "2.0.0"));
+ b.getCapabilities().addCapability(factory.createPackage(PACKAGEB, "2.0.0"));
+ b.setPathsAndPackageNames(B.class);
+ contextB = install(b);
+ moduleB = assertModule(contextB);
+ ClassLoader clB = assertClassLoader(contextB);
+ classB = clB.loadClass(B.class.getName());
+ domainB = moduleB.checkDomain();
+ }
+
+ protected void setUpABCDE() throws Exception
+ {
+ setUpAB();
+
+ MockClassLoadingMetaData c = new MockClassLoadingMetaData("c", "2.0.0");
+ c.getRequirements().addRequirement(factory.createRequireModule("ModuleA", VersionRange.valueOf("1.0.0")));
+ c.getRequirements().addRequirement(factory.createRequirePackage(PACKAGEA, VersionRange.valueOf("1.0.0")));
+ c.setDomain("main");
+ contextC = install(c);
+ moduleC = assertModule(contextC);
+ ClassLoader clC = assertClassLoader(contextC);
+ clC.loadClass(A.class.getName());
+
+ MockClassLoadingMetaData d = new MockClassLoadingMetaData("d", "5.0.0");
+ d.getRequirements().addRequirement(factory.createRequireModule("ModuleB", new VersionRange("2.0.0")));
+ d.getRequirements().addRequirement(factory.createRequirePackage(PACKAGEB, new VersionRange("2.0.0")));
+ d.setDomain("other");
+ KernelControllerContext contextD = install(d);
+ moduleD = assertModule(contextD);
+ ClassLoader clD = assertClassLoader(contextD);
+ clD.loadClass(B.class.getName());
+
+ MockClassLoadingMetaData e = new MockClassLoadingMetaData("e", "5.0.0");
+ e.getRequirements().addRequirement(factory.createRequireModule("ModuleB", new VersionRange("2.0.0")));
+ e.setDomain("other");
+ KernelControllerContext contextE = install(e);
+ moduleE = assertModule(contextE);
+ ClassLoader clE = assertClassLoader(contextE);
+ clE.loadClass(B.class.getName());
+ }
+
+ public void testGetModuleForClass() throws Exception
+ {
+ setUpAB();
+
+ assertEquals(moduleA, classLoading.getModuleForClass(classA));
+ assertEquals(moduleA, domainA.getModuleForClass(classA));
+
+ assertEquals(moduleB, classLoading.getModuleForClass(classB));
+ assertEquals(moduleB, domainB.getModuleForClass(classB));
+
+ assertNull(classLoading.getModuleForClass(Object.class));
+ assertNull(domainA.getModuleForClass(Object.class));
+
+ uninstall(contextB);
+
+ assertNull(classLoading.getModuleForClass(classB));
+ assertNull(domainB.getModuleForClass(classB));
+ }
+
+ public void testGetModules() throws Exception
+ {
+ setUpAB();
+
+ assertGetModules("ModuleA", null, moduleA, moduleA2);
+ assertGetModules(domainA, "ModuleA", null, moduleA, moduleA2);
+ assertGetModules(domainB, "ModuleA", null);
+
+ assertGetModules("ModuleB", null, moduleB);
+ assertGetModules(domainA, "ModuleB", null);
+ assertGetModules(domainB, "ModuleB", null, moduleB);
+
+ assertGetModules("ModuleA", "[1.0.0,1.0.0]", moduleA);
+ assertGetModules(domainA, "ModuleA", "[1.0.0,1.0.0]", moduleA);
+ assertGetModules(domainB, "ModuleA", "[1.0.0,1.0.0]");
+
+ assertGetModules("ModuleA", "[1.0.0,2.0.0]", moduleA, moduleA2);
+ assertGetModules(domainA, "ModuleA", "[1.0.0,2.0.0]", moduleA, moduleA2);
+ assertGetModules(domainB, "ModuleA", "[1.0.0,2.0.0]");
+
+ assertGetModules("ModuleA", "[0.0.0,0.0.0]");
+ assertGetModules(domainA, "ModuleA", "[0.0.0,0.0.0]");
+ assertGetModules(domainB, "ModuleA", "[0.0.0,0.0.0]");
+
+ assertGetModules("ModuleBAlias", null, moduleB);
+ assertGetModules(domainA, "ModuleBAlias", null);
+ assertGetModules(domainB, "ModuleBAlias", null, moduleB);
+
+ assertGetModules("ModuleBAlias", "[3.0.0,4.0.0]", moduleB);
+ assertGetModules(domainA, "ModuleBAlias", "[3.0.0,4.0.0]");
+ assertGetModules(domainB, "ModuleBAlias", "[3.0.0,4.0.0]", moduleB);
+
+ uninstall(contextA2);
+
+ assertGetModules("ModuleA", null, moduleA);
+ assertGetModules(domainA, "ModuleA", null, moduleA);
+ assertGetModules(domainB, "ModuleA", null);
+
+ assertGetModules("ModuleA", "[1.0.0,2.0.0]", moduleA);
+ assertGetModules(domainA, "ModuleA", "[1.0.0,2.0.0]", moduleA);
+ assertGetModules(domainB, "ModuleA", "[1.0.0,2.0.0]");
+ }
+
+ public void testModuleExportingPackages() throws Exception
+ {
+ setUpAB();
+
+ assertModuleExportingPackages(moduleA, new ExportingPackage(moduleA, PACKAGEA, "1.0.0"));
+ assertModuleExportingPackages(domainA, moduleA, new ExportingPackage(moduleA, PACKAGEA, "1.0.0"));
+
+ assertModuleExportingPackages(moduleA2, new ExportingPackage(moduleA2, PACKAGEA, "2.0.0"), new ExportingPackage(moduleA2, PACKAGEB, "2.0.0"));
+ assertModuleExportingPackages(domainA2, moduleA2, new ExportingPackage(moduleA2, PACKAGEA, "2.0.0"), new ExportingPackage(moduleA2, PACKAGEB, "2.0.0"));
+
+ uninstall(contextA2);
+
+ assertModuleExportingPackages(moduleA2);
+ assertModuleExportingPackages(domainA2, moduleA2);
+ }
+
+ public void testExportingPackages() throws Exception
+ {
+ setUpABCDE();
+
+ assertExportingPackages(PACKAGEA, null, new ExportingPackage(moduleA, PACKAGEA, "1.0.0"), new ExportingPackage(moduleA2, PACKAGEA, "2.0.0"));
+ assertExportingPackages(domainA, PACKAGEA, null, new ExportingPackage(moduleA, PACKAGEA, "1.0.0"), new ExportingPackage(moduleA2, PACKAGEA, "2.0.0"));
+ assertExportingPackages(domainB, PACKAGEA, null);
+
+ assertExportingPackages(PACKAGEA, "[0.0.0,1.0.0]", new ExportingPackage(moduleA, PACKAGEA, "1.0.0"));
+ assertExportingPackages(domainA, PACKAGEA, "[0.0.0,1.0.0]", new ExportingPackage(moduleA, PACKAGEA, "1.0.0"));
+ assertExportingPackages(domainB, PACKAGEA, "[0.0.0,1.0.0]");
+
+ assertExportingPackages(PACKAGEB, null, new ExportingPackage(moduleB, PACKAGEB, "2.0.0"), new ExportingPackage(moduleA2, PACKAGEB, "2.0.0"));
+ assertExportingPackages(domainA, PACKAGEB, null, new ExportingPackage(moduleA2, PACKAGEB, "2.0.0"));
+ assertExportingPackages(domainB, PACKAGEB, null, new ExportingPackage(moduleB, PACKAGEB, "2.0.0"));
+
+ assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+ assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("2.0.0"));
+ assertExportedPackageImporting(domainA, PACKAGEB, VersionRange.valueOf("2.0.0"));
+ assertExportedPackageImporting(domainB, PACKAGEB, VersionRange.valueOf("2.0.0"), moduleD);
+
+ uninstall(contextA2);
+
+ assertExportingPackages(PACKAGEA, null, new ExportingPackage(moduleA, PACKAGEA, "1.0.0"));
+ assertExportingPackages(domainA, PACKAGEA, null, new ExportingPackage(moduleA, PACKAGEA, "1.0.0"));
+ assertExportingPackages(domainB, PACKAGEA, null);
+
+ uninstall(contextC);
+
+ assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"));
+ }
+
+ public void testImportingModules() throws Exception
+ {
+ setUpABCDE();
+
+ assertImportingModule("ModuleA", null, new ImportingModule(moduleA));
+ assertImportingModule(domainA, "ModuleA", null, new ImportingModule(moduleA));
+ assertImportingModule(domainB, "ModuleA", null);
+
+ assertImportingModule("ModuleA", "[0.0.0,1.0.0]", new ImportingModule(moduleA));
+ assertImportingModule(domainA, "ModuleA", "[0.0.0,1.0.0]", new ImportingModule(moduleA));
+ assertImportingModule(domainB, "ModuleA", "[0.0.0,1.0.0]");
+
+ assertImportingModule("ModuleA", "[0.0.0,0.0.0]");
+ assertImportingModule(domainA, "ModuleA", "[0.0.0,0.0.0]");
+ assertImportingModule(domainB, "ModuleA", "[0.0.0,0.0.0]");
+
+ assertImportingModule(null, null, new ImportingModule(moduleA), new ImportingModule(moduleB));
+ assertImportingModule(domainA, null, null, new ImportingModule(moduleA));
+ assertImportingModule(domainB, null, null, new ImportingModule(moduleB));
+
+ assertImportedModulesImporting("ModuleA", moduleC);
+ assertImportedModulesImporting("ModuleB", moduleD, moduleE);
+
+ uninstall(contextC);
+
+ assertImportingModule("ModuleA", null);
+ assertImportingModule(domainA, "ModuleA", null);
+ assertImportingModule(domainB, "ModuleA", null);
+
+ assertNoImportedModules("ModuleA");
+ }
+
+ protected void assertGetModules(String name, String versionRange, Module... modules) throws Exception
+ {
+ Collection<Module> expected = new HashSet<Module>();
+ for (Module module : modules)
+ expected.add(module);
+
+ VersionRange range = null;
+ if (versionRange != null)
+ range = VersionRange.parseRangeSpec(versionRange);
+ Collection<Module> actual = classLoading.getModules(name, range);
+
+ assertEquals(expected, actual);
+ }
+
+ protected void assertGetModules(Domain domain, String name, String versionRange, Module... modules) throws Exception
+ {
+ Collection<Module> expected = new HashSet<Module>();
+ for (Module module : modules)
+ expected.add(module);
+
+ VersionRange range = null;
+ if (versionRange != null)
+ range = VersionRange.parseRangeSpec(versionRange);
+ Collection<Module> actual = domain.getModules(name, range);
+
+ assertEquals(expected, actual);
+ }
+
+ protected void assertModuleExportingPackages(Module module, ExportingPackage... expect) throws Exception
+ {
+ Set<ExportingPackage> expected = new HashSet<ExportingPackage>();
+ for (ExportingPackage e : expect)
+ expected.add(e);
+
+ Set<ExportingPackage> actual = new HashSet<ExportingPackage>();
+ Collection<ExportPackage> exported = classLoading.getExportedPackages(module);
+ for (ExportPackage export : exported)
+ actual.add(new ExportingPackage(export.getModule(), export.getName(), export.getVersion()));
+
+ assertEquals(expected, actual);
+ }
+
+ protected void assertModuleExportingPackages(Domain domain, Module module, ExportingPackage... expect) throws Exception
+ {
+ Set<ExportingPackage> expected = new HashSet<ExportingPackage>();
+ for (ExportingPackage e : expect)
+ expected.add(e);
+
+ Set<ExportingPackage> actual = new HashSet<ExportingPackage>();
+ Collection<ExportPackage> exported = domain.getExportedPackages(module);
+ for (ExportPackage export : exported)
+ actual.add(new ExportingPackage(export.getModule(), export.getName(), export.getVersion()));
+
+ assertEquals(expected, actual);
+ }
+
+ protected void assertExportingPackages(String name, String versionRange, ExportingPackage... expect) throws Exception
+ {
+ Set<ExportingPackage> expected = new HashSet<ExportingPackage>();
+ for (ExportingPackage e : expect)
+ expected.add(e);
+
+ VersionRange range = null;
+ if (versionRange != null)
+ range = VersionRange.parseRangeSpec(versionRange);
+
+ Set<ExportingPackage> actual = new HashSet<ExportingPackage>();
+ Collection<ExportPackage> exported = classLoading.getExportedPackages(name, range);
+ for (ExportPackage export : exported)
+ actual.add(new ExportingPackage(export.getModule(), export.getName(), export.getVersion()));
+
+ assertEquals(expected, actual);
+ }
+
+ protected void assertExportingPackages(Domain domain, String name, String versionRange, ExportingPackage... expect) throws Exception
+ {
+ Set<ExportingPackage> expected = new HashSet<ExportingPackage>();
+ for (ExportingPackage e : expect)
+ expected.add(e);
+
+ VersionRange range = null;
+ if (versionRange != null)
+ range = VersionRange.parseRangeSpec(versionRange);
+
+ Set<ExportingPackage> actual = new HashSet<ExportingPackage>();
+ Collection<ExportPackage> exported = domain.getExportedPackages(name, range);
+ for (ExportPackage export : exported)
+ actual.add(new ExportingPackage(export.getModule(), export.getName(), export.getVersion()));
+
+ assertEquals(expected, actual);
+ }
+
+ protected void assertExportedPackageImporting(String name, Module... expected) throws Exception
+ {
+ assertExportedPackageImporting(name, null, expected);
+ }
+
+ protected void assertExportedPackageImporting(String name, VersionRange range, Module... expected) throws Exception
+ {
+ Collection<ExportPackage> exportPackages = classLoading.getExportedPackages(name, range);
+ assertTrue(exportPackages.toString(), exportPackages.size() == 1);
+ ExportPackage exportPackage = exportPackages.iterator().next();
+ assertModules(exportPackage.getImportingModules(), expected);
+ }
+
+ protected void assertExportedPackageImporting(Domain domain, String name, Module... expected) throws Exception
+ {
+ assertExportedPackageImporting(domain, name, null, expected);
+ }
+
+ protected void assertExportedPackageImporting(Domain domain, String name, VersionRange range, Module... expected) throws Exception
+ {
+ Collection<ExportPackage> exportPackages = domain.getExportedPackages(name, range);
+ assertTrue(exportPackages.toString(), exportPackages.size() == 1);
+ ExportPackage exportPackage = exportPackages.iterator().next();
+ assertModules(exportPackage.getImportingModules(), expected);
+ }
+
+ protected void assertImportingModule(String name, String versionRange, ImportingModule... expect) throws Exception
+ {
+ Set<ImportingModule> expected = new HashSet<ImportingModule>();
+ for (ImportingModule e : expect)
+ expected.add(e);
+
+ VersionRange range = null;
+ if (versionRange != null)
+ range = VersionRange.parseRangeSpec(versionRange);
+
+ Set<ImportingModule> actual = new HashSet<ImportingModule>();
+ Collection<ImportModule> imported = classLoading.getImportedModules(name, range);
+ for (ImportModule imp : imported)
+ actual.add(new ImportingModule(imp.getModule()));
+
+ assertEquals(expected, actual);
+ }
+
+ protected void assertImportingModule(Domain domain, String name, String versionRange, ImportingModule... expect) throws Exception
+ {
+ Set<ImportingModule> expected = new HashSet<ImportingModule>();
+ for (ImportingModule e : expect)
+ expected.add(e);
+
+ VersionRange range = null;
+ if (versionRange != null)
+ range = VersionRange.parseRangeSpec(versionRange);
+
+ Set<ImportingModule> actual = new HashSet<ImportingModule>();
+ Collection<ImportModule> imported = domain.getImportedModules(name, range);
+ for (ImportModule imp : imported)
+ actual.add(new ImportingModule(imp.getModule()));
+
+ assertEquals(expected, actual);
+ }
+
+ protected void assertNoImportedModules(String name) throws Exception
+ {
+ Collection<ImportModule> importedModules = classLoading.getImportedModules(name, null);
+ assertTrue(importedModules.toString(), importedModules.isEmpty());
+ }
+
+ protected void assertImportedModulesImporting(String name, Module... expected) throws Exception
+ {
+ Collection<ImportModule> importedModules = classLoading.getImportedModules(name, null);
+ assertTrue(importedModules.toString(), importedModules.size() == 1);
+ ImportModule importModule = importedModules.iterator().next();
+ assertModules(importModule.getImportingModules(), expected);
+ }
+
+ protected void assertModules(Collection<Module> actual, Module... expected) throws Exception
+ {
+ Set<Module> expect = new HashSet<Module>();
+ for (Module module : expected)
+ expect.add(module);
+
+ Set<Module> act = new HashSet<Module>(actual);
+
+ assertEquals(expect, act);
+ }
+
+ private class ExportingPackage
+ {
+ Module module;
+ String name;
+ Object version;
+
+ public ExportingPackage(Module module, String name, Object version)
+ {
+ this.module = module;
+ this.name = name;
+ this.version = version;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ return true;
+ if (obj == null || obj instanceof ExportingPackage == false)
+ return false;
+
+ ExportingPackage other = (ExportingPackage) obj;
+ if (notEquals(module, other.module))
+ return false;
+ if (notEquals(name, other.name))
+ return false;
+ if (notEquals(version, other.version))
+ return false;
+ return true;
+ }
+
+ public int hashCode()
+ {
+ return name.hashCode();
+ }
+
+ public String toString()
+ {
+ if (version != null)
+ return module + "/" + name + ":" + version;
+ return module + "/" + name;
+ }
+ }
+
+ private class ImportingModule
+ {
+ Module module;
+
+ public ImportingModule(Module module)
+ {
+ this.module = module;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ return true;
+ if (obj == null || obj instanceof ImportingModule == false)
+ return false;
+
+ ImportingModule other = (ImportingModule) obj;
+ if (notEquals(module, other.module))
+ return false;
+ return true;
+ }
+
+ public int hashCode()
+ {
+ return module.hashCode();
+ }
+
+ public String toString()
+ {
+ return module.toString();
+ }
+ }
+
+ static boolean notEquals(Object one, Object two)
+ {
+ if (one == null && two == null)
+ return false;
+ if (one == null && two != null)
+ return true;
+ return one.equals(two) == false;
+ }
+}
Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/LifeCycleTestSuite.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/LifeCycleTestSuite.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/LifeCycleTestSuite.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -26,6 +26,7 @@
import junit.textui.TestRunner;
import org.jboss.test.classloading.lifecycle.test.LifeCycleUnitTestCase;
+import org.jboss.test.classloading.lifecycle.test.RefreshModulesUnitTestCase;
/**
* LifeCycle Test Suite.
@@ -55,6 +56,7 @@
TestSuite suite = new TestSuite("LifeCycle Tests");
suite.addTest(LifeCycleUnitTestCase.suite());
+ suite.addTest(RefreshModulesUnitTestCase.suite());
return suite;
}
Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/support/a/MockLifeCycle.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/support/a/MockLifeCycle.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/support/a/MockLifeCycle.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -36,11 +36,9 @@
public boolean gotUnresolved = false;
public boolean gotResolve = false;
public boolean gotUnresolve = false;
+ public boolean gotBounce = false;
public boolean gotStart= false;
public boolean gotStop = false;
-
- public boolean lazyResolve = false;
- public boolean lazyStart = false;
public MockLifeCycle(Module module)
{
@@ -58,6 +56,7 @@
gotUnresolved = false;
gotResolve = false;
gotUnresolve = false;
+ gotBounce = false;
gotStart = false;
gotStop = false;
}
@@ -70,9 +69,11 @@
}
@Override
- public void resolved()
+ public void bounce()
{
- gotResolved = true;
+ gotBounce = true;
+ getModule().unresolveIt();
+ getModule().resolveIt();
}
@Override
@@ -91,23 +92,18 @@
public void unresolve()
{
gotUnresolve = true;
+ getModule().unresolveIt();
}
@Override
- public void unresolved()
+ public void resolved()
{
- gotUnresolved = true;
+ gotResolved = true;
}
@Override
- public boolean isLazyResolve()
+ public void unresolved()
{
- return lazyResolve;
+ gotUnresolved = true;
}
-
- @Override
- public boolean isLazyStart()
- {
- return lazyStart;
- }
}
Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/support/a/MockLifeCycleClassLoaderPolicyModule.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/support/a/MockLifeCycleClassLoaderPolicyModule.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/support/a/MockLifeCycleClassLoaderPolicyModule.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -70,4 +70,18 @@
throw new Error("Error", t);
}
}
+
+ void unresolveIt()
+ {
+ ControllerContext context = getControllerContext();
+ Controller controller = context.getController();
+ try
+ {
+ controller.change(context, ControllerState.CONFIGURED);
+ }
+ catch (Throwable t)
+ {
+ throw new Error("Error", t);
+ }
+ }
}
Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/AbstractMockLifeCycleUnitTest.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/AbstractMockLifeCycleUnitTest.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/AbstractMockLifeCycleUnitTest.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -29,6 +29,7 @@
import org.jboss.classloader.spi.ParentPolicy;
import org.jboss.classloading.spi.dependency.ClassLoading;
import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoadingMetaData;
+import org.jboss.dependency.spi.ControllerContext;
import org.jboss.dependency.spi.ControllerMode;
import org.jboss.dependency.spi.ControllerState;
import org.jboss.kernel.Kernel;
@@ -51,6 +52,8 @@
private KernelController controller;
protected ClassLoaderSystem system;
+
+ protected ClassLoading classLoading;
public AbstractMockLifeCycleUnitTest(String name)
{
@@ -101,6 +104,14 @@
return assertClassLoader(context);
}
+ protected ClassLoader assertIsResolved(KernelControllerContext context) throws Exception
+ {
+ MockLifeCycle lifeCycle = assertLifeCycle(context);
+ assertTrue(context.getName() + " should be resolved: " + context.getDependencyInfo().getUnresolvedDependencies(null), lifeCycle.isResolved());
+ assertFalse(context.getName() + " should not be started", lifeCycle.isStarted());
+ return assertClassLoader(context);
+ }
+
protected ClassLoader assertStarted(KernelControllerContext context) throws Exception
{
MockLifeCycle lifeCycle = assertLifeCycle(context);
@@ -228,6 +239,9 @@
builder.addMethodUninstallCallback("removeModule", null, null, ControllerState.CONFIGURED, null);
install(builder.getBeanMetaData());
+
+ ControllerContext ctx = controller.getInstalledContext("ClassLoading");
+ classLoading = (ClassLoading) ctx.getTarget();
}
protected void tearDown() throws Exception
Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/LifeCycleUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/LifeCycleUnitTestCase.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/LifeCycleUnitTestCase.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -24,12 +24,14 @@
import junit.framework.Test;
import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.filter.ClassFilterUtils;
import org.jboss.classloading.plugins.metadata.PackageRequirement;
import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoadingMetaData;
import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
import org.jboss.kernel.spi.dependency.KernelControllerContext;
import org.jboss.test.classloading.lifecycle.support.a.A;
import org.jboss.test.classloading.lifecycle.support.a.MockLifeCycle;
+import org.jboss.test.classloading.lifecycle.support.a.MockLifeCycleClassLoaderPolicyModule;
/**
* LifeCycleUnitTestCase.
@@ -82,6 +84,70 @@
}
}
+ public void testResolveUsingClassLoadingAdmin() throws Exception
+ {
+ MockClassLoadingMetaData metaData1 = new MockClassLoadingMetaData("test1");
+ KernelControllerContext context1 = install(metaData1);
+ try
+ {
+ MockLifeCycleClassLoaderPolicyModule module1 = assertMockClassPolicyModule(context1);
+ assertNotResolved(context1);
+
+ MockClassLoadingMetaData metaData2 = new MockClassLoadingMetaData("test2");
+ KernelControllerContext context2 = install(metaData2);
+ try
+ {
+ MockLifeCycleClassLoaderPolicyModule module2 = assertMockClassPolicyModule(context2);
+ assertNotResolved(context2);
+
+ assertTrue(classLoading.resolveModules(module1, module2));
+ assertResolved(context1);
+ assertResolved(context2);
+ }
+ finally
+ {
+ uninstall(context2);
+ }
+ }
+ finally
+ {
+ uninstall(context1);
+ }
+ }
+
+ public void testNotResolvedUsingClassLoadingAdmin() throws Exception
+ {
+ MockClassLoadingMetaData metaData1 = new MockClassLoadingMetaData("test1");
+ KernelControllerContext context1 = install(metaData1);
+ try
+ {
+ MockLifeCycleClassLoaderPolicyModule module1 = assertMockClassPolicyModule(context1);
+ assertNotResolved(context1);
+
+ ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+ MockClassLoadingMetaData metaData2 = new MockClassLoadingMetaData("test2");
+ metaData2.getRequirements().addRequirement(factory.createRequireModule("doesNotExist"));
+ KernelControllerContext context2 = install(metaData2);
+ try
+ {
+ MockLifeCycleClassLoaderPolicyModule module2 = assertMockClassPolicyModule(context2);
+ assertNotResolved(context2);
+
+ assertFalse(classLoading.resolveModules(module1, module2));
+ assertResolved(context1);
+ assertNotResolved(context2);
+ }
+ finally
+ {
+ uninstall(context2);
+ }
+ }
+ finally
+ {
+ uninstall(context1);
+ }
+ }
+
public void testUnresolve() throws Exception
{
MockClassLoadingMetaData metaData = new MockClassLoadingMetaData("test");
@@ -177,7 +243,7 @@
{
assertNotResolved(context);
MockLifeCycle lifeCycleA = assertNotResolved(contextA);
- lifeCycleA.lazyResolve = true;
+ lifeCycleA.setLazyResolve(true);
resolve(context);
ClassLoader cl = assertResolved(context);
@@ -213,6 +279,30 @@
}
}
+ public void testNotLazyStartWithFilter() throws Exception
+ {
+ MockClassLoadingMetaData metaData = new MockClassLoadingMetaData("test");
+ metaData.setPathsAndPackageNames(A.class);
+ KernelControllerContext context = install(metaData);
+ try
+ {
+ assertNotResolved(context);
+ MockLifeCycle lifeCycle = assertNotResolved(context);
+ lifeCycle.setLazyStart(true);
+ lifeCycle.setLazyStartFilter(ClassFilterUtils.NOTHING);
+
+ resolve(context);
+ ClassLoader cl = assertResolved(context);
+ assertLoadClass(A.class, cl);
+ assertResolved(context);
+ assertFalse("Should NOT get start invocation", lifeCycle.gotStart);
+ }
+ finally
+ {
+ uninstall(context);
+ }
+ }
+
public void testLazyStart() throws Exception
{
MockClassLoadingMetaData metaData = new MockClassLoadingMetaData("test");
@@ -221,7 +311,7 @@
try
{
MockLifeCycle lifeCycle = assertNotResolved(context);
- lifeCycle.lazyStart = true;
+ lifeCycle.setLazyStart(true);
resolve(context);
ClassLoader cl = assertResolved(context);
@@ -233,4 +323,27 @@
uninstall(context);
}
}
+
+ public void testLazyStartWithFilter() throws Exception
+ {
+ MockClassLoadingMetaData metaData = new MockClassLoadingMetaData("test");
+ metaData.setPathsAndPackageNames(A.class);
+ KernelControllerContext context = install(metaData);
+ try
+ {
+ assertNotResolved(context);
+ MockLifeCycle lifeCycle = assertNotResolved(context);
+ lifeCycle.setLazyStart(true);
+ lifeCycle.setLazyStartFilter(ClassFilterUtils.createPackageClassFilter(ClassLoaderUtils.getClassPackageName(A.class.getName())));
+
+ resolve(context);
+ ClassLoader cl = assertResolved(context);
+ assertLoadClass(A.class, cl);
+ assertTrue("Should get start invocation", lifeCycle.gotStart);
+ }
+ finally
+ {
+ uninstall(context);
+ }
+ }
}
Added: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/RefreshModulesUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/RefreshModulesUnitTestCase.java (rev 0)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/lifecycle/test/RefreshModulesUnitTestCase.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -0,0 +1,630 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloading.lifecycle.test;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ShutdownPolicy;
+import org.jboss.classloading.spi.dependency.Domain;
+import org.jboss.classloading.spi.dependency.ExportPackage;
+import org.jboss.classloading.spi.dependency.Module;
+import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoaderPolicyModule;
+import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoadingMetaData;
+import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
+import org.jboss.classloading.spi.version.VersionRange;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.test.classloading.dependency.support.a.A;
+import org.jboss.test.classloading.dependency.support.b.B;
+import org.jboss.test.classloading.lifecycle.support.a.MockLifeCycle;
+
+/**
+ * ClassLoadingAdmin unit tests
+ *
+ * @author adrian at jboss.org
+ */
+public class RefreshModulesUnitTestCase extends AbstractMockLifeCycleUnitTest
+{
+ static String PACKAGEA = ClassLoaderUtils.getClassPackageName(A.class.getName());
+ static String PACKAGEB = ClassLoaderUtils.getClassPackageName(B.class.getName());
+
+ boolean lazyShutdown;
+
+ public static Test suite()
+ {
+ return suite(RefreshModulesUnitTestCase.class);
+ }
+
+ public RefreshModulesUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public RefreshModulesUnitTestCase(String name, boolean lazyShutdown)
+ {
+ super(name);
+ this.lazyShutdown = lazyShutdown;
+ }
+
+ ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+
+ MockClassLoaderPolicyModule moduleA;
+ MockLifeCycle lifecycleA;
+ Class<?> classA;
+ Domain domainA;
+ KernelControllerContext contextA;
+
+ MockClassLoaderPolicyModule moduleA2;
+ MockLifeCycle lifecycleA2;
+ Class<?> classA2;
+ Domain domainA2;
+ KernelControllerContext contextA2;
+
+ MockClassLoaderPolicyModule moduleB;
+ MockLifeCycle lifecycleB;
+ Class<?> classB;
+ Domain domainB;
+ KernelControllerContext contextB;
+
+ MockClassLoaderPolicyModule moduleC;
+ MockLifeCycle lifecycleC;
+ KernelControllerContext contextC;
+
+ MockClassLoaderPolicyModule moduleD;
+ MockLifeCycle lifecycleD;
+ KernelControllerContext contextD;
+
+ MockClassLoaderPolicyModule moduleE;
+ MockLifeCycle lifecycleE;
+ KernelControllerContext contextE;
+
+ @Override
+ protected KernelControllerContext install(MockClassLoadingMetaData metaData) throws Exception
+ {
+ if (lazyShutdown)
+ metaData.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+ return super.install(metaData);
+ }
+
+ protected void setUpA() throws Exception
+ {
+ MockClassLoadingMetaData a = new MockClassLoadingMetaData("a", "1.0.0");
+ a.getCapabilities().addCapability(factory.createModule("ModuleA", "1.0.0"));
+ a.getCapabilities().addCapability(factory.createPackage(PACKAGEA, "1.0.0"));
+ a.setPathsAndPackageNames(A.class);
+ a.setDomain("main");
+ contextA = install(a);
+ moduleA = assertMockClassPolicyModule(contextA);
+ lifecycleA = assertLifeCycle(contextA);
+ resolve(contextA);
+ ClassLoader clA = assertClassLoader(contextA);
+ classA = clA.loadClass(A.class.getName());
+ domainA = moduleA.checkDomain();
+ }
+
+ protected void setUpB() throws Exception
+ {
+ MockClassLoadingMetaData b = new MockClassLoadingMetaData("b", "2.0.0");
+ b.setDomain("other");
+ b.getCapabilities().addCapability(factory.createModule("ModuleBAlias", "3.0.0"));
+ b.getCapabilities().addCapability(factory.createModule("ModuleB", "2.0.0"));
+ b.getCapabilities().addCapability(factory.createPackage(PACKAGEB, "2.0.0"));
+ b.setPathsAndPackageNames(B.class);
+ contextB = install(b);
+ moduleB = assertMockClassPolicyModule(contextB);
+ lifecycleB = assertLifeCycle(contextB);
+ resolve(contextB);
+ ClassLoader clB = assertClassLoader(contextB);
+ classB = clB.loadClass(B.class.getName());
+ domainB = moduleB.checkDomain();
+ }
+
+ protected void setUpAB() throws Exception
+ {
+ setUpA();
+
+ MockClassLoadingMetaData a2 = new MockClassLoadingMetaData("a", "2.0.0");
+ a2.getCapabilities().addCapability(factory.createModule("ModuleA", "2.0.0"));
+ a2.getCapabilities().addCapability(factory.createPackage(PACKAGEA, "2.0.0"));
+ a2.getCapabilities().addCapability(factory.createPackage(PACKAGEB, "2.0.0"));
+ a2.setPathsAndPackageNames(A.class);
+ a2.setDomain("main");
+ contextA2 = install(a2);
+ moduleA2 = assertMockClassPolicyModule(contextA2);
+ lifecycleA2 = assertLifeCycle(contextA2);
+ resolve(contextA2);
+ ClassLoader clA2 = assertClassLoader(contextA2);
+ classA2 = clA2.loadClass(A.class.getName());
+ domainA2 = moduleA2.checkDomain();
+
+ setUpB();
+ }
+
+ protected void setUpABCDE() throws Exception
+ {
+ setUpAB();
+
+ MockClassLoadingMetaData c = new MockClassLoadingMetaData("c", "2.0.0");
+ c.getRequirements().addRequirement(factory.createRequireModule("ModuleA", VersionRange.valueOf("1.0.0")));
+ c.getRequirements().addRequirement(factory.createRequirePackage(PACKAGEA, VersionRange.valueOf("1.0.0")));
+ c.setDomain("main");
+ contextC = install(c);
+ moduleC = assertMockClassPolicyModule(contextC);
+ lifecycleC = assertLifeCycle(contextC);
+ resolve(contextC);
+ ClassLoader clC = assertClassLoader(contextC);
+ clC.loadClass(A.class.getName());
+
+ MockClassLoadingMetaData d = new MockClassLoadingMetaData("d", "5.0.0");
+ d.getRequirements().addRequirement(factory.createRequireModule("ModuleB", new VersionRange("2.0.0")));
+ d.getRequirements().addRequirement(factory.createRequirePackage(PACKAGEB, new VersionRange("2.0.0")));
+ d.setDomain("other");
+ contextD = install(d);
+ moduleD = assertMockClassPolicyModule(contextD);
+ lifecycleD = assertLifeCycle(contextD);
+ resolve(contextD);
+ ClassLoader clD = assertClassLoader(contextD);
+ clD.loadClass(B.class.getName());
+
+ MockClassLoadingMetaData e = new MockClassLoadingMetaData("e", "5.0.0");
+ e.getRequirements().addRequirement(factory.createRequireModule("ModuleB", new VersionRange("2.0.0")));
+ e.setDomain("other");
+ contextE = install(e);
+ moduleE = assertMockClassPolicyModule(contextB);
+ lifecycleE = assertLifeCycle(contextE);
+ resolve(contextE);
+ moduleE = assertMockClassPolicyModule(contextE);
+ ClassLoader clE = assertClassLoader(contextE);
+ clE.loadClass(B.class.getName());
+ }
+
+ public void testRefreshModulesSimple() throws Exception
+ {
+ setUpAB();
+
+ resetFlags();
+ classLoading.refreshModules(moduleA);
+ assertBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ }
+
+ public void testRefreshModulesMultiple() throws Exception
+ {
+ setUpAB();
+
+ resetFlags();
+ classLoading.refreshModules(moduleA, moduleB);
+ assertBounce(contextA);
+ assertNoBounce(contextA2);
+ assertBounce(contextB);
+ }
+
+ public void testRefreshModulesNothing() throws Exception
+ {
+ setUpAB();
+
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ }
+
+ public void testRefreshModulesCascaded() throws Exception
+ {
+ setUpABCDE();
+
+ resetFlags();
+ classLoading.refreshModules(moduleA);
+ assertBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertReResolved(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesNonCascaded() throws Exception
+ {
+ lazyShutdown = true;
+ setUpABCDE();
+
+ resetFlags();
+ classLoading.refreshModules(moduleA);
+ assertBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesNotResolvedCascaded() throws Exception
+ {
+ setUpABCDE();
+
+ resetFlags();
+ unresolve(contextA);
+ assertNotResolved(contextA);
+ assertNotResolved(contextC);
+
+ resetFlags();
+ classLoading.refreshModules(moduleA);
+ assertNotResolved(contextA);
+ assertNoBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertNotResolved(contextC);
+ assertNoBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesNotResolvedNonCascaded() throws Exception
+ {
+ lazyShutdown = true;
+ setUpABCDE();
+
+ resetFlags();
+ unresolve(contextA);
+ assertNotResolved(contextA);
+ assertIsResolved(contextC);
+
+ resetFlags();
+ classLoading.refreshModules(moduleA);
+ assertNotResolved(contextA);
+ assertNoBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertFailedBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesUninstalledCascaded() throws Exception
+ {
+ setUpABCDE();
+
+ resetFlags();
+ uninstall(contextA);
+ assertNotResolved(contextC);
+
+ resetFlags();
+ classLoading.refreshModules(moduleA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertNoBounce(contextC);
+ assertNotResolved(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesUninstalledNonCascaded() throws Exception
+ {
+ lazyShutdown = true;
+ setUpABCDE();
+
+ resetFlags();
+ uninstall(contextA);
+ assertIsResolved(contextC);
+
+ resetFlags();
+ classLoading.refreshModules(moduleA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertFailedBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesAllCascaded() throws Exception
+ {
+ setUpABCDE();
+
+ resetFlags();
+ uninstall(contextA);
+ assertNotResolved(contextC);
+
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertNoBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesAllNonCascaded() throws Exception
+ {
+ lazyShutdown = true;
+ setUpABCDE();
+
+ resetFlags();
+ uninstall(contextA);
+ assertIsResolved(contextC);
+
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertFailedBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+
+ // Shouldn't do it twice
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertNoBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesAllMultipleCascaded() throws Exception
+ {
+ setUpABCDE();
+
+ resetFlags();
+ uninstall(contextA);
+ uninstall(contextB);
+ assertIsResolved(contextA2);
+ assertNotResolved(contextC);
+ assertNotResolved(contextD);
+ assertNotResolved(contextE);
+
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA2);
+ assertNoBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesAllMultipleNonCascaded() throws Exception
+ {
+ lazyShutdown = true;
+ setUpABCDE();
+
+ resetFlags();
+ uninstall(contextA);
+ uninstall(contextB);
+ assertIsResolved(contextA2);
+ assertIsResolved(contextC);
+ assertIsResolved(contextD);
+ assertIsResolved(contextE);
+
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA2);
+ assertFailedBounce(contextC);
+ assertFailedBounce(contextD);
+ assertFailedBounce(contextE);
+
+ // Shouldn't do it twice
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA2);
+ assertNoBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesReinstalledCascaded() throws Exception
+ {
+ setUpABCDE();
+
+ assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+
+ resetFlags();
+ uninstall(contextA);
+ assertNotResolved(contextC);
+
+ setUpA();
+ assertResolved(contextA);
+ assertResolved(contextC);
+
+ ExportPackage result = assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+ assertEquals(moduleA, result.getModule());
+
+ resetFlags();
+ classLoading.refreshModules(moduleA);
+ assertBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertReResolved(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+
+ result = assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+ assertEquals(moduleA, result.getModule());
+ }
+
+ public void testRefreshModulesReinstalledNonCascaded() throws Exception
+ {
+ lazyShutdown = true;
+ setUpABCDE();
+
+ assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+
+ resetFlags();
+ Module oldModuleA = moduleA;
+ uninstall(contextA);
+ assertIsResolved(contextC);
+
+ setUpA();
+ assertResolved(contextA);
+ assertNoBounce(contextC);
+
+ ExportPackage result = assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"));
+ assertEquals(moduleA, result.getModule());
+
+ resetFlags();
+ classLoading.refreshModules(oldModuleA);
+ assertNoBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+ }
+
+ public void testRefreshModulesAllReinstalledCascaded() throws Exception
+ {
+ setUpABCDE();
+
+ assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+
+ resetFlags();
+ uninstall(contextA);
+ assertNotResolved(contextC);
+
+ setUpA();
+ assertResolved(contextA);
+ assertResolved(contextC);
+
+ ExportPackage result = assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+ assertEquals(moduleA, result.getModule());
+
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertNoBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+
+ result = assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+ assertEquals(moduleA, result.getModule());
+ }
+
+ public void testRefreshModulesAllReinstalledNonCascaded() throws Exception
+ {
+ lazyShutdown = true;
+ setUpABCDE();
+
+ assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+
+ resetFlags();
+ uninstall(contextA);
+ assertIsResolved(contextC);
+
+ setUpA();
+ assertResolved(contextA);
+ assertNoBounce(contextC);
+
+ ExportPackage result = assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"));
+ assertEquals(moduleA, result.getModule());
+
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+
+ // Should not do it twice
+ resetFlags();
+ classLoading.refreshModules();
+ assertNoBounce(contextA);
+ assertNoBounce(contextA2);
+ assertNoBounce(contextB);
+ assertNoBounce(contextC);
+ assertNoBounce(contextD);
+ assertNoBounce(contextE);
+
+ result = assertExportedPackageImporting(PACKAGEA, VersionRange.valueOf("1.0.0"), moduleC);
+ assertEquals(moduleA, result.getModule());
+ }
+
+ protected void assertBounce(KernelControllerContext context) throws Exception
+ {
+ MockLifeCycle lifecycle = assertLifeCycle(context);
+ assertTrue(context.getName() + " should have bounced", lifecycle.gotBounce);
+ assertTrue(context.getName() + " should have unresolved", lifecycle.gotUnresolved);
+ assertResolved(context);
+ }
+
+ protected void assertReResolved(KernelControllerContext context) throws Exception
+ {
+ MockLifeCycle lifecycle = assertLifeCycle(context);
+ assertTrue(context.getName() + " should have unresolved", lifecycle.gotUnresolved);
+ assertResolved(context);
+ }
+
+ protected void assertFailedBounce(KernelControllerContext context) throws Exception
+ {
+ MockLifeCycle lifecycle = assertLifeCycle(context);
+ assertTrue(context.getName() + " should have bounced", lifecycle.gotBounce);
+ assertTrue(context.getName() + " should have unresolved", lifecycle.gotUnresolved);
+ assertNotResolved(context);
+ }
+
+ protected void assertNoBounce(KernelControllerContext context) throws Exception
+ {
+ MockLifeCycle lifecycle = assertLifeCycle(context);
+ assertFalse(context.getName() + " should not have bounced", lifecycle.gotBounce);
+ assertFalse(context.getName() + " should not have unresolved", lifecycle.gotUnresolved);
+ assertFalse(context.getName() + " should not have resolved", lifecycle.gotResolved);
+ }
+
+ protected ExportPackage assertExportedPackageImporting(String name, VersionRange range, Module... expected) throws Exception
+ {
+ Collection<ExportPackage> exportPackages = classLoading.getExportedPackages(name, range);
+ assertTrue(exportPackages.toString(), exportPackages.size() == 1);
+ ExportPackage exportPackage = exportPackages.iterator().next();
+ assertModules(exportPackage.getImportingModules(), expected);
+ return exportPackage;
+ }
+
+ protected void assertModules(Collection<Module> actual, Module... expected) throws Exception
+ {
+ Set<Module> expect = new HashSet<Module>();
+ for (Module module : expected)
+ expect.add(module);
+
+ Set<Module> act = new HashSet<Module>(actual);
+
+ assertEquals(expect, act);
+ }
+
+ protected void resetFlags()
+ {
+ lifecycleA.resetFlags();
+ lifecycleA2.resetFlags();
+ lifecycleB.resetFlags();
+ if (lifecycleC != null)
+ lifecycleC.resetFlags();
+ if (lifecycleD != null)
+ lifecycleD.resetFlags();
+ if (lifecycleE != null)
+ lifecycleE.resetFlags();
+ }
+}
Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/version/test/VersionRangeUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/version/test/VersionRangeUnitTestCase.java 2010-03-02 13:00:00 UTC (rev 101713)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/version/test/VersionRangeUnitTestCase.java 2010-03-02 13:11:14 UTC (rev 101714)
@@ -235,6 +235,70 @@
assertEquals(range, other);
}
+ public void testParseVersionRange() throws Exception
+ {
+ testParseVersionRange("", null, true, null, true);
+
+ testParseVersionRange("[,]", null, true, null, true);
+ testParseVersionRange("[,)", null, true, null, false);
+ testParseVersionRange("(,]", null, false, null, true);
+ testParseVersionRange("(,)", null, false, null, false);
+
+ testParseVersionRange("2.0.0", "2.0.0", true, "2.0.0", true);
+ testParseVersionRange("[2.0.0]", "2.0.0", true, "2.0.0", true);
+ testParseVersionRange("[2.0.0)", "2.0.0", true, null, false);
+ testParseVersionRange("(2.0.0)", "2.0.0", false, null, false);
+
+ testParseVersionRange("[,2.0.0]", null, true, "2.0.0", true);
+ testParseVersionRange("[1.0.0,]", "1.0.0", true, "1.0.0", true);
+
+ testParseVersionRange("[1.0.0,1.0.0]", "1.0.0", true, "1.0.0", true);
+
+ testParseVersionRange("[1.0.0,2.0.0]", "1.0.0", true, "2.0.0", true);
+ testParseVersionRange("[1.0.0,2.0.0)", "1.0.0", true, "2.0.0", false);
+ testParseVersionRange("(1.0.0,2.0.0]", "1.0.0", false, "2.0.0", true);
+ testParseVersionRange("(1.0.0,2.0.0)", "1.0.0", false, "2.0.0", false);
+
+ testParseVersionRange(" (1.0.0,2.0.0)", "1.0.0", false, "2.0.0", false);
+ testParseVersionRange("( 1.0.0,2.0.0)", "1.0.0", false, "2.0.0", false);
+ testParseVersionRange("(1.0.0 ,2.0.0)", "1.0.0", false, "2.0.0", false);
+ testParseVersionRange("(1.0.0, 2.0.0)", "1.0.0", false, "2.0.0", false);
+ testParseVersionRange("(1.0.0,2.0.0 )", "1.0.0", false, "2.0.0", false);
+ testParseVersionRange("(1.0.0,2.0.0) ", "1.0.0", false, "2.0.0", false);
+
+ testBadParseVersionRange(null, IllegalArgumentException.class);
+ testBadParseVersionRange("x", IllegalArgumentException.class);
+ testBadParseVersionRange("1,", IllegalArgumentException.class);
+ testBadParseVersionRange(",1", IllegalArgumentException.class);
+ testBadParseVersionRange("1,x", IllegalArgumentException.class);
+ testBadParseVersionRange("x,1", IllegalArgumentException.class);
+
+ testBadParseVersionRange("[", IllegalArgumentException.class);
+ testBadParseVersionRange("(", IllegalArgumentException.class);
+ testBadParseVersionRange("]", IllegalArgumentException.class);
+ testBadParseVersionRange(")", IllegalArgumentException.class);
+ testBadParseVersionRange(",", IllegalArgumentException.class);
+ testBadParseVersionRange("[1,2", IllegalArgumentException.class);
+ testBadParseVersionRange("(1,2", IllegalArgumentException.class);
+ testBadParseVersionRange("1,2]", IllegalArgumentException.class);
+ testBadParseVersionRange("1,2)", IllegalArgumentException.class);
+ testBadParseVersionRange("[x]", IllegalArgumentException.class);
+ testBadParseVersionRange("[1,x]", IllegalArgumentException.class);
+ testBadParseVersionRange("[x,1]", IllegalArgumentException.class);
+
+ testBadParseVersionRangeWrongPlace("[");
+ testBadParseVersionRangeWrongPlace("(");
+ testBadParseVersionRangeWrongPlace("]");
+ testBadParseVersionRangeWrongPlace(")");
+ testBadParseVersionRangeWrongPlace(",");
+
+ testBadParseVersionRange("(1.0.0]", IllegalArgumentException.class);
+ testBadParseVersionRange("(1.0.0,0.0.0)", IllegalArgumentException.class);
+ testBadParseVersionRange("(1.0.0,1.0.0)", IllegalArgumentException.class);
+ testBadParseVersionRange("[1.0.0,1.0.0)", IllegalArgumentException.class);
+ testBadParseVersionRange("(1.0.0,1.0.0]", IllegalArgumentException.class);
+ }
+
protected void testVersionRangeFromString(String low)
{
testVersionRange(low);
@@ -554,4 +618,42 @@
else
assertFalse("Expected " + range1 + ".isConsistent(" + range2 + ") to be false", range1.isConsistent(range2));
}
+
+ protected void testParseVersionRange(String range, String low, boolean lowInclusive, String high, boolean highInclusive) throws Exception
+ {
+ VersionRange expected = new VersionRange(low, lowInclusive, high, highInclusive);
+ VersionRange actual = VersionRange.parseRangeSpec(range);
+ assertEquals(expected, actual);
+ }
+
+ protected void testBadParseVersionRange(String range, Class<? extends Throwable> expected) throws Exception
+ {
+ try
+ {
+ VersionRange.parseRangeSpec(range);
+ fail("Should not be here: " + range);
+ }
+ catch (Throwable t)
+ {
+ checkThrowable(expected, t);
+ }
+ }
+
+ protected void testBadParseVersionRangeWrongPlace(String wrong) throws Exception
+ {
+ testBadParseVersionRangeWrongPlace("[", "]", wrong);
+ testBadParseVersionRangeWrongPlace("[", ")", wrong);
+ testBadParseVersionRangeWrongPlace("(", "]", wrong);
+ testBadParseVersionRangeWrongPlace("(", ")", wrong);
+ }
+
+ protected void testBadParseVersionRangeWrongPlace(String start, String end, String wrong) throws Exception
+ {
+ testBadParseVersionRange(wrong + start + "1,2" + end, IllegalArgumentException.class);
+ testBadParseVersionRange(start + wrong + "1,2" + end, IllegalArgumentException.class);
+ testBadParseVersionRange(start + "1" + wrong + ",2" + end, IllegalArgumentException.class);
+ testBadParseVersionRange(start + "1," + wrong + "2" + end, IllegalArgumentException.class);
+ testBadParseVersionRange(start + "1,2" + wrong + end, IllegalArgumentException.class);
+ testBadParseVersionRange(start + "1,2" + end + wrong, IllegalArgumentException.class);
+ }
}
More information about the jboss-cvs-commits
mailing list