TOMEE-3222 support for default-context-path since addition in Servlet 4
This should really be implemented in Tomcat because it's a bit hacky to do it in TomEE
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/WebAppInfo.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/WebAppInfo.java
index 9dcdf3a..de6f3e3 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/WebAppInfo.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/WebAppInfo.java
@@ -32,6 +32,7 @@
public String moduleId;
public String host;
public String contextRoot;
+ public String defaultContextPath;
public int sessionTimeout;
public final Set<String> watchedResources = new TreeSet<>();
public final Set<String> restClass = new TreeSet<>();
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java b/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
index 868b9dd..23d4e12 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
@@ -437,6 +437,8 @@
webAppInfo.contextRoot = webModule.getContextRoot();
}
+ webAppInfo.defaultContextPath = webModule.getDefaultContextPath();
+
webAppInfo.sessionTimeout = 30;
if (webModule.getWebApp() != null && webModule.getWebApp().getSessionConfig() != null) {
for (final SessionConfig sessionConfig : webModule.getWebApp().getSessionConfig()) {
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java b/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
index 19872a0..c8d4434 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
@@ -1075,6 +1075,7 @@
webModule.setAddedUrls(addedUrls);
webModule.setRarUrls(Arrays.asList(urls.get(RAR_URLS_KEY)));
webModule.setScannableUrls(scannableUrls);
+ webModule.setDefaultContextPath(webApp.getDefaultContextPath());
webModule.getAltDDs().putAll(descriptors);
webModule.getWatchedResources().add(warPath);
webModule.getWatchedResources().add(warFile.getAbsolutePath());
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/ReadDescriptors.java b/container/openejb-core/src/main/java/org/apache/openejb/config/ReadDescriptors.java
index 0ed48a9..58936f3 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/config/ReadDescriptors.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/config/ReadDescriptors.java
@@ -58,7 +58,6 @@
import org.apache.openejb.sxc.FacesConfigXml;
import org.apache.openejb.sxc.HandlerChainsXml;
import org.apache.openejb.sxc.TldTaglibXml;
-import org.apache.openejb.sxc.WebXml;
import org.apache.openejb.sxc.WebservicesXml;
import org.apache.openejb.util.LengthInputStream;
import org.apache.openejb.util.LogCategory;
@@ -833,7 +832,9 @@
public static WebApp readWebApp(final URL url) throws OpenEJBException {
final WebApp webApp;
try {
- webApp = WebXml.unmarshal(url);
+ webApp = (WebApp) JaxbJavaee.unmarshalJavaee(WebApp.class, IO.read(url));
+ // don't use the SXC version with the accessors as it's not up to date
+ // webApp = WebXml.unmarshal(url);
} catch (final SAXException e) {
throw new OpenEJBException("Cannot parse the web.xml file: " + url.toExternalForm(), e);
} catch (final JAXBException e) {
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/WebModule.java b/container/openejb-core/src/main/java/org/apache/openejb/config/WebModule.java
index 3df658c..e026872 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/config/WebModule.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/config/WebModule.java
@@ -46,6 +46,7 @@
private Webservices webservices;
private String host;
private String contextRoot;
+ private String defaultContextPath;
private final List<TldTaglib> taglibs = new ArrayList<>();
private final Set<String> watchedResources = new TreeSet<>();
// List of all faces configuration files found in this web module
@@ -119,6 +120,14 @@
return id.getLocation();
}
+ public String getDefaultContextPath() {
+ return defaultContextPath;
+ }
+
+ public void setDefaultContextPath(final String defaultContextPath) {
+ this.defaultContextPath = defaultContextPath;
+ }
+
@Override
public URI getModuleUri() {
return id.getUri();
diff --git a/container/openejb-jee/src/main/java/org/apache/openejb/jee/WebApp.java b/container/openejb-jee/src/main/java/org/apache/openejb/jee/WebApp.java
index 90ac693..3f59ece 100644
--- a/container/openejb-jee/src/main/java/org/apache/openejb/jee/WebApp.java
+++ b/container/openejb-jee/src/main/java/org/apache/openejb/jee/WebApp.java
@@ -70,6 +70,7 @@
"listener",
"servlet",
"servletMapping",
+ "defaultContextPath",
"sessionConfig",
"mimeMapping",
"welcomeFileList",
@@ -177,6 +178,8 @@
@XmlElement(name = "module-name")
protected String moduleName;
+ @XmlElement(name = "default-context-path")
+ protected String defaultContextPath;
@XmlElement(name = "absolute-ordering")
protected AbsoluteOrdering absoluteOrdering;
@@ -238,6 +241,14 @@
return displayName.get();
}
+ public String getDefaultContextPath() {
+ return defaultContextPath;
+ }
+
+ public void setDefaultContextPath(final String defaultContextPath) {
+ this.defaultContextPath = defaultContextPath;
+ }
+
@Override
public Collection<Icon> getIcons() {
if (icon == null) {
@@ -774,6 +785,11 @@
return this;
}
+ public WebApp defaultContextPath(final String path) {
+ setDefaultContextPath(path);
+ return this;
+ }
+
public WebApp addListener(final String classname) {
final Listener l = new Listener();
l.setListenerClass(classname);
diff --git a/container/openejb-jee/src/test/java/org/apache/openejb/jee/JeeTest.java b/container/openejb-jee/src/test/java/org/apache/openejb/jee/JeeTest.java
index 17d3fb5..bc1058d 100644
--- a/container/openejb-jee/src/test/java/org/apache/openejb/jee/JeeTest.java
+++ b/container/openejb-jee/src/test/java/org/apache/openejb/jee/JeeTest.java
@@ -217,6 +217,10 @@
marshalAndUnmarshal(WebApp.class, "web_2.3-example.xml", "web_2.3-example-expected.xml");
}
+ public void testWar5() throws Exception {
+ marshalAndUnmarshal(WebApp.class, "web_5-example.xml", "web_5-example-expected.xml");
+ }
+
public void testTld() throws Exception {
marshalAndUnmarshal(TldTaglib.class, "tld-example.xml", null);
}
diff --git a/container/openejb-jee/src/test/resources/web_5-example-expected.xml b/container/openejb-jee/src/test/resources/web_5-example-expected.xml
new file mode 100644
index 0000000..a6d4f91
--- /dev/null
+++ b/container/openejb-jee/src/test/resources/web_5-example-expected.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <!--
+
+ 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-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5.0" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <display-name>SerSpecDefaultContextPath</display-name>
+ <servlet>
+ <servlet-name>TestServlet</servlet-name>
+ <servlet-class>com.sun.ts.tests.servlet.spec.defaultcontextpath.TestServlet</servlet-class>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>TestServlet</servlet-name>
+ <url-pattern>/TestServlet</url-pattern>
+ </servlet-mapping>
+ <default-context-path>/defaultContextPath</default-context-path>
+ <session-config>
+ <session-timeout>54</session-timeout>
+ </session-config>
+</web-app>
diff --git a/container/openejb-jee/src/test/resources/web_5-example.xml b/container/openejb-jee/src/test/resources/web_5-example.xml
new file mode 100644
index 0000000..a6d4f91
--- /dev/null
+++ b/container/openejb-jee/src/test/resources/web_5-example.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <!--
+
+ 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-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5.0" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <display-name>SerSpecDefaultContextPath</display-name>
+ <servlet>
+ <servlet-name>TestServlet</servlet-name>
+ <servlet-class>com.sun.ts.tests.servlet.spec.defaultcontextpath.TestServlet</servlet-class>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>TestServlet</servlet-name>
+ <url-pattern>/TestServlet</url-pattern>
+ </servlet-mapping>
+ <default-context-path>/defaultContextPath</default-context-path>
+ <session-config>
+ <session-timeout>54</session-timeout>
+ </session-config>
+</web-app>
diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
index 84fc828..bc0c6cd 100644
--- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
+++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
@@ -124,7 +124,6 @@
import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.apache.tomcat.util.descriptor.web.ResourceBase;
-import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.apache.tomcat.util.http.CookieProcessor;
import org.apache.tomcat.util.scan.StandardJarScanFilter;
import org.apache.tomee.catalina.cdi.ServletContextHandler;
@@ -149,8 +148,6 @@
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
-import javax.security.jacc.PolicyConfiguration;
-import javax.security.jacc.PolicyConfigurationFactory;
import javax.servlet.ServletContext;
import javax.servlet.SessionTrackingMode;
import javax.servlet.http.HttpServletRequest;
@@ -158,6 +155,7 @@
import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Field;
@@ -519,6 +517,20 @@
standardContext.setConfigFile(contextXmlUrl);
}
+ // override path if needed - hack at this moment just to pass the TCK
+ // Tomcat should definitely implement it, but community does not seem to like the feature and therefore
+ // willing to implement it.
+ // default context path must start with / but not end with slash
+ try {
+ if (webApp.defaultContextPath != null && webApp.defaultContextPath.matches("^/\\w*[^/]$")) {
+ standardContext.setPath(webApp.defaultContextPath);
+ }
+
+ } catch (final Exception e) {
+ // don't fail because it's a hack, just output the exception
+ e.printStackTrace();
+ }
+
if (standardContext.getPath() != null) {
webApp.contextRoot = standardContext.getPath();
}