You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by jo...@apache.org on 2015/10/12 04:32:14 UTC

deltaspike git commit: DELTASPIKE-1001 Non-caching support for ClassDeactivation.

Repository: deltaspike
Updated Branches:
  refs/heads/master 138c8b328 -> 40cc44418


DELTASPIKE-1001 Non-caching support for ClassDeactivation.

Separated out util into controllers.  Most work is done in the base class, Non-caching extends without
changes while Caching builds a local cache of the data.  Util creates a new controller if not present
and calculates it based on the project stage (assuming project stage is immutabile).


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

Branch: refs/heads/master
Commit: 40cc44418ae128317d66359e2f7cf4d3aacb1512
Parents: 138c8b3
Author: John D. Ament <jo...@apache.org>
Authored: Sun Oct 11 22:32:18 2015 -0400
Committer: John D. Ament <jo...@apache.org>
Committed: Sun Oct 11 22:32:18 2015 -0400

----------------------------------------------------------------------
 .../core/util/ClassDeactivationUtils.java       | 153 +++--------------
 .../BaseClassDeactivationController.java        | 168 +++++++++++++++++++
 .../CachingClassDeactivationController.java     |  61 +++++++
 .../NonCachingClassDeactivationController.java  |  27 +++
 .../CachingClassDeactivationControllerTest.java |  43 +++++
 .../util/activation/GenericDeactivatable.java   |  26 +++
 .../util/activation/GenericDeactivator.java     |  33 ++++
 ...nCachingClassDeactivationControllerTest.java |  44 +++++
 .../test/api/config/TestConfigSource.java       |   1 +
 9 files changed, 422 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40cc4441/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java
index 6fcd715..28d9290 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java
@@ -18,17 +18,15 @@
  */
 package org.apache.deltaspike.core.util;
 
-import org.apache.deltaspike.core.api.config.ConfigResolver;
-import org.apache.deltaspike.core.api.config.base.CoreBaseConfig;
-import org.apache.deltaspike.core.spi.activation.ClassDeactivator;
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
 import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.util.activation.BaseClassDeactivationController;
+import org.apache.deltaspike.core.util.activation.CachingClassDeactivationController;
+import org.apache.deltaspike.core.util.activation.NonCachingClassDeactivationController;
 
 import javax.enterprise.inject.Typed;
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
 
 /**
  * Helper methods for {@link ClassDeactivator}
@@ -36,24 +34,11 @@ import java.util.logging.Logger;
 @Typed()
 public abstract class ClassDeactivationUtils
 {
-    private static final Logger LOG = Logger.getLogger(ClassDeactivationUtils.class.getName());
+    private static final List<ProjectStage> NON_CACHING_PROJECT_STAGES =
+        Arrays.asList(ProjectStage.Development,ProjectStage.UnitTest);
 
-    /**
-     * This Map holds the ClassLoader as first level to make it possible to have different configurations per 
-     * WebApplication in an EAR or other Multi-ClassLoader scenario.
-     * 
-     * The Map then contains a List of {@link ClassDeactivator}s in order of their configured ordinal.
-     */
-    private static Map<ClassLoader, List<ClassDeactivator>> classDeactivatorMap
-        = new ConcurrentHashMap<ClassLoader, List<ClassDeactivator>>();
+    private static BaseClassDeactivationController classDeactivationController = null;
 
-    /**
-     * Cache for the result. It won't contain many classes but it might be accessed frequently.
-     * Valid entries are only true or false. If an entry isn't available or null, it gets calculated.
-     */
-    private static Map<Class<? extends Deactivatable>, Boolean> activationStatusCache
-        = new ConcurrentHashMap<Class<? extends Deactivatable>, Boolean>();
-    
     private ClassDeactivationUtils()
     {
         // prevent instantiation
@@ -67,130 +52,30 @@ public abstract class ClassDeactivationUtils
      */
     public static boolean isActivated(Class<? extends Deactivatable> targetClass)
     {
-        Boolean activatedClassCacheEntry = activationStatusCache.get(targetClass);
-
-        if (activatedClassCacheEntry == null)
-        {
-            initDeactivatableCacheFor(targetClass);
-            activatedClassCacheEntry = activationStatusCache.get(targetClass);
-        }
-        return activatedClassCacheEntry;
+        return getController().isActivated(targetClass);
     }
 
-    private static synchronized void initDeactivatableCacheFor(Class<? extends Deactivatable> targetClass)
+    private static BaseClassDeactivationController getController()
     {
-        Boolean activatedClassCacheEntry = activationStatusCache.get(targetClass);
-
-        if (activatedClassCacheEntry != null) //double-check
+        if (classDeactivationController == null)
         {
-            return;
+            classDeactivationController = calculateControllerToUse();
         }
 
-        List<ClassDeactivator> classDeactivators = getClassDeactivators();
-
-        Boolean isActivated = Boolean.TRUE;
-        Class<? extends ClassDeactivator> deactivatedBy = null;
-
-        LOG.fine("start evaluation if " + targetClass.getName() + " is de-/activated");
-
-        // we get the classActivators ordered by it's ordinal
-        // thus the last one which returns != null 'wins' ;)
-        for (ClassDeactivator classDeactivator : classDeactivators)
-        {
-            Boolean isLocallyActivated = classDeactivator.isActivated(targetClass);
-
-            if (isLocallyActivated != null)
-            {
-                isActivated = isLocallyActivated;
-
-                /*
-                * Check and log the details across class-deactivators
-                */
-                if (!isActivated)
-                {
-                    deactivatedBy = classDeactivator.getClass();
-                    LOG.fine("Deactivating class " + targetClass);
-                }
-                else if (deactivatedBy != null)
-                {
-                    LOG.fine("Reactivation of: " + targetClass.getName() + " by " +
-                            classDeactivator.getClass().getName() +
-                            " - original deactivated by: " + deactivatedBy.getName() + ".\n" +
-                            "If that isn't the intended behaviour, you have to use a higher ordinal for " +
-                            deactivatedBy.getName());
-                }
-            }
-        }
-
-        cacheResult(targetClass, isActivated);
-    }
-
-    private static void cacheResult(Class<? extends Deactivatable> targetClass, Boolean activated)
-    {
-        activationStatusCache.put(targetClass, activated);
-        LOG.info("class: " + targetClass.getName() + " activated=" + activated);
+        return classDeactivationController;
     }
 
-    /**
-     * @return the List of configured @{link ClassDeactivator}s for the current context ClassLoader.
-     */
-    private static List<ClassDeactivator> getClassDeactivators()
+    private static BaseClassDeactivationController calculateControllerToUse()
     {
-        ClassLoader classLoader = ClassUtils.getClassLoader(null);
-        List<ClassDeactivator> classDeactivators = classDeactivatorMap.get(classLoader);
+        ProjectStage currentProjectStage = ProjectStageProducer.getInstance().getProjectStage();
 
-        if (classDeactivators == null)
+        if (NON_CACHING_PROJECT_STAGES.contains(currentProjectStage))
         {
-            return initConfiguredClassDeactivators(classLoader);
+            return new NonCachingClassDeactivationController();
         }
-
-        return classDeactivators;
-    }
-
-    //synchronized isn't needed - #initDeactivatableCacheFor is already synchronized
-    private static List<ClassDeactivator> initConfiguredClassDeactivators(ClassLoader classLoader)
-    {
-        if (!ServiceUtils.loadServiceImplementations(ClassDeactivator.class).isEmpty())
+        else
         {
-            CoreBaseConfig.Validation.ViolationMode violationMode = CoreBaseConfig.Validation.VIOLATION_MODE;
-
-            String message = "It isn't supported to configure " + ClassDeactivator.class.getName() +
-                    " via the std. service-loader config. " +
-                    "Please remove all META-INF/services/" + ClassDeactivator.class.getName() + " files. " +
-                    "Please configure it via the DeltaSpike-Config (e.g. META-INF/apache-deltaspike.properties).";
-
-            if (violationMode == CoreBaseConfig.Validation.ViolationMode.FAIL)
-            {
-                throw new IllegalStateException(message);
-            }
-            else if (violationMode == CoreBaseConfig.Validation.ViolationMode.WARN)
-            {
-                LOG.warning(message);
-            }
-        }
-
-        List<String> classDeactivatorClassNames = ConfigResolver.getAllPropertyValues(ClassDeactivator.class.getName());
-
-        List<ClassDeactivator> classDeactivators = new ArrayList<ClassDeactivator>();
-
-        for (String classDeactivatorClassName : classDeactivatorClassNames)
-        {
-            LOG.fine("processing ClassDeactivator: " + classDeactivatorClassName);
-
-            try
-            {
-                ClassDeactivator currentClassDeactivator =
-                        (ClassDeactivator) ClassUtils.instantiateClassForName(classDeactivatorClassName);
-                classDeactivators.add(currentClassDeactivator);
-            }
-            catch (Exception e)
-            {
-                LOG.warning(classDeactivatorClassName + " can't be instantiated");
-                throw new IllegalStateException(e);
-            }
+            return new CachingClassDeactivationController();
         }
-
-        classDeactivatorMap.put(classLoader, classDeactivators);
-        return classDeactivators;
     }
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40cc4441/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/BaseClassDeactivationController.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/BaseClassDeactivationController.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/BaseClassDeactivationController.java
new file mode 100644
index 0000000..74c3b34
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/BaseClassDeactivationController.java
@@ -0,0 +1,168 @@
+/*
+ * 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.util.activation;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.api.config.base.CoreBaseConfig;
+import org.apache.deltaspike.core.spi.activation.ClassDeactivator;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.util.ClassUtils;
+import org.apache.deltaspike.core.util.ServiceUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+public abstract class BaseClassDeactivationController
+{
+    private static final Logger LOG = Logger.getLogger(BaseClassDeactivationController.class.getName());
+
+    /**
+     * This Map holds the ClassLoader as first level to make it possible to have different configurations per
+     * WebApplication in an EAR or other Multi-ClassLoader scenario.
+     *
+     * The Map then contains a List of {@link ClassDeactivator}s in order of their configured ordinal.
+     */
+    private static Map<ClassLoader, List<ClassDeactivator>> classDeactivatorMap =
+        new ConcurrentHashMap<ClassLoader, List<ClassDeactivator>>();
+
+    /**
+     * Evaluates if the given {@link Deactivatable} is active.
+     *
+     * @param targetClass {@link Deactivatable} under test.
+     * @return <code>true</code> if it is active, <code>false</code> otherwise
+     */
+    public boolean isActivated(Class<? extends Deactivatable> targetClass)
+    {
+        return calculateDeactivationStatusFor(targetClass);
+    }
+
+    /**
+     * Determines if the given class is activated or not.  ClassDeactivators are cached at a class loader level.
+     *
+     * @param targetClass the Deactivatable class to search on
+     * @return true if this class is activated, false if its not activated
+     */
+    protected static synchronized boolean calculateDeactivationStatusFor(Class<? extends Deactivatable> targetClass)
+    {
+        List<ClassDeactivator> classDeactivators = getClassDeactivators();
+
+        Boolean isActivated = Boolean.TRUE;
+        Class<? extends ClassDeactivator> deactivatedBy = null;
+
+        LOG.fine("start evaluation if " + targetClass.getName() + " is de-/activated");
+
+        // we get the classActivators ordered by it's ordinal
+        // thus the last one which returns != null 'wins' ;)
+        for (ClassDeactivator classDeactivator : classDeactivators)
+        {
+            Boolean isLocallyActivated = classDeactivator.isActivated(targetClass);
+
+            if (isLocallyActivated != null)
+            {
+                isActivated = isLocallyActivated;
+
+                /*
+                * Check and log the details across class-deactivators
+                */
+                if (!isActivated)
+                {
+                    deactivatedBy = classDeactivator.getClass();
+                    LOG.fine("Deactivating class " + targetClass);
+                }
+                else if (deactivatedBy != null)
+                {
+                    LOG.fine("Reactivation of: " + targetClass.getName() + " by " +
+                            classDeactivator.getClass().getName() +
+                            " - original deactivated by: " + deactivatedBy.getName() + ".\n" +
+                            "If that isn't the intended behaviour, you have to use a higher ordinal for " +
+                            deactivatedBy.getName());
+                }
+            }
+        }
+
+        return isActivated;
+    }
+
+    /**
+     * @return the List of configured @{link ClassDeactivator}s for the current context ClassLoader.
+     */
+    private static List<ClassDeactivator> getClassDeactivators()
+    {
+        ClassLoader classLoader = ClassUtils.getClassLoader(null);
+        List<ClassDeactivator> classDeactivators = classDeactivatorMap.get(classLoader);
+
+        if (classDeactivators == null)
+        {
+            return initConfiguredClassDeactivators(classLoader);
+        }
+
+        return classDeactivators;
+    }
+
+    //synchronized isn't needed - #initDeactivatableCacheFor is already synchronized
+    private static List<ClassDeactivator> initConfiguredClassDeactivators(ClassLoader classLoader)
+    {
+        if (!ServiceUtils.loadServiceImplementations(ClassDeactivator.class).isEmpty())
+        {
+            CoreBaseConfig.Validation.ViolationMode violationMode = CoreBaseConfig.Validation.VIOLATION_MODE;
+
+            String message = "It isn't supported to configure " + ClassDeactivator.class.getName() +
+                    " via the std. service-loader config. " +
+                    "Please remove all META-INF/services/" + ClassDeactivator.class.getName() + " files. " +
+                    "Please configure it via the DeltaSpike-Config (e.g. META-INF/apache-deltaspike.properties).";
+
+            if (violationMode == CoreBaseConfig.Validation.ViolationMode.FAIL)
+            {
+                throw new IllegalStateException(message);
+            }
+            else if (violationMode == CoreBaseConfig.Validation.ViolationMode.WARN)
+            {
+                LOG.warning(message);
+            }
+        }
+
+        List<String> classDeactivatorClassNames = ConfigResolver.getAllPropertyValues(ClassDeactivator.class.getName());
+
+        List<ClassDeactivator> classDeactivators = new ArrayList<ClassDeactivator>();
+
+        for (String classDeactivatorClassName : classDeactivatorClassNames)
+        {
+            LOG.fine("processing ClassDeactivator: " + classDeactivatorClassName);
+
+            try
+            {
+                ClassDeactivator currentClassDeactivator =
+                        (ClassDeactivator) ClassUtils.instantiateClassForName(classDeactivatorClassName);
+                classDeactivators.add(currentClassDeactivator);
+            }
+            catch (Exception e)
+            {
+                LOG.warning(classDeactivatorClassName + " can't be instantiated");
+                throw new IllegalStateException(e);
+            }
+        }
+
+        classDeactivatorMap.put(classLoader, classDeactivators);
+        return classDeactivators;
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40cc4441/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/CachingClassDeactivationController.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/CachingClassDeactivationController.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/CachingClassDeactivationController.java
new file mode 100644
index 0000000..729a384
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/CachingClassDeactivationController.java
@@ -0,0 +1,61 @@
+/*
+ * 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.util.activation;
+
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+
+import javax.enterprise.inject.Typed;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Typed()
+public class CachingClassDeactivationController extends BaseClassDeactivationController
+{
+    /**
+     * Cache for the result. It won't contain many classes but it might be accessed frequently.
+     * Valid entries are only true or false. If an entry isn't available or null, it gets calculated.
+     */
+    private Map<Class<? extends Deactivatable>, Boolean> activationStatusCache
+        = new ConcurrentHashMap<Class<? extends Deactivatable>, Boolean>();
+
+    /**
+     * Evaluates if the given {@link Deactivatable} is active.
+     *
+     * @param targetClass {@link Deactivatable} under test.
+     * @return <code>true</code> if it is active, <code>false</code> otherwise
+     */
+    public boolean isActivated(Class<? extends Deactivatable> targetClass)
+    {
+        Boolean activatedClassCacheEntry = activationStatusCache.get(targetClass);
+
+        if (activatedClassCacheEntry == null)
+        {
+            activatedClassCacheEntry = loadAndCacheResult(targetClass);
+        }
+        return activatedClassCacheEntry;
+    }
+
+    private synchronized boolean loadAndCacheResult(Class<? extends Deactivatable> targetClass)
+    {
+        boolean activatedClassCacheEntry = BaseClassDeactivationController.calculateDeactivationStatusFor(targetClass);
+        activationStatusCache.put(targetClass, activatedClassCacheEntry);
+        return activatedClassCacheEntry;
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40cc4441/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/NonCachingClassDeactivationController.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/NonCachingClassDeactivationController.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/NonCachingClassDeactivationController.java
new file mode 100644
index 0000000..1020d38
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/activation/NonCachingClassDeactivationController.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.core.util.activation;
+
+import javax.enterprise.inject.Typed;
+
+@Typed()
+public class NonCachingClassDeactivationController extends BaseClassDeactivationController
+{
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40cc4441/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/CachingClassDeactivationControllerTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/CachingClassDeactivationControllerTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/CachingClassDeactivationControllerTest.java
new file mode 100644
index 0000000..4c8cdd3
--- /dev/null
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/CachingClassDeactivationControllerTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.util.activation;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CachingClassDeactivationControllerTest {
+    @Before
+    public void initGenericDeactivator()
+    {
+        GenericDeactivator.ACTIVATED = null;
+    }
+
+    @Test
+    public void shouldIgnoreChangesToModifiedStatus()
+    {
+        CachingClassDeactivationController controller = new CachingClassDeactivationController();
+        boolean activated = controller.isActivated(GenericDeactivatable.class);
+        Assert.assertTrue(activated);
+        GenericDeactivator.ACTIVATED = false;
+        activated = controller.isActivated(GenericDeactivatable.class);
+        Assert.assertTrue(activated);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40cc4441/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/GenericDeactivatable.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/GenericDeactivatable.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/GenericDeactivatable.java
new file mode 100644
index 0000000..ba6841e
--- /dev/null
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/GenericDeactivatable.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.core.util.activation;
+
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+
+public class GenericDeactivatable implements Deactivatable
+{
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40cc4441/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/GenericDeactivator.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/GenericDeactivator.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/GenericDeactivator.java
new file mode 100644
index 0000000..a137a37
--- /dev/null
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/GenericDeactivator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.util.activation;
+
+import org.apache.deltaspike.core.spi.activation.ClassDeactivator;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+
+public class GenericDeactivator implements ClassDeactivator
+{
+    public static Boolean ACTIVATED = null;
+    @Override
+    public Boolean isActivated(Class<? extends Deactivatable> targetClass)
+    {
+        return ACTIVATED;
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40cc4441/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/NonCachingClassDeactivationControllerTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/NonCachingClassDeactivationControllerTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/NonCachingClassDeactivationControllerTest.java
new file mode 100644
index 0000000..82ddcd3
--- /dev/null
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/NonCachingClassDeactivationControllerTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.util.activation;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class NonCachingClassDeactivationControllerTest
+{
+    @Before
+    public void initGenericDeactivator()
+    {
+        GenericDeactivator.ACTIVATED = null;
+    }
+    @Test
+    public void shouldNotCacheResults()
+    {
+
+        NonCachingClassDeactivationController controller = new NonCachingClassDeactivationController();
+        boolean activated = controller.isActivated(GenericDeactivatable.class);
+        Assert.assertTrue(activated);
+        GenericDeactivator.ACTIVATED = false;
+        activated = controller.isActivated(GenericDeactivatable.class);
+        Assert.assertFalse(activated);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/40cc4441/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
index 7f0897c..5cebd4c 100644
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
@@ -77,6 +77,7 @@ public class TestConfigSource implements ConfigSource
         props.put("deltaspike.test.class-value", "org.apache.deltaspike.test.api.config.TestConfigSource");
         props.put("deltaspike.test.date-value", "2014-12-24");
         props.put("deltaspike.test.invalid-value", "wrong");
+        props.put("org.apache.deltaspike.core.spi.activation.ClassDeactivator","org.apache.deltaspike.core.util.activation.GenericDeactivator");
     }
 
     @Override