diff --git a/environments/se/core/src/main/java/org/jboss/weld/environment/se/Weld.java b/environments/se/core/src/main/java/org/jboss/weld/environment/se/Weld.java index d5960d6ed9e..7092c119ae2 100644 --- a/environments/se/core/src/main/java/org/jboss/weld/environment/se/Weld.java +++ b/environments/se/core/src/main/java/org/jboss/weld/environment/se/Weld.java @@ -40,6 +40,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.UUID; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -144,10 +145,10 @@ * *
  * Weld builder = new Weld()
- *    .disableDiscovery()
- *    .packages(Main.class, Utils.class)
- *    .interceptors(TransactionalInterceptor.class)
- *    .property("org.jboss.weld.construction.relaxed", true);
+ *  .disableDiscovery()
+ *  .packages(Main.class, Utils.class)
+ *  .interceptors(TransactionalInterceptor.class)
+ *  .property("org.jboss.weld.construction.relaxed", true);
  * WeldContainer container = builder.initialize();
  * 
* @@ -230,7 +231,7 @@ public class Weld implements ContainerInstanceFactory { private ResourceLoader resourceLoader; public Weld() { - this(RegistrySingletonProvider.STATIC_INSTANCE); + this(null); } /** @@ -370,8 +371,8 @@ public Weld addExtension(Extension extension) { /** * Enable interceptors for the synthetic bean archive, all previous values are removed. *

- * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the - * absence of the beans.xml descriptor. + * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the absence of the + * beans.xml descriptor. * * @param interceptorClasses * @return self @@ -387,8 +388,8 @@ public Weld interceptors(Class... interceptorClasses) { /** * Add an interceptor class to the list of enabled interceptors for the synthetic bean archive. *

- * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the - * absence of the beans.xml descriptor. + * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the absence of the + * beans.xml descriptor. * * @param interceptorClass * @return self @@ -397,11 +398,12 @@ public Weld addInterceptor(Class interceptorClass) { enabledInterceptors.add(syntheticMetadata(interceptorClass)); return this; } + /** * Enable decorators for the synthetic bean archive, all previous values are removed. *

- * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the - * absence of the beans.xml descriptor. + * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the absence of the + * beans.xml descriptor. * * @param decoratorClasses * @return self @@ -417,8 +419,8 @@ public Weld decorators(Class... decoratorClasses) { /** * Add a decorator class to the list of enabled decorators for the synthetic bean archive. *

- * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the - * absence of the beans.xml descriptor. + * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the absence of the + * beans.xml descriptor. * * @param decoratorClass * @return self @@ -431,8 +433,8 @@ public Weld addDecorator(Class decoratorClass) { /** * Select alternatives for the synthetic bean archive, all previous values are removed. *

- * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the - * absence of the beans.xml descriptor. + * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the absence of the + * beans.xml descriptor. * * @param alternativeClasses * @return self @@ -448,8 +450,8 @@ public Weld alternatives(Class... alternativeClasses) { /** * Add an alternative class to the list of selected alternatives for a synthetic bean archive. *

- * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the - * absence of the beans.xml descriptor. + * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the absence of the + * beans.xml descriptor. * * @param alternativeClass * @return self @@ -462,8 +464,8 @@ public Weld addAlternative(Class alternativeClass) { /** * Select alternative stereotypes for the synthetic bean archive, all previous values are removed. *

- * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the - * absence of the beans.xml descriptor. + * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the absence of the + * beans.xml descriptor. * * @param alternativeStereotypeClasses * @return self @@ -480,8 +482,8 @@ public final Weld alternativeStereotypes(Class... alternat /** * Add an alternative stereotype class to the list of selected alternative stereotypes for a synthetic bean archive. *

- * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the - * absence of the beans.xml descriptor. + * This method does not add any class to the set of bean classes for the synthetic bean archive. It's purpose is solely to compensate the absence of the + * beans.xml descriptor. * * @param alternativeStereotypeClass * @return self @@ -533,7 +535,7 @@ public Weld resetAll() { reset(); properties.clear(); enableDiscovery(); - containerId(RegistrySingletonProvider.STATIC_INSTANCE); + containerId(null); return this; } @@ -567,7 +569,7 @@ public boolean isDiscoveryEnabled() { } /** - * Bootstraps a new Weld SE container with the current {@link #containerId}. + * Bootstraps a new Weld SE container with the current container id (generated value if not set through {@link #containerId(String)}). *

* The container must be shut down properly when an application is stopped. Applications are encouraged to use the try-with-resources statement or invoke * {@link WeldContainer#shutdown()} explicitly. @@ -602,38 +604,24 @@ public WeldContainer initialize() { } deployment.getServices().add(ExternalConfiguration.class, configurationBuilder.build()); + final String containerId = this.containerId != null ? this.containerId : UUID.randomUUID().toString(); bootstrap.startContainer(containerId, Environments.SE, deployment); - bootstrap.startInitialization(); - bootstrap.deployBeans(); - bootstrap.validateBeans(); - bootstrap.endInitialization(); - final WeldContainer weldContainer = WeldContainer.initialize(containerId, bootstrap.getManager(getDeterminingBeanDeploymentArchive(deployment)), - bootstrap, isEnabled(SHUTDOWN_HOOK_SYSTEM_PROPERTY, true)); + final WeldContainer weldContainer = WeldContainer.startInitialization(containerId, deployment, bootstrap); - initializedContainers.put(containerId, weldContainer); - return weldContainer; - } - - private BeanDeploymentArchive getDeterminingBeanDeploymentArchive(Deployment deployment) { - Collection beanDeploymentArchives = deployment.getBeanDeploymentArchives(); - if (beanDeploymentArchives.size() == 1) { - // Only one bean archive or isolation is disabled - return beanDeploymentArchives.iterator().next(); + try { + bootstrap.startInitialization(); + bootstrap.deployBeans(); + bootstrap.validateBeans(); + bootstrap.endInitialization(); + WeldContainer.endInitialization(weldContainer, isEnabled(SHUTDOWN_HOOK_SYSTEM_PROPERTY, true)); + initializedContainers.put(containerId, weldContainer); + } catch (Throwable e) { + // Discard the container if a bootstrap problem occurs, e.g. validation error + WeldContainer.discard(weldContainer.getId()); + throw e; } - for (BeanDeploymentArchive beanDeploymentArchive : beanDeploymentArchives) { - if (WeldDeployment.SYNTHETIC_BDA_ID.equals(beanDeploymentArchive.getId())) { - // Synthetic bean archive takes precedence - return beanDeploymentArchive; - } - } - for (BeanDeploymentArchive beanDeploymentArchive : beanDeploymentArchives) { - if (!WeldDeployment.ADDITIONAL_BDA_ID.equals(beanDeploymentArchive.getId())) { - // Get the first non-additional bean deployment archive - return beanDeploymentArchive; - } - } - return deployment.loadBeanDeploymentArchive(WeldContainer.class); + return weldContainer; } /** diff --git a/environments/se/core/src/main/java/org/jboss/weld/environment/se/WeldContainer.java b/environments/se/core/src/main/java/org/jboss/weld/environment/se/WeldContainer.java index 512952f9d3a..a96811e06bb 100644 --- a/environments/se/core/src/main/java/org/jboss/weld/environment/se/WeldContainer.java +++ b/environments/se/core/src/main/java/org/jboss/weld/environment/se/WeldContainer.java @@ -16,6 +16,7 @@ */ package org.jboss.weld.environment.se; +import java.util.Collection; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -26,10 +27,14 @@ import javax.enterprise.inject.spi.BeanManager; import org.jboss.weld.AbstractCDI; +import org.jboss.weld.bean.builtin.BeanManagerProxy; import org.jboss.weld.bootstrap.api.Bootstrap; import org.jboss.weld.bootstrap.api.Singleton; import org.jboss.weld.bootstrap.api.SingletonProvider; +import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive; +import org.jboss.weld.bootstrap.spi.Deployment; import org.jboss.weld.environment.ContainerInstance; +import org.jboss.weld.environment.deployment.WeldDeployment; import org.jboss.weld.environment.se.events.ContainerInitialized; import org.jboss.weld.environment.se.events.ContainerShutdown; import org.jboss.weld.environment.se.logging.WeldSELogger; @@ -37,7 +42,6 @@ import org.jboss.weld.literal.DestroyedLiteral; import org.jboss.weld.literal.InitializedLiteral; import org.jboss.weld.manager.BeanManagerImpl; -import org.jboss.weld.manager.api.WeldManager; import org.jboss.weld.util.collections.ImmutableList; /** @@ -125,21 +129,31 @@ public static List getRunningContainerIds() { } /** + * Start the initialization. * * @param id * @param manager * @param bootstrap * @return the initialized Weld container */ - static WeldContainer initialize(String id, WeldManager manager, Bootstrap bootstrap, boolean isShutdownHookEnabled) { + static WeldContainer startInitialization(String id, Deployment deployment, Bootstrap bootstrap) { if (SINGLETON.isSet(id)) { throw WeldSELogger.LOG.weldContainerAlreadyRunning(id); } - WeldContainer weldContainer = new WeldContainer(id, manager, bootstrap); + WeldContainer weldContainer = new WeldContainer(id, deployment, bootstrap); SINGLETON.set(id, weldContainer); RUNNING_CONTAINER_IDS.add(id); - WeldSELogger.LOG.weldContainerInitialized(id); - manager.fireEvent(new ContainerInitialized(id), InitializedLiteral.APPLICATION); + return weldContainer; + } + + /** + * Finish the initialization. + * + * @param container + * @param isShutdownHookEnabled + */ + static void endInitialization(WeldContainer container, boolean isShutdownHookEnabled) { + container.complete(); // If needed, register one shutdown hook for all containers if (shutdownHook == null && isShutdownHookEnabled) { synchronized (LOCK) { @@ -149,37 +163,51 @@ static WeldContainer initialize(String id, WeldManager manager, Bootstrap bootst } } } - return weldContainer; + } + + /** + * + * @param containerId + */ + static void discard(String containerId) { + SINGLETON.clear(containerId); + RUNNING_CONTAINER_IDS.remove(containerId); } // This replicates org.jboss.weld.Container.contextId private final String id; - private final WeldManager manager; + private final Deployment deployment; private final Bootstrap bootstrap; - private final WeldInstance instance; + private volatile WeldInstance instance; + + private volatile Event event; - private final Event event; + private volatile CreationalContext creationalContext; - private final CreationalContext creationalContext; + private volatile BeanManagerImpl beanManager; /** * * @param id - * @param manager + * @param deployment * @param bootstrap */ - private WeldContainer(String id, WeldManager manager, Bootstrap bootstrap) { + private WeldContainer(String id, Deployment deployment, Bootstrap bootstrap) { super(); this.id = id; - this.manager = manager; + this.deployment = deployment; this.bootstrap = bootstrap; - this.creationalContext = manager.createCreationalContext(null); - BeanManagerImpl beanManagerImpl = ((BeanManagerImpl) manager.unwrap()); - this.instance = beanManagerImpl.getInstance(creationalContext); - this.event = beanManagerImpl.event(); + } + + private void complete() { + this.creationalContext = beanManager().createCreationalContext(null); + this.instance = beanManager().getInstance(creationalContext); + this.event = beanManager().event(); + beanManager().fireEvent(new ContainerInitialized(id), InitializedLiteral.APPLICATION); + WeldSELogger.LOG.weldContainerInitialized(id); } /** @@ -189,7 +217,7 @@ private WeldContainer(String id, WeldManager manager, Bootstrap bootstrap) { */ public Instance instance() { checkState(); - return instance; + return getInstance(); } /** @@ -219,8 +247,8 @@ public String getId() { * Provides direct access to the BeanManager. */ public BeanManager getBeanManager() { - checkState(); - return manager; + checkIsRunning(); + return new BeanManagerProxy(beanManager()); } /** @@ -229,31 +257,24 @@ public BeanManager getBeanManager() { * @see Weld#initialize() */ public synchronized void shutdown() { - if (isRunning()) { - try { - manager.fireEvent(new ContainerShutdown(id), DestroyedLiteral.APPLICATION); - } finally { - SINGLETON.clear(id); - RUNNING_CONTAINER_IDS.remove(id); - // Destroy all the dependent beans correctly - creationalContext.release(); - bootstrap.shutdown(); - WeldSELogger.LOG.weldContainerShutdown(id); - } - } else { - if (WeldSELogger.LOG.isTraceEnabled()) { - WeldSELogger.LOG.tracev("Spurious call to shutdown from: {0}", (Object[]) Thread.currentThread().getStackTrace()); - } - throw WeldSELogger.LOG.weldContainerAlreadyShutDown(id); + checkIsRunning(); + try { + beanManager().fireEvent(new ContainerShutdown(id), DestroyedLiteral.APPLICATION); + } finally { + discard(id); + // Destroy all the dependent beans correctly + creationalContext.release(); + bootstrap.shutdown(); + WeldSELogger.LOG.weldContainerShutdown(id); } } /** * - * @return true if the container was not shut down yet, false otherwise + * @return true if the container was initialized completely and is not shut down yet, false otherwise */ public boolean isRunning() { - return SINGLETON.isSet(id); + return SINGLETON.isSet(id) && instance != null; } @Override @@ -286,9 +307,55 @@ public void run() { @Override protected void checkState() { - if (!isRunning()) { + checkInitializedCompletely(); + checkIsRunning(); + } + + private void checkInitializedCompletely() { + if (instance == null) { + throw WeldSELogger.LOG.weldContainerNotInitializedCompletely(id); + } + } + + private void checkIsRunning() { + if (!SINGLETON.isSet(id)) { + if (WeldSELogger.LOG.isTraceEnabled()) { + WeldSELogger.LOG.tracev("Spurious call to shutdown from: {0}", (Object[]) Thread.currentThread().getStackTrace()); + } throw WeldSELogger.LOG.weldContainerAlreadyShutDown(id); } } + private BeanManagerImpl beanManager() { + if (beanManager == null) { + synchronized (this) { + if (beanManager == null) { + beanManager = BeanManagerProxy.unwrap(bootstrap.getManager(getDeterminingBeanDeploymentArchive(deployment))); + } + } + } + return beanManager; + } + + private BeanDeploymentArchive getDeterminingBeanDeploymentArchive(Deployment deployment) { + Collection beanDeploymentArchives = deployment.getBeanDeploymentArchives(); + if (beanDeploymentArchives.size() == 1) { + // Only one bean archive or isolation is disabled + return beanDeploymentArchives.iterator().next(); + } + for (BeanDeploymentArchive beanDeploymentArchive : beanDeploymentArchives) { + if (WeldDeployment.SYNTHETIC_BDA_ID.equals(beanDeploymentArchive.getId())) { + // Synthetic bean archive takes precedence + return beanDeploymentArchive; + } + } + for (BeanDeploymentArchive beanDeploymentArchive : beanDeploymentArchives) { + if (!WeldDeployment.ADDITIONAL_BDA_ID.equals(beanDeploymentArchive.getId())) { + // Get the first non-additional bean deployment archive + return beanDeploymentArchive; + } + } + return deployment.loadBeanDeploymentArchive(WeldContainer.class); + } + } \ No newline at end of file diff --git a/environments/se/core/src/main/java/org/jboss/weld/environment/se/logging/WeldSELogger.java b/environments/se/core/src/main/java/org/jboss/weld/environment/se/logging/WeldSELogger.java index 52a40552876..7560015022f 100644 --- a/environments/se/core/src/main/java/org/jboss/weld/environment/se/logging/WeldSELogger.java +++ b/environments/se/core/src/main/java/org/jboss/weld/environment/se/logging/WeldSELogger.java @@ -65,4 +65,7 @@ public interface WeldSELogger extends WeldEnvironmentLogger { // 2013 used to warn on deprecated org.jboss.weld.environment.se.contexts.interceptors.ActivateThreadScope + @Message(id = 2014, value = "Weld SE container {0} not initialized completely", format = Format.MESSAGE_FORMAT) + IllegalStateException weldContainerNotInitializedCompletely(Object id); + } diff --git a/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/builder/WeldBuilderTest.java b/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/builder/WeldBuilderTest.java index b231d1c51fd..0598bcf9930 100644 --- a/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/builder/WeldBuilderTest.java +++ b/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/builder/WeldBuilderTest.java @@ -23,14 +23,12 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map.Entry; import javax.enterprise.event.ObserverException; import javax.enterprise.inject.Any; import javax.enterprise.inject.spi.DefinitionException; import org.jboss.weld.Container; -import org.jboss.weld.bootstrap.api.helpers.RegistrySingletonProvider; import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive; import org.jboss.weld.config.ConfigurationKey; import org.jboss.weld.config.WeldConfiguration; @@ -62,13 +60,14 @@ public void testSyntheticBeanArchive() throws Exception { assertNull(WeldContainer.instance("FOO")); // Test alternatives selected for the synthetic BDA try (WeldContainer container = weld.beanClasses(Foo.class, Bar.class, Cat.class).alternatives(Bar.class) - .alternativeStereotypes(AlternativeStereotype.class).initialize()) { + .alternativeStereotypes(AlternativeStereotype.class).initialize()) { assertEquals(10, container.select(Foo.class).get().getVal()); assertEquals(1, container.select(Bar.class).get().getVal()); assertEquals(5, container.select(Cat.class).get().getVal()); } // Test interceptor enabled for the synthetic BDA - try (WeldContainer container = weld.reset().beanClasses(Qux.class, MonitoringInterceptor.class).interceptors(MonitoringInterceptor.class).initialize()) { + try (WeldContainer container = weld.reset().beanClasses(Qux.class, MonitoringInterceptor.class).interceptors(MonitoringInterceptor.class) + .initialize()) { assertEquals(Integer.valueOf(11), container.select(Qux.class).get().ping()); } // Test decorator enabled for the synthetic BDA @@ -111,23 +110,23 @@ public void testMultipleWeldInstancesCreated() { @Test public void testConfigurationProperties() { try (WeldContainer container = new Weld().disableDiscovery().beanClasses(Foo.class).property(ConfigurationKey.CONCURRENT_DEPLOYMENT.get(), false) - .initialize()) { + .initialize()) { assertFalse(container.select(BeanManagerImpl.class).get().getServices().get(WeldConfiguration.class) - .getBooleanProperty(ConfigurationKey.CONCURRENT_DEPLOYMENT)); + .getBooleanProperty(ConfigurationKey.CONCURRENT_DEPLOYMENT)); } } @Test public void testReset() { Weld weld = new Weld().containerId("FOO").disableDiscovery().property(ConfigurationKey.BEAN_IDENTIFIER_INDEX_OPTIMIZATION.get(), true) - .beanClasses(Foo.class); + .beanClasses(Foo.class); weld.reset(); assertFalse(weld.isDiscoveryEnabled()); assertEquals("FOO", weld.getContainerId()); try (WeldContainer container = weld.beanClasses(Bar.class).initialize()) { assertTrue(container.select(Foo.class).isUnsatisfied()); assertTrue(container.select(BeanManagerImpl.class).get().getServices().get(WeldConfiguration.class) - .getBooleanProperty(ConfigurationKey.BEAN_IDENTIFIER_INDEX_OPTIMIZATION)); + .getBooleanProperty(ConfigurationKey.BEAN_IDENTIFIER_INDEX_OPTIMIZATION)); } } @@ -136,12 +135,12 @@ public void testResetAll() { Weld weld = new Weld().containerId("FOO").disableDiscovery().property(ConfigurationKey.RELAXED_CONSTRUCTION.get(), false).beanClasses(Foo.class); weld.resetAll(); assertTrue(weld.isDiscoveryEnabled()); - assertEquals(RegistrySingletonProvider.STATIC_INSTANCE, weld.getContainerId()); + assertNull(weld.getContainerId()); weld.disableDiscovery(); try (WeldContainer container = weld.beanClasses(Bar.class).initialize()) { assertTrue(container.select(Foo.class).isUnsatisfied()); assertTrue(container.select(BeanManagerImpl.class).get().getServices().get(WeldConfiguration.class) - .getBooleanProperty(ConfigurationKey.BEAN_IDENTIFIER_INDEX_OPTIMIZATION)); + .getBooleanProperty(ConfigurationKey.BEAN_IDENTIFIER_INDEX_OPTIMIZATION)); } } @@ -190,11 +189,10 @@ public void testSyntheticBeanArchivePackages() throws Exception { try (WeldContainer container = weld.reset().addPackage(true, Any.class).initialize()) { // There is no managed bean discovered, therefore we only check the the bean class was found boolean found = false; - for (Entry entry : Container.instance().beanDeploymentArchives().entrySet()) { - for (String className : entry.getKey().getBeanClasses()) { - if (className.equals(DefinitionException.class.getName())) { - found = true; - } + for (BeanDeploymentArchive beanDeploymentArchive : Container.instance(container.getId()).beanDeploymentArchives().keySet()) { + if (beanDeploymentArchive.getBeanClasses().contains(DefinitionException.class.getName())) { + found = true; + break; } } assertTrue(found); diff --git a/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/container/provider/TestExtension.java b/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/container/provider/TestExtension.java new file mode 100644 index 00000000000..7e16d847d97 --- /dev/null +++ b/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/container/provider/TestExtension.java @@ -0,0 +1,65 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2016, Red Hat, Inc., and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.weld.environment.se.test.container.provider; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +import java.util.concurrent.atomic.AtomicReference; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.BeforeBeanDiscovery; +import javax.enterprise.inject.spi.CDI; +import javax.enterprise.inject.spi.Extension; + +import org.jboss.weld.environment.se.WeldContainer; + +public class TestExtension implements Extension { + + static AtomicReference beanManagerReference = new AtomicReference(null); + + static AtomicReference> fooBeanReference = new AtomicReference>(null); + + public void beforeBeanDiscovery(@Observes BeforeBeanDiscovery event) { + CDI cdi = CDI.current(); + @SuppressWarnings("resource") + WeldContainer container = (WeldContainer) cdi; + assertFalse(container.isRunning()); + try { + cdi.select(Object.class); + fail(); + } catch (IllegalStateException expected) { + } + beanManagerReference.set(cdi.getBeanManager()); + } + + public void afterBeanDiscovery(@Observes AfterBeanDiscovery event) { + BeanManager beanManager = beanManagerReference.get(); + if (beanManager != null) { + fooBeanReference.set(beanManager.resolve(beanManager.getBeans(Foo.class))); + } + } + + static void reset() { + beanManagerReference.set(null); + fooBeanReference.set(null); + } + +} diff --git a/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/container/provider/WeldSEProviderTest.java b/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/container/provider/WeldSEProviderTest.java index 04777f59023..e2d75fbfaa6 100644 --- a/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/container/provider/WeldSEProviderTest.java +++ b/environments/se/core/src/test/java/org/jboss/weld/environment/se/test/container/provider/WeldSEProviderTest.java @@ -17,8 +17,11 @@ package org.jboss.weld.environment.se.test.container.provider; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.CDI; import org.jboss.weld.environment.se.Weld; @@ -61,6 +64,17 @@ public void testMultipleContainers() { } } + @Test + public void testExtension() { + TestExtension.reset(); + try (WeldContainer weldContainer = new Weld().disableDiscovery().beanClasses(Foo.class).addExtension(new TestExtension()).initialize()) { + BeanManager beanManager = TestExtension.beanManagerReference.get(); + assertNotNull(beanManager); + Bean fooBean = TestExtension.fooBeanReference.get(); + assertNotNull(fooBean); + } + } + private void assertCdi(CDI cdi, String id) { assertTrue(cdi instanceof WeldContainer); assertEquals(id, ((WeldContainer) cdi).getId()); diff --git a/impl/src/main/java/org/jboss/weld/AbstractCDI.java b/impl/src/main/java/org/jboss/weld/AbstractCDI.java index 03b7e77354c..22493876f05 100644 --- a/impl/src/main/java/org/jboss/weld/AbstractCDI.java +++ b/impl/src/main/java/org/jboss/weld/AbstractCDI.java @@ -70,65 +70,57 @@ public WeldInstance apply(BeanManagerImpl beanManager) { @Override public Iterator iterator() { - checkState(); - return getInstance().iterator(); + return instanceInternal().iterator(); } @Override public T get() { - checkState(); - return getInstance().get(); + return instanceInternal().get(); } @Override public WeldInstance select(Annotation... qualifiers) { - checkState(); - return getInstance().select(qualifiers); + return instanceInternal().select(qualifiers); } @Override public WeldInstance select(Class subtype, Annotation... qualifiers) { - checkState(); - return getInstance().select(subtype, qualifiers); + return instanceInternal().select(subtype, qualifiers); } @Override public WeldInstance select(TypeLiteral subtype, Annotation... qualifiers) { - checkState(); - return getInstance().select(subtype, qualifiers); + return instanceInternal().select(subtype, qualifiers); } @Override public boolean isUnsatisfied() { - checkState(); - return getInstance().isUnsatisfied(); + return instanceInternal().isUnsatisfied(); } @Override public boolean isAmbiguous() { - checkState(); - return getInstance().isAmbiguous(); + return instanceInternal().isAmbiguous(); } @Override public void destroy(T instance) { - checkState(); - getInstance().destroy(instance); + instanceInternal().destroy(instance); } @Override public Handler getHandler() { - return getInstance().getHandler(); + return instanceInternal().getHandler(); } @Override public boolean isResolvable() { - return getInstance().isResolvable(); + return instanceInternal().isResolvable(); } @Override public Iterable> handlers() { - return getInstance().handlers(); + return instanceInternal().handlers(); } /** @@ -149,6 +141,11 @@ protected String getCallingClassName() { throw BeanManagerLogger.LOG.unableToIdentifyBeanManager(); } + private WeldInstance instanceInternal() { + checkState(); + return getInstance(); + } + /** * Subclasses are allowed to override the default behavior, i.e. to cache instance per BeanManager. * @@ -159,7 +156,9 @@ protected WeldInstance getInstance() { } /** - * Check whether container is running + * Check whether the container is in a "valid" state, no-op by default. + *

+ * Subclasses are allowed to override the default behavior, i.e. to check whether a container is running. */ protected void checkState(){ //no-op