Author: jstrachan Date: Tue Sep 4 13:50:42 2012 New Revision: 1380649 URL: http://svn.apache.org/viewvc?rev=1380649&view=rev Log: fixes CAMEL-5560; adds a workaround for @Startup on @ApplicationScoped / @Singleton beans to the CamelExtension to ensure they are eagly started; so that we know that camel routes will startup eagerly
Modified: camel/trunk/components/camel-cdi/pom.xml camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Main.java camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java camel/trunk/examples/camel-example-cdi/src/main/java/org/apache/camel/example/cdi/MyRouteConfig.java camel/trunk/parent/pom.xml Modified: camel/trunk/components/camel-cdi/pom.xml URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/pom.xml?rev=1380649&r1=1380648&r2=1380649&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/pom.xml (original) +++ camel/trunk/components/camel-cdi/pom.xml Tue Sep 4 13:50:42 2012 @@ -79,6 +79,11 @@ </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-ejb_3.1_spec</artifactId> + <version>${geronimo-ejb_3.1_spec.version}</version> + </dependency> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jcdi_1.0_spec</artifactId> <version>${geronimo-jcdi-1.0-spec.version}</version> </dependency> Modified: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Main.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Main.java?rev=1380649&r1=1380648&r2=1380649&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Main.java (original) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Main.java Tue Sep 4 13:50:42 2012 @@ -41,6 +41,7 @@ public class Main extends MainSupport { private JAXBContext jaxbContext; private CdiContainer cdiContainer; + public static void main(String... args) throws Exception { Main main = new Main(); instance = main; @@ -126,6 +127,8 @@ public class Main extends MainSupport { protected void doStart() throws Exception { cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); + cdiContainer.getContextControl().startContexts(); + super.doStart(); } Modified: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java?rev=1380649&r1=1380648&r2=1380649&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java (original) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java Tue Sep 4 13:50:42 2012 @@ -21,6 +21,8 @@ import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; +import javax.ejb.Startup; +import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.AfterBeanDiscovery; @@ -35,6 +37,7 @@ import javax.enterprise.inject.spi.Proce import javax.enterprise.inject.spi.ProcessBean; import javax.enterprise.inject.spi.ProcessInjectionTarget; import javax.inject.Inject; +import javax.inject.Singleton; import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; @@ -59,7 +62,10 @@ public class CamelExtension implements E private CamelContext camelContext; private DefaultCamelBeanPostProcessor postProcessor; - private Map<Bean<?>, BeanAdapter> beanAdapters = new HashMap<Bean<?>, BeanAdapter>(); + private Map<Bean<?>, BeanAdapter> eagerBeans = new HashMap<Bean<?>, BeanAdapter>(); + + public CamelExtension() { + } /** * Process camel context aware bean definitions. @@ -128,30 +134,48 @@ public class CamelExtension implements E */ public void detectConsumeBeans(@Observes ProcessBean<?> event) { final Bean<?> bean = event.getBean(); - ReflectionHelper.doWithMethods(bean.getBeanClass(), new ReflectionHelper.MethodCallback() { + Class<?> beanClass = bean.getBeanClass(); + ReflectionHelper.doWithMethods(beanClass, new ReflectionHelper.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Consume consume = method.getAnnotation(Consume.class); if (consume != null) { - BeanAdapter beanAdapter = getBeanAdapter(bean); - beanAdapter.addConsumeMethod(method); + eagerlyCreate(bean); } } }); + + // lets force singletons and application scoped objects + // to be created eagerly to ensure they startup + if (eagerlyCreateSingletonsOnStartup() && + isApplicationScopeOrSingleton(beanClass) && + beanClass.getAnnotation(Startup.class) != null) { + eagerlyCreate(bean); + } + } + + /** + * Should we eagerly startup @Singleton and @ApplicationScoped beans annotated with @Startup? + * Defaults to true which enables us to start camel contexts on startup + */ + protected boolean eagerlyCreateSingletonsOnStartup() { + return true; } + /** * Lets force the CDI container to create all beans annotated with @Consume so that the consumer becomes active */ public void startConsumeBeans(@Observes AfterDeploymentValidation event, BeanManager beanManager) { ObjectHelper.notNull(getCamelContext(), "camelContext"); - Set<Map.Entry<Bean<?>, BeanAdapter>> entries = beanAdapters.entrySet(); + Set<Map.Entry<Bean<?>, BeanAdapter>> entries = eagerBeans.entrySet(); for (Map.Entry<Bean<?>, BeanAdapter> entry : entries) { Bean<?> bean = entry.getKey(); BeanAdapter adapter = entry.getValue(); CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean); - Object reference = beanManager.getReference(bean, Object.class, creationalContext); + // force lazy creation + beanManager.getReference(bean, Object.class, creationalContext); } } @@ -159,6 +183,7 @@ public class CamelExtension implements E /** * Lets perform injection of all beans which use Camel annotations */ + @SuppressWarnings("unchecked") public void onInjectionTarget(@Observes ProcessInjectionTarget event) { final InjectionTarget injectionTarget = event.getInjectionTarget(); final Class beanClass = event.getAnnotatedType().getJavaClass(); @@ -237,11 +262,11 @@ public class CamelExtension implements E return postProcessor; } - protected BeanAdapter getBeanAdapter(Bean<?> bean) { - BeanAdapter beanAdapter = beanAdapters.get(bean); + protected BeanAdapter eagerlyCreate(Bean<?> bean) { + BeanAdapter beanAdapter = eagerBeans.get(bean); if (beanAdapter == null) { beanAdapter = new BeanAdapter(); - beanAdapters.put(bean, beanAdapter); + eagerBeans.put(bean, beanAdapter); } return beanAdapter; } @@ -260,4 +285,11 @@ public class CamelExtension implements E protected static boolean injectAnnotatedField(Field field) { return field.getAnnotation(Inject.class) != null; } + + /** + * Returns true for singletons or application scoped beans + */ + private boolean isApplicationScopeOrSingleton(Class<?> aClass) { + return aClass.getAnnotation(Singleton.class) != null || aClass.getAnnotation(ApplicationScoped.class) != null; + } } Modified: camel/trunk/examples/camel-example-cdi/src/main/java/org/apache/camel/example/cdi/MyRouteConfig.java URL: http://svn.apache.org/viewvc/camel/trunk/examples/camel-example-cdi/src/main/java/org/apache/camel/example/cdi/MyRouteConfig.java?rev=1380649&r1=1380648&r2=1380649&view=diff ============================================================================== --- camel/trunk/examples/camel-example-cdi/src/main/java/org/apache/camel/example/cdi/MyRouteConfig.java (original) +++ camel/trunk/examples/camel-example-cdi/src/main/java/org/apache/camel/example/cdi/MyRouteConfig.java Tue Sep 4 13:50:42 2012 @@ -33,8 +33,8 @@ import org.apache.camel.cdi.Uri; /** * Configures all our Camel components, endpoints and beans and create the Camel routes */ -@Startup @ApplicationScoped +@Startup public class MyRouteConfig { @Inject @@ -82,7 +82,6 @@ public class MyRouteConfig { */ @PostConstruct public void start() throws Exception { - System.out.println("======= Starting MyRouteConfig!!"); camelContext.addRoutes(createRoutes()); } Modified: camel/trunk/parent/pom.xml URL: http://svn.apache.org/viewvc/camel/trunk/parent/pom.xml?rev=1380649&r1=1380648&r2=1380649&view=diff ============================================================================== --- camel/trunk/parent/pom.xml (original) +++ camel/trunk/parent/pom.xml Tue Sep 4 13:50:42 2012 @@ -79,6 +79,7 @@ <fop-version>1.0</fop-version> <ftpserver-version>1.0.6</ftpserver-version> <freemarker-version>2.3.19</freemarker-version> + <geronimo-ejb_3.1_spec.version>1.0.2</geronimo-ejb_3.1_spec.version> <geronimo-el-spec-version>1.0.1</geronimo-el-spec-version> <geronimo-j2ee-connector-spec-version>2.0.0</geronimo-j2ee-connector-spec-version> <geronimo-j2ee-jacc-spec-version>1.1</geronimo-j2ee-jacc-spec-version>