You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by gp...@apache.org on 2012/02/14 08:49:30 UTC

git commit: DELTASPIKE-61 global alternatives

Updated Branches:
  refs/heads/master 0dd1de1de -> 5bab94504


DELTASPIKE-61 global alternatives


Project: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/commit/5bab9450
Tree: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/tree/5bab9450
Diff: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/diff/5bab9450

Branch: refs/heads/master
Commit: 5bab9450442b18f121de852d3e7c94712f5a9de6
Parents: 0dd1de1
Author: gpetracek <gp...@apache.org>
Authored: Thu Jan 26 17:04:36 2012 +0100
Committer: gpetracek <gp...@apache.org>
Committed: Tue Feb 14 08:39:25 2012 +0100

----------------------------------------------------------------------
 .../deltaspike/core/api/config/ConfigResolver.java |    3 +-
 .../core/impl/exclude/ExcludeExtension.java        |  208 ++++++++++++++-
 .../core/impl/exclude/GlobalAlternative.java       |   28 ++
 .../core/api/alternative/global/BaseBean1.java     |   29 ++
 .../api/alternative/global/BaseInterface1.java     |   26 ++
 .../BaseInterface1AlternativeImplementation.java   |   31 +++
 .../BaseInterface1DefaultImplementation.java       |   29 ++
 .../alternative/global/GlobalAlternativeTest.java  |  102 +++++++
 .../core/api/alternative/global/SubBaseBean1.java  |   32 +++
 .../global/qualifier/AlternativeBaseBeanB.java     |   32 +++
 .../alternative/global/qualifier/BaseBeanA.java    |   30 ++
 .../alternative/global/qualifier/BaseBeanB.java    |   30 ++
 .../alternative/global/qualifier/BaseBeanB2.java   |   30 ++
 .../global/qualifier/BaseInterface.java            |   25 ++
 .../alternative/global/qualifier/QualifierA.java   |   42 +++
 .../alternative/global/qualifier/QualifierB.java   |   45 +++
 .../global/qualifier/QualifierValue1.java          |   25 ++
 .../global/qualifier/QualifierValue2.java          |   25 ++
 .../test/core/api/alternative/local/BaseBean2.java |   30 ++
 .../core/api/alternative/local/BaseInterface2.java |   27 ++
 .../BaseInterface2AlternativeImplementation.java   |   38 +++
 .../local/BaseInterface2DefaultImplementation.java |   30 ++
 .../api/alternative/local/BdaAlternativeTest.java  |   84 ++++++
 .../core/api/alternative/local/SubBaseBean2.java   |   37 +++
 .../core/api/projectstage/TestProjectStages.java   |    3 +
 .../api/temptestutil/ShrinkWrapArchiveUtil.java    |    2 +-
 .../META-INF/apache-deltaspike.properties          |    5 +
 27 files changed, 1018 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
index 2590986..3efb649 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
@@ -60,7 +60,8 @@ public final class ConfigResolver
      * and use the one with the highest priority.
      * 
      * @param key the property key.
-     * @return the configured property value from the {@link ConfigSource} with the highest ordinal.
+     * @return the configured property value from the {@link ConfigSource} with the highest ordinal or
+     * null if there is no configured value for it.
      */
     public static String getPropertyValue(String key)
     {

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/ExcludeExtension.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/ExcludeExtension.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/ExcludeExtension.java
index ffd2ba3..5533b1c 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/ExcludeExtension.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/ExcludeExtension.java
@@ -18,19 +18,31 @@
  */
 package org.apache.deltaspike.core.impl.exclude;
 
-import org.apache.deltaspike.core.util.ProjectStageProducer;
-import org.apache.deltaspike.core.util.ClassDeactivation;
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.api.metadata.builder.AnnotatedTypeBuilder;
 import org.apache.deltaspike.core.spi.activation.Deactivatable;
 import org.apache.deltaspike.core.api.exclude.Exclude;
 import org.apache.deltaspike.core.api.interpreter.ExpressionInterpreter;
 import org.apache.deltaspike.core.api.projectstage.ProjectStage;
-import org.apache.deltaspike.core.util.ClassUtils;
 import org.apache.deltaspike.core.impl.interpreter.PropertyExpressionInterpreter;
+import org.apache.deltaspike.core.util.ClassDeactivation;
+import org.apache.deltaspike.core.util.ClassUtils;
+import org.apache.deltaspike.core.util.ProjectStageProducer;
 
 import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Alternative;
 import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.Extension;
 import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.enterprise.util.Nonbinding;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -45,6 +57,7 @@ public class ExcludeExtension implements Extension, Deactivatable
     private static final Logger LOG = Logger.getLogger(ExcludeExtension.class.getName());
 
     private Boolean isActivated = null;
+    private Boolean isGlobalAlternativeActivated = null;
 
     /**
      * triggers initialization in any case
@@ -61,16 +74,28 @@ public class ExcludeExtension implements Extension, Deactivatable
      * @param processAnnotatedType observed event
      */
     @SuppressWarnings("UnusedDeclaration")
-    protected void vetoBeans(@Observes ProcessAnnotatedType<Object> processAnnotatedType)
+    protected void vetoBeans(@Observes ProcessAnnotatedType<Object> processAnnotatedType, BeanManager beanManager)
     {
-        if (!isActivated() ||
-                !processAnnotatedType.getAnnotatedType().getJavaClass().isAnnotationPresent(Exclude.class))
+        initActivation();
+
+        //we need to do it before the exclude logic to keep the @Exclude support for global alternatives
+        if (this.isGlobalAlternativeActivated)
+        {
+            activateGlobalAlternatives(processAnnotatedType, beanManager);
+        }
+
+        if (!this.isActivated)
         {
             return;
         }
 
         //TODO needs further discussions for a different feature CodiStartupBroadcaster.broadcastStartup();
 
+        if (!processAnnotatedType.getAnnotatedType().getJavaClass().isAnnotationPresent(Exclude.class))
+        {
+            return;
+        }
+
         Exclude exclude = processAnnotatedType.getAnnotatedType().getJavaClass().getAnnotation(Exclude.class);
 
         if (!evalExcludeWithoutCondition(processAnnotatedType, exclude))
@@ -91,6 +116,173 @@ public class ExcludeExtension implements Extension, Deactivatable
         evalExcludeWithExpression(processAnnotatedType, exclude);
     }
 
+    //just #veto the original implementation and remove @Alternative from the ProcessAnnotatedType of
+    // the configured alternative doesn't work with OWB (due to OWB-643)
+    private void activateGlobalAlternatives(ProcessAnnotatedType<Object> processAnnotatedType, BeanManager beanManager)
+    {
+        //the current bean is the bean with a potential global alternative
+        Class<Object> currentBean = processAnnotatedType.getAnnotatedType().getJavaClass();
+
+        Set<Class> beanBaseTypes = resolveBeanTypes(currentBean);
+
+        boolean isAlternativeBeanImplementation = currentBean.isAnnotationPresent(Alternative.class);
+
+        List<Annotation> qualifiersOfCurrentBean =
+            resolveQualifiers(processAnnotatedType.getAnnotatedType().getAnnotations(), beanManager);
+
+        String configuredBeanName;
+        List<Annotation> qualifiersOfConfiguredBean;
+        Class<Object> alternativeBeanClass;
+        Set<Annotation> alternativeBeanAnnotations;
+        
+        for (Class currentType : beanBaseTypes)
+        {
+            alternativeBeanAnnotations = new HashSet<Annotation>();
+
+            configuredBeanName = ConfigResolver.getPropertyValue(currentType.getName());
+            if (configuredBeanName != null && configuredBeanName.length() > 0)
+            {
+                alternativeBeanClass = ClassUtils.tryToLoadClassForName(configuredBeanName);
+
+                if (alternativeBeanClass == null)
+                {
+                    throw new IllegalStateException("Can't find class " + configuredBeanName + " which is configured" +
+                            " for " + currentType.getName());
+                }
+                alternativeBeanAnnotations.addAll(Arrays.asList(alternativeBeanClass.getAnnotations()));
+                qualifiersOfConfiguredBean = resolveQualifiers(alternativeBeanAnnotations, beanManager);
+            }
+            else
+            {
+                continue;
+            }
+
+            if (isAlternativeBeanImplementation)
+            {
+                if (doQualifiersMatch(qualifiersOfCurrentBean, qualifiersOfConfiguredBean))
+                {
+                    //veto if the current annotated-type is a global alternative - it replaced the original type already
+                    processAnnotatedType.veto();
+                    break;
+                }
+            }
+            else
+            {
+                if (!alternativeBeanClass.isAnnotationPresent(Alternative.class))
+                {
+                    continue;
+                }
+
+                if (doQualifiersMatch(qualifiersOfCurrentBean, qualifiersOfConfiguredBean))
+                {
+                    AnnotatedTypeBuilder<Object> annotatedTypeBuilder
+                        = new AnnotatedTypeBuilder<Object>().readFromType(alternativeBeanClass);
+
+                    //just to avoid issues with switching between app-servers,...
+                    annotatedTypeBuilder.removeFromClass(Alternative.class);
+                    processAnnotatedType.setAnnotatedType(annotatedTypeBuilder.create());
+                }
+            }
+        }
+    }
+
+    private boolean doQualifiersMatch(List<Annotation> qualifiersOfCurrentBean,
+                                      List<Annotation> qualifiersOfConfiguredBean)
+    {
+        if (qualifiersOfCurrentBean.size() != qualifiersOfConfiguredBean.size())
+        {
+            return false;
+        }
+
+        int matchingQualifiers = 0;
+        for (Annotation currentQualifier : qualifiersOfCurrentBean)
+        {
+            for (Annotation qualifierConfiguredBean : qualifiersOfConfiguredBean)
+            {
+                if (doesQualifierMatch(currentQualifier, qualifierConfiguredBean))
+                {
+                    matchingQualifiers++;
+                    break;
+                }
+            }
+        }
+        return qualifiersOfConfiguredBean.size() == matchingQualifiers;
+    }
+
+    private boolean doesQualifierMatch(Annotation currentQualifier, Annotation qualifierConfiguredBean)
+    {
+        if (!currentQualifier.annotationType().equals(qualifierConfiguredBean.annotationType()))
+        {
+            return false;
+        }
+
+        Object currentValue;
+        Object valueOfQualifierConfiguredBean;
+        for (Method currentMethod : currentQualifier.annotationType().getDeclaredMethods())
+        {
+            if (currentMethod.isAnnotationPresent(Nonbinding.class))
+            {
+                continue;
+            }
+
+            try
+            {
+                currentMethod.setAccessible(true);
+                currentValue = currentMethod.invoke(currentQualifier);
+                valueOfQualifierConfiguredBean = currentMethod.invoke(qualifierConfiguredBean);
+
+                if (!currentValue.equals(valueOfQualifierConfiguredBean))
+                {
+                    return false;
+                }
+            }
+            catch (Exception e)
+            {
+                throw new IllegalStateException("Can't compare " + currentQualifier.annotationType().getName() +
+                    " with " + qualifierConfiguredBean.annotationType().getName());
+            }
+        }
+        return true;
+    }
+
+    private List<Annotation> resolveQualifiers(Set<Annotation> annotations, BeanManager beanManager)
+    {
+        List<Annotation> result = new ArrayList<Annotation>();
+
+        for (Annotation annotation : annotations)
+        {
+            if (beanManager.isQualifier(annotation.annotationType()))
+            {
+                result.add(annotation);
+            }
+        }
+        return result;
+    }
+
+    private Set<Class> resolveBeanTypes(Class beanClass)
+    {
+        Set<Class> result = new HashSet<Class>();
+
+        Class<?> currentClass = beanClass;
+        while (currentClass != null && !Object.class.getName().equals(currentClass.getName()))
+        {
+            result.add(currentClass);
+
+            for (Class interfaceClass : currentClass.getInterfaces())
+            {
+                if (interfaceClass.getName().startsWith("java.") || interfaceClass.getName().startsWith("javax."))
+                {
+                    continue;
+                }
+                result.addAll(resolveBeanTypes(interfaceClass));
+            }
+
+            currentClass = currentClass.getSuperclass();
+        }
+
+        return result;
+    }
+
     private boolean evalExcludeWithoutCondition(ProcessAnnotatedType<Object> processAnnotatedType, Exclude exclude)
     {
         if (exclude.ifProjectStage().length == 0 && exclude.exceptIfProjectStage().length == 0 &&
@@ -199,12 +391,12 @@ public class ExcludeExtension implements Extension, Deactivatable
                 processAnnotatedType.getAnnotatedType().getJavaClass());
     }
 
-    public boolean isActivated()
+    public void initActivation()
     {
         if (isActivated == null)
         {
             isActivated = ClassDeactivation.isActivated(getClass());
+            isGlobalAlternativeActivated = ClassDeactivation.isActivated(GlobalAlternative.class);
         }
-        return isActivated;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/GlobalAlternative.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/GlobalAlternative.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/GlobalAlternative.java
new file mode 100644
index 0000000..2ea8244
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/GlobalAlternative.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.deltaspike.core.impl.exclude;
+
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+
+/**
+ * Allows to deactivate only the global alternative feature (needed if we keep it in the exclude extension)
+ */
+public interface GlobalAlternative extends Deactivatable
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseBean1.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseBean1.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseBean1.java
new file mode 100644
index 0000000..392dcd5
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseBean1.java
@@ -0,0 +1,29 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global;
+
+import javax.enterprise.context.Dependent;
+
+/**
+ * Simple base bean which gets overruled by an global alternative
+ */
+@Dependent
+public class BaseBean1
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1.java
new file mode 100644
index 0000000..5b81837
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1.java
@@ -0,0 +1,26 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global;
+
+/**
+ * Simple interface - at runtime the global alternative gets activated
+ */
+public interface BaseInterface1
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1AlternativeImplementation.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1AlternativeImplementation.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1AlternativeImplementation.java
new file mode 100644
index 0000000..dcec5cc
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1AlternativeImplementation.java
@@ -0,0 +1,31 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Alternative;
+
+/**
+ * Global alternative
+ */
+@Alternative
+@Dependent
+public class BaseInterface1AlternativeImplementation implements BaseInterface1
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1DefaultImplementation.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1DefaultImplementation.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1DefaultImplementation.java
new file mode 100644
index 0000000..2a99e18
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1DefaultImplementation.java
@@ -0,0 +1,29 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global;
+
+import javax.enterprise.context.Dependent;
+
+/**
+ * Default implementation which gets overruled by the alternative
+ */
+@Dependent
+public class BaseInterface1DefaultImplementation implements BaseInterface1
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/GlobalAlternativeTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/GlobalAlternativeTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/GlobalAlternativeTest.java
new file mode 100644
index 0000000..fa70b90
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/GlobalAlternativeTest.java
@@ -0,0 +1,102 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global;
+
+
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.test.core.api.alternative.global.qualifier.AlternativeBaseBeanB;
+import org.apache.deltaspike.test.core.api.alternative.global.qualifier.BaseBeanA;
+import org.apache.deltaspike.test.core.api.alternative.global.qualifier.BaseInterface;
+import org.apache.deltaspike.test.core.api.alternative.global.qualifier.QualifierA;
+import org.apache.deltaspike.test.core.api.alternative.global.qualifier.QualifierB;
+import org.apache.deltaspike.test.core.api.alternative.global.qualifier.QualifierValue1;
+import org.apache.deltaspike.test.core.api.temptestutil.ShrinkWrapArchiveUtil;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import java.util.List;
+
+/**
+ * Tests for @Alternative across BDAs
+ */
+@RunWith(Arquillian.class)
+public class GlobalAlternativeTest
+{
+    @Inject
+    private BaseInterface1 bean;
+
+    @Inject
+    @QualifierA(QualifierValue1.class)
+    private BaseInterface beanA;
+
+    @Inject
+    @QualifierB(QualifierValue1.class)
+    private BaseInterface beanB;
+
+    /**
+     * X TODO creating a WebArchive is only a workaround because JavaArchive cannot contain other archives.
+     */
+    @Deployment
+    public static WebArchive deploy()
+    {
+        return ShrinkWrap.create(WebArchive.class)
+                .addAsLibraries(ShrinkWrapArchiveUtil.getArchives(null,
+                        "META-INF/beans.xml",
+                        new String[]{"org.apache.deltaspike.core",
+                                "org.apache.deltaspike.test.core.api.alternative"},
+                        new String[]{"META-INF.config"}))
+                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
+                .addAsManifestResource(EmptyAsset.INSTANCE, "GlobalAlternativeTest.INFO");
+    }
+
+    /**
+     * The alternative configured in the low-level config should get used instead of the default implementation
+     */
+    @Test
+    public void alternativeImplementationWithClassAsBaseType()
+    {
+        List<BaseBean1> testBeans = BeanProvider.getContextualReferences(BaseBean1.class, true);
+
+        Assert.assertEquals(1, testBeans.size());
+        Assert.assertEquals(SubBaseBean1.class.getName(), testBeans.get(0).getClass().getName());
+    }
+
+    /**
+     * The alternative configured in the low-level config should get used instead of the default implementation
+     */
+    @Test
+    public void alternativeImplementationWithInterfaceAsBaseType()
+    {
+        Assert.assertEquals(BaseInterface1AlternativeImplementation.class.getName(), this.bean.getClass().getName());
+    }
+
+    @Test
+    public void alternativeImplementationWithInterfaceAsBaseTypeAndQualifier()
+    {
+        Assert.assertEquals(BaseBeanA.class.getName(), this.beanA.getClass().getName());
+        Assert.assertEquals(AlternativeBaseBeanB.class.getName(), this.beanB.getClass().getName());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/SubBaseBean1.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/SubBaseBean1.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/SubBaseBean1.java
new file mode 100644
index 0000000..bd67b63
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/SubBaseBean1.java
@@ -0,0 +1,32 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global;
+
+import org.apache.deltaspike.test.core.api.alternative.global.BaseBean1;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Alternative;
+
+/**
+ */
+@Alternative
+@Dependent
+public class SubBaseBean1 extends BaseBean1
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/AlternativeBaseBeanB.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/AlternativeBaseBeanB.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/AlternativeBaseBeanB.java
new file mode 100644
index 0000000..e84c644
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/AlternativeBaseBeanB.java
@@ -0,0 +1,32 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global.qualifier;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Alternative;
+
+/**
+ *
+ */
+@Dependent
+@Alternative
+@QualifierB(value = QualifierValue1.class, hint = "non-binding hint")
+public class AlternativeBaseBeanB implements BaseInterface
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanA.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanA.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanA.java
new file mode 100644
index 0000000..8b7b436
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanA.java
@@ -0,0 +1,30 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global.qualifier;
+
+import javax.enterprise.context.Dependent;
+
+/**
+ *
+ */
+@Dependent
+@QualifierA(QualifierValue1.class)
+public class BaseBeanA implements BaseInterface
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB.java
new file mode 100644
index 0000000..e24a0a5
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB.java
@@ -0,0 +1,30 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global.qualifier;
+
+import javax.enterprise.context.Dependent;
+
+/**
+ *
+ */
+@Dependent
+@QualifierB(QualifierValue1.class)
+public class BaseBeanB implements BaseInterface
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB2.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB2.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB2.java
new file mode 100644
index 0000000..03b7586
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB2.java
@@ -0,0 +1,30 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global.qualifier;
+
+import javax.enterprise.context.Dependent;
+
+/**
+ *
+ */
+@Dependent
+@QualifierB(QualifierValue2.class)
+public class BaseBeanB2 implements BaseInterface
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseInterface.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseInterface.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseInterface.java
new file mode 100644
index 0000000..5932252
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseInterface.java
@@ -0,0 +1,25 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global.qualifier;
+
+/**
+ */
+public interface BaseInterface
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierA.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierA.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierA.java
new file mode 100644
index 0000000..c812b09
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierA.java
@@ -0,0 +1,42 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global.qualifier;
+
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ *
+ */
+@Qualifier
+
+@Target({FIELD, METHOD, TYPE})
+@Retention(RUNTIME)
+
+public @interface QualifierA
+{
+    Class value();
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierB.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierB.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierB.java
new file mode 100644
index 0000000..88936f8
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierB.java
@@ -0,0 +1,45 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global.qualifier;
+
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ *
+ */
+@Qualifier
+
+@Target({FIELD, METHOD, TYPE})
+@Retention(RUNTIME)
+
+public @interface QualifierB
+{
+    Class value();
+
+    @Nonbinding
+    String hint() default "default hint";
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue1.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue1.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue1.java
new file mode 100644
index 0000000..796231d
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue1.java
@@ -0,0 +1,25 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global.qualifier;
+
+/**
+ */
+public interface QualifierValue1
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue2.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue2.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue2.java
new file mode 100644
index 0000000..89ce292
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue2.java
@@ -0,0 +1,25 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.global.qualifier;
+
+/**
+ */
+public interface QualifierValue2
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseBean2.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseBean2.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseBean2.java
new file mode 100644
index 0000000..59518df
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseBean2.java
@@ -0,0 +1,30 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.local;
+
+import javax.enterprise.context.Dependent;
+
+/**
+ * Simple base bean which doesn't get overruled by an global alternative
+ */
+//Workaround until different config files for unit tests work correctly
+@Dependent
+public class BaseBean2
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2.java
new file mode 100644
index 0000000..9ae5890
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2.java
@@ -0,0 +1,27 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.local;
+
+/**
+ * Simple interface - at runtime the default implementation gets activated
+ */
+//Workaround until different config files for unit tests work correctly
+public interface BaseInterface2
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2AlternativeImplementation.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2AlternativeImplementation.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2AlternativeImplementation.java
new file mode 100644
index 0000000..29a84e9
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2AlternativeImplementation.java
@@ -0,0 +1,38 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.local;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Alternative;
+
+/**
+ * Alternative which isn't configured as global alternative.
+ *
+ * (A normal alternative usually it would be in a different BDA - here we have the same BDA but no config in
+ * beans.xml which simulates the behaviour - compared to {@link org.apache.deltaspike.test.core.api.alternative.global.BaseInterface1AlternativeImplementation} which is also
+ * not configured in the beans.xml, but as global alternative (via DeltaSpike). Since we don't test the CDI
+ * implementation itself, it's ok to simulate it.
+ * Otherwise it will break with CDI 1.1 or at least with the default behaviour of OWB.)
+ */
+@Alternative
+@Dependent
+//Workaround until different config files for unit tests work correctly
+public class BaseInterface2AlternativeImplementation implements BaseInterface2
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2DefaultImplementation.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2DefaultImplementation.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2DefaultImplementation.java
new file mode 100644
index 0000000..81ae08e
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2DefaultImplementation.java
@@ -0,0 +1,30 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.local;
+
+import javax.enterprise.context.Dependent;
+
+/**
+ * Default implementation which doesn't get overruled by the alternative
+ */
+@Dependent
+//Workaround until different config files for unit tests work correctly
+public class BaseInterface2DefaultImplementation implements BaseInterface2
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BdaAlternativeTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BdaAlternativeTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BdaAlternativeTest.java
new file mode 100644
index 0000000..cf17fb6
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BdaAlternativeTest.java
@@ -0,0 +1,84 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.local;
+
+
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.test.core.api.temptestutil.ShrinkWrapArchiveUtil;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.inject.Inject;
+import java.util.List;
+
+/**
+ * Keep in sync with {@link org.apache.deltaspike.test.core.api.alternative.global.GlobalAlternativeTest} -
+ * but without configuring the alternatives and check for the default implementations.
+ *
+ * Tests which checks the behaviour with deactivated global alternates.
+ */
+@RunWith(Arquillian.class)
+public class BdaAlternativeTest
+{
+    @Inject
+    private BaseInterface2 bean;
+
+    /**
+     * X TODO creating a WebArchive is only a workaround because JavaArchive cannot contain other archives.
+     */
+    @Deployment
+    public static WebArchive deploy()
+    {
+        return ShrinkWrap.create(WebArchive.class)
+                .addAsLibraries(ShrinkWrapArchiveUtil.getArchives(null,
+                        "META-INF/beans.xml",
+                        new String[]{"org.apache.deltaspike.core",
+                                "org.apache.deltaspike.test.core.api.alternative"},
+                        new String[]{"META-INF.config"}))
+                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
+                .addAsManifestResource(EmptyAsset.INSTANCE, "GlobalAlternativeTest.INFO");
+    }
+
+    /*
+     * The default implementation should be found
+     */
+    @Test
+    public void alternativeImplementationWithClassAsBaseType()
+    {
+        List<BaseBean2> testBeans = BeanProvider.getContextualReferences(BaseBean2.class, true);
+
+        Assert.assertEquals(1, testBeans.size());
+        Assert.assertEquals(BaseBean2.class.getName(), testBeans.get(0).getClass().getName());
+    }
+
+    /*
+     * The default implementation should be found
+     */
+    @Test
+    public void alternativeImplementationWithInterfaceAsBaseType()
+    {
+        Assert.assertEquals(BaseInterface2DefaultImplementation.class.getName(), this.bean.getClass().getName());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/SubBaseBean2.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/SubBaseBean2.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/SubBaseBean2.java
new file mode 100644
index 0000000..b64375e
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/SubBaseBean2.java
@@ -0,0 +1,37 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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.deltaspike.test.core.api.alternative.local;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Alternative;
+
+/**
+ * Alternative which isn't configured as global alternative.
+ *
+ * (A normal alternative usually it would be in a different BDA - here we have the same BDA but no config in
+ * beans.xml which simulates the behaviour - compared to {@link org.apache.deltaspike.test.core.api.alternative.global.SubBaseBean1} which is also not configured
+ * in the beans.xml, but as global alternative (via DeltaSpike). Since we don't test the CDI implementation itself,
+ * it's ok to simulate it. Otherwise it will break with CDI 1.1 or at least with the default behaviour of OWB.)
+ */
+@Alternative
+@Dependent
+//Workaround until different config files for unit tests work correctly
+public class SubBaseBean2 extends BaseBean2
+{
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/projectstage/TestProjectStages.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/projectstage/TestProjectStages.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/projectstage/TestProjectStages.java
index 0e5eafb..4f0f37d 100644
--- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/projectstage/TestProjectStages.java
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/projectstage/TestProjectStages.java
@@ -22,6 +22,8 @@ package org.apache.deltaspike.test.core.api.projectstage;
 import org.apache.deltaspike.core.api.projectstage.ProjectStage;
 import org.apache.deltaspike.core.api.projectstage.ProjectStageHolder;
 
+import javax.enterprise.inject.Typed;
+
 /**
  * This is a test ProjectStage. It demonstrates how to add custom ProjectStages.
  * This TestProjectStage must get registered via the {@link java.util.ServiceLoader}
@@ -32,6 +34,7 @@ import org.apache.deltaspike.core.api.projectstage.ProjectStageHolder;
  */
 public class TestProjectStages implements ProjectStageHolder
 {
+    @Typed()
     public static final class CustomProjectStage extends ProjectStage
     {
         private static final long serialVersionUID = 1029095387976167179L;

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/temptestutil/ShrinkWrapArchiveUtil.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/temptestutil/ShrinkWrapArchiveUtil.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/temptestutil/ShrinkWrapArchiveUtil.java
index c6305b8..7cda19b 100644
--- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/temptestutil/ShrinkWrapArchiveUtil.java
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/temptestutil/ShrinkWrapArchiveUtil.java
@@ -193,7 +193,7 @@ public class ShrinkWrapArchiveUtil
 
             // exclude rule
             if (excludeIfPackageExists(entryName, excludeIfPackageExists)) {
-                return null;
+                continue;
             }
 
             // include rule

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/5bab9450/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties b/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
index 6dbde66..6d43562 100644
--- a/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
+++ b/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
@@ -19,3 +19,8 @@ testProperty03=test_value_03
 org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.apache.deltaspike.test.core.impl.activation.TestClassDeactivator
 testProperty02=test_value_02
 db=prodDB
+
+org.apache.deltaspike.test.core.api.alternative.global.BaseBean1=org.apache.deltaspike.test.core.api.alternative.global.SubBaseBean1
+org.apache.deltaspike.test.core.api.alternative.global.BaseInterface1=org.apache.deltaspike.test.core.api.alternative.global.BaseInterface1AlternativeImplementation
+
+org.apache.deltaspike.test.core.api.alternative.global.qualifier.BaseInterface=org.apache.deltaspike.test.core.api.alternative.global.qualifier.AlternativeBaseBeanB