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: [email protected]
For additional commands, e-mail: [email protected]