Merge pull request #6 from rotty3000/trim-and-excludes
Trim and excludes
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedImpl.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedImpl.java
index 62d54d5..463fc05 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedImpl.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedImpl.java
@@ -14,7 +14,7 @@
package org.apache.aries.cdi.container.internal.annotated;
-import static java.util.stream.Collectors.*;
+import static java.util.stream.Collectors.toSet;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
@@ -68,4 +68,9 @@
return _annotatedElement.isAnnotationPresent(annotationType);
}
+ @Override
+ public String toString() {
+ return _baseType.getTypeName();
+ }
+
}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Discovery.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Discovery.java
index bd1cb97..96e68ce 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Discovery.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Discovery.java
@@ -14,16 +14,22 @@
package org.apache.aries.cdi.container.internal.container;
+import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
+import java.net.URL;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
@@ -38,6 +44,13 @@
import javax.enterprise.inject.spi.AnnotatedType;
import javax.inject.Inject;
import javax.inject.Named;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
import org.apache.aries.cdi.container.internal.annotated.AnnotatedTypeImpl;
import org.apache.aries.cdi.container.internal.model.BeansModel;
@@ -64,15 +77,50 @@
import org.osgi.service.cdi.reference.BindService;
import org.osgi.service.cdi.reference.BindServiceReference;
import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import aQute.lib.exceptions.Exceptions;
public class Discovery {
private static final List<Type> BIND_TYPES = Arrays.asList(BindService.class, BindBeanServiceObjects.class, BindServiceReference.class);
+ static final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ static final XPathFactory xpf = XPathFactory.newInstance();
+ static final XPathExpression trimExpression;
+ static final XPathExpression excludeExpression;
+
+ static {
+ try {
+ dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ dbf.setXIncludeAware(false);
+ dbf.setExpandEntityReferences(false);
+ XPath xPath = xpf.newXPath();
+ trimExpression = xPath.compile("boolean(/beans/trim)");
+ excludeExpression = xPath.compile("/beans/scan/exclude");
+ } catch (Throwable t) {
+ throw Exceptions.duck(t);
+ }
+ }
+
public Discovery(ContainerState containerState) {
_containerState = containerState;
_beansModel = _containerState.beansModel();
_containerTemplate = _containerState.containerDTO().template.components.get(0);
+
+ AtomicBoolean trim = new AtomicBoolean();
+
+ _excludes = new ArrayList<>();
+
+ _beansModel.getBeansXml().stream().map(this::readXMLResource).forEach(doc -> {
+ if (!trim.get()) trim.set(checkTrim(doc));
+ _excludes.addAll(getExcludes(doc));
+ });
+
+ _trim = trim.get();
}
public void discover() {
@@ -81,6 +129,10 @@
AnnotatedType<?> annotatedType = new AnnotatedTypeImpl<>(osgiBean.getBeanClass());
+ if (trimIt(annotatedType) || exclude(annotatedType)) {
+ return;
+ }
+
try {
String beanName = Annotates.beanName(annotatedType);
Class<? extends Annotation> beanScope = Annotates.beanScope(annotatedType);
@@ -154,6 +206,23 @@
postProcessComponentScopedBeans();
}
+ boolean exclude(AnnotatedType<?> annotatedType) {
+ // See https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#exclude_filters
+ return _excludes.stream().anyMatch(ex -> ex.exclude(annotatedType));
+ }
+
+ boolean trimIt(AnnotatedType<?> annotatedType) {
+ // See https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#trimmed_bean_archive
+ if (!_trim) return false;
+
+ if (Annotates.hasBeanDefiningAnnotations(annotatedType)) return false;
+
+ // or any scope annotation
+ if (Annotates.beanScope(annotatedType, null) != null) return false;
+
+ return true;
+ }
+
<X> boolean isInject(AnnotatedMember<X> annotatedMember) {
return (annotatedMember.isAnnotationPresent(Inject.class) && !annotatedMember.isStatic());
}
@@ -389,9 +458,177 @@
}
}
+ boolean checkTrim(Document document) {
+ try {
+ return Boolean.class.cast(trimExpression.evaluate(document, XPathConstants.BOOLEAN));
+ } catch (XPathExpressionException e) {
+ throw Exceptions.duck(e);
+ }
+ }
+
+ List<Exclude> getExcludes(Document document) {
+ try {
+ List<Exclude> excludes = new ArrayList<>();
+
+ NodeList excludeNodes = NodeList.class.cast(excludeExpression.evaluate(document, XPathConstants.NODESET));
+
+ for (int i = 0; i < excludeNodes.getLength(); i++) {
+ Element excludeElement = (Element)excludeNodes.item(i);
+
+ excludes.add(new Exclude(excludeElement));
+ }
+
+ return excludes;
+ }
+ catch (Exception e) {
+ throw Exceptions.duck(e);
+ }
+ }
+
+ Document readXMLResource(URL resource) {
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ try (InputStream is = resource.openStream()) {
+ return db.parse(is);
+ } catch (Throwable t) {
+ return db.newDocument();
+ }
+ }
+ catch (Exception e) {
+ throw Exceptions.duck(e);
+ }
+ }
+
private final BeansModel _beansModel;
private final Set<OSGiBean> _componentScoped = new HashSet<>();
private final ComponentTemplateDTO _containerTemplate;
private final ContainerState _containerState;
+ private final boolean _trim;
+ private final List<Exclude> _excludes;
+
+ enum Match {
+ CLASSNAME, PACKAGE_NAME, PACKAGE_PREFIX
+ }
+
+ class Exclude {
+
+ private final String name;
+ private final Match match;
+ private final List<String> ifClassAvailableS = new ArrayList<>();
+ private final List<String> ifClassesNotAvailableS = new ArrayList<>();
+ private final Map<String, String> ifSystemPropertyS = new HashMap<>();
+
+ public Exclude(Element excludeElement) {
+ String glob = excludeElement.getAttribute("name");
+
+ if (glob.endsWith(".**")) {
+ match = Match.PACKAGE_PREFIX;
+ name = glob.substring(0, glob.length() - 3);
+ }
+ else if (glob.endsWith(".*")) {
+ match = Match.PACKAGE_NAME;
+ name = glob.substring(0, glob.length() - 2);
+ }
+ else {
+ match = Match.CLASSNAME;
+ name = glob;
+ }
+
+ NodeList ifClassAvailableNodes = excludeElement.getElementsByTagName("if-class-available");
+
+ for (int iCAIdx = 0; iCAIdx < ifClassAvailableNodes.getLength(); iCAIdx++) {
+ Element ifClassAvailableElement = (Element)ifClassAvailableNodes.item(iCAIdx);
+
+ Attr nameAttribute = ifClassAvailableElement.getAttributeNode("name");
+
+ ifClassAvailableS.add(nameAttribute.getValue());
+ }
+
+ NodeList ifClassNotAvailableNodes = excludeElement.getElementsByTagName("if-class-not-available");
+
+ for (int iCNAIdx = 0; iCNAIdx < ifClassNotAvailableNodes.getLength(); iCNAIdx++) {
+ Element ifClassNotAvailableElement = (Element)ifClassNotAvailableNodes.item(iCNAIdx);
+
+ Attr nameAttribute = ifClassNotAvailableElement.getAttributeNode("name");
+
+ ifClassesNotAvailableS.add(nameAttribute.getValue());
+ }
+
+ NodeList ifSystemPropertyNodes = excludeElement.getElementsByTagName("if-system-property");
+
+ for (int iCNAIdx = 0; iCNAIdx < ifSystemPropertyNodes.getLength(); iCNAIdx++) {
+ Element ifSystemPropertyElement = (Element)ifSystemPropertyNodes.item(iCNAIdx);
+
+ String value = "";
+
+ if (ifSystemPropertyElement.hasAttribute("value")) {
+ value = ifSystemPropertyElement.getAttributeNode("value").getValue();
+ }
+
+ Attr nameAttribute = ifSystemPropertyElement.getAttributeNode("name");
+
+ ifSystemPropertyS.put(nameAttribute.getValue(), value);
+ }
+ }
+
+ public boolean exclude(AnnotatedType<?> annotatedType) {
+ String className = annotatedType.getJavaClass().getName();
+ String packageName = annotatedType.getJavaClass().getPackage().getName();
+
+ boolean matches = false;
+ switch (match) {
+ case CLASSNAME: {
+ matches = className.equals(name);
+ break;
+ }
+ case PACKAGE_NAME: {
+ matches = packageName.equals(name);
+ break;
+ }
+ case PACKAGE_PREFIX: {
+ matches = packageName.startsWith(name);
+ }
+ }
+
+ if (matches &&
+ ifClassAvailableS.stream().allMatch(this::classIsAvailable) &&
+ ifClassesNotAvailableS.stream().allMatch(this::classIsNotAvailable) &&
+ ifSystemPropertyS.entrySet().stream().allMatch(this::isPropertySet)) {
+
+ return true;
+ }
+
+ return false;
+ }
+
+ boolean classIsNotAvailable(String className) {
+ return !classIsAvailable(className);
+ }
+
+ boolean classIsAvailable(String className) {
+ try {
+ Class.forName(className, false, _containerState.classLoader());
+ return true;
+ }
+ catch (ClassNotFoundException cnfe) {
+ return false;
+ }
+ }
+
+ boolean isPropertySet(Entry<String, String> entry) {
+ if (entry.getValue().isEmpty()) {
+ return _containerState.bundleContext().getProperty(entry.getKey()) != null;
+ }
+ else {
+ return entry.getValue().equals(_containerState.bundleContext().getProperty(entry.getKey()));
+ }
+ }
+
+ @Override
+ public String toString() {
+ return name + ":" + match;
+ }
+
+ }
}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Annotates.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Annotates.java
index 93da73a..9239d4a 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Annotates.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Annotates.java
@@ -23,6 +23,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -30,8 +31,14 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import javax.decorator.Decorator;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.NormalScope;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.inject.Stereotype;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMember;
@@ -47,6 +54,7 @@
import javax.inject.Named;
import javax.inject.Qualifier;
import javax.inject.Scope;
+import javax.interceptor.Interceptor;
import org.osgi.service.cdi.ServiceScope;
import org.osgi.service.cdi.annotations.Service;
@@ -58,6 +66,16 @@
// no instances
}
+ private static final Predicate<Annotation> isBeanDefining = annotation ->
+ ApplicationScoped.class.isAssignableFrom(annotation.annotationType()) ||
+ ConversationScoped.class.isAssignableFrom(annotation.annotationType()) ||
+ Decorator.class.isAssignableFrom(annotation.annotationType()) ||
+ Dependent.class.isAssignableFrom(annotation.annotationType()) ||
+ Interceptor.class.isAssignableFrom(annotation.annotationType()) ||
+ RequestScoped.class.isAssignableFrom(annotation.annotationType()) ||
+ SessionScoped.class.isAssignableFrom(annotation.annotationType()) ||
+ Stereotype.class.isAssignableFrom(annotation.annotationType());
+
private static final Predicate<Annotation> isQualifier = annotation ->
!annotation.annotationType().equals(Qualifier.class) &&
annotation.annotationType().isAnnotationPresent(Qualifier.class);
@@ -132,7 +150,11 @@
}
public static Set<Annotation> qualifiers(Annotated annotated) {
- return collect(annotated.getAnnotations()).stream().filter(isQualifier).collect(Collectors.toSet());
+ return collect(annotated, isQualifier);
+ }
+
+ public static Set<Annotation> collect(Annotated annotated, Predicate<Annotation> predicate) {
+ return collect(annotated.getAnnotations()).stream().filter(predicate).collect(Collectors.toSet());
}
private static List<Annotation> collect(Collection<Annotation> annotations) {
@@ -303,9 +325,23 @@
}
public static Class<? extends Annotation> beanScope(Annotated annotated) {
+ return beanScope(annotated, Dependent.class);
+ }
+
+ public static Class<? extends Annotation> beanScope(Annotated annotated, Class<? extends Annotation> defaultValue) {
Class<? extends Annotation> scope = collect(annotated.getAnnotations()).stream().filter(isScope).map(Annotation::annotationType).findFirst().orElse(null);
- return (scope == null) ? Dependent.class : scope;
+ return (scope == null) ? defaultValue : scope;
+ }
+
+ public static boolean hasBeanDefiningAnnotations(AnnotatedType<?> annotatedType) {
+ Set<Annotation> beanDefiningAnnotations = new HashSet<>();
+
+ beanDefiningAnnotations.addAll(collect(annotatedType, isBeanDefining));
+ beanDefiningAnnotations.addAll(annotatedType.getFields().stream().flatMap(field -> collect(field, isBeanDefining).stream()).collect(Collectors.toSet()));
+ beanDefiningAnnotations.addAll(annotatedType.getMethods().stream().flatMap(method -> collect(method, isBeanDefining).stream()).collect(Collectors.toSet()));
+
+ return !beanDefiningAnnotations.isEmpty();
}
}
\ No newline at end of file
diff --git a/cdi-itests/base-itest.bndrun b/cdi-itests/base-itest.bndrun
index cbf4ddb..a82ea48 100644
--- a/cdi-itests/base-itest.bndrun
+++ b/cdi-itests/base-itest.bndrun
@@ -20,7 +20,9 @@
logback.configurationFile=file:${.}/logback.xml,\
org.osgi.service.http.port=0,\
osgi.console=,\
- tck.config.test.javaconfig.converter.stringvalues=foo
+ tck.config.test.javaconfig.converter.stringvalues=foo,\
+ test.property.a=blah,\
+ test.property.b=
-resolve.effective: resolve, active
diff --git a/cdi-itests/bnd.bnd b/cdi-itests/bnd.bnd
index d574c45..1c801b6 100644
--- a/cdi-itests/bnd.bnd
+++ b/cdi-itests/bnd.bnd
@@ -58,7 +58,11 @@
tb12.jar,\
tb13.jar,\
tb14.jar,\
- tb16.jar
+ tb16.jar,\
+ tb17.jar,\
+ tb18.jar,\
+ tb19.jar,\
+ tb20.jar
# Don't forget that we had to coax the `maven-jar-plugin` NOT to include the `sub-bundle` packages in
# the root bundle:
diff --git a/cdi-itests/bnd/tb17.bnd b/cdi-itests/bnd/tb17.bnd
new file mode 100644
index 0000000..cd800e9
--- /dev/null
+++ b/cdi-itests/bnd/tb17.bnd
@@ -0,0 +1,14 @@
+# 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.
+
+Export-Package: ${p}.tb17.*;-split-package:=first
+-includeresource: META-INF/beans.xml=bnd/tb17.xml
\ No newline at end of file
diff --git a/cdi-itests/bnd/tb17.xml b/cdi-itests/bnd/tb17.xml
new file mode 100644
index 0000000..0602e2a
--- /dev/null
+++ b/cdi-itests/bnd/tb17.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/**
+ * 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.
+ */
+-->
+
+<beans
+ xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://xmlns.jcp.org/xml/ns/javaee
+ http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+ bean-discovery-mode="all" version="2.0">
+
+ <trim/>
+</beans>
\ No newline at end of file
diff --git a/cdi-itests/bnd/tb18.bnd b/cdi-itests/bnd/tb18.bnd
new file mode 100644
index 0000000..1c2e6c2
--- /dev/null
+++ b/cdi-itests/bnd/tb18.bnd
@@ -0,0 +1,15 @@
+# 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.
+
+Export-Package: ${p}.tb18.*;-split-package:=first
+-includeresource: META-INF/beans.xml=bnd/tb18.xml
+-cdiannotations: *;discover=all
\ No newline at end of file
diff --git a/cdi-itests/bnd/tb18.xml b/cdi-itests/bnd/tb18.xml
new file mode 100644
index 0000000..d9f0a3f
--- /dev/null
+++ b/cdi-itests/bnd/tb18.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/**
+ * 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.
+ */
+-->
+
+<beans
+ xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://xmlns.jcp.org/xml/ns/javaee
+ http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+ bean-discovery-mode="all" version="2.0">
+
+ <scan>
+ <exclude name="org.apache.aries.cdi.test.tb18.B" />
+
+ <exclude name="org.apache.aries.cdi.test.tb18.pA.**" />
+
+ <exclude name="org.apache.aries.cdi.test.tb18.pB.*" />
+ </scan>
+</beans>
\ No newline at end of file
diff --git a/cdi-itests/bnd/tb19.bnd b/cdi-itests/bnd/tb19.bnd
new file mode 100644
index 0000000..aa9f63a
--- /dev/null
+++ b/cdi-itests/bnd/tb19.bnd
@@ -0,0 +1,15 @@
+# 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.
+
+Export-Package: ${p}.tb19.*;-split-package:=first
+-includeresource: META-INF/beans.xml=bnd/tb19.xml
+-cdiannotations: *;discover=all
\ No newline at end of file
diff --git a/cdi-itests/bnd/tb19.xml b/cdi-itests/bnd/tb19.xml
new file mode 100644
index 0000000..ab2a051
--- /dev/null
+++ b/cdi-itests/bnd/tb19.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/**
+ * 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.
+ */
+-->
+
+<beans
+ xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://xmlns.jcp.org/xml/ns/javaee
+ http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+ bean-discovery-mode="all" version="2.0">
+
+ <scan>
+ <exclude name="org.apache.aries.cdi.test.tb19.A">
+ <if-class-not-available name="com.foo.Bar"/>
+ </exclude>
+ <exclude name="org.apache.aries.cdi.test.tb19.B">
+ <if-class-not-available name="com.foo.Bar"/>
+ </exclude>
+ <exclude name="org.apache.aries.cdi.test.tb19.C">
+ <if-class-available name="org.osgi.service.cdi.annotations.Service"/>
+ </exclude>
+ </scan>
+</beans>
\ No newline at end of file
diff --git a/cdi-itests/bnd/tb20.bnd b/cdi-itests/bnd/tb20.bnd
new file mode 100644
index 0000000..67ec8e3
--- /dev/null
+++ b/cdi-itests/bnd/tb20.bnd
@@ -0,0 +1,15 @@
+# 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.
+
+Export-Package: ${p}.tb20.*;-split-package:=first
+-includeresource: META-INF/beans.xml=bnd/tb20.xml
+-cdiannotations: *;discover=all
\ No newline at end of file
diff --git a/cdi-itests/bnd/tb20.xml b/cdi-itests/bnd/tb20.xml
new file mode 100644
index 0000000..4653be4
--- /dev/null
+++ b/cdi-itests/bnd/tb20.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/**
+ * 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.
+ */
+-->
+
+<beans
+ xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://xmlns.jcp.org/xml/ns/javaee
+ http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+ bean-discovery-mode="all" version="2.0">
+
+ <scan>
+ <exclude name="org.apache.aries.cdi.test.tb20.A">
+ <if-system-property name="test.property.a" value="blah" />
+ </exclude>
+
+ <exclude name="org.apache.aries.cdi.test.tb20.B">
+ <if-system-property name="test.property.b" />
+ </exclude>
+
+ <exclude name="org.apache.aries.cdi.test.tb20.C">
+ <if-system-property name="test.property.c" value="bar" />
+ </exclude>
+ </scan>
+</beans>
\ No newline at end of file
diff --git a/cdi-itests/pom.xml b/cdi-itests/pom.xml
index 9697bb8..9534981 100644
--- a/cdi-itests/pom.xml
+++ b/cdi-itests/pom.xml
@@ -81,6 +81,10 @@
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-interceptor_1.2_spec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jcdi_2.0_spec</artifactId>
</dependency>
<dependency>
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/ExcludeTests.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/ExcludeTests.java
new file mode 100644
index 0000000..6e73fa1
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/ExcludeTests.java
@@ -0,0 +1,112 @@
+/**
+ * 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.aries.cdi.test.cases;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.service.cdi.runtime.CDIComponentRuntime;
+import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ExcludeTests extends AbstractTestCase {
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ runtimeTracker = new ServiceTracker<>(
+ bundleContext, CDIComponentRuntime.class, null);
+ runtimeTracker.open();
+ }
+
+ @AfterClass
+ public static void afterClass() throws Exception {
+ runtimeTracker.close();
+ }
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ cdiRuntime = runtimeTracker.waitForService(timeout);
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testExclude_ByName() throws Exception {
+ Bundle tb2Bundle = installBundle("tb18.jar", false);
+
+ tb2Bundle.start();
+
+ try {
+ ContainerDTO containerDTO = getContainerDTO(cdiRuntime, tb2Bundle);
+ assertNotNull(containerDTO);
+
+ assertEquals(1, containerDTO.template.components.size());
+
+ assertEquals(3, containerDTO.template.components.get(0).beans.size());
+ }
+ finally {
+ tb2Bundle.uninstall();
+ }
+ }
+
+ @Test
+ public void testExclude_IfClassAvailable() throws Exception {
+ Bundle tb2Bundle = installBundle("tb19.jar", false);
+
+ tb2Bundle.start();
+
+ try {
+ ContainerDTO containerDTO = getContainerDTO(cdiRuntime, tb2Bundle);
+ assertNotNull(containerDTO);
+
+ assertEquals(1, containerDTO.template.components.size());
+
+ assertEquals(1, containerDTO.template.components.get(0).beans.size());
+ }
+ finally {
+ tb2Bundle.uninstall();
+ }
+ }
+
+ @Test
+ public void testExclude_IfSystemProperty() throws Exception {
+ Bundle tb2Bundle = installBundle("tb20.jar", false);
+
+ tb2Bundle.start();
+
+ try {
+ ContainerDTO containerDTO = getContainerDTO(cdiRuntime, tb2Bundle);
+ assertNotNull(containerDTO);
+
+ assertEquals(1, containerDTO.template.components.size());
+
+ assertEquals(2, containerDTO.template.components.get(0).beans.size());
+ }
+ finally {
+ tb2Bundle.uninstall();
+ }
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/TrimTests.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/TrimTests.java
new file mode 100644
index 0000000..0a054b4
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/TrimTests.java
@@ -0,0 +1,76 @@
+/**
+ * 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.aries.cdi.test.cases;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.service.cdi.runtime.CDIComponentRuntime;
+import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class TrimTests extends AbstractTestCase {
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ runtimeTracker = new ServiceTracker<>(
+ bundleContext, CDIComponentRuntime.class, null);
+ runtimeTracker.open();
+ }
+
+ @AfterClass
+ public static void afterClass() throws Exception {
+ runtimeTracker.close();
+ }
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ cdiRuntime = runtimeTracker.waitForService(timeout);
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testTrimmed() throws Exception {
+ Bundle tb2Bundle = installBundle("tb17.jar", false);
+
+ tb2Bundle.start();
+
+ try {
+ ContainerDTO containerDTO = getContainerDTO(cdiRuntime, tb2Bundle);
+ assertNotNull(containerDTO);
+
+ assertEquals(5, containerDTO.template.components.get(0).beans.size());
+
+ assertEquals(2, containerDTO.template.components.size());
+
+ assertEquals(2, containerDTO.template.components.get(1).beans.size());
+ }
+ finally {
+ tb2Bundle.uninstall();
+ }
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/A.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/A.java
new file mode 100644
index 0000000..463d105
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/A.java
@@ -0,0 +1,19 @@
+package org.apache.aries.cdi.test.tb17;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class A implements Pojo {
+
+ @Override
+ public String foo(String fooInput) {
+ return "A" + fooInput;
+ }
+
+ @Override
+ public int getCount() {
+ return 1;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/B.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/B.java
new file mode 100644
index 0000000..0dd89e6
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/B.java
@@ -0,0 +1,36 @@
+/**
+ * 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.aries.cdi.test.tb17;
+
+import javax.enterprise.context.Dependent;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Dependent
+@Service
+public class B implements Pojo {
+
+ @Override
+ public String foo(String fooInput) {
+ return "B" + fooInput;
+ }
+
+ @Override
+ public int getCount() {
+ return 1;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/C.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/C.java
new file mode 100644
index 0000000..2b267c3
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/C.java
@@ -0,0 +1,21 @@
+package org.apache.aries.cdi.test.tb17;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+import org.osgi.service.cdi.annotations.SingleComponent;
+
+@Service
+@SingleComponent
+public class C implements Pojo {
+
+ @Override
+ public String foo(String fooInput) {
+ return "C" + fooInput;
+ }
+
+ @Override
+ public int getCount() {
+ return 1;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/D.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/D.java
new file mode 100644
index 0000000..1193d22
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/D.java
@@ -0,0 +1,19 @@
+package org.apache.aries.cdi.test.tb17;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.ComponentScoped;
+
+@ComponentScoped
+public class D implements Pojo {
+
+ @Override
+ public String foo(String fooInput) {
+ return "D" + fooInput;
+ }
+
+ @Override
+ public int getCount() {
+ return 1;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/E.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/E.java
new file mode 100644
index 0000000..b378b98
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/E.java
@@ -0,0 +1,20 @@
+package org.apache.aries.cdi.test.tb17;
+
+import javax.enterprise.context.ApplicationScoped;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+
+@ApplicationScoped
+public class E implements Pojo {
+
+ @Override
+ public String foo(String fooInput) {
+ return "E" + fooInput;
+ }
+
+ @Override
+ public int getCount() {
+ return 1;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/F.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/F.java
new file mode 100644
index 0000000..f331996
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/F.java
@@ -0,0 +1,25 @@
+package org.apache.aries.cdi.test.tb17;
+
+import javax.decorator.Decorator;
+import javax.decorator.Delegate;
+import javax.inject.Inject;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Reference;
+
+@Decorator
+public class F implements Pojo {
+
+ @Inject @Delegate @Reference Pojo pojo;
+
+ @Override
+ public String foo(String fooInput) {
+ return "F" + pojo.foo(fooInput);
+ }
+
+ @Override
+ public int getCount() {
+ return pojo.getCount();
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/G.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/G.java
new file mode 100644
index 0000000..6488d05
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/G.java
@@ -0,0 +1,20 @@
+package org.apache.aries.cdi.test.tb17;
+
+import javax.enterprise.context.ConversationScoped;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+
+@ConversationScoped
+public class G implements Pojo {
+
+ @Override
+ public String foo(String fooInput) {
+ return "G" + fooInput;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/H.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/H.java
new file mode 100644
index 0000000..d3d6f1e
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/H.java
@@ -0,0 +1,27 @@
+package org.apache.aries.cdi.test.tb17;
+
+import javax.inject.Inject;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.log.Logger;
+
+@Interceptor
+public class H {
+
+ @Inject Logger log;
+ @Inject Pojo pojo;
+
+ @AroundInvoke
+ public Object authorize(InvocationContext ic) throws Exception {
+ if (pojo.getCount() > 0) {
+ log.debug("Pojo Count {}", pojo.getCount());
+ }
+ else {
+ log.debug("Pojo has no count");
+ }
+ return ic.proceed();
+ }
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/package-info.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/package-info.java
new file mode 100644
index 0000000..2558a7e
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb17/package-info.java
@@ -0,0 +1,16 @@
+/**
+ * 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.
+ */
+
+@org.osgi.service.cdi.annotations.Beans
+package org.apache.aries.cdi.test.tb17;
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/A.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/A.java
new file mode 100644
index 0000000..89dad56
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/A.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class A implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/B.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/B.java
new file mode 100644
index 0000000..33e8aec
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/B.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class B implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "B" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/C.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/C.java
new file mode 100644
index 0000000..5aeb4f9
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/C.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18.pA;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class C implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/D.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/D.java
new file mode 100644
index 0000000..5496a17
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/D.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18.pA;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class D implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/pAA/E.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/pAA/E.java
new file mode 100644
index 0000000..25c1777
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/pAA/E.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18.pA.pAA;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class E implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/pAA/F.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/pAA/F.java
new file mode 100644
index 0000000..f8d4d27
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pA/pAA/F.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18.pA.pAA;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class F implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/C.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/C.java
new file mode 100644
index 0000000..598a0d8
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/C.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18.pB;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class C implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/D.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/D.java
new file mode 100644
index 0000000..ca071a9
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/D.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18.pB;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class D implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/pBB/E.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/pBB/E.java
new file mode 100644
index 0000000..d6b82cd
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/pBB/E.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18.pB.pBB;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class E implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/pBB/F.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/pBB/F.java
new file mode 100644
index 0000000..1622925
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb18/pB/pBB/F.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb18.pB.pBB;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class F implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/A.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/A.java
new file mode 100644
index 0000000..fa75bbe
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/A.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb19;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class A implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/B.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/B.java
new file mode 100644
index 0000000..71af86b
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/B.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb19;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class B implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "B" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/C.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/C.java
new file mode 100644
index 0000000..91236f6
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/C.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb19;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class C implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "B" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/D.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/D.java
new file mode 100644
index 0000000..11106ee
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb19/D.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb19;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class D implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "B" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/A.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/A.java
new file mode 100644
index 0000000..2dd932e
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/A.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb20;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class A implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "A" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/B.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/B.java
new file mode 100644
index 0000000..af260a7
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/B.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb20;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class B implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "B" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/C.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/C.java
new file mode 100644
index 0000000..8cf6bfd
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/C.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb20;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class C implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "B" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/D.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/D.java
new file mode 100644
index 0000000..f9bdd20
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb20/D.java
@@ -0,0 +1,33 @@
+/**
+ * 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.aries.cdi.test.tb20;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class D implements Pojo {
+
+ @Override
+ public String foo(String input) {
+ return "B" + input;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+}