From 43934cf1f0f9f84be3dd5b9139c0b37f5b091010 Mon Sep 17 00:00:00 2001 From: "Lincoln Baxter, III" Date: Fri, 1 Nov 2013 17:38:29 -0400 Subject: [PATCH] Cleanup ThreadLocals on completion. --- .../forge/furnace/util/SecurityActions.java | 58 ++++++ .../jboss/forge/furnace/impl/FurnaceImpl.java | 13 +- .../impl/addons/AddonLifecycleManager.java | 28 ++- .../furnace/impl/addons/AddonLoader.java | 11 +- .../impl/addons/AddonRegistryImpl.java | 11 +- .../furnace/impl/addons/AddonRunnable.java | 14 +- .../impl/addons/AddonStateManager.java | 10 +- .../impl/modules/AddonModuleFileCache.java | 11 +- .../modules/AddonModuleIdentifierCache.java | 7 +- .../impl/modules/AddonModuleLoader.java | 16 +- .../jboss/forge/furnace/proxy/Proxies.java | 26 ++- .../arquillian/ForgeDeployableContainer.java | 21 +- .../test/impl/TestContextHandler.java | 86 --------- .../ForgeDeploymentScenarioGenerator.java | 7 +- .../arquillian/maven/PlexusContainer.java | 9 + .../forge/arquillian/maven/ProjectHelper.java | 179 +++++++++--------- 16 files changed, 287 insertions(+), 220 deletions(-) delete mode 100644 test-harness/arquillian/core/src/main/java/org/jboss/arquillian/test/impl/TestContextHandler.java diff --git a/container-api/src/main/java/org/jboss/forge/furnace/util/SecurityActions.java b/container-api/src/main/java/org/jboss/forge/furnace/util/SecurityActions.java index e13eb845..56692c50 100644 --- a/container-api/src/main/java/org/jboss/forge/furnace/util/SecurityActions.java +++ b/container-api/src/main/java/org/jboss/forge/furnace/util/SecurityActions.java @@ -22,11 +22,18 @@ package org.jboss.forge.furnace.util; +import java.lang.ref.Reference; +import java.lang.reflect.Array; +import java.lang.reflect.Field; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.logging.Level; +import java.util.logging.Logger; public final class SecurityActions { + private static final Logger log = Logger.getLogger(SecurityActions.class.getName()); + private SecurityActions() { // forbidden inheritance @@ -81,4 +88,55 @@ public Object run() } } + /** + * Cleanup {@link ThreadLocal} instances of the given {@link Thread}. + * + * @param thread The {@link Thread} to clean up. + */ + public static void cleanupThreadLocals(Thread thread) + { + try + { + cleanField(thread, Thread.class.getDeclaredField("threadLocals")); + cleanField(thread, Thread.class.getDeclaredField("inheritableThreadLocals")); + } + catch (Exception e) + { + log.log(Level.WARNING, "Failed to cleanup ThreadLocal instances for Thread [" + thread + "]", e); + } + } + + private static void cleanField(Thread thread, Field threadLocalsField) throws IllegalAccessException, + ClassNotFoundException, NoSuchFieldException + { + threadLocalsField.setAccessible(true); + Object threadLocalTable = threadLocalsField.get(thread); + + // Get a reference to the array holding the thread local variables inside the + // ThreadLocalMap of the current thread + Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); + Field tableField = threadLocalMapClass.getDeclaredField("table"); + tableField.setAccessible(true); + Object table = tableField.get(threadLocalTable); + + // The key to the ThreadLocalMap is a WeakReference object. The referent field of this object + // is a reference to the actual ThreadLocal variable + Field referentField = Reference.class.getDeclaredField("referent"); + referentField.setAccessible(true); + + for (int i = 0; i < Array.getLength(table); i++) + { + // Each entry in the table array of ThreadLocalMap is an Entry object + // representing the thread local reference and its value + Object entry = Array.get(table, i); + if (entry != null) + { + // Get a reference to the thread local object and remove it from the table + ThreadLocal threadLocal = (ThreadLocal) referentField.get(entry); + if (threadLocal != null) + threadLocal.remove(); + } + } + } + } diff --git a/container/src/main/java/org/jboss/forge/furnace/impl/FurnaceImpl.java b/container/src/main/java/org/jboss/forge/furnace/impl/FurnaceImpl.java index 98205021..061ae12f 100644 --- a/container/src/main/java/org/jboss/forge/furnace/impl/FurnaceImpl.java +++ b/container/src/main/java/org/jboss/forge/furnace/impl/FurnaceImpl.java @@ -190,11 +190,22 @@ public Furnace start(ClassLoader loader) } fireAfterContainerStoppedEvent(); + cleanup(); + return this; + } + + private void cleanup() + { for (ListenerRegistration registation : loadedListenerRegistrations) { registation.removeListener(); } - return this; + registeredListeners.clear(); + lastRepoVersionSeen.clear(); + loader = null; + manager.dispose(); + manager = null; + repositories.clear(); } private void fireBeforeConfigurationScanEvent() diff --git a/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonLifecycleManager.java b/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonLifecycleManager.java index 1ae4aeba..a299731e 100644 --- a/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonLifecycleManager.java +++ b/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonLifecycleManager.java @@ -48,16 +48,16 @@ public class AddonLifecycleManager private static final Logger logger = Logger.getLogger(AddonLifecycleManager.class.getName()); private final LockManager lock; - private FurnaceImpl furnace; - private AddonLoader loader; - private AddonStateManager stateManager; + private final FurnaceImpl furnace; + private final AddonLoader loader; + private final AddonStateManager stateManager; - private Set addons = Sets.getConcurrentSet(); + private final Set addons = Sets.getConcurrentSet(); private final Map views = new ConcurrentHashMap(); private final AtomicInteger starting = new AtomicInteger(-1); private final ExecutorService executor = Executors.newCachedThreadPool(); - private AddonModuleLoader moduleLoader; + private final AddonModuleLoader moduleLoader; public AddonLifecycleManager(FurnaceImpl furnace) { @@ -73,6 +73,18 @@ public AddonLifecycleManager(FurnaceImpl furnace) logger.log(Level.FINE, "Instantiated AddonRTegistryImpl: " + this); } + public void dispose() + { + for (AddonView view : views.keySet()) + { + view.dispose(); + } + this.views.clear(); + this.stateManager.dispose(); + this.loader.dispose(); + this.moduleLoader.dispose(); + } + public long getVersion(AddonView view) { Long version = views.get(view); @@ -266,11 +278,6 @@ public boolean isStartingAddons() return starting.get() > 0; } - public void dispose(AddonView view) - { - furnace.disposeAddonView(view); - } - public void startAddon(Addon addon) { Assert.notNull(addon, "Addon to start must not be null."); @@ -317,6 +324,7 @@ public void removeView(AddonView view) { if (!views.keySet().contains(view)) throw new IllegalArgumentException("The given view does not belong to this Furnace instance."); + views.remove(view); } @Override diff --git a/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonLoader.java b/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonLoader.java index 537db1a2..51e4d821 100644 --- a/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonLoader.java +++ b/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonLoader.java @@ -27,7 +27,8 @@ public class AddonLoader private AddonStateManager stateManager; private AddonModuleLoader loader; - public AddonLoader(Furnace furnace, AddonLifecycleManager lifecycleManager, AddonStateManager stateManager, AddonModuleLoader loader) + public AddonLoader(Furnace furnace, AddonLifecycleManager lifecycleManager, AddonStateManager stateManager, + AddonModuleLoader loader) { this.lock = furnace.getLockManager(); this.lifecycleManager = lifecycleManager; @@ -35,6 +36,14 @@ public AddonLoader(Furnace furnace, AddonLifecycleManager lifecycleManager, Addo this.loader = loader; } + public void dispose() + { + this.lock = null; + this.lifecycleManager = null; + this.stateManager = null; + this.loader = null; + } + public void loadAddon(Addon addon) { Assert.notNull(addon, "Addon to load must not be null."); diff --git a/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonRegistryImpl.java b/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonRegistryImpl.java index 33c41cba..759aee76 100644 --- a/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonRegistryImpl.java +++ b/container/src/main/java/org/jboss/forge/furnace/impl/addons/AddonRegistryImpl.java @@ -36,12 +36,10 @@ public class AddonRegistryImpl implements AddonRegistry { private static final Logger logger = Logger.getLogger(AddonRegistryImpl.class.getName()); - private final LockManager lock; + private LockManager lock; private List repositories; - private AddonLifecycleManager manager; - - private String name; + private final String name; public AddonRegistryImpl(LockManager lock, AddonLifecycleManager manager, List repositories, String name) @@ -62,7 +60,10 @@ public AddonRegistryImpl(LockManager lock, AddonLifecycleManager manager, List states = new HashMap(); + private final Map states = new HashMap(); private AddonModuleLoader loader; public AddonStateManager(LockManager lock) @@ -33,6 +33,14 @@ public AddonStateManager(LockManager lock) this.lock = lock; } + public void dispose() + { + this.lock = null; + this.graph = null; + this.states.clear(); + this.loader = null; + } + public void setModuleLoader(AddonModuleLoader loader) { this.loader = loader; diff --git a/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleFileCache.java b/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleFileCache.java index e956155b..062e93c9 100644 --- a/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleFileCache.java +++ b/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleFileCache.java @@ -24,7 +24,7 @@ class AddonModuleJarFileCache { private static final Logger logger = Logger.getLogger(AddonModuleJarFileCache.class.getName()); - private Map> map = new ConcurrentHashMap>(); + private final Map> map = new ConcurrentHashMap>(); public void closeJarFileReferences(ModuleIdentifier id) { @@ -64,4 +64,13 @@ public void addJarFileReference(ModuleIdentifier id, JarFile file) files.add(file); } + public void dispose() + { + for (ModuleIdentifier id : map.keySet()) + { + closeJarFileReferences(id); + } + map.clear(); + } + } diff --git a/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleIdentifierCache.java b/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleIdentifierCache.java index a501611a..b918f456 100644 --- a/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleIdentifierCache.java +++ b/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleIdentifierCache.java @@ -22,13 +22,18 @@ */ class AddonModuleIdentifierCache { - private Map map = new HashMap(); + private final Map map = new HashMap(); public void clear(Addon addon) { map.remove(addon); } + public void dispose() + { + map.clear(); + } + public ModuleIdentifier getModuleId(Addon addon) { if (!map.containsKey(addon)) diff --git a/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleLoader.java b/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleLoader.java index ba31a7e0..ce9fd199 100644 --- a/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleLoader.java +++ b/container/src/main/java/org/jboss/forge/furnace/impl/modules/AddonModuleLoader.java @@ -53,13 +53,13 @@ public class AddonModuleLoader extends ModuleLoader private Iterable moduleProviders; - private AddonModuleIdentifierCache moduleCache; - private AddonModuleJarFileCache moduleJarFileCache; + private final AddonModuleIdentifierCache moduleCache; + private final AddonModuleJarFileCache moduleJarFileCache; private AddonLifecycleManager lifecycleManager; private AddonStateManager stateManager; - private ThreadLocal currentAddon = new ThreadLocal(); + private final ThreadLocal currentAddon = new ThreadLocal(); private Furnace furnace; @@ -73,6 +73,16 @@ public AddonModuleLoader(Furnace furnace, AddonLifecycleManager lifecycleManager installModuleMBeanServer(); } + public void dispose() + { + this.furnace = null; + this.lifecycleManager = null; + this.stateManager = null; + this.moduleCache.dispose(); + this.moduleJarFileCache.dispose(); + this.moduleProviders = null; + } + /** * Loads a module for the given Addon. */ diff --git a/proxy/src/main/java/org/jboss/forge/furnace/proxy/Proxies.java b/proxy/src/main/java/org/jboss/forge/furnace/proxy/Proxies.java index 8882b823..e0f7676f 100644 --- a/proxy/src/main/java/org/jboss/forge/furnace/proxy/Proxies.java +++ b/proxy/src/main/java/org/jboss/forge/furnace/proxy/Proxies.java @@ -6,10 +6,11 @@ */ package org.jboss.forge.furnace.proxy; +import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.util.Collection; import java.util.Map; -import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; import javassist.util.proxy.MethodFilter; import javassist.util.proxy.Proxy; @@ -21,7 +22,7 @@ */ public class Proxies { - private static Map> cache = new WeakHashMap>(); + private static Map>> cache = new ConcurrentHashMap>>(); private static MethodFilter filter = new MethodFilter() { @@ -49,7 +50,14 @@ public static T enhance(final ClassLoader loader, Object instance, ForgeProx Class type = Proxies.unwrapProxyTypes(instance.getClass(), loader); Object result = null; - Class proxyType = cache.get(type.hashCode()); + Class proxyType = null; + + WeakReference> ref = cache.get(type.hashCode()); + if (ref != null) + { + proxyType = ref.get(); + } + if (proxyType == null) { Class[] hierarchy = null; @@ -93,7 +101,7 @@ protected ClassLoader getClassLoader() proxyType = f.createClass(); - cache.put(type.hashCode(), proxyType); + cache.put(type.hashCode(), new WeakReference>(proxyType)); } try @@ -130,8 +138,14 @@ else if (result instanceof ProxyObject) public static T enhance(Class type, ForgeProxy handler) { Object result = null; + Class proxyType = null; + + WeakReference> ref = cache.get(type.hashCode()); + if (ref != null) + { + proxyType = ref.get(); + } - Class proxyType = cache.get(type.hashCode()); if (proxyType == null) { Class[] hierarchy = null; @@ -160,7 +174,7 @@ else if (type.isInterface()) proxyType = f.createClass(); - cache.put(type.hashCode(), proxyType); + cache.put(type.hashCode(), new WeakReference>(proxyType)); } try diff --git a/test-harness/arquillian/classpath/src/main/java/org/jboss/forge/arquillian/ForgeDeployableContainer.java b/test-harness/arquillian/classpath/src/main/java/org/jboss/forge/arquillian/ForgeDeployableContainer.java index 643858d8..6b2da210 100644 --- a/test-harness/arquillian/classpath/src/main/java/org/jboss/forge/arquillian/ForgeDeployableContainer.java +++ b/test-harness/arquillian/classpath/src/main/java/org/jboss/forge/arquillian/ForgeDeployableContainer.java @@ -49,6 +49,7 @@ import org.jboss.forge.furnace.util.Callables; import org.jboss.forge.furnace.util.ClassLoaders; import org.jboss.forge.furnace.util.OperatingSystemUtils; +import org.jboss.forge.furnace.util.SecurityActions; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.descriptor.api.Descriptor; @@ -60,14 +61,14 @@ public class ForgeDeployableContainer implements DeployableContainer deploymentInstance; - private FurnaceHolder furnaceHolder = new FurnaceHolder(); + private final FurnaceHolder furnaceHolder = new FurnaceHolder(); private ForgeRunnable runnable; private File addonDir; private MutableAddonRepository repository; - private Map deploymentRepositories = new ConcurrentHashMap(); + private final Map deploymentRepositories = new ConcurrentHashMap(); - private Map deployedAddons = new HashMap(); + private final Map deployedAddons = new HashMap(); private Thread thread; private boolean undeploying = false; @@ -215,7 +216,6 @@ private void cleanup() { try { - deploymentRepositories.clear(); stop(); start(); } @@ -318,7 +318,12 @@ public void stop() throws LifecycleException private void stopContainer() { + + this.repository = null; + this.deployedAddons.clear(); + this.deploymentRepositories.clear(); this.runnable.stop(); + this.thread = null; } @Override @@ -354,8 +359,8 @@ public void undeploy(Descriptor descriptor) throws DeploymentException private class ForgeRunnable implements Runnable { - private Furnace furnace; - private ClassLoader loader; + private final Furnace furnace; + private final ClassLoader loader; public ForgeRunnable(ClassLoader loader) { @@ -380,7 +385,9 @@ public Object call() throws Exception { furnace.setServerMode(true); furnace.start(loader); - return furnace; + + SecurityActions.cleanupThreadLocals(thread); + return null; } }); } diff --git a/test-harness/arquillian/core/src/main/java/org/jboss/arquillian/test/impl/TestContextHandler.java b/test-harness/arquillian/core/src/main/java/org/jboss/arquillian/test/impl/TestContextHandler.java deleted file mode 100644 index ea7a9ae0..00000000 --- a/test-harness/arquillian/core/src/main/java/org/jboss/arquillian/test/impl/TestContextHandler.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.jboss.arquillian.test.impl; - -import org.jboss.arquillian.core.api.Instance; -import org.jboss.arquillian.core.api.InstanceProducer; -import org.jboss.arquillian.core.api.annotation.Inject; -import org.jboss.arquillian.core.api.annotation.Observes; -import org.jboss.arquillian.core.spi.EventContext; -import org.jboss.arquillian.test.spi.TestClass; -import org.jboss.arquillian.test.spi.annotation.ClassScoped; -import org.jboss.arquillian.test.spi.context.ClassContext; -import org.jboss.arquillian.test.spi.context.SuiteContext; -import org.jboss.arquillian.test.spi.context.TestContext; -import org.jboss.arquillian.test.spi.event.suite.After; -import org.jboss.arquillian.test.spi.event.suite.AfterClass; -import org.jboss.arquillian.test.spi.event.suite.ClassEvent; -import org.jboss.arquillian.test.spi.event.suite.SuiteEvent; -import org.jboss.arquillian.test.spi.event.suite.TestEvent; - -/** - * TestContextHandler - * - * @author Aslak Knutsen - * @version $Revision: $ - */ -public class TestContextHandler -{ - @Inject - private Instance suiteContextInstance; - - @Inject - private Instance classContextInstance; - - @Inject - private Instance testContextInstance; - - @Inject - @ClassScoped - private InstanceProducer testClassProducer; - - public void createSuiteContext(@Observes(precedence = 100) EventContext context) - { - SuiteContext suiteContext = this.suiteContextInstance.get(); - try - { - suiteContext.activate(); - context.proceed(); - } - finally - { - suiteContext.deactivate(); - } - } - - public void createClassContext(@Observes(precedence = 100) EventContext context) - { - ClassContext classContext = this.classContextInstance.get(); - try - { - classContext.activate(context.getEvent().getTestClass().getJavaClass()); - testClassProducer.set(context.getEvent().getTestClass()); - context.proceed(); - } - finally - { - classContext.deactivate(); - if (AfterClass.class.isAssignableFrom(context.getEvent().getClass())) - classContext.destroy(context.getEvent().getTestClass().getJavaClass()); - } - } - - public void createTestContext(@Observes(precedence = 100) EventContext context) - { - TestContext testContext = this.testContextInstance.get(); - try - { - testContext.activate(context.getEvent().getTestInstance()); - context.proceed(); - } - finally - { - testContext.deactivate(); - if (After.class.isAssignableFrom(context.getEvent().getClass())) - testContext.destroy(context.getEvent().getTestInstance()); - } - } -} diff --git a/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/ForgeDeploymentScenarioGenerator.java b/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/ForgeDeploymentScenarioGenerator.java index 3c1622f9..eeb76566 100644 --- a/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/ForgeDeploymentScenarioGenerator.java +++ b/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/ForgeDeploymentScenarioGenerator.java @@ -34,12 +34,6 @@ public class ForgeDeploymentScenarioGenerator implements DeploymentScenarioGener { Map dependencyMap; - ProjectHelper projectHelper; - - public ForgeDeploymentScenarioGenerator() { - this.projectHelper = new ProjectHelper(); - } - @Override public List generate(TestClass testClass) { @@ -105,6 +99,7 @@ private Collection generateDependencyDeployments(Class */ private String resolveVersionFromPOM(Class classUnderTest, String name) { + ProjectHelper projectHelper = new ProjectHelper(); if (dependencyMap == null) { dependencyMap = new HashMap(); diff --git a/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/maven/PlexusContainer.java b/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/maven/PlexusContainer.java index 45550103..8e6e5237 100644 --- a/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/maven/PlexusContainer.java +++ b/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/maven/PlexusContainer.java @@ -40,6 +40,15 @@ public T call() throws Exception } } + public void shutdown() + { + if (plexusContainer != null) + { + plexusContainer.dispose(); + plexusContainer = null; + } + } + private org.codehaus.plexus.PlexusContainer getPlexusContainer() throws Exception { if (plexusContainer == null) diff --git a/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/maven/ProjectHelper.java b/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/maven/ProjectHelper.java index c3d76730..4aca2002 100644 --- a/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/maven/ProjectHelper.java +++ b/test-harness/arquillian/core/src/main/java/org/jboss/forge/arquillian/maven/ProjectHelper.java @@ -41,14 +41,12 @@ public class ProjectHelper { - private MavenContainer mavenContainer; - private PlexusContainer plexus; - private ProjectBuildingRequest projectBuildingRequest; + private final MavenContainer mavenContainer; + private ProjectBuildingRequest request; public ProjectHelper() { this.mavenContainer = new MavenContainer(); - this.plexus = new PlexusContainer(); } public Model loadPomFromFile(File pomFile, String... profiles) @@ -88,108 +86,117 @@ public Model loadPomFromFile(File pomFile, String... profiles) public List resolveDependenciesFromPOM(File pomFile) throws Exception { - ProjectBuildingRequest request = getBuildingRequest(); - request.setResolveDependencies(true); - ProjectBuilder builder = plexus.lookup(ProjectBuilder.class); - ProjectBuildingResult build = builder.build(pomFile, request); - return build.getDependencyResolutionResult().getDependencies(); + PlexusContainer plexus = new PlexusContainer(); + List result; + try + { + ProjectBuildingRequest request = getBuildingRequest(plexus); + request.setResolveDependencies(true); + ProjectBuilder builder = plexus.lookup(ProjectBuilder.class); + ProjectBuildingResult build = builder.build(pomFile, request); + result = build.getDependencyResolutionResult().getDependencies(); + } + finally + { + plexus.shutdown(); + } + return result; } - private ProjectBuildingRequest getBuildingRequest() + private ProjectBuildingRequest getBuildingRequest(PlexusContainer plexus) { - if (projectBuildingRequest != null) - { - return projectBuildingRequest; - } - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - try + if (this.request == null) { - Settings settings = mavenContainer.getSettings(); - // TODO this needs to be configurable via .forge - // TODO this reference to the M2_REPO should probably be centralized - MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest(); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + try + { + Settings settings = mavenContainer.getSettings(); + // TODO this needs to be configurable via .forge + // TODO this reference to the M2_REPO should probably be centralized + MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest(); - RepositorySystem repositorySystem = plexus.lookup(RepositorySystem.class); - MavenExecutionRequestPopulator requestPopulator = plexus.lookup(MavenExecutionRequestPopulator.class); + RepositorySystem repositorySystem = plexus.lookup(RepositorySystem.class); + MavenExecutionRequestPopulator requestPopulator = plexus.lookup(MavenExecutionRequestPopulator.class); - requestPopulator.populateFromSettings(executionRequest, settings); - requestPopulator.populateDefaults(executionRequest); + requestPopulator.populateFromSettings(executionRequest, settings); + requestPopulator.populateDefaults(executionRequest); - ProjectBuildingRequest request = executionRequest.getProjectBuildingRequest(); + ProjectBuildingRequest request = executionRequest.getProjectBuildingRequest(); - org.apache.maven.artifact.repository.ArtifactRepository localRepository = RepositoryUtils - .toArtifactRepository("local", - new File(settings.getLocalRepository()).toURI().toURL().toString(), null, true, true); - request.setLocalRepository(localRepository); + org.apache.maven.artifact.repository.ArtifactRepository localRepository = RepositoryUtils + .toArtifactRepository("local", + new File(settings.getLocalRepository()).toURI().toURL().toString(), null, true, true); + request.setLocalRepository(localRepository); - List settingsRepos = new ArrayList( - request.getRemoteRepositories()); - List activeProfiles = settings.getActiveProfiles(); + List settingsRepos = new ArrayList( + request.getRemoteRepositories()); + List activeProfiles = settings.getActiveProfiles(); - Map profiles = settings.getProfilesAsMap(); + Map profiles = settings.getProfilesAsMap(); - for (String id : activeProfiles) - { - Profile profile = profiles.get(id); - if (profile != null) + for (String id : activeProfiles) { - List repositories = profile.getRepositories(); - for (Repository repository : repositories) + Profile profile = profiles.get(id); + if (profile != null) { - settingsRepos.add(RepositoryUtils.convertFromMavenSettingsRepository(repository)); + List repositories = profile.getRepositories(); + for (Repository repository : repositories) + { + settingsRepos.add(RepositoryUtils.convertFromMavenSettingsRepository(repository)); + } } } - } - request.setRemoteRepositories(settingsRepos); - request.setSystemProperties(System.getProperties()); + request.setRemoteRepositories(settingsRepos); + request.setSystemProperties(System.getProperties()); - DefaultRepositorySystemSession repositorySession = MavenRepositorySystemUtils.newSession(); - Proxy activeProxy = settings.getActiveProxy(); - if (activeProxy != null) - { - DefaultProxySelector dps = new DefaultProxySelector(); - dps.add(RepositoryUtils.convertFromMavenProxy(activeProxy), activeProxy.getNonProxyHosts()); - repositorySession.setProxySelector(dps); - } - LocalRepository localRepo = new LocalRepository(settings.getLocalRepository()); + DefaultRepositorySystemSession repositorySession = MavenRepositorySystemUtils.newSession(); + Proxy activeProxy = settings.getActiveProxy(); + if (activeProxy != null) + { + DefaultProxySelector dps = new DefaultProxySelector(); + dps.add(RepositoryUtils.convertFromMavenProxy(activeProxy), activeProxy.getNonProxyHosts()); + repositorySession.setProxySelector(dps); + } + LocalRepository localRepo = new LocalRepository(settings.getLocalRepository()); - repositorySession.setLocalRepositoryManager(repositorySystem.newLocalRepositoryManager(repositorySession, - localRepo)); - repositorySession.setOffline(settings.isOffline()); - List mirrors = executionRequest.getMirrors(); - if (mirrors != null) - { - DefaultMirrorSelector mirrorSelector = new DefaultMirrorSelector(); - for (Mirror mirror : mirrors) + repositorySession.setLocalRepositoryManager(repositorySystem.newLocalRepositoryManager(repositorySession, + localRepo)); + repositorySession.setOffline(settings.isOffline()); + List mirrors = executionRequest.getMirrors(); + if (mirrors != null) { - mirrorSelector.add(mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, mirror.getMirrorOf(), - mirror.getMirrorOfLayouts()); + DefaultMirrorSelector mirrorSelector = new DefaultMirrorSelector(); + for (Mirror mirror : mirrors) + { + mirrorSelector.add(mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, mirror.getMirrorOf(), + mirror.getMirrorOfLayouts()); + } + repositorySession.setMirrorSelector(mirrorSelector); } - repositorySession.setMirrorSelector(mirrorSelector); - } - request.setRepositorySession(repositorySession); - request.setProcessPlugins(false); - request.setResolveDependencies(false); - projectBuildingRequest = request; - return projectBuildingRequest; - } - catch (RuntimeException e) - { - throw e; - } - catch (Exception e) - { - throw new RuntimeException( - "Could not create Maven project building request", e); - } - finally - { - /* - * We reset the classloader to prevent potential modules bugs if Classwords container changes classloaders on - * us - */ - Thread.currentThread().setContextClassLoader(cl); + request.setRepositorySession(repositorySession); + request.setProcessPlugins(false); + request.setResolveDependencies(false); + this.request = request; + } + catch (RuntimeException e) + { + throw e; + } + catch (Exception e) + { + throw new RuntimeException( + "Could not create Maven project building request", e); + } + finally + { + /* + * We reset the classloader to prevent potential modules bugs if Classwords container changes classloaders + * on us + */ + Thread.currentThread().setContextClassLoader(cl); + } } + return request; } }