You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2019/06/28 09:31:11 UTC

[tomcat] branch master updated: Add example support for CDI 2 and JAX-RS

This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/master by this push:
     new addfaa7  Add example support for CDI 2 and JAX-RS
addfaa7 is described below

commit addfaa7740266fde67bb78adbf16620c2acbea81
Author: remm <re...@apache.org>
AuthorDate: Fri Jun 28 11:30:59 2019 +0200

    Add example support for CDI 2 and JAX-RS
    
    This provides user buildable optional modules (with a simple POM) which
    build two shaded JARs.
    The integration code for OpenWebBeans is supposed to be removed once the
    code is integrated in the upstream project and is present in an official
    release available in the Maven repository. It may take some time.
    The CXF module uses a single empty bean class for json provider
    registration (in this environment, it doesn't work without it for some
    reason).
---
 modules/cxf/.gitignore                             |  12 ++
 modules/cxf/pom.xml                                | 169 +++++++++++++++++++
 modules/cxf/src/main/java/tomcat/cxf/JsonBean.java |  28 ++++
 modules/cxf/src/main/resources/META-INF/beans.xml  |  27 ++++
 .../src/main/resources/META-INF/web-fragment.xml   |  39 +++++
 modules/owb/.gitignore                             |  13 ++
 modules/owb/pom.xml                                | 119 ++++++++++++++
 .../OpenWebBeansContextLifecycleListener.java      | 121 ++++++++++++++
 .../web/tomcat/OpenWebBeansInstanceManager.java    | 141 ++++++++++++++++
 .../webbeans/web/tomcat/OpenWebBeansListener.java  |  61 +++++++
 .../web/tomcat/OpenWebBeansSecurityValve.java      |  59 +++++++
 .../apache/webbeans/web/tomcat/TomcatPlugin.java   | 101 ++++++++++++
 .../webbeans/web/tomcat/TomcatSecurityService.java | 103 ++++++++++++
 .../META-INF/openwebbeans/openwebbeans.properties  | 158 ++++++++++++++++++
 ....apache.webbeans.spi.plugins.OpenWebBeansPlugin |  17 ++
 .../webbeans/web/tomcat/LocalStrings.properties    |  19 +++
 webapps/docs/cdi.xml                               | 179 +++++++++++++++++++++
 webapps/docs/changelog.xml                         |   5 +
 webapps/docs/project.xml                           |   1 +
 19 files changed, 1372 insertions(+)

diff --git a/modules/cxf/.gitignore b/modules/cxf/.gitignore
new file mode 100644
index 0000000..5f2dbe1
--- /dev/null
+++ b/modules/cxf/.gitignore
@@ -0,0 +1,12 @@
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+
+# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
+!/.mvn/wrapper/maven-wrapper.jar
diff --git a/modules/cxf/pom.xml b/modules/cxf/pom.xml
new file mode 100644
index 0000000..d64ca45
--- /dev/null
+++ b/modules/cxf/pom.xml
@@ -0,0 +1,169 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<!--
+
+    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.
+-->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>21</version>
+    </parent>
+
+    <groupId>org.apache.tomcat</groupId>
+    <artifactId>tomcat-cxf</artifactId>
+    <name>Apache CXF for Apache Tomcat CDI</name>
+    <description>Apache CXF packaged for Apache Tomcat CDI</description>
+    <version>1.0</version>
+    <packaging>jar</packaging>
+
+    <properties>
+        <cxf.version>3.3.2</cxf.version>
+        <geronimo-jcdi.version>1.0.1</geronimo-jcdi.version>
+        <javax.json-api.version>1.1.4</javax.json-api.version>
+        <javax.json.bind-api.version>1.0</javax.json.bind-api.version>
+        <johnzon.version>1.1.12</johnzon.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jcdi_2.0_spec</artifactId>
+            <version>${geronimo-jcdi.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.json</groupId>
+            <artifactId>javax.json-api</artifactId>
+            <version>${javax.json-api.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.json.bind</groupId>
+            <artifactId>javax.json.bind-api</artifactId>
+            <version>${javax.json.bind-api.version}</version>
+        </dependency>
+        <!-- Apache CXF -->
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-integration-cdi</artifactId>
+            <version>${cxf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-client</artifactId>
+            <version>${cxf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+            <version>${cxf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-extension-providers</artifactId>
+            <version>${cxf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-json-basic</artifactId>
+            <version>${cxf.version}</version>
+        </dependency>
+        <!-- Apache Johnzon -->
+        <dependency>
+            <groupId>org.apache.johnzon</groupId>
+            <artifactId>johnzon-jsonb</artifactId>
+            <version>${johnzon.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- Build any extra classes for your custom Tomcat components if needed -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>3.0.0</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <createDependencyReducedPom>false</createDependencyReducedPom>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/cxf/bus-extensions.txt</resource>
+                                </transformer>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>${mainClass}</mainClass>
+                                </transformer>
+                            </transformers>
+				            <artifactSet>
+                                <excludes>
+                                    <!-- Already present in Tomcat or in the CDI bundle -->
+                                    <exclude>javax.annotation:javax.annotation-api</exclude>
+									<exclude>javax.el:*</exclude>
+									<exclude>javax.enterprise:cdi-api</exclude>
+									<exclude>javax.inject:*</exclude>
+									<exclude>javax.interceptor:*</exclude>
+									<!-- Exclude other unneeded dependencies -->
+									<exclude>org.apache.ant:*</exclude>
+									<exclude>org.codehaus.woodstox:*</exclude>
+									<exclude>org.glassfish.jaxb:*</exclude>
+									<exclude>org.jvnet.staxex:*</exclude>
+									<exclude>com.fasterxml.woodstox:*</exclude>
+									<exclude>com.sun.istack:*</exclude>
+									<exclude>com.sun.xml.*:*</exclude>
+								</excludes>
+                            </artifactSet>
+					        <filters>
+                                <filter>
+						            <artifact>*:*</artifact>
+						            <excludes>
+										<exclude>META-INF/*.SF</exclude>
+										<exclude>META-INF/*.DSA</exclude>
+										<exclude>META-INF/*.RSA</exclude>
+										<exclude>META-INF/LICENSE.txt</exclude>
+										<exclude>META-INF/LICENSE</exclude>
+										<exclude>META-INF/NOTICE.txt</exclude>
+										<exclude>META-INF/NOTICE</exclude>
+										<!-- Unneeded configuration files -->
+										<exclude>META-INF/cxf/cxf.*</exclude>
+										<exclude>META-INF/cxf/cxf-servlet.*</exclude>
+										<exclude>META-INF/cxf/org.apache.cxf.bus.factory</exclude>
+										<exclude>META-INF/services/org.apache.cxf.bus.factory</exclude>
+										<exclude>META-INF/spring.*</exclude>
+						            </excludes>
+                                </filter>
+					        </filters>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/modules/cxf/src/main/java/tomcat/cxf/JsonBean.java b/modules/cxf/src/main/java/tomcat/cxf/JsonBean.java
new file mode 100644
index 0000000..88ce138
--- /dev/null
+++ b/modules/cxf/src/main/java/tomcat/cxf/JsonBean.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 tomcat.cxf;
+
+import javax.enterprise.context.Dependent;
+import javax.ws.rs.Produces;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.johnzon.jaxrs.jsonb.jaxrs.JsonbJaxrsProvider;
+
+@Produces("application/json")
+@Provider
+@Dependent
+public class JsonBean<T> extends JsonbJaxrsProvider<T> {}
diff --git a/modules/cxf/src/main/resources/META-INF/beans.xml b/modules/cxf/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..d483402
--- /dev/null
+++ b/modules/cxf/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+    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.
+-->
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="annotated"
+       version="2.0">
+       <exclude name="com.*" />
+       <exclude name="javax.*" />
+       <exclude name="mozilla.*" />
+       <exclude name="org.*" />
+</beans>
diff --git a/modules/cxf/src/main/resources/META-INF/web-fragment.xml b/modules/cxf/src/main/resources/META-INF/web-fragment.xml
new file mode 100644
index 0000000..75ec8db
--- /dev/null
+++ b/modules/cxf/src/main/resources/META-INF/web-fragment.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+    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.
+-->
+<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
+  version="4.0">
+    <name>tomcat-cxf</name>
+    <ordering>
+        <before>
+            <others/>
+        </before>
+    </ordering>
+    <servlet>
+        <servlet-name>ApacheTomcatCXFServlet</servlet-name>
+        <display-name>Apache Tomcat CXF Servlet</display-name>
+        <servlet-class>org.apache.cxf.cdi.CXFCdiServlet</servlet-class>    
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>ApacheTomcatCXFServlet</servlet-name>
+        <url-pattern>/api/*</url-pattern>
+    </servlet-mapping>
+</web-fragment>
diff --git a/modules/owb/.gitignore b/modules/owb/.gitignore
new file mode 100644
index 0000000..6c3c891
--- /dev/null
+++ b/modules/owb/.gitignore
@@ -0,0 +1,13 @@
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+
+# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
+!/.mvn/wrapper/maven-wrapper.jar
+/bin/
diff --git a/modules/owb/pom.xml b/modules/owb/pom.xml
new file mode 100644
index 0000000..9e63efe
--- /dev/null
+++ b/modules/owb/pom.xml
@@ -0,0 +1,119 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<!--
+
+    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.
+-->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>21</version>
+    </parent>
+
+    <groupId>org.apache.tomcat</groupId>
+    <artifactId>tomcat-owb</artifactId>
+    <name>Apache Tomcat CDI 2 support</name>
+    <description>Apache Tomcat CDI 2 support using Apache OpenWebBeans</description>
+    <version>1.0</version>
+    <packaging>jar</packaging>
+
+    <properties>
+        <geronimo-atinject.version>1.0</geronimo-atinject.version>
+        <geronimo-interceptor.version>1.0</geronimo-interceptor.version>
+        <geronimo-jcdi.version>1.0.1</geronimo-jcdi.version>
+        <owb.version>2.0.10</owb.version>
+        <tomcat.version>9.0.21</tomcat.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-atinject_1.0_spec</artifactId>
+           <version>${geronimo-atinject.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-interceptor_1.2_spec</artifactId>
+            <version>${geronimo-interceptor.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jcdi_2.0_spec</artifactId>
+            <version>${geronimo-jcdi.version}</version>
+        </dependency>
+        <!-- Apache OpenWebBeans -->
+        <dependency>
+            <groupId>org.apache.openwebbeans</groupId>
+            <artifactId>openwebbeans-spi</artifactId>
+            <version>${owb.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.openwebbeans</groupId>
+            <artifactId>openwebbeans-impl</artifactId>
+            <version>${owb.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.openwebbeans</groupId>
+            <artifactId>openwebbeans-web</artifactId>
+            <version>${owb.version}</version>
+        </dependency>
+        <!-- Allows building integration code, temporarily located here -->
+        <dependency>
+            <groupId>org.apache.tomcat</groupId>
+            <artifactId>tomcat-catalina</artifactId>
+            <version>${tomcat.version}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>3.0.0</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <createDependencyReducedPom>false</createDependencyReducedPom>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>${mainClass}</mainClass>
+                                </transformer>
+                            </transformers>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansContextLifecycleListener.java b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansContextLifecycleListener.java
new file mode 100644
index 0000000..909c7f4
--- /dev/null
+++ b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansContextLifecycleListener.java
@@ -0,0 +1,121 @@
+/*
+ * 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.webbeans.web.tomcat;
+
+import java.util.LinkedList;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.Pipeline;
+import org.apache.catalina.Valve;
+import org.apache.tomcat.InstanceManager;
+import org.apache.webbeans.servlet.WebBeansConfigurationListener;
+
+
+/**
+ * Context lifecycle listener.
+ */
+public class OpenWebBeansContextLifecycleListener implements LifecycleListener {
+
+    /**
+     * Start without a beans.xml file.
+     */
+    protected boolean startWithoutBeansXml = true;
+
+    /**
+     * @return the startWithoutBeansXml
+     */
+    public boolean getStartWithoutBeansXml() {
+        return startWithoutBeansXml;
+    }
+
+    /**
+     * @param startWithoutBeansXml the startWithoutBeansXml to set
+     */
+    public void setStartWithoutBeansXml(boolean startWithoutBeansXml) {
+        this.startWithoutBeansXml = startWithoutBeansXml;
+    }
+
+    @Override
+    public void lifecycleEvent(LifecycleEvent event) {
+        if (event.getSource() instanceof Context) {
+            Context context = (Context) event.getSource();
+            if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
+                if (getStartWithoutBeansXml()
+                        || context.getResources().getResource("/WEB-INF/beans.xml").exists()
+                        || context.getResources().getResource("/WEB-INF/classes/META-INF/beans.xml").exists()) {
+                    // Registering ELResolver with JSP container
+                    System.setProperty("org.apache.webbeans.application.jsp", "true");
+                    // Add Listeners
+                    String[] oldListeners = context.findApplicationListeners();
+                    LinkedList<String> listeners = new LinkedList<>();
+                    listeners.addFirst(WebBeansConfigurationListener.class.getName());
+                    for (String listener : oldListeners) {
+                        listeners.add(listener);
+                        context.removeApplicationListener(listener);
+                    }
+                    for (String listener : listeners) {
+                        context.addApplicationListener(listener);
+                    }
+                    Pipeline pipeline = context.getPipeline();
+                    // Add to the corresponding pipeline to get a notification once configure is done
+                    if (pipeline instanceof Lifecycle) {
+                        boolean contextLifecycleListenerFound = false;
+                        for (LifecycleListener listener : ((Lifecycle) pipeline).findLifecycleListeners()) {
+                            if (listener instanceof OpenWebBeansContextLifecycleListener) {
+                                contextLifecycleListenerFound = true;
+                            }
+                        }
+                        if (!contextLifecycleListenerFound) {
+                            ((Lifecycle) pipeline).addLifecycleListener(this);
+                        }
+                    }
+                    // Add security valve
+                    boolean securityValveFound = false;
+                    for (Valve valve : pipeline.getValves()) {
+                        if (valve instanceof OpenWebBeansSecurityValve) {
+                            securityValveFound = true;
+                        }
+                    }
+                    if (!securityValveFound) {
+                        pipeline.addValve(new OpenWebBeansSecurityValve());
+                    }
+                }
+            }
+        } else if (event.getSource() instanceof Pipeline && event.getType().equals(Lifecycle.START_EVENT)) {
+            // This notification occurs once the configuration is fully done, including naming resources setup
+            // Otherwise, the instance manager is not ready for creation
+            Pipeline pipeline = (Pipeline) event.getSource();
+            if (pipeline.getContainer() instanceof Context) {
+                Context context = (Context) pipeline.getContainer();
+                if (!(context.getInstanceManager() instanceof OpenWebBeansInstanceManager)) {
+                    InstanceManager processor = context.getInstanceManager();
+                    if (processor == null) {
+                        processor = context.createInstanceManager();
+                    }
+                    InstanceManager custom = new OpenWebBeansInstanceManager(context.getLoader().getClassLoader(), processor);
+                    context.setInstanceManager(custom);
+                }
+            }
+        }
+    }
+
+}
diff --git a/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansInstanceManager.java b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansInstanceManager.java
new file mode 100644
index 0000000..6ccc9e3
--- /dev/null
+++ b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansInstanceManager.java
@@ -0,0 +1,141 @@
+/*
+ * 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.webbeans.web.tomcat;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Producer;
+import javax.naming.NamingException;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.InstanceManager;
+import org.apache.tomcat.util.res.StringManager;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.container.BeanManagerImpl;
+import org.apache.webbeans.inject.OWBInjector;
+
+public class OpenWebBeansInstanceManager implements InstanceManager {
+
+    private static final Log log = LogFactory.getLog(OpenWebBeansInstanceManager.class);
+    private static final StringManager sm = StringManager.getManager(OpenWebBeansInstanceManager.class);
+
+    private final ClassLoader loader;
+    private final InstanceManager instanceManager;
+    private final Map<Object, Instance> instances = new ConcurrentHashMap<>();
+    private static final class Instance {
+        private final Object object;
+        private final CreationalContext<?> context;
+        private Instance(Object object, CreationalContext<?> context) {
+            this.object = object;
+            this.context = context;
+        }
+    }
+
+    public OpenWebBeansInstanceManager(ClassLoader loader, InstanceManager instanceManager) {
+        this.loader = loader;
+        this.instanceManager = instanceManager;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void destroyInstance(Object object)
+            throws IllegalAccessException, InvocationTargetException {
+        Instance injectorInstance = instances.get(object);
+        if (injectorInstance != null) {
+            try {
+                ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
+                Thread.currentThread().setContextClassLoader(loader);
+                try {
+                    BeanManagerImpl beanManager = WebBeansContext.currentInstance().getBeanManagerImpl();
+                    @SuppressWarnings("rawtypes")
+                    Producer producer = beanManager.getProducerForJavaEeComponent(injectorInstance.object.getClass());
+                    if (producer != null) {
+                        producer.dispose(injectorInstance.object);
+                    } else if (injectorInstance.context != null) {
+                        injectorInstance.context.release();
+                    }
+                } finally {
+                    Thread.currentThread().setContextClassLoader(oldLoader);
+                }
+            } catch (Exception e) {
+                log.error(sm.getString("instanceManager.destroyError", object), e);
+            }
+        }
+        this.instanceManager.destroyInstance(object);
+    }
+
+    @Override
+    public Object newInstance(Class<?> aClass) throws IllegalAccessException,
+            InvocationTargetException, NamingException, InstantiationException,
+            IllegalArgumentException, NoSuchMethodException, SecurityException {
+        Object object = this.instanceManager.newInstance(aClass);
+        inject(object);
+        return object;
+    }
+
+    @Override
+    public Object newInstance(String str)
+            throws IllegalAccessException, InvocationTargetException,
+            NamingException, InstantiationException, ClassNotFoundException,
+            IllegalArgumentException, NoSuchMethodException, SecurityException {
+        Object object = this.instanceManager.newInstance(str);
+        inject(object);
+        return object;
+    }
+
+    @Override
+    public void newInstance(Object object) throws IllegalAccessException,
+            InvocationTargetException, NamingException {
+        inject(object);
+    }
+
+    @Override
+    public Object newInstance(String str, ClassLoader cl)
+            throws IllegalAccessException, InvocationTargetException,
+            NamingException, InstantiationException, ClassNotFoundException,
+            IllegalArgumentException, NoSuchMethodException, SecurityException {
+        Object object = this.instanceManager.newInstance(str, cl);
+        inject(object);
+        return object;
+    }
+
+    private void inject(Object object) {
+        try {
+            ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
+            Thread.currentThread().setContextClassLoader(loader);
+            CreationalContext<?> context = null;
+            try {
+                BeanManager beanManager = WebBeansContext.currentInstance().getBeanManagerImpl();
+                context = beanManager.createCreationalContext(null);
+                OWBInjector.inject(beanManager, object, context);
+            } finally {
+                Thread.currentThread().setContextClassLoader(oldLoader);
+            }
+            instances.put(object, new Instance(object, context));
+        } catch (Exception e) {
+            log.error(sm.getString("instanceManager.injectError", object), e);
+        }
+    }
+
+}
diff --git a/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansListener.java b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansListener.java
new file mode 100644
index 0000000..dcab474
--- /dev/null
+++ b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansListener.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.webbeans.web.tomcat;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.core.FrameworkListener;
+
+/**
+ * This listener must be declared in server.xml as a Server listener to be active.
+ * It will add OpenWebBeansContextLifecycleListener on all contexts.
+ */
+public class OpenWebBeansListener extends FrameworkListener {
+
+    public OpenWebBeansListener() {
+        // Try loading a class from OpenWebBeans to make sure it is available
+        new org.apache.webbeans.exception.WebBeansConfigurationException("");
+    }
+
+    @Override
+    protected LifecycleListener createLifecycleListener(Context context) {
+        OpenWebBeansContextLifecycleListener listener = new OpenWebBeansContextLifecycleListener();
+        listener.setStartWithoutBeansXml(getStartWithoutBeansXml());
+        return listener;
+    }
+
+    /**
+     * Start without a beans.xml file.
+     */
+    protected boolean startWithoutBeansXml = true;
+
+    /**
+     * @return the startWithoutBeansXml
+     */
+    public boolean getStartWithoutBeansXml() {
+        return startWithoutBeansXml;
+    }
+
+    /**
+     * @param startWithoutBeansXml the startWithoutBeansXml to set
+     */
+    public void setStartWithoutBeansXml(boolean startWithoutBeansXml) {
+        this.startWithoutBeansXml = startWithoutBeansXml;
+    }
+
+}
diff --git a/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansSecurityValve.java b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansSecurityValve.java
new file mode 100644
index 0000000..747f932
--- /dev/null
+++ b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansSecurityValve.java
@@ -0,0 +1,59 @@
+/*
+ * 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.webbeans.web.tomcat;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import javax.servlet.ServletException;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.valves.ValveBase;
+
+
+/**
+ * Valve which sets the UserPrincipal into a ThreadLocal
+ * to make it injectable via a CDI Producer.
+ */
+public class OpenWebBeansSecurityValve extends ValveBase {
+
+    private static ThreadLocal<Principal> principal = new ThreadLocal<>();
+
+    public static Principal getPrincipal() {
+        return principal.get();
+    }
+
+    @Override
+    public void invoke(Request request, Response response)
+            throws IOException, ServletException {
+        Principal p = request.getUserPrincipal();
+        try {
+            if (p != null) {
+                principal.set(p);
+            }
+            getNext().invoke(request, response);
+        } finally {
+            if (p != null) {
+                principal.remove();
+            }
+        }
+    }
+
+}
diff --git a/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/TomcatPlugin.java b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/TomcatPlugin.java
new file mode 100644
index 0000000..7eb8f21
--- /dev/null
+++ b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/TomcatPlugin.java
@@ -0,0 +1,101 @@
+/*
+ * 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.webbeans.web.tomcat;
+
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionListener;
+
+import java.util.EventListener;
+
+import org.apache.tomcat.util.res.StringManager;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.exception.WebBeansConfigurationException;
+import org.apache.webbeans.spi.SecurityService;
+import org.apache.webbeans.spi.plugins.AbstractOwbPlugin;
+
+/**
+ * Tomcat plugin for OpenWebBeans.
+ */
+public class TomcatPlugin extends AbstractOwbPlugin {
+
+    private static final StringManager sm = StringManager.getManager(TomcatPlugin.class);
+
+    /**
+     * Security service implementation.
+     */
+    private final TomcatSecurityService securityService = new TomcatSecurityService(WebBeansContext.getInstance());
+
+    @Override
+    public <T> T getSupportedService(Class<T> serviceClass) {
+        if (serviceClass.equals(SecurityService.class)) {
+            return serviceClass.cast(this.securityService);
+        }
+        return null;
+    }
+
+    @Override
+    public void isManagedBean(Class<?> clazz) {
+        if (isServletSpecClass(clazz)) {
+            throw new WebBeansConfigurationException(sm.getString("plugin.notManagedBean", clazz.getName()));
+        }
+    }
+
+    @Override
+    public boolean supportsJavaEeComponentInjections(Class<?> clazz) {
+        if (isServletSpecClass(clazz)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isServletSpecClass(Class<?> clazz) {
+        if (Servlet.class.isAssignableFrom(clazz)
+                || Filter.class.isAssignableFrom(clazz)) {
+            return true;
+        }
+        if (EventListener.class.isAssignableFrom(clazz)) {
+            return ServletContextListener.class.isAssignableFrom(clazz)
+                    || ServletContextAttributeListener.class.isAssignableFrom(clazz)
+                    || HttpSessionActivationListener.class.isAssignableFrom(clazz)
+                    || HttpSessionAttributeListener.class.isAssignableFrom(clazz)
+                    || HttpSessionBindingListener.class.isAssignableFrom(clazz)
+                    || HttpSessionListener.class.isAssignableFrom(clazz)
+                    || ServletRequestListener.class.isAssignableFrom(clazz)
+                    || ServletRequestAttributeListener.class.isAssignableFrom(clazz);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean supportService(Class<?> serviceClass) {
+        if (serviceClass.equals(SecurityService.class)) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/TomcatSecurityService.java b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/TomcatSecurityService.java
new file mode 100644
index 0000000..cf055ca
--- /dev/null
+++ b/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/TomcatSecurityService.java
@@ -0,0 +1,103 @@
+/*
+ * 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.webbeans.web.tomcat;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.security.Principal;
+import java.util.Objects;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.CDI;
+import javax.security.auth.Subject;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.corespi.security.SimpleSecurityService;
+
+public class TomcatSecurityService extends SimpleSecurityService {
+    private final boolean useWrapper;
+    private final Principal proxy;
+
+    public TomcatSecurityService(final WebBeansContext context) {
+        useWrapper = "true".equalsIgnoreCase(context.getOpenWebBeansConfiguration()
+                .getProperty("org.apache.webbeans.component.PrincipalBean.proxy", "true"));
+        final ClassLoader loader = SimpleSecurityService.class.getClassLoader();
+        final Class<?>[] apiToProxy = Stream.concat(
+                Stream.of(Principal.class),
+                Stream.of(context.getOpenWebBeansConfiguration()
+                        .getProperty("org.apache.webbeans.component.PrincipalBean.proxyApis", "org.eclipse.microprofile.jwt.JsonWebToken").split(","))
+                        .map(String::trim)
+                        .filter(it -> !it.isEmpty())
+                        .map(it -> {
+                            try { // if MP JWT-Auth is available
+                                return loader.loadClass(it.trim());
+                            } catch (final NoClassDefFoundError | ClassNotFoundException e) {
+                                return null;
+                            }
+                        })).filter(Objects::nonNull).toArray(Class[]::new);
+        proxy = apiToProxy.length == 1 ? new TomcatSecurityServicePrincipal() : Principal.class.cast(
+                Proxy.newProxyInstance(loader, apiToProxy, (proxy, method, args) -> {
+                    try {
+                        return method.invoke(getCurrentPrincipal(), args);
+                    } catch (final InvocationTargetException ite) {
+                        throw ite.getTargetException();
+                    }
+                }));
+
+    }
+
+    @Override // reason of that class
+    public Principal getCurrentPrincipal() {
+        return useWrapper ? proxy : getUserPrincipal();
+    }
+
+    // ensure it is contextual
+    private static class TomcatSecurityServicePrincipal implements Principal {
+        @Override
+        public String getName() {
+            return unwrap().getName();
+        }
+
+        @Override
+        public boolean implies(final Subject subject) {
+            return unwrap().implies(subject);
+        }
+
+        private Principal unwrap() {
+            return getUserPrincipal();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static Principal getUserPrincipal() {
+        final BeanManager beanManager = CDI.current().getBeanManager();
+        final HttpServletRequest request = HttpServletRequest.class.cast(
+                beanManager.getReference(
+                        beanManager.resolve(beanManager.getBeans(HttpServletRequest.class)), HttpServletRequest.class,
+                        beanManager.createCreationalContext(null)));
+        final Object supplier = request.getAttribute(Principal.class.getName() + ".supplier");
+        if (supplier != null) {
+            return ((Supplier<Principal>) supplier).get();
+        }
+        return request.getUserPrincipal();
+    }
+}
diff --git a/modules/owb/src/main/resources/META-INF/openwebbeans/openwebbeans.properties b/modules/owb/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
new file mode 100644
index 0000000..fa5a3fb
--- /dev/null
+++ b/modules/owb/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
@@ -0,0 +1,158 @@
+#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.
+
+org.apache.webbeans.spi.SecurityService=org.apache.webbeans.web.tomcat.TomcatSecurityService
+org.apache.webbeans.spi.adaptor.ELAdaptor=org.apache.webbeans.el22.EL22Adaptor
+org.apache.webbeans.spi.ContainerLifecycle=org.apache.webbeans.web.lifecycle.WebContainerLifecycle
+org.apache.webbeans.spi.ScannerService=org.apache.webbeans.web.scanner.WebScannerService
+org.apache.webbeans.spi.ContextsService=org.apache.webbeans.web.context.WebContextsService
+org.apache.webbeans.application.jsp=true
+org.apache.webbeans.spi.ConversationService=org.apache.webbeans.web.context.WebConversationService
+org.apache.webbeans.application.supportsConversation=true
+org.apache.webbeans.spi.JNDIService=org.apache.webbeans.corespi.se.DefaultJndiService
+org.apache.webbeans.spi.BeanArchiveService=org.apache.webbeans.xml.DefaultBeanArchiveService
+org.apache.webbeans.spi.ApplicationBoundaryService=org.apache.webbeans.corespi.se.DefaultApplicationBoundaryService
+org.apache.webbeans.spi.LoaderService=org.apache.webbeans.service.DefaultLoaderService
+org.apache.webbeans.spi.deployer.useEjbMetaDataDiscoveryService=false
+org.apache.webbeans.spi.InjectionPointService=org.apache.webbeans.service.DefaultInjectionPointService
+org.apache.webbeans.service.DefaultInjectionPointService.implicitSupport = true
+org.apache.webbeans.useBDABeansXMLScanner=false
+org.apache.webbeans.proxy.mapping.javax.enterprise.context.ApplicationScoped=org.apache.webbeans.intercept.ApplicationScopedBeanInterceptorHandler
+org.apache.webbeans.proxy.mapping.javax.enterprise.context.RequestScoped=org.apache.webbeans.intercept.RequestScopedBeanInterceptorHandler
+org.apache.webbeans.proxy.mapping.javax.enterprise.context.SessionScoped=org.apache.webbeans.intercept.SessionScopedBeanInterceptorHandler
+org.apache.webbeans.web.eagerSessionInitialisation=false
+
+######################### Bean Scanning ########################################################
+# A list of known JARs/paths which should not be scanned for beans
+# if they don't have an explicit META-INF/beans.xml
+org.apache.webbeans.scanExclusionPaths=/jre/lib, \
+        /Contents/Home/, \
+        /dt.jar, \
+        /tools.jar, \
+        /bootstrap.jar, \
+        /asm, \
+        /javassist, \
+        /xbean-, \
+        /jconsole.jar, \
+        /geronimo-connector,\
+        /geronimo-j2ee-,\
+        /geronimo-jpa_,\
+        /geronimo-javamail,\
+        /geronimo-transaction,\
+        /commons-, \
+        /arquillian-, \
+        /bsh-, \
+        /shrinkwrap-, \
+        /junit-, \
+        /testng-, \
+        /openjpa-, \
+        /bcel, \
+        /hamcrest, \
+        /mysql-connector, \
+        /testng, \
+        /idea_rt, \
+        /eclipse, \
+        /jcommander, \
+        /tomcat, \
+        /catalina, \
+        /jasper, \
+        /jsp-api, \
+        /myfaces-api, \
+        /myfaces-impl, \
+        /servlet-api, \
+        /javax, \
+        /annotation-api, \
+        /el-api, \
+        /mojarra, \
+        /sisu-guice-, \
+        /sisu-inject-, \
+        /aether-, \
+        /plexus-, \
+        /maven-, \
+        /guava-, \
+        /openwebbeans-, \
+        /bcprov-jdk14-, \
+        /bcmail-jdk14-, \
+        /bctsp-jdk14-, \
+        /bcmail-jdk14-, \
+        /ss_css2-, \
+        /itext-, \
+        /pd4ml-, \
+        /xmlpull-, \
+        /log4j-, \
+        /slf4j-, \
+        /logkit, \
+        /gson-, \
+        /xstream-, \
+        /httpclient-, \
+        /httpcore-, \
+        /backport-util-concurrent-, \
+        /xml-apis, \
+        /xpp3_min-, \
+        /bval-core, \
+        /bval-jsr, \
+        /hsqldb, \
+        /quartz-2, \
+        /jetty-, \
+        /plexus-, \
+        /surefire-, \
+        /byte-buddy-, \
+        /cglib-, \
+        /okhttp-, \
+        /htmlunit-, \
+        /wagon-http-, \
+        /wagon-provider-, \
+        /wagon-file-, \
+        /phantomjsdriver, \
+        /error_prone_annotations-, \
+        /j2objc-, \
+        /xalan-, \
+        /aopalliance-, \
+        /owasp-, \
+        /jdom2-, \
+        /jfreechart-, \
+        /stax-api-, \
+        /jboss-logging-, \
+        /barcode4j-, \
+        /poi-, \
+        /selenium-, \
+        /graphene-, \
+        /httpmime-, \
+        /cssparser-, \
+        /animal-sniffer-annotations-, \
+        /objenesis-, \
+        /xercesImpl-, \
+        /neko-htmlunit-, \
+        /checker-compat-qual-, \
+        /awaitility-, \
+        /okio-, \
+        /jsr305-, \
+        /guice-, \
+        /jsoup-
+################################################################################################
+
+
+######################### Bean Scanning ########################################################
+# A list of known classes which might contain final methods but should be proxyable nonetheless
+# Some of those classes are from the JDK and have been proxyable in older versions.
+# This setting can be overridden as jvm param via -Djavax.enterprise.inject.allowProxying.classes=...
+# or an environment key with the name JAVAX_ENTERPRISE_INJECT_ALLOWPROXYING_CLASSES=...
+javax.enterprise.inject.allowProxying.classes=\
+        java.util.HashMap, \
+        java.util.Calendar
+################################################################################################
+
diff --git a/modules/owb/src/main/resources/META-INF/services/org.apache.webbeans.spi.plugins.OpenWebBeansPlugin b/modules/owb/src/main/resources/META-INF/services/org.apache.webbeans.spi.plugins.OpenWebBeansPlugin
new file mode 100644
index 0000000..9b7d288
--- /dev/null
+++ b/modules/owb/src/main/resources/META-INF/services/org.apache.webbeans.spi.plugins.OpenWebBeansPlugin
@@ -0,0 +1,17 @@
+# 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.
+org.apache.webbeans.web.tomcat.TomcatPlugin
\ No newline at end of file
diff --git a/modules/owb/src/main/resources/org/apache/webbeans/web/tomcat/LocalStrings.properties b/modules/owb/src/main/resources/org/apache/webbeans/web/tomcat/LocalStrings.properties
new file mode 100644
index 0000000..33ec8f7
--- /dev/null
+++ b/modules/owb/src/main/resources/org/apache/webbeans/web/tomcat/LocalStrings.properties
@@ -0,0 +1,19 @@
+# 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.
+
+instanceManager.destroyError=An error occurred destroying the injector for instance [{0}]
+instanceManager.injectError=An error occurred injecting the dependencies for instance [{0}]
+
+plugin.notManagedBean=Given class [{0}] is not a managed bean
diff --git a/webapps/docs/cdi.xml b/webapps/docs/cdi.xml
new file mode 100644
index 0000000..a812b4e
--- /dev/null
+++ b/webapps/docs/cdi.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<!DOCTYPE document [
+  <!ENTITY project SYSTEM "project.xml">
+]>
+<document url="cdi.html">
+
+    &project;
+
+  <properties>
+    <title>CDI 2, JAX-RS and dependent libraries support</title>
+  </properties>
+
+<body>
+
+<section name="Table of Contents">
+<toc/>
+</section>
+
+  <section name="Introduction">
+
+  <p>
+    CDI and JAX-RS are dependencies for many other APIs and libraries. This
+    guide explains how to add support for them in Tomcat using two optional
+    modules that are provided in the Tomcat sources.
+  </p>
+
+  </section>
+
+  <section name="CDI 2 support">
+
+  <p>
+    CDI 2 support is provided by the <code>modules/owb</code> optional module.
+    It packages the Apache OpenWebBeans project and allows adding CDI 2 support
+    to the Tomcat container. The build process of the module uses Apache Maven,
+    and is not available as a binary bundle as it is built using a number of
+    publicly available JARs.
+  </p>
+
+  <p>
+    The process to build CDI support is the following.
+    <source><![CDATA[cd $TOMCAT_SRC/modules/cdi
+mvn clean && mvn package]]></source>
+    The resulting JAR at
+    <code>target/tomcat-cdi-1.0.jar</code>
+    should then be placed into the <code>lib</code> folder of the Tomcat
+    installation.<br/>
+    CDI support can then be enabled for all webapps in the container by adding
+    the following listener in <code>server.xml</code> nested inside the
+    <code>Server</code> element:
+    <source><![CDATA[<Listener className="org.apache.webbeans.web.tomcat.OpenWebBeansListener" optional="true" startWithoutBeansXml="false" />]]></source>
+    The listener will produce a non fatal error if the CDI container loading
+    fails.<br/>
+    CDI support can also be enabled at the individual webapp level by adding
+    the following listner to the webapp <code>context.xml</code> file nested
+    inside the <code>Server</code> element:
+    <source><![CDATA[<Listener className="org.apache.webbeans.web.tomcat.OpenWebBeansContextLifecycleListener" />]]></source>
+  </p>
+
+  </section>
+
+  <section name="JAX-RS support">
+
+  <p>
+    JAX-RS support is provided by the <code>modules/cxf</code> optional module.
+    It packages the Apache CXF project and allows adding JAX-RS support
+    to individual webapps. The build process of the module uses Apache Maven,
+    and is not available as a binary bundle as it is built using a number of
+    publicly available JARs. The support depends on CDI 2 support, which should
+    have previously been installed at either the container or webapp level.
+  </p>
+
+  <p>
+    The process to build JAX-RS support is the following.
+    <source><![CDATA[cd $TOMCAT_SRC/modules/cxf
+mvn clean && mvn package]]></source>
+    The resulting JAR at
+    <code>target/tomcat-cxf-1.0.jar</code>
+    should then be placed into the <code>/WEB-INF/lib</code> folder of the
+    desired web application.
+  </p>
+
+  <p>
+    If the CDI 2 support is available at the container
+    level, the JAR can also be placed in the Tomcat <code>lib</code> folder,
+    but in that case the CXF Servlet declaration must be individually added
+    in each webapp as needed (it is normally loaded by the web fragment that is
+    present in the JAR). The CXF Servlet class that should be used is
+    <code>org.apache.cxf.cdi.CXFCdiServlet</code> and should be mapped to the
+    desired root path where JAX-RS resources will be available.
+  </p>
+
+  </section>
+
+  <section name="Eclipse Microprofile support">
+
+  <p>
+    ASF artifacts are available that implement Eclipse Microprofile
+    specifications using CDI 2 extensions. Once the CDI 2 and JAX-RS support
+    is installed, they will be usable by individual webapps.
+  </p>
+
+  <p>
+    The following implementations are available (reference:
+    <code>org.apache.tomee.microprofile.TomEEMicroProfileListener</code>) as
+    Maven artifacts which must be added to the webapp <code>/WEB-INF/lib</code>
+    folders:
+    <ul>
+      <li><strong>Configuration</strong>:
+        Maven artifact:
+        <code>org.apache.geronimo.config:geronimo-config</code>
+        CDI extension class:
+        <code>org.apache.geronimo.config.cdi.ConfigExtension</code>
+      </li>
+      <li><strong>Fault Tolerance</strong>:
+        Maven artifact:
+        <code>org.apache.geronimo.safeguard:safeguard-parent</code>
+        CDI extension class:
+        <code>org.apache.safeguard.impl.cdi.SafeguardExtension</code>
+      </li>
+      <li><strong>Health</strong>:
+        Maven artifact:
+        <code>org.apache.geronimo:geronimo-health</code>
+        CDI extension class:
+        <code>org.apache.geronimo.microprofile.impl.health.cdi.GeronimoHealthExtension</code>
+      </li>
+      <li><strong>Metrics</strong>:
+        Maven artifact:
+        <code>org.apache.geronimo:geronimo-metrics</code>
+        CDI extension class:
+        <code>org.apache.geronimo.microprofile.metrics.cdi.MetricsExtension</code>
+      </li>
+      <li><strong>OpenTracing</strong>:
+        Maven artifact:
+        <code>org.apache.geronimo:geronimo-opentracing</code>
+        CDI extension class:
+        <code>org.apache.geronimo.microprofile.opentracing.microprofile.cdi.OpenTracingExtension</code>
+      </li>
+      <li><strong>OpenAPI</strong>:
+        Maven artifact:
+        <code>org.apache.geronimo:geronimo-openapi</code>
+        CDI extension class:
+        <code>org.apache.geronimo.microprofile.openapi.cdi.GeronimoOpenAPIExtension</code>
+      </li>
+      <li><strong>Rest client</strong>:
+        Maven artifact:
+        <code>org.apache.cxf:cxf-rt-rs-mp-client</code>
+        CDI extension class:
+        <code>org.apache.cxf.microprofile.client.cdi.RestClientExtension</code>
+      </li>
+      <li><strong>JSON Web Tokens</strong>:
+        Note: Fore reference only, unusable outside Apache TomEE;
+        Maven artifact:
+        <code>org.apache.tomee:mp-jwt</code>
+        CDI extension class:
+        <code>org.apache.tomee.microprofile.jwt.cdi.MPJWTCDIExtension</code>
+      </li>
+    </ul>
+  </p>
+
+  </section>
+
+</body>
+</document>
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 5093cc1..98908b6 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -93,6 +93,11 @@
         stdout does not work when output is piped to another process. Patch
         provided by Radosław Józwik. (markt)
       </fix>
+      <add>
+        Add user buildable optional modules for easier CDI 2 and JAX-RS
+        support. Also include a new documentation page describing how
+        to use it. (remm)
+      </add>
     </changelog>
   </subsection>
 </section>
diff --git a/webapps/docs/project.xml b/webapps/docs/project.xml
index 979b242..1ce12e7 100644
--- a/webapps/docs/project.xml
+++ b/webapps/docs/project.xml
@@ -76,6 +76,7 @@
               href="jdbc-pool.html"/>
         <item name="33) WebSocket"          href="web-socket-howto.html"/>
         <item name="34) Rewrite"            href="rewrite.html"/>
+        <item name="34) CDI 2 and JAX-RS"   href="cdi.html"/>
     </menu>
 
     <menu name="Reference">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org