You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jl...@apache.org on 2022/01/25 17:17:01 UTC
[tomee] 01/01: Add some fixes and prepare for some refactoring
This is an automated email from the ASF dual-hosted git repository.
jlmonteiro pushed a commit to branch jaxws-improvements
in repository https://gitbox.apache.org/repos/asf/tomee.git
commit f2a77ae409561a26cf450e42c96ee449afc081c8
Author: Jean-Louis Monteiro <jl...@tomitribe.com>
AuthorDate: Tue Jan 25 18:16:41 2022 +0100
Add some fixes and prepare for some refactoring
---
.../tests/jaxws/WebServiceContextEJBTest.java | 30 ++++++--
.../main/java/org/apache/openejb/util/Strings.java | 26 ++++++-
.../java/org/apache/openejb/util/StringsTest.java | 89 ++++++++++++++++++++++
.../main/java/org/apache/openejb/jee/WebApp.java | 14 ++--
.../openejb/server/webservices/WsService.java | 14 ++--
.../apache/tomee/webservices/TomcatWsRegistry.java | 84 +++++---------------
6 files changed, 176 insertions(+), 81 deletions(-)
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxws-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxws/WebServiceContextEJBTest.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxws-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxws/WebServiceContextEJBTest.java
index 131d05c..a3c3145 100644
--- a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxws-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxws/WebServiceContextEJBTest.java
+++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxws-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxws/WebServiceContextEJBTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.openejb.arquillian.tests.jaxws;
+import org.apache.openejb.loader.IO;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
@@ -26,10 +27,12 @@ import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.descriptor.api.Descriptors;
import org.jboss.shrinkwrap.descriptor.api.webapp31.WebAppDescriptor;
import org.junit.Assert;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.annotation.Resource;
+import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.jws.WebMethod;
import javax.jws.WebParam;
@@ -73,9 +76,6 @@ public class WebServiceContextEJBTest {
.createServletMapping()
.servletName("HelloService")
.urlPattern("/internal/Hello")
- .up()
- .createServletMapping()
- .servletName("HelloService")
.urlPattern("/tomee/Hello")
.up()
;
@@ -90,21 +90,31 @@ public class WebServiceContextEJBTest {
@Test
public void invokePojo() throws Exception {
- // System.out.println(IO.slurp(new URL(url.toExternalForm() + "/ws/Hello?wsdl")));
+ System.out.println("----");
+ System.out.println(IO.slurp(new URL(url.toExternalForm() + "/ws/Hello?wsdl")));
+ System.out.println("----");
final Service service = Service.create(new URL(url.toExternalForm() + "/ws/Hello?wsdl"), new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "Hello"));
final QName portQName = new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "HelloService");
assertServiceInvocation(service, portQName);
}
@Test
+ //@Ignore
public void invokePojoAlternate() throws Exception {
+ System.out.println("----");
+ System.out.println(IO.slurp(new URL(url.toExternalForm() + "/internal/Hello?wsdl")));
+ System.out.println("----");
final Service service = Service.create(new URL(url.toExternalForm() + "/internal/Hello?wsdl"), new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "Hello"));
final QName portQName = new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "HelloService");
assertServiceInvocation(service, portQName);
}
@Test
+ //@Ignore
public void invokePojoAlternate2() throws Exception {
+ System.out.println("----");
+ System.out.println(IO.slurp(new URL(url.toExternalForm() + "/tomee/Hello?wsdl")));
+ System.out.println("----");
final Service service = Service.create(new URL(url.toExternalForm() + "/tomee/Hello?wsdl"), new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "Hello"));
final QName portQName = new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "HelloService");
assertServiceInvocation(service, portQName);
@@ -123,19 +133,29 @@ public class WebServiceContextEJBTest {
*/
@Test
public void invokeEjb() throws Exception {
- // System.out.println(IO.slurp(new URL(url.toExternalForm() + "/webservices/ws/HelloEjb?wsdl")));
+ System.out.println("----");
+ System.out.println(IO.slurp(new URL(url.toExternalForm() + "/webservices/ws/HelloEjb?wsdl")));
+ System.out.println("----");
final Service service = Service.create(new URL(url.toExternalForm() + "/webservices/ws/HelloEjb?wsdl"), new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "Hello"));
assertServiceInvocationWithPort(service);
}
@Test
+ //@Ignore
public void invokeEjbAlternate() throws Exception {
+ System.out.println("----");
+ System.out.println(IO.slurp(new URL(url.toExternalForm() + "/webservices/internal/HelloEjb?wsdl")));
+ System.out.println("----");
final Service service = Service.create(new URL(url.toExternalForm() + "/webservices/internal/HelloEjb?wsdl"), new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "Hello"));
assertServiceInvocationWithPort(service);
}
@Test
+ //@Ignore
public void invokeEjbAlternate2() throws Exception {
+ System.out.println("----");
+ System.out.println(IO.slurp(new URL(url.toExternalForm() + "/webservices/tomee/HelloEjb?wsdl")));
+ System.out.println("----");
final Service service = Service.create(new URL(url.toExternalForm() + "/webservices/tomee/HelloEjb?wsdl"), new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "Hello"));
assertServiceInvocationWithPort(service);
}
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/util/Strings.java b/container/openejb-core/src/main/java/org/apache/openejb/util/Strings.java
index b568308..4d0edd2 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/util/Strings.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/util/Strings.java
@@ -110,8 +110,32 @@ public class Strings {
public static String lastPart(final String className, final char sep) {
final int idx = className.lastIndexOf(sep);
if (idx >= 0) {
- return className.substring(idx + 1, className.length());
+ return className.substring(idx + 1);
}
return className;
}
+
+ public static String forceSlash(final String property) {
+ if (property == null) {
+ return "/";
+ }
+ if (!property.startsWith("/")) {
+ return "/" + property;
+ }
+ return property;
+ }
+
+ public static String slashify(final String ... parts) {
+ if (parts == null || parts.length == 0) {
+ return "/";
+ }
+ final StringBuilder path = new StringBuilder();
+ for (String part : parts) {
+ if (path.length() >= 1 && path.charAt(path.length() - 1) == '/') {
+ path.deleteCharAt(path.length() - 1);
+ }
+ path.append(forceSlash(part));
+ }
+ return path.toString();
+ }
}
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/util/StringsTest.java b/container/openejb-core/src/test/java/org/apache/openejb/util/StringsTest.java
new file mode 100644
index 0000000..677c132
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/util/StringsTest.java
@@ -0,0 +1,89 @@
+/**
+ *
+ * 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.openejb.util;
+
+import junit.framework.TestCase;
+
+public class StringsTest extends TestCase {
+
+ public void testForceSlash() {
+ assertEquals("/", Strings.forceSlash(null));
+ assertEquals("/", Strings.forceSlash(""));
+ assertEquals("/", Strings.forceSlash("/"));
+ assertEquals("/hello", Strings.forceSlash("/hello"));
+ assertEquals("/test/", Strings.forceSlash("/test/"));
+ assertEquals("/path/", Strings.forceSlash("path/"));
+ }
+
+ public void testSlashify() {
+
+ // same as previous
+ assertEquals("/", Strings.slashify(null));
+ assertEquals("/", Strings.slashify(""));
+ assertEquals("/", Strings.slashify("/"));
+ assertEquals("/hello", Strings.slashify("/hello"));
+ assertEquals("/test/", Strings.slashify("/test/"));
+ assertEquals("/path/", Strings.slashify("path/"));
+
+ assertEquals("/", Strings.slashify(null, null));
+ assertEquals("/", Strings.slashify(null, ""));
+ assertEquals("/", Strings.slashify(null, "/"));
+ assertEquals("/hello", Strings.slashify(null, "/hello"));
+ assertEquals("/test/", Strings.slashify(null, "/test/"));
+ assertEquals("/path/", Strings.slashify(null, "path/"));
+
+ assertEquals("/", Strings.slashify("", null));
+ assertEquals("/", Strings.slashify("", ""));
+ assertEquals("/", Strings.slashify("", "/"));
+ assertEquals("/hello", Strings.slashify("", "/hello"));
+ assertEquals("/test/", Strings.slashify("", "/test/"));
+ assertEquals("/path/", Strings.slashify("", "path/"));
+
+ assertEquals("/", Strings.slashify("/", null));
+ assertEquals("/", Strings.slashify("/", ""));
+ assertEquals("/", Strings.slashify("/", "/"));
+ assertEquals("/hello", Strings.slashify("/", "/hello"));
+ assertEquals("/test/", Strings.slashify("/", "/test/"));
+ assertEquals("/path/", Strings.slashify("/", "path/"));
+
+ assertEquals("/hello/", Strings.slashify("/hello", null));
+ assertEquals("/hello/", Strings.slashify("/hello", ""));
+ assertEquals("/hello/", Strings.slashify("/hello", "/"));
+ assertEquals("/hello/hello", Strings.slashify("/hello", "/hello"));
+ assertEquals("/hello/test/", Strings.slashify("/hello", "/test/"));
+ assertEquals("/hello/path/", Strings.slashify("/hello", "path/"));
+
+ assertEquals("/test/", Strings.slashify("/test/", null));
+ assertEquals("/test/", Strings.slashify("/test/", ""));
+ assertEquals("/test/", Strings.slashify("/test/", "/"));
+ assertEquals("/test/hello", Strings.slashify("/test/", "/hello"));
+ assertEquals("/test/test/", Strings.slashify("/test/", "/test/"));
+ assertEquals("/test/path/", Strings.slashify("/test/", "path/"));
+
+ assertEquals("/path/", Strings.slashify("path/", null));
+ assertEquals("/path/", Strings.slashify("path/", ""));
+ assertEquals("/path/", Strings.slashify("path/", "/"));
+ assertEquals("/path/hello", Strings.slashify("path/", "/hello"));
+ assertEquals("/path/test/", Strings.slashify("path/", "/test/"));
+ assertEquals("/path/path/", Strings.slashify("path/", "path/"));
+
+ // double slash in the middle of a part should not be altered
+ assertEquals("/path/te//st/", Strings.slashify("path/", "/te//st/"));
+ }
+
+}
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 3f59ece..b604d94 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
@@ -656,27 +656,29 @@ public class WebApp implements WebCommon, Lifecycle, NamedModule {
}
public List<String> getServletMappings(final String servletName) {
- if (servletMapping == null || servletName == null) {
+ if (servletName == null || servletMapping == null || servletMapping.isEmpty()) {
return Collections.emptyList();
}
+ final List<String> mappings = new ArrayList<>();
for (final ServletMapping mapping : servletMapping) {
if (servletName.equals(mapping.getServletName())) {
- return mapping.getUrlPattern();
+ mappings.addAll(mapping.getUrlPattern());
}
}
- return Collections.emptyList();
+ return mappings;
}
public List<String> getFilterMappings(final String filterName) {
- if (filterMapping == null || filterName == null) {
+ if (filterName == null || filterMapping == null || filterMapping.isEmpty()) {
return Collections.emptyList();
}
+ final List<String> mappings = new ArrayList<>();
for (final FilterMapping mapping : filterMapping) {
if (filterName.equals(mapping.getFilterName())) {
- return mapping.getUrlPattern();
+ mappings.addAll(mapping.getUrlPattern());
}
}
- return Collections.emptyList();
+ return mappings;
}
private Servlet findServlet(final String name) {
diff --git a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java
index 7540cbe..38b960a 100644
--- a/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java
+++ b/server/openejb-webservices/src/main/java/org/apache/openejb/server/webservices/WsService.java
@@ -438,12 +438,14 @@ public abstract class WsService implements ServerService, SelfManaging {
// one of the registered addresses to be the connonical address
final String address = HttpUtil.selectSingleAddress(addresses);
- // add address to global registry
- portAddressRegistry.addPort(portInfo.serviceId, portInfo.wsdlService, portInfo.portId, portInfo.wsdlPort, portInfo.seiInterfaceName, address);
- setWsdl(container, address);
- LOGGER.info("Webservice(wsdl=" + address + ", qname=" + port.getWsdlService() + ") --> Pojo(id=" + portInfo.portId + ")");
- servletAddresses.put(webApp.moduleId + "." + servlet.servletName, address);
- addressesForApp(webApp.moduleId).add(new EndpointInfo(address, port.getWsdlService(), target.getName()));
+ if (address != null) {
+ // add address to global registry
+ portAddressRegistry.addPort(portInfo.serviceId, portInfo.wsdlService, portInfo.portId, portInfo.wsdlPort, portInfo.seiInterfaceName, address);
+ setWsdl(container, address);
+ LOGGER.info("Webservice(wsdl=" + address + ", qname=" + port.getWsdlService() + ") --> Pojo(id=" + portInfo.portId + ")");
+ servletAddresses.put(webApp.moduleId + "." + servlet.servletName, address);
+ addressesForApp(webApp.moduleId).add(new EndpointInfo(address, port.getWsdlService(), target.getName()));
+ }
}
} catch (final Throwable e) {
LOGGER.error("Error deploying CXF webservice for servlet " + portInfo.serviceLink, e);
diff --git a/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java b/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
index fc03249..0b2e80a 100644
--- a/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
+++ b/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
@@ -37,6 +37,7 @@ import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.server.httpd.HttpListener;
import org.apache.openejb.server.webservices.WsRegistry;
import org.apache.openejb.server.webservices.WsServlet;
+import org.apache.openejb.util.Strings;
import org.apache.tomcat.util.descriptor.web.LoginConfig;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
@@ -57,7 +58,7 @@ import java.util.concurrent.ConcurrentHashMap;
import static java.util.Arrays.asList;
public class TomcatWsRegistry implements WsRegistry {
- private static final String WEBSERVICE_SUB_CONTEXT = forceSlash(SystemInstance.get().getOptions().get("tomee.jaxws.subcontext", "/webservices"));
+ private static final String WEBSERVICE_SUB_CONTEXT = Strings.slashify(SystemInstance.get().getOptions().get("tomee.jaxws.subcontext", "/webservices"));
private static final boolean WEBSERVICE_OLDCONTEXT_ACTIVE = SystemInstance.get().getOptions().get("tomee.jaxws.oldsubcontext", false);
private static final String TOMEE_JAXWS_SECURITY_ROLE_PREFIX = "tomee.jaxws.security-role.";
@@ -79,17 +80,6 @@ public class TomcatWsRegistry implements WsRegistry {
}
}
- private static String forceSlash(final String property) {
- if (property == null) {
- return "/";
- }
- if (!property.startsWith("/")) {
- return "/" + property;
- }
- return property;
- }
-
-
@Override
public List<String> setWsContainer(final HttpListener httpListener,
final ClassLoader classLoader,
@@ -103,7 +93,7 @@ public class TomcatWsRegistry implements WsRegistry {
final Container host = engine.findChild(virtualHost);
if (host == null) {
- throw new IllegalArgumentException("Invalid virtual host '" + virtualHost + "'. Do you have a matchiing Host entry in the server.xml?");
+ throw new IllegalArgumentException("Invalid virtual host '" + virtualHost + "'. Do you have a matching Host entry in the server.xml?");
}
if ("ROOT".equals(contextRoot)) { // doesn't happen in tomee itself but with all our tooling around
@@ -124,7 +114,7 @@ public class TomcatWsRegistry implements WsRegistry {
}
// for Pojo web services, we need to change the servlet class which is the service implementation
- // by the WsServler class
+ // by the WsServlet class
wrapper.setServletClass(WsServlet.class.getName());
if (wrapper.getServlet() != null) {
wrapper.unload(); // deallocate previous one
@@ -138,15 +128,16 @@ public class TomcatWsRegistry implements WsRegistry {
// add service locations
final List<String> addresses = new ArrayList<>();
for (final Connector connector : connectors) {
- for (final String mapping : wrapper.findMappings()) {
- final URI address = new URI(connector.getScheme(), null, host.getName(), connector.getPort(), (contextRoot.startsWith("/") ? "" : "/") + contextRoot + mapping, null, null);
+ for (final String mapping : servletInfo.mappings) {
+ final String absoluteMapping = Strings.slashify(contextRoot, mapping);
+ final URI address = new URI(connector.getScheme(), null, host.getName(), connector.getPort(),
+ absoluteMapping, null, null);
addresses.add(address.toString());
}
}
return addresses;
}
-
@Override
public void clearWsContainer(final String contextRoot, String virtualHost, final ServletInfo servletInfo, final String moduleId) {
if (virtualHost == null) {
@@ -155,7 +146,7 @@ public class TomcatWsRegistry implements WsRegistry {
final Container host = engine.findChild(virtualHost);
if (host == null) {
- throw new IllegalArgumentException("Invalid virtual host '" + virtualHost + "'. Do you have a matchiing Host entry in the server.xml?");
+ throw new IllegalArgumentException("Invalid virtual host '" + virtualHost + "'. Do you have a matching Host entry in the server.xml?");
}
final Context context = (Context) host.findChild("/" + contextRoot);
@@ -193,9 +184,7 @@ public class TomcatWsRegistry implements WsRegistry {
}
// assure context root with a leading slash
- if (!path.startsWith("/")) {
- path = "/" + path;
- }
+ path = Strings.slashify(path);
// find the existing host (we do not auto-create hosts)
if (virtualHost == null) {
@@ -220,15 +209,11 @@ public class TomcatWsRegistry implements WsRegistry {
if (webAppContext != null) {
// sub context = '/' means the service address is provided by webservices
- if (WEBSERVICE_SUB_CONTEXT.equals("/") && path.startsWith("/")) {
- addServlet(host, webAppContext, path, httpListener, path, addresses, false, moduleId);
- } else if (WEBSERVICE_SUB_CONTEXT.equals("/") && !path.startsWith("/")) {
- addServlet(host, webAppContext, '/' + path, httpListener, path, addresses, false, moduleId);
- } else {
- addServlet(host, webAppContext, WEBSERVICE_SUB_CONTEXT + path, httpListener, path, addresses, false, moduleId);
- }
+ addServlet(host, webAppContext, Strings.slashify(WEBSERVICE_SUB_CONTEXT, path), httpListener,
+ path, addresses, false, moduleId);
} else if (!WEBSERVICE_OLDCONTEXT_ACTIVE) { // deploying in a jar
- deployInFakeWebapp(path, classLoader, authMethod, transportGuarantee, realmName, host, httpListener, addresses, context);
+ deployInFakeWebapp(path, classLoader, authMethod, transportGuarantee,
+ realmName, host, httpListener, addresses, context);
}
}
return addresses;
@@ -271,24 +256,12 @@ public class TomcatWsRegistry implements WsRegistry {
fakeContextReferences.put(name, ref + 1);
}
- String mapping = path;
- if (!mapping.startsWith("/")) { // TODO: check it can happen or move it away
- mapping = '/' + mapping;
- }
- addServlet(host, (Context) context, mapping, httpListener, path, addresses, true, null);
+ addServlet(host, (Context) context, Strings.slashify(path), httpListener, path, addresses, true, null);
}
private static Context createNewContext(final ClassLoader classLoader, String authMethod, String transportGuarantee, final String realmName, final String name) {
- String path = name;
- if (path == null) {
- path = "/";
- }
- if (!path.startsWith("/")) {
- path = "/" + path;
- }
-
final StandardContext context = new IgnoredStandardContext();
- context.setPath(path);
+ context.setPath(Strings.slashify(name));
context.setDocBase("");
context.setParentClassLoader(classLoader);
context.setDelegate(true);
@@ -371,28 +344,15 @@ public class TomcatWsRegistry implements WsRegistry {
// register wsdl locations for service-ref resolution
for (final Connector connector : connectors) {
- final StringBuilder fullContextpath;
+ final String fullContextPath;
if (!WEBSERVICE_OLDCONTEXT_ACTIVE && !fakeDeployment) {
- String contextPath = context.getPath();
- if (contextPath == null || !contextPath.isEmpty()) {
- if (contextPath != null && !contextPath.startsWith("/")) {
- contextPath = "/" + contextPath;
- } else if (contextPath == null) {
- contextPath = "/";
- }
- }
-
- fullContextpath = new StringBuilder(contextPath);
- if (!WEBSERVICE_SUB_CONTEXT.equals("/")) {
- fullContextpath.append(WEBSERVICE_SUB_CONTEXT);
- }
- fullContextpath.append(path);
+ fullContextPath = Strings.slashify(context.getPath(), WEBSERVICE_SUB_CONTEXT, path);
} else {
- fullContextpath = new StringBuilder(context.getPath()).append(path);
+ fullContextPath = Strings.slashify(context.getPath(), path);
}
try {
- final URI address = new URI(connector.getScheme(), null, host.getName(), connector.getPort(), fullContextpath.toString(), null, null);
+ final URI address = new URI(connector.getScheme(), null, host.getName(), connector.getPort(), fullContextPath, null, null);
addresses.add(address.toString());
} catch (final URISyntaxException ignored) {
// no-op
@@ -407,9 +367,7 @@ public class TomcatWsRegistry implements WsRegistry {
}
// assure context root with a leading slash
- if (!path.startsWith("/")) {
- path = "/" + path;
- }
+ path = Strings.slashify(path);
if (TomcatHelper.isStopping()) {
return;