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

Reply via email to