deltaspike-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From strub...@apache.org
Subject deltaspike git commit: DELTASPIKE-648 lookup to the parent ClassLoader and re-use their configs
Date Thu, 12 Feb 2015 21:03:27 GMT
Repository: deltaspike
Updated Branches:
  refs/heads/master 4a325499b -> cdefea9d3


DELTASPIKE-648 lookup to the parent ClassLoader and re-use their configs

First try. Probably need to debug deeper into various containers.
Let's see if Jenkins complains ;)


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

Branch: refs/heads/master
Commit: cdefea9d308a2c0bf02b7a9c7d36a89e2b74493e
Parents: 4a32549
Author: Mark Struberg <struberg@apache.org>
Authored: Thu Feb 12 22:01:43 2015 +0100
Committer: Mark Struberg <struberg@apache.org>
Committed: Thu Feb 12 22:01:43 2015 +0100

----------------------------------------------------------------------
 .../core/api/config/PropertyFileConfig.java     | 11 +++
 .../impl/config/ConfigurationExtension.java     | 73 ++++++++++++++++++--
 2 files changed, 79 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/cdefea9d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyFileConfig.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyFileConfig.java
b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyFileConfig.java
index fed736c..5d25b3a 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyFileConfig.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyFileConfig.java
@@ -34,6 +34,17 @@ package org.apache.deltaspike.core.api.config;
  * <p>
  * Please note that the configuration will only be available after the boot is finished.
This means that you cannot use
  * this configuration inside a CDI Extension before the boot is finished!</p>
+ *
+ * <p><b>Attention:</b> When using this logic inside an EAR then you might
get
+ * different behaviour depending on the Java EE
+ * server you are using. Some EE container use a different ClassLoader to bootstrap
+ * the application than later to serve Requests.
+ * In that case we would register the ConfigSources on the <em>wrong</em> ConfigResolver
+ * (means we register it to the wrong ClassLoader). If you did hit such an application server
+ * then you might need to switch back to manually register the
+ * {@link org.apache.deltaspike.core.spi.config.ConfigSource} or
+ * {@link org.apache.deltaspike.core.spi.config.ConfigSourceProvider} via the
+ * {@link java.util.ServiceLoader} mechanism described there.</p>.
  */
 public interface PropertyFileConfig extends DeltaSpikeConfig
 {

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/cdefea9d/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
index baec960..d578312 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
@@ -26,13 +26,18 @@ import javax.enterprise.inject.spi.Extension;
 import javax.enterprise.inject.spi.ProcessAnnotatedType;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.deltaspike.core.api.config.ConfigResolver;
 import org.apache.deltaspike.core.api.config.PropertyFileConfig;
 import org.apache.deltaspike.core.spi.activation.Deactivatable;
 import org.apache.deltaspike.core.spi.config.ConfigSource;
 import org.apache.deltaspike.core.util.ClassDeactivationUtils;
+import org.apache.deltaspike.core.util.ClassUtils;
 
 /**
  * This extension handles {@link org.apache.deltaspike.core.api.config.PropertyFileConfig}s
@@ -43,12 +48,24 @@ public class ConfigurationExtension implements Extension, Deactivatable
     private static final String CANNOT_CREATE_CONFIG_SOURCE_FOR_CUSTOM_PROPERTY_FILE_CONFIG
=
         "Cannot create ConfigSource for custom property-file config ";
 
+    /**
+     * This is a trick for EAR scenarios in some containers.
+     * They e.g. boot up the shared EAR lib with the ear ClassLoader.
+     * Thus any {@link org.apache.deltaspike.core.api.config.PropertyFileConfig} configuration
will just get
+     * activated for this very single EAR ClassLoader but <em>not</em> for all
the webapps.
+     * But if I have a property file in a jar in the shared EAR lib then I most likely also
like to get it
+     * if I call this from my webapp (TCCL).
+     * So we also automatically register all the PropertyFileConfigs we found in the 'parent
BeanManager'
+     * as well.
+     */
+    private static Map<ClassLoader, List<Class<? extends PropertyFileConfig>>>
detectedParentPropertyFileConfigs
+        = new ConcurrentHashMap<ClassLoader, List<Class<? extends PropertyFileConfig>>>();
+
     private boolean isActivated = true;
 
-    private List<Class<? extends PropertyFileConfig>> configSourcesClasses
+    private List<Class<? extends PropertyFileConfig>> propertyFileConfigClasses
         = new ArrayList<Class<?  extends PropertyFileConfig>>();
 
-
     @SuppressWarnings("UnusedDeclaration")
     protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery)
     {
@@ -74,7 +91,7 @@ public class ConfigurationExtension implements Extension, Deactivatable
             return;
         }
 
-        configSourcesClasses.add(pcsClass);
+        propertyFileConfigClasses.add(pcsClass);
     }
 
     @SuppressWarnings("UnusedDeclaration")
@@ -85,24 +102,70 @@ public class ConfigurationExtension implements Extension, Deactivatable
             return;
         }
 
-        List<ConfigSource> configSources = new ArrayList<ConfigSource>();
+        // create a local copy with all the collected PropertyFileConfig
+        Set<Class<? extends PropertyFileConfig>> allPropertyFileConfigClasses
+            = new HashSet<Class<? extends PropertyFileConfig>>(this.propertyFileConfigClasses);
+
+        // now add any PropertyFileConfigs from a 'parent BeanManager'
+        // we start with the current TCCL
+        ClassLoader currentClassLoader = ClassUtils.getClassLoader(null);
+        addParentPropertyFileConfigs(currentClassLoader, allPropertyFileConfigClasses);
 
-        for (Class<? extends PropertyFileConfig> propertyFileConfigClass : configSourcesClasses)
+        // now let's add our own PropertyFileConfigs to the detected ones.
+        // because maybe WE are a parent BeanManager ourselves!
+        if (!this.propertyFileConfigClasses.isEmpty())
+        {
+            detectedParentPropertyFileConfigs.put(currentClassLoader, this.propertyFileConfigClasses);
+        }
+
+        // collect all the ConfigSources from our PropertyFileConfigs
+        List<ConfigSource> configSources = new ArrayList<ConfigSource>();
+        for (Class<? extends PropertyFileConfig> propertyFileConfigClass : allPropertyFileConfigClasses)
         {
             configSources.addAll(createPropertyConfigSource(propertyFileConfigClass));
         }
 
+
         // finally add all
         ConfigResolver.addConfigSources(configSources);
     }
 
     /**
+     * Add all registered PropertyFileConfigs which got picked up in a parent ClassLoader
already
+     */
+    private void addParentPropertyFileConfigs(ClassLoader currentClassLoader,
+                                              Set<Class<? extends PropertyFileConfig>>
propertyFileConfigClasses)
+    {
+        if (currentClassLoader.getParent() == null)
+        {
+            return;
+        }
+
+        for (Map.Entry<ClassLoader, List<Class<? extends PropertyFileConfig>>>
classLoaderListEntry :
+                detectedParentPropertyFileConfigs.entrySet())
+        {
+            if (currentClassLoader.getParent().equals(classLoaderListEntry.getKey()))
+            {
+                // if this is the direct parent ClassLoader then lets add those PropertyFileConfigs.
+                propertyFileConfigClasses.addAll(classLoaderListEntry.getValue());
+
+                // even check further parents
+                addParentPropertyFileConfigs(classLoaderListEntry.getKey(), propertyFileConfigClasses);
+
+                // and be done. There can only be a single parent CL...
+                return;
+            }
+        }
+    }
+
+    /**
      * This method triggers freeing of the ConfigSources.
      */
     @SuppressWarnings("UnusedDeclaration")
     public void freeConfigSources(@Observes BeforeShutdown bs)
     {
         ConfigResolver.freeConfigSources();
+        detectedParentPropertyFileConfigs.remove(ClassUtils.getClassLoader(null));
     }
 
     /**


Mime
View raw message