Hi Guys, Hello Tapestry, I've noticed that tapestry-cdi rather aggresively protects tapestry managed beans from CDI beans. When I introduced my CDI managed JAR which also had its own components, tapestry-cdi vetoed it.
For example, consiter Tap5 app root is: com.foo.bar And some CDI enabled JAR library contains beans in: com.foo.vodoo.components tapestry-cdi will veto all beans from that JAR even though there is no way for namespace collision to occur. Since I can't modify package structure in my JAR, I modified tapestry-cdi to be less aggressive. Attached is the patch as well as the complete source file. Feel free to commit/improve or whatever. In this path, I took a rather naive (but safe, imo) approach to pass app root via -D and be less aggressive if detected. If there is a way to automatically detect it within the extension, then this could be even simplier. In any case, it's tested and works like a charm in my project. Regards, Adam
diff --git a/src/main/java/org/apache/tapestry5/cdi/extension/TapestryExtension.java b/src/main/java/org/apache/tapestry5/cdi/extension/TapestryExtension.java index 849a273..3b35e13 100644 --- a/src/main/java/org/apache/tapestry5/cdi/extension/TapestryExtension.java +++ b/src/main/java/org/apache/tapestry5/cdi/extension/TapestryExtension.java @@ -33,6 +33,24 @@ private static Logger logger = LoggerFactory.getLogger(TapestryExtension.class); /** + * Root package of the Tapestry5 application running with this CDI extension. + * If defined, CDI veto process will be less rigorous as it will check + * specific tapestry packages rather than aggressively reject any CDI bean + * that may happen to contain a tapestry package name in its path. For example, + * consider a CDI managed JAR with beans inside {@code com.foo.bar.components}. + * Also, consider a CDI enabled Tapestry 5 application with base path of + * {@code com.foo.xxx} which depends on that JAR. Tapestry components would reside in + * {@code com.foo.xxx.components}. If -D system property for app base is passed + * a veto will occur only if a CDI bean is detected exactly in {@code com.foo.xxx.components}, + * however, if app base is not provided, then any package containing the + * sub package {@code components} (including {@code com.foo.bar.components} + * will have its CDI beans rejected. + * + * @since 1.0.1 + */ + public static final String APP_BASE = "tap5-cdi.app-root"; + + /** * Exclude Tapestry resources from CDI management * Veto each Tapestry pages, components and mixins * @param pat a ProcessAnnotatedType @@ -41,8 +59,16 @@ String annotatedTypeClassName = pat.getAnnotatedType().getJavaClass().getName(); logger.debug("Annotated type : "+annotatedTypeClassName); + String base = System.getProperty(APP_BASE); + for (String subpackage : InternalConstants.SUBPACKAGES){ - if(annotatedTypeClassName.contains("."+subpackage+".")){ + + boolean veto = (base == null ? + annotatedTypeClassName.contains("."+subpackage+".") : + annotatedTypeClassName.startsWith(String.format("%s.%s", base, subpackage))); + + if(veto){ + logger.trace("subpackage: {}", subpackage); logger.debug("Tapestry page/component/mixins found! - will be exclude from CDI management : "+annotatedTypeClassName); pat.veto(); }
/** * Copyright 2013 GOT5 * * 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.apache.tapestry5.cdi.extension; import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.Extension; import javax.enterprise.inject.spi.ProcessAnnotatedType; import org.apache.tapestry5.internal.InternalConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * An spi extension to exclude tapestry resources from CDI management * Veto each Tapestry pages, components and mixins to avoid CDI try to manage them * Without this extension, CDI will complain about Tapestry services not well loaded in injection points from the webapp's pages,components and mixins */ public class TapestryExtension implements Extension { private static Logger logger = LoggerFactory.getLogger(TapestryExtension.class); /** * Root package of the Tapestry5 application running with this CDI extension. * If defined, CDI veto process will be less rigorous as it will check * specific tapestry packages rather than aggressively reject any CDI bean * that may happen to contain a tapestry package name in its path. For example, * consider a CDI managed JAR with beans inside {@code com.foo.bar.components}. * Also, consider a CDI enabled Tapestry 5 application with base path of * {@code com.foo.xxx} which depends on that JAR. Tapestry components would reside in * {@code com.foo.xxx.components}. If -D system property for app base is passed * a veto will occur only if a CDI bean is detected exactly in {@code com.foo.xxx.components}, * however, if app base is not provided, then any package containing the * sub package {@code components} (including {@code com.foo.bar.components} * will have its CDI beans rejected. * * @since 1.0.1 */ public static final String APP_BASE = "tap5-cdi.app-root"; /** * Exclude Tapestry resources from CDI management * Veto each Tapestry pages, components and mixins * @param pat a ProcessAnnotatedType */ protected <T> void excludeTapestryResources(@Observes final ProcessAnnotatedType<T> pat){ String annotatedTypeClassName = pat.getAnnotatedType().getJavaClass().getName(); logger.debug("Annotated type : "+annotatedTypeClassName); String base = System.getProperty(APP_BASE); for (String subpackage : InternalConstants.SUBPACKAGES){ boolean veto = (base == null ? annotatedTypeClassName.contains("."+subpackage+".") : annotatedTypeClassName.startsWith(String.format("%s.%s", base, subpackage))); if(veto){ logger.trace("subpackage: {}", subpackage); logger.debug("Tapestry page/component/mixins found! - will be exclude from CDI management : "+annotatedTypeClassName); pat.veto(); } } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org