[jboss-cvs] JBossAS SVN: r102060 - in projects/jboss-cl/trunk: classloader/src/main/java/org/jboss/classloader/spi and 4 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Mar 8 08:07:27 EST 2010
Author: adrian at jboss.org
Date: 2010-03-08 08:07:26 -0500 (Mon, 08 Mar 2010)
New Revision: 102060
Modified:
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseDelegateLoader.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/test/java/org/jboss/test/classloading/dependency/test/DependencyUnitTestCase.java
projects/jboss-cl/trunk/pom.xml
Log:
[JBCL-156] - Add circular dependency checking - fix the delegate construction so it is back to being lazy.
Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java 2010-03-08 12:32:07 UTC (rev 102059)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java 2010-03-08 13:07:26 UTC (rev 102060)
@@ -449,7 +449,20 @@
@Override
protected void toLongString(StringBuilder builder)
{
- builder.append(" delegates=").append(getDelegates());
+ List<? extends DelegateLoader> delegates = getDelegates();
+ if (delegates != null && delegates.isEmpty() == false)
+ {
+ builder.append(" delegates=[");
+ boolean first = true;
+ for (DelegateLoader delegate : delegates)
+ {
+ if (first == false)
+ builder.append(',');
+ first = false;
+ builder.append(delegate.toLongString());
+ }
+ builder.append(']');
+ }
String[] packageNames = getPackageNames();
if (packageNames != null)
builder.append(" exported=").append(Arrays.asList(packageNames));
Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseDelegateLoader.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseDelegateLoader.java 2010-03-08 12:32:07 UTC (rev 102059)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseDelegateLoader.java 2010-03-08 13:07:26 UTC (rev 102060)
@@ -113,15 +113,9 @@
BaseClassLoader getBaseClassLoader(String message, String context)
{
BaseClassLoader result = null;
- try
- {
- BaseClassLoaderPolicy policy = getPolicy();
- if (policy != null)
- result = policy.getClassLoader();
- }
- catch (IllegalStateException ignored)
- {
- }
+ BaseClassLoaderPolicy policy = getPolicy();
+ if (policy != null)
+ result = policy.getClassLoaderUnchecked();
if (result == null)
log.warn("Not " + message + context + " from policy that has no classLoader: " + toLongString());
return result;
@@ -185,7 +179,7 @@
builder.append(getClass().getSimpleName());
builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
if (delegate != null)
- builder.append("{delegate=").append(delegate.toLongString());
+ builder.append("{delegate=").append(delegate);
else
builder.append("{factory=").append(factory);
toLongString(builder);
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-08 12:32:07 UTC (rev 102059)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Module.java 2010-03-08 13:07:26 UTC (rev 102060)
@@ -39,15 +39,12 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
-import org.jboss.classloader.spi.ClassLoaderPolicy;
import org.jboss.classloader.spi.ClassLoaderSystem;
import org.jboss.classloader.spi.DelegateLoader;
import org.jboss.classloader.spi.ParentPolicy;
import org.jboss.classloader.spi.ShutdownPolicy;
import org.jboss.classloader.spi.base.BaseClassLoader;
import org.jboss.classloader.spi.filter.ClassFilter;
-import org.jboss.classloader.spi.filter.FilteredDelegateLoader;
-import org.jboss.classloader.spi.filter.PackageClassFilter;
import org.jboss.classloading.plugins.metadata.PackageCapability;
import org.jboss.classloading.plugins.metadata.PackageRequirement;
import org.jboss.classloading.spi.helpers.NameAndVersionSupport;
@@ -59,6 +56,7 @@
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.plugins.ResolvedState;
import org.jboss.dependency.spi.Controller;
import org.jboss.dependency.spi.ControllerContext;
import org.jboss.dependency.spi.ControllerState;
@@ -728,8 +726,8 @@
if (dependencies == null || dependencies.isEmpty())
return;
- // Maps the ClassLoaderPolicy that we get from the iDependOnModule to the list of package names that we are importing
- Map<ClassLoaderPolicy, List<String>> delegateToRequiredPackages = new LinkedHashMap<ClassLoaderPolicy, List<String>>();
+ // Maps the iDependOnModule to the list of package names that we are importing
+ Map<Module, List<String>> delegateToRequiredPackages = new LinkedHashMap<Module, List<String>>();
for (RequirementDependencyItem item : dependencies)
{
@@ -749,26 +747,22 @@
dynamic.add(delegate);
continue;
}
-
- String name = (String) item.getIDependOn();
- if (name == null)
+
+ Module iDependOnModule = item.getResolvedModule();
+ if (iDependOnModule == null)
{
- // Optional requirement, just ignore
- if (requirement.isOptional())
- continue;
- // Something has gone wrong
- throw new IllegalStateException("No iDependOn for item: " + item);
+ // Do it the hard way - probably optional or a self dependency?
+ String name = (String) item.getIDependOn();
+ if (name != null)
+ iDependOnModule = checkDomain().getModule(name);
+ if (iDependOnModule == null)
+ {
+ if (requirement.isOptional())
+ continue;
+ throw new IllegalStateException("Module not found for requirement: " + item);
+ }
}
-
- Module iDependOnModule = checkDomain().getModule(name);
- if (iDependOnModule == null)
- throw new IllegalStateException("Module not found with name: " + name);
- // Determine the delegate loader for the module
- DelegateLoader delegate = iDependOnModule.getDelegateLoader(module, requirement);
- if (delegate == null)
- throw new IllegalStateException("Cannot obtain delegate for: " + requirement);
-
// Check for re-export by the module
if (requirement.wantReExports())
addDelegates(iDependOnModule, delegates, dynamic, visited, true);
@@ -779,12 +773,11 @@
// If we are connecting to another module we collect the imported package names per delegate
if (requirement instanceof PackageRequirement)
{
- ClassLoaderPolicy policy = delegate.getPolicy();
- List<String> packageNames = delegateToRequiredPackages.get(policy);
+ List<String> packageNames = delegateToRequiredPackages.get(iDependOnModule);
if (packageNames == null)
{
packageNames = new ArrayList<String>();
- delegateToRequiredPackages.put(policy, packageNames);
+ delegateToRequiredPackages.put(iDependOnModule, packageNames);
}
PackageRequirement packageRequirement = (PackageRequirement)requirement;
@@ -792,6 +785,10 @@
}
else
{
+ // Determine the delegate loader for the module
+ DelegateLoader delegate = iDependOnModule.getDelegateLoader(module, requirement);
+ if (delegate == null)
+ throw new IllegalStateException("Cannot obtain delegate for: " + requirement);
delegates.add(delegate);
}
}
@@ -799,10 +796,11 @@
}
// Add FilteredDelegateLoaders for all collected package requirements
- for (Entry<ClassLoaderPolicy, List<String>> entry : delegateToRequiredPackages.entrySet())
+ for (Entry<Module, List<String>> entry : delegateToRequiredPackages.entrySet())
{
- PackageClassFilter filter = PackageClassFilter.createPackageClassFilter(entry.getValue());
- delegates.add(new FilteredDelegateLoader(entry.getKey(), filter));
+ Module iDependOnModule = entry.getKey();
+ DelegateLoader delegate = iDependOnModule.getDelegateLoader(module, entry.getValue());
+ delegates.add(delegate);
}
}
@@ -825,6 +823,15 @@
public abstract DelegateLoader getDelegateLoader(Module requiringModule, Requirement requirement);
/**
+ * Get a delegate loader filtered by packages
+ *
+ * @param requiringModule the requiring module
+ * @param packages the packages to filter on
+ * @return the delegate loader
+ */
+ public abstract DelegateLoader getDelegateLoader(Module requiringModule, List<String> packages);
+
+ /**
* Get the exported packages
*
* @return the exported packages
@@ -1223,7 +1230,7 @@
throw new IllegalStateException("No controller context");
// Remove the DependsOnMe part of this item
- item.setResolved(false);
+ item.setResolved(ResolvedState.UNRESOLVED);
// Remove the IDependOn part of this item
DependencyInfo dependencyInfo = context.getDependencyInfo();
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-08 12:32:07 UTC (rev 102059)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java 2010-03-08 13:07:26 UTC (rev 102060)
@@ -23,6 +23,7 @@
import org.jboss.classloading.spi.metadata.Requirement;
import org.jboss.dependency.plugins.AbstractDependencyItem;
+import org.jboss.dependency.plugins.ResolvedState;
import org.jboss.dependency.spi.Controller;
import org.jboss.dependency.spi.ControllerContext;
import org.jboss.dependency.spi.ControllerState;
@@ -48,7 +49,7 @@
private Requirement requirement;
/** The module we resolved to */
- private Module resolvedModule;
+ private volatile Module resolvedModule;
/**
* Create a new RequirementDependencyItem.
@@ -128,26 +129,26 @@
// Self dependency
if (module == this.module)
{
- Object iDependOn = module.getContextName();
- ControllerContext context = controller.getContext(iDependOn, null);
+ ControllerContext context = module.getControllerContext();
setIDependOn(context.getName());
setResolved(true);
- return isResolved();
+ return true;
}
- // Resolved against a context in the dependent state
- Object iDependOn = module.getContextName();
- ControllerContext context = controller.getContext(iDependOn, getDependentState());
+ resolvedModule = module;
+
+ // Use semi-resolve to avoid circular references
+ ControllerContext context = module.getControllerContext();
if (context != null)
{
- setIDependOn(context.getName());
- resolvedModule = module;
- module.addDepends(this);
- if (module.isCascadeShutdown())
- addDependsOnMe(controller, context);
- setResolved(true);
- if (module.getClassLoadingSpace() == null)
- log.warn(getModule() + " resolved " + getRequirement() + " to " + module + " which has import-all=true. Cannot check its consistency.");
+ boolean resolved = semiResolve(context);
+ if (resolved)
+ {
+ setIDependOn(context.getName());
+ module.addDepends(this);
+ if (module.getClassLoadingSpace() == null)
+ log.warn(getModule() + " resolved " + getRequirement() + " to " + module + " which has import-all=true. Cannot check its consistency.");
+ }
return isResolved();
}
@@ -156,6 +157,15 @@
}
@Override
+ protected void addDependsOnMe(Controller controller, ControllerContext context)
+ {
+ Module resolvedModule = getResolvedModule();
+ if (resolvedModule != null && resolvedModule.isCascadeShutdown() == false)
+ return;
+ super.addDependsOnMe(controller, context);
+ }
+
+ @Override
public boolean unresolved(Controller controller)
{
setIDependOn(null);
@@ -164,9 +174,10 @@
}
@Override
- protected void setResolved(boolean resolved)
+ public void setResolved(ResolvedState resolved)
{
- if (resolved == false && resolvedModule != null)
+ Module resolvedModule = getResolvedModule();
+ if (resolved == ResolvedState.UNRESOLVED && resolvedModule != null)
{
resolvedModule.removeDepends(this);
resolvedModule.removeDependsOnMe(this);
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-08 12:32:07 UTC (rev 102059)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/ClassLoaderPolicyModule.java 2010-03-08 13:07:26 UTC (rev 102060)
@@ -24,6 +24,7 @@
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.util.List;
import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
import org.jboss.classloader.spi.ClassLoaderPolicy;
@@ -33,7 +34,9 @@
import org.jboss.classloader.spi.Loader;
import org.jboss.classloader.spi.ParentPolicy;
import org.jboss.classloader.spi.base.BaseClassLoader;
+import org.jboss.classloader.spi.filter.FilteredDelegateLoader;
import org.jboss.classloader.spi.filter.LazyFilteredDelegateLoader;
+import org.jboss.classloader.spi.filter.PackageClassFilter;
import org.jboss.classloading.spi.dependency.Domain;
import org.jboss.classloading.spi.dependency.Module;
import org.jboss.classloading.spi.dependency.RequirementDependencyItem;
@@ -266,24 +269,31 @@
@Override
public DelegateLoader getDelegateLoader(Module requiringModule, Requirement requirement)
{
- // self dependency
- if (this == requiringModule)
+ ClassLoaderPolicyFactory clpf = new ClassLoaderPolicyFactory()
{
- ClassLoaderPolicyFactory clpf = new ClassLoaderPolicyFactory()
+ public ClassLoaderPolicy createClassLoaderPolicy()
{
- public ClassLoaderPolicy createClassLoaderPolicy()
- {
- if (policy == null)
- throw new IllegalStateException("ClassLoaderPolicy not available");
- return policy;
- }
- };
- return new DelegateLoader(clpf);
- }
- else
+ if (policy == null)
+ throw new IllegalStateException("ClassLoaderPolicy not available");
+ return policy;
+ }
+ };
+ PackageClassFilter filter = PackageClassFilter.createPackageClassFilter(determinePackageNames(true));
+ return new FilteredDelegateLoader(clpf, filter);
+ }
+
+ @Override
+ public DelegateLoader getDelegateLoader(Module requiringModule, List<String> packages)
+ {
+ ClassLoaderPolicyFactory clpf = new ClassLoaderPolicyFactory()
{
- return getPolicy().getExported();
- }
+ public ClassLoaderPolicy createClassLoaderPolicy()
+ {
+ return getPolicy();
+ }
+ };
+ PackageClassFilter filter = PackageClassFilter.createPackageClassFilter(packages);
+ return new FilteredDelegateLoader(clpf, filter);
}
@Override
Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/DependencyUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/DependencyUnitTestCase.java 2010-03-08 12:32:07 UTC (rev 102059)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/DependencyUnitTestCase.java 2010-03-08 13:07:26 UTC (rev 102060)
@@ -37,6 +37,7 @@
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.dependency.support.c.C;
/**
* DependencyUnitTestCase.
@@ -404,4 +405,136 @@
}
assertNoClassLoader(contextA);
}
+
+ public void testCircularModule() throws Exception
+ {
+ ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+ MockClassLoadingMetaData a = new MockClassLoadingMetaData("a");
+ a.setPathsAndPackageNames(A.class);
+ a.getRequirements().addRequirement(factory.createRequireModule("b"));
+ KernelControllerContext contextA = install(a);
+ try
+ {
+ assertNoClassLoader(contextA);
+
+ MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+ b.setPathsAndPackageNames(B.class);
+ b.getRequirements().addRequirement(factory.createRequireModule("a"));
+ KernelControllerContext contextB = install(b);
+ try
+ {
+ ClassLoader clA = assertClassLoader(contextA);
+ assertLoadClass(A.class, clA);
+ assertLoadClassFail(B.class, clA);
+ ClassLoader clB = assertClassLoader(contextB);
+ assertLoadClass(B.class, clB);
+ assertLoadClass(A.class, clB, clA);
+ }
+ finally
+ {
+ uninstall(contextB);
+ }
+ assertNoClassLoader(contextA);
+ assertNoClassLoader(contextB);
+ }
+ finally
+ {
+ uninstall(contextA);
+ }
+ assertNoClassLoader(contextA);
+ }
+
+ public void testCircularPackage() throws Exception
+ {
+ ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+ MockClassLoadingMetaData a = new MockClassLoadingMetaData("a");
+ a.setPathsAndPackageNames(A.class);
+ a.getRequirements().addRequirement(factory.createRequirePackage(B.class.getPackage().getName()));
+ KernelControllerContext contextA = install(a);
+ try
+ {
+ assertNoClassLoader(contextA);
+
+ MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+ b.setPathsAndPackageNames(B.class);
+ b.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+ KernelControllerContext contextB = install(b);
+ try
+ {
+ ClassLoader clA = assertClassLoader(contextA);
+ assertLoadClass(A.class, clA);
+ assertLoadClassFail(B.class, clA);
+ ClassLoader clB = assertClassLoader(contextB);
+ assertLoadClass(B.class, clB);
+ assertLoadClass(A.class, clB, clA);
+ }
+ finally
+ {
+ uninstall(contextB);
+ }
+ assertNoClassLoader(contextA);
+ assertNoClassLoader(contextB);
+ }
+ finally
+ {
+ uninstall(contextA);
+ }
+ assertNoClassLoader(contextA);
+ }
+
+ public void testTransitiveCircularPackage() throws Exception
+ {
+ ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+ MockClassLoadingMetaData a = new MockClassLoadingMetaData("a");
+ a.setPathsAndPackageNames(A.class);
+ a.getRequirements().addRequirement(factory.createRequirePackage(B.class.getPackage().getName()));
+ KernelControllerContext contextA = install(a);
+ try
+ {
+ assertNoClassLoader(contextA);
+
+ MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+ b.setPathsAndPackageNames(B.class);
+ b.getRequirements().addRequirement(factory.createRequirePackage(C.class.getPackage().getName()));
+ KernelControllerContext contextB = install(b);
+ try
+ {
+ assertNoClassLoader(contextB);
+
+ MockClassLoadingMetaData c = new MockClassLoadingMetaData("c");
+ c.setPathsAndPackageNames(C.class);
+ c.getRequirements().addRequirement(factory.createRequirePackage(A.class.getPackage().getName()));
+ KernelControllerContext contextC = install(c);
+ try
+ {
+ ClassLoader clA = assertClassLoader(contextA);
+ assertLoadClass(A.class, clA);
+ assertLoadClassFail(B.class, clA);
+ ClassLoader clB = assertClassLoader(contextB);
+ assertLoadClass(B.class, clB);
+ assertLoadClass(B.class, clA, clB);
+ ClassLoader clC = assertClassLoader(contextC);
+ assertLoadClass(C.class, clB, clC);
+ assertLoadClass(C.class, clC);
+ assertLoadClass(A.class, clC, clA);
+ }
+ finally
+ {
+ uninstall(contextC);
+ }
+ assertNoClassLoader(contextA);
+ assertNoClassLoader(contextB);
+ assertNoClassLoader(contextC);
+ }
+ finally
+ {
+ uninstall(contextB);
+ }
+ }
+ finally
+ {
+ uninstall(contextA);
+ }
+ assertNoClassLoader(contextA);
+ }
}
Modified: projects/jboss-cl/trunk/pom.xml
===================================================================
--- projects/jboss-cl/trunk/pom.xml 2010-03-08 12:32:07 UTC (rev 102059)
+++ projects/jboss-cl/trunk/pom.xml 2010-03-08 13:07:26 UTC (rev 102060)
@@ -33,7 +33,7 @@
<version.jboss.vfs>3.0.0.CR1</version.jboss.vfs>
<version.jboss.man>2.1.1.SP1</version.jboss.man>
<version.jboss.mdr>2.2.0.Alpha1</version.jboss.mdr>
- <version.jboss.kernel>2.2.0.Alpha6</version.jboss.kernel>
+ <version.jboss.kernel>2.2.0-SNAPSHOT</version.jboss.kernel>
<version.jboss.common.core>2.2.17.GA</version.jboss.common.core>
<version.jboss.logging.spi>2.2.0.CR1</version.jboss.logging.spi>
<version.jboss.classloading.spi>6.0.0-Alpha8</version.jboss.classloading.spi>
More information about the jboss-cvs-commits
mailing list