MEECROWAVE-182 MEECROWAVE-181 antijarlocking and global context customizers

git-svn-id: https://svn.apache.org/repos/asf/openwebbeans/meecrowave/trunk@1853377 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/meecrowave-arquillian/src/main/java/org/apache/meecrowave/arquillian/MeecrowaveConfiguration.java b/meecrowave-arquillian/src/main/java/org/apache/meecrowave/arquillian/MeecrowaveConfiguration.java
index 087ef33..659a5db 100644
--- a/meecrowave-arquillian/src/main/java/org/apache/meecrowave/arquillian/MeecrowaveConfiguration.java
+++ b/meecrowave-arquillian/src/main/java/org/apache/meecrowave/arquillian/MeecrowaveConfiguration.java
@@ -109,6 +109,7 @@
     private Integer webSessionTimeout;
     private String webSessionCookieConfig;
     private boolean tomcatJspDevelopment;
+    private boolean antiJarLocking;
 
     // configurable cause when set to Local arquillian bypass some protocol configuration cause of container default
     private String arquillianProtocol = "Servlet 3.1";
@@ -811,4 +812,12 @@
     public void setWebSessionCookieConfig(final String webSessionCookieConfig) {
         this.webSessionCookieConfig = webSessionCookieConfig;
     }
+
+    public boolean isAntiJarLocking() {
+        return antiJarLocking;
+    }
+
+    public void setAntiJarLocking(final boolean antiJarLocking) {
+        this.antiJarLocking = antiJarLocking;
+    }
 }
diff --git a/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java b/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
index d9b56e3..703b77a 100644
--- a/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
+++ b/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
@@ -51,6 +51,7 @@
 import java.util.ArrayList;
 import java.util.Base64;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -97,7 +98,6 @@
 import org.apache.catalina.session.ManagerBase;
 import org.apache.catalina.session.StandardManager;
 import org.apache.catalina.startup.Catalina;
-import org.apache.meecrowave.tomcat.MeecrowaveContextConfig;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.coyote.http2.Http2Protocol;
 import org.apache.meecrowave.api.StartListening;
@@ -118,6 +118,7 @@
 import org.apache.meecrowave.service.ValueTransformer;
 import org.apache.meecrowave.tomcat.CDIInstanceManager;
 import org.apache.meecrowave.tomcat.LoggingAccessLogPattern;
+import org.apache.meecrowave.tomcat.MeecrowaveContextConfig;
 import org.apache.meecrowave.tomcat.NoDescriptorRegistry;
 import org.apache.meecrowave.tomcat.OWBJarScanner;
 import org.apache.meecrowave.tomcat.ProvidedLoader;
@@ -190,7 +191,11 @@
         final ProvidedLoader loader = new ProvidedLoader(classLoader, configuration.isTomcatWrapLoader());
         final Consumer<Context> builtInCustomizer = c -> {
             c.setLoader(loader);
+            if (configuration.antiJarLocking && StandardContext.class.isInstance(c)) {
+                StandardContext.class.cast(c).setAntiResourceLocking(true);
+            }
             configuration.getInitializers().forEach(i -> c.addServletContainerInitializer(i, emptySet()));
+            configuration.getGlobalContextConfigurers().forEach(it -> it.accept(c));
         };
         return deployWebapp(new DeploymentMeta(meta.context, meta.docBase, ofNullable(meta.consumer).map(c -> (Consumer<Context>) ctx -> {
             builtInCustomizer.accept(ctx);
@@ -719,6 +724,14 @@
                 .forEach(c -> c.accept(tomcat));
         configuration.instanceCustomizers.forEach(c -> c.accept(tomcat));
 
+        StreamSupport.stream(ServiceLoader.load(Meecrowave.ContextCustomizer.class).spliterator(), false)
+                .peek(i -> {
+                    if (MeecrowaveAwareContextCustomizer.class.isInstance(i)) {
+                        MeecrowaveAwareContextCustomizer.class.cast(i).setMeecrowave(this);
+                    }
+                })
+                .forEach(configuration::addGlobalContextCustomizer);
+
         beforeStart();
 
 
@@ -1381,6 +1394,12 @@
         @CliOption(name = "servlet-container-initializer", description = "ServletContainerInitializer instances.")
         private Collection<ServletContainerInitializer> initializers = new ArrayList<>();
 
+        @CliOption(name = "tomcat-antijarlocking", description = "Should anti-jar-locking be activated on StandardContext.")
+        private boolean antiJarLocking;
+
+        @CliOption(name = "tomcat-context-configurer", description = "Configurers for all webapps. The Consumer<Context> instances will be applied to all deployments.")
+        private Collection<Consumer<Context>> contextConfigurers;
+
         public Builder() { // load defaults
             extensions.put(ValueTransformers.class, new ValueTransformers());
             StreamSupport.stream(ServiceLoader.load(Meecrowave.ConfigurationCustomizer.class).spliterator(), false)
@@ -1400,6 +1419,18 @@
             }));
         }
 
+        public boolean isAntiJarLocking() {
+            return antiJarLocking;
+        }
+
+        public void setAntiJarLocking(final boolean antiJarLocking) {
+            this.antiJarLocking = antiJarLocking;
+        }
+
+        public Collection<Consumer<Context>> getGlobalContextConfigurers() {
+            return ofNullable(contextConfigurers).orElseGet(Collections::emptySet);
+        }
+
         public boolean isTomcatJspDevelopment() {
             return tomcatJspDevelopment;
         }
@@ -2116,6 +2147,13 @@
             configurationCustomizer.accept(this);
         }
 
+        public void addGlobalContextCustomizer(final Consumer<Context> contextConfigurer) {
+            if (contextConfigurers == null) {
+                contextConfigurers = new ArrayList<>();
+            }
+            contextConfigurers.add(contextConfigurer);
+        }
+
         public void addServletContextInitializer(final ServletContainerInitializer initializer) {
             initializers.add(initializer);
         }
@@ -2654,6 +2692,13 @@
     public interface InstanceCustomizer extends Consumer<Tomcat> {
     }
 
+    public interface ContextCustomizer extends Consumer<Context> {
+    }
+
+    public interface MeecrowaveAwareContextCustomizer extends ContextCustomizer {
+        void setMeecrowave(Meecrowave meecrowave);
+    }
+
     // since it is too early to have CDI and lookup the instance we must set it manually
     public interface MeecrowaveAwareInstanceCustomizer extends InstanceCustomizer {
         void setMeecrowave(Meecrowave meecrowave);
diff --git a/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveExtension.java b/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveExtension.java
index af13b18..a5ffdeb 100644
--- a/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveExtension.java
+++ b/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveExtension.java
@@ -100,6 +100,15 @@
     private Integer webSessionTimeout;
     private String webSessionCookieConfig;
     private boolean tomcatJspDevelopment;
+    private boolean antiJarLocking;
+
+    public boolean isAntiJarLocking() {
+        return antiJarLocking;
+    }
+
+    public void setAntiJarLocking(final boolean antiJarLocking) {
+        this.antiJarLocking = antiJarLocking;
+    }
 
     public boolean isTomcatJspDevelopment() {
         return tomcatJspDevelopment;
diff --git a/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveTask.java b/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveTask.java
index 867a716..07c99a1 100644
--- a/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveTask.java
+++ b/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveTask.java
@@ -246,6 +246,10 @@
 
     @Input
     @Optional
+    private boolean antiJarLocking = true;
+
+    @Input
+    @Optional
     private List<File> modules;
 
     @Input
@@ -1232,4 +1236,12 @@
     public void setTomcatJspDevelopment(final boolean tomcatJspDevelopment) {
         this.tomcatJspDevelopment = tomcatJspDevelopment;
     }
+
+    public boolean isAntiJarLocking() {
+        return antiJarLocking;
+    }
+
+    public void setAntiJarLocking(final boolean antiJarLocking) {
+        this.antiJarLocking = antiJarLocking;
+    }
 }
diff --git a/meecrowave-maven-plugin/src/main/java/org/apache/meecrowave/maven/MeecrowaveRunMojo.java b/meecrowave-maven-plugin/src/main/java/org/apache/meecrowave/maven/MeecrowaveRunMojo.java
index 095a257..60c9c72 100644
--- a/meecrowave-maven-plugin/src/main/java/org/apache/meecrowave/maven/MeecrowaveRunMojo.java
+++ b/meecrowave-maven-plugin/src/main/java/org/apache/meecrowave/maven/MeecrowaveRunMojo.java
@@ -91,6 +91,9 @@
     @Parameter(property = "meecrowave.useTomcatDefaults", defaultValue = "true")
     private boolean useTomcatDefaults;
 
+    @Parameter(property = "meecrowave.antiJarLocking", defaultValue = "false")
+    private boolean antiJarLocking;
+
     @Parameter
     private Map<String, String> properties;