Skip to content

Commit

Permalink
WELD-2393 Fix event firing ordering for ProcessInjectionTarget, Proce…
Browse files Browse the repository at this point in the history
…ssProducer and ProcessBeanAttributes. Added a tests for this.
  • Loading branch information
manovotn authored and mkouba committed Jun 8, 2017
1 parent 17b6bf8 commit c528f3c
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 22 deletions.
Expand Up @@ -97,7 +97,7 @@ protected BeanManagerImpl getManager() {
}

// interceptors, decorators and observers go first
public AbstractBeanDeployer<E> deploySpecialized() {
protected AbstractBeanDeployer<E> deploySpecialized() {
// ensure that all decorators are initialized before initializing
// the rest of the beans
for (DecoratorImpl<?> bean : getEnvironment().getDecorators()) {
Expand All @@ -115,37 +115,50 @@ public AbstractBeanDeployer<E> deploySpecialized() {
return this;
}

public AbstractBeanDeployer<E> initializeBeans() {
protected AbstractBeanDeployer<E> initializeBeans() {
for (RIBean<?> bean : getEnvironment().getBeans()) {
bean.initialize(getEnvironment());
}
return this;
}

public AbstractBeanDeployer<E> fireBeanEvents() {
protected AbstractBeanDeployer<E> fireProcessBeanEvents() {
for (RIBean<?> bean : getEnvironment().getBeans()) {
fireBeanEvents(bean);
if (!(bean instanceof NewBean)) {
containerLifecycleEvents.fireProcessBean(getManager(), bean);
}
}
return this;
}

public void fireBeanEvents(RIBean<?> bean) {
if (!(bean instanceof NewBean)) {
if (bean instanceof AbstractProducerBean<?, ?, ?>) {
containerLifecycleEvents.fireProcessProducer(manager, Reflections.<AbstractProducerBean<?, ?, Member>>cast(bean));
} else if (bean instanceof AbstractClassBean<?>) {
containerLifecycleEvents.fireProcessInjectionTarget(manager, (AbstractClassBean<?>) bean);
protected void processInjectionTargetEvents(Iterable<? extends AbstractBean<?, ?>> beans) {
if (!containerLifecycleEvents.isProcessInjectionTargetObserved()) {
return;
}
for (AbstractBean<?, ?> bean : beans) {
if (!(bean instanceof NewBean) && bean instanceof AbstractClassBean<?>) {
containerLifecycleEvents.fireProcessInjectionTarget(getManager(), (AbstractClassBean<?>) bean);
}
}
}

protected void processProducerEvents(Iterable<? extends AbstractBean<?, ?>> beans) {
if (!containerLifecycleEvents.isProcessProducerObserved()) {
return;
}
for (AbstractBean<?, ?> bean : beans) {
if (!(bean instanceof NewBean) && bean instanceof AbstractProducerBean<?, ?, ?>) {
containerLifecycleEvents.fireProcessProducer(getManager(), Reflections.<AbstractProducerBean<?, ?, Member>>cast(bean));
}
containerLifecycleEvents.fireProcessBean(getManager(), bean);
}
}

public AbstractBeanDeployer<E> deployBeans() {
protected AbstractBeanDeployer<E> deployBeans() {
manager.addBeans(getEnvironment().getBeans());
return this;
}

public AbstractBeanDeployer<E> initializeObserverMethods() {
protected AbstractBeanDeployer<E> initializeObserverMethods() {
for (ObserverInitializationContext<?, ?> observerInitializer : getEnvironment().getObservers()) {
if (Observers.isObserverMethodEnabled(observerInitializer.getObserver(), manager)) {
observerInitializer.initialize();
Expand All @@ -154,7 +167,7 @@ public AbstractBeanDeployer<E> initializeObserverMethods() {
return this;
}

public AbstractBeanDeployer<E> deployObserverMethods() {
protected AbstractBeanDeployer<E> deployObserverMethods() {
for (ObserverInitializationContext<?, ?> observerInitializer : getEnvironment().getObservers()) {
if (Observers.isObserverMethodEnabled(observerInitializer.getObserver(), manager)) {
BootstrapLogger.LOG.foundObserverMethod(observerInitializer.getObserver());
Expand Down Expand Up @@ -295,7 +308,7 @@ public void addBuiltInBean(AbstractBuiltInBean<?> bean) {
getEnvironment().addBuiltInBean(bean);
}

public void addExtension(ExtensionBean bean) {
protected void addExtension(ExtensionBean bean) {
getEnvironment().addExtension(bean);
}

Expand Down
22 changes: 15 additions & 7 deletions impl/src/main/java/org/jboss/weld/bootstrap/BeanDeployer.java
Expand Up @@ -241,9 +241,9 @@ public void processClassBeanAttributes() {
preInitializeBeans(getEnvironment().getDecorators());
preInitializeBeans(getEnvironment().getInterceptors());

processBeanAttributes(getEnvironment().getClassBeans());
processBeanAttributes(getEnvironment().getDecorators());
processBeanAttributes(getEnvironment().getInterceptors());
processBeans(getEnvironment().getClassBeans());
processBeans(getEnvironment().getDecorators());
processBeans(getEnvironment().getInterceptors());

// now that we know that the bean won't be vetoed, it's the right time to register @New injection points
searchForNewBeanDeclarations(getEnvironment().getClassBeans());
Expand All @@ -257,6 +257,14 @@ private void preInitializeBeans(Iterable<? extends AbstractBean<?, ?>> beans) {
}
}

protected void processBeans(Iterable<? extends AbstractBean<?, ?>> beans) {
// firstly, we handle PIT and PP
processInjectionTargetEvents(beans);
processProducerEvents(beans);
// now we move onto PBA
processBeanAttributes(beans);
}

protected void processBeanAttributes(Iterable<? extends AbstractBean<?, ?>> beans) {
if (!containerLifecycleEvents.isProcessBeanAttributesObserved()) {
return;
Expand Down Expand Up @@ -284,7 +292,7 @@ protected void processBeanAttributes(Iterable<? extends AbstractBean<?, ?>> bean
getEnvironment().vetoBean(bean);
}
// if a specializing bean was vetoed, let's process the specializing bean now
processBeanAttributes(previouslySpecializedBeans);
processBeans(previouslySpecializedBeans);
}

protected void searchForNewBeanDeclarations(Iterable<? extends AbstractBean<?, ?>> beans) {
Expand All @@ -300,11 +308,11 @@ public void createProducersAndObservers() {
}

public void processProducerAttributes() {
processBeanAttributes(getEnvironment().getProducerFields());
processBeans(getEnvironment().getProducerFields());
searchForNewBeanDeclarations(getEnvironment().getProducerFields());
// process BeanAttributes for producer methods
preInitializeBeans(getEnvironment().getProducerMethodBeans());
processBeanAttributes(getEnvironment().getProducerMethodBeans());
processBeans(getEnvironment().getProducerMethodBeans());
searchForNewBeanDeclarations(getEnvironment().getProducerMethodBeans());
}

Expand All @@ -320,7 +328,7 @@ public void createNewBeans() {

public void deploy() {
initializeBeans();
fireBeanEvents();
fireProcessBeanEvents();
deployBeans();
initializeObserverMethods();
deployObserverMethods();
Expand Down
@@ -0,0 +1,35 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2017, 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.tests.event.lifecycle.ordering;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

/**
*
* @author <a href="mailto:manovotn@redhat.com">Matej Novotny</a>
*/
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER })
public @interface HastilyWritten {

}
@@ -0,0 +1,31 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2017, 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.tests.event.lifecycle.ordering;

import javax.enterprise.inject.Vetoed;

/**
*
* @author <a href="mailto:manovotn@redhat.com">Matej Novotny</a>
*/
@Vetoed
public class HighQualityAndLowCostProduct {

public void operateUntilWarrantyVoids() {

}
}
@@ -0,0 +1,75 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2017, 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.tests.event.lifecycle.ordering;

import java.util.List;

import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessBeanAttributes;
import javax.enterprise.inject.spi.ProcessInjectionPoint;
import javax.enterprise.inject.spi.ProcessInjectionTarget;
import javax.enterprise.inject.spi.ProcessManagedBean;
import javax.enterprise.inject.spi.ProcessProducer;
import javax.enterprise.inject.spi.ProcessProducerMethod;
import javax.inject.Inject;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.BeanArchive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.weld.test.util.Utils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
*
* @author <a href="mailto:manovotn@redhat.com">Matej Novotny</a>
*/
@RunWith(Arquillian.class)
public class LifecycleEventOrderingTest {

@Deployment
public static Archive<?> getDeployment() {
return ShrinkWrap.create(BeanArchive.class, Utils.getDeploymentNameAsHash(LifecycleEventOrderingTest.class)).addPackage(LifecycleEventOrderingTest.class.getPackage())
.addAsServiceProvider(Extension.class, ProductManagement.class);
}

@Inject
ProductManagement extension;

@Test
public void testEventsWereFiredInCorrectOrderForProducer() {
List<Object> actualListOfEvents = extension.getListOfProducerEvents();
Assert.assertEquals(4, actualListOfEvents.size());
Assert.assertTrue(actualListOfEvents.get(0) instanceof ProcessInjectionPoint);
Assert.assertTrue(actualListOfEvents.get(1) instanceof ProcessProducer);
Assert.assertTrue(actualListOfEvents.get(2) instanceof ProcessBeanAttributes);
Assert.assertTrue(actualListOfEvents.get(3) instanceof ProcessProducerMethod);
}

@Test
public void testEventsWereFiredInCorrectOrderForOrdinaryBean() {
List<Object> actualListOfEvents = extension.getListOfBeanEvents();
Assert.assertEquals(4, actualListOfEvents.size());
Assert.assertTrue(actualListOfEvents.get(0) instanceof ProcessInjectionPoint);
Assert.assertTrue(actualListOfEvents.get(1) instanceof ProcessInjectionTarget);
Assert.assertTrue(actualListOfEvents.get(2) instanceof ProcessBeanAttributes);
Assert.assertTrue(actualListOfEvents.get(3) instanceof ProcessManagedBean);
}
}
@@ -0,0 +1,28 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2017, 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.tests.event.lifecycle.ordering;

import javax.enterprise.context.Dependent;

/**
*
* @author <a href="mailto:manovotn@redhat.com">Matej Novotny</a>
*/
@Dependent
public class MassiveJugCoffee {

}
@@ -0,0 +1,43 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2017, 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.tests.event.lifecycle.ordering;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;

/**
*
* @author <a href="mailto:manovotn@redhat.com">Matej Novotny</a>
*/
@ApplicationScoped
public class PoorWorker {

@Inject
MassiveJugCoffee coffee;

@Produces
public HighQualityAndLowCostProduct makeManagersHappy(@HastilyWritten String docs) {
return new HighQualityAndLowCostProduct();
}

@Produces
@HastilyWritten
public String dontForgetTheDocumentation() {
return "Made in NeverLand!";
}
}

0 comments on commit c528f3c

Please sign in to comment.