You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2023/01/23 20:02:05 UTC
[tomcat] 03/03: Refactcor custom URL handler to use ServiceLoader
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 5fdaada8e41ddd113b5034b1fba59dc7efd9568a
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Jan 23 14:56:29 2023 +0000
Refactcor custom URL handler to use ServiceLoader
---
bin/catalina.bat | 4 --
bin/catalina.sh | 4 --
build.xml | 2 +
.../catalina/loader/WebappClassLoaderBase.java | 4 +-
.../apache/catalina/webresources/StandardRoot.java | 11 +++--
.../TomcatURLStreamHandlerFactory.java | 17 +++-----
.../TomcatURLStreamHandlerProvider.java | 47 ++++++++++++++++++++++
.../services/java.net.spi.URLStreamHandlerProvider | 16 ++++++++
.../services/java.net.spi.URLStreamHandlerProvider | 16 ++++++++
.../services/java.net.spi.URLStreamHandlerProvider | 17 ++++++++
.../TestClasspathUrlStreamHandler.java | 6 ---
.../webresources/TestJarWarResourceSet.java | 7 ----
.../TestTomcatURLStreamHandlerFactory.java | 10 ++---
.../catalina/webresources/war/TestHandler.java | 9 -----
.../webresources/war/TestWarURLConnection.java | 9 -----
.../apache/tomcat/util/buf/TesterUriUtilBase.java | 3 --
.../tomcat/util/file/TestConfigFileLoader.java | 2 -
.../util/scan/TestAbstractInputStreamJar.java | 8 ----
webapps/docs/changelog.xml | 4 ++
19 files changed, 118 insertions(+), 78 deletions(-)
diff --git a/bin/catalina.bat b/bin/catalina.bat
index 824773b460..b00c20c5fa 100755
--- a/bin/catalina.bat
+++ b/bin/catalina.bat
@@ -203,10 +203,6 @@ set "JSSE_OPTS=-Djdk.tls.ephemeralDHKeySize=2048"
:gotJsseOpts
set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS%"
-rem Register custom URL handlers
-rem Do this here so custom URL handles (specifically 'war:...') can be used in the security policy
-set "JAVA_OPTS=%JAVA_OPTS% -Djava.protocol.handler.pkgs=org.apache.catalina.webresources"
-
if not "%CATALINA_LOGGING_CONFIG%" == "" goto noJuliConfig
set CATALINA_LOGGING_CONFIG=-Dnop
if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuliConfig
diff --git a/bin/catalina.sh b/bin/catalina.sh
index a15accbdb5..6d13d7ab1a 100755
--- a/bin/catalina.sh
+++ b/bin/catalina.sh
@@ -251,10 +251,6 @@ if [ -z "$JSSE_OPTS" ] ; then
fi
JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS"
-# Register custom URL handlers
-# Do this here so custom URL handles (specifically 'war:...') can be used in the security policy
-JAVA_OPTS="$JAVA_OPTS -Djava.protocol.handler.pkgs=org.apache.catalina.webresources"
-
# Set juli LogManager config file if it is present and an override has not been issued
if [ -z "$CATALINA_LOGGING_CONFIG" ]; then
if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then
diff --git a/build.xml b/build.xml
index cc5bdddada..d445abb842 100644
--- a/build.xml
+++ b/build.xml
@@ -1156,6 +1156,7 @@
<jarIt jarfile="${catalina.jar}"
filesDir="${tomcat.classes}"
filesId="files.catalina"
+ meta-inf="${tomcat.manifests}/catalina.jar"
addOSGi="true" />
<!-- Catalina Cluster/HA JAR File -->
@@ -1682,6 +1683,7 @@
<jarIt jarfile="${tomcat-embed-core.jar}"
filesDir="${tomcat.classes}"
filesId="files.tomcat-embed-core"
+ manifest="${tomcat.manifests}/tomcat-embed-core.jar"
notice="${tomcat.manifests}/servlet-api.jar.notice"
license="${tomcat.manifests}/servlet-api.jar.license"
addOSGi="true"
diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
index 6ba682b610..5e3e7742db 100644
--- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
@@ -69,7 +69,6 @@ import org.apache.catalina.LifecycleListener;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.WebResource;
import org.apache.catalina.WebResourceRoot;
-import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
import org.apache.juli.WebappProperties;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
@@ -1669,6 +1668,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
/**
* Clear references.
*/
+ @SuppressWarnings("deprecation")
protected void clearReferences() {
// If the JVM is shutting down, skip the memory leak checks
@@ -1721,7 +1721,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
java.beans.Introspector.flushCaches();
// Clear any custom URLStreamHandlers
- TomcatURLStreamHandlerFactory.release(this);
+ org.apache.catalina.webresources.TomcatURLStreamHandlerFactory.release(this);
}
diff --git a/java/org/apache/catalina/webresources/StandardRoot.java b/java/org/apache/catalina/webresources/StandardRoot.java
index 69efa79b73..8e8dac4be2 100644
--- a/java/org/apache/catalina/webresources/StandardRoot.java
+++ b/java/org/apache/catalina/webresources/StandardRoot.java
@@ -45,7 +45,6 @@ import org.apache.catalina.util.LifecycleMBeanBase;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.UriUtil;
-import org.apache.tomcat.util.compat.JreCompat;
import org.apache.tomcat.util.http.RequestUtil;
import org.apache.tomcat.util.res.StringManager;
@@ -719,12 +718,12 @@ public class StandardRoot extends LifecycleMBeanBase implements WebResourceRoot
}
}
+ /**
+ * @deprecated Unused. Will be removed in Tomcat 11 onwards.
+ */
+ @Deprecated
protected void registerURLStreamHandlerFactory() {
- if (!JreCompat.isGraalAvailable()) {
- // Ensure support for jar:war:file:/ URLs will be available (required
- // for resource JARs in packed WAR files).
- TomcatURLStreamHandlerFactory.register();
- }
+ // NO-OP
}
@Override
diff --git a/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java b/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java
index d58f9d3fef..830858e774 100644
--- a/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java
+++ b/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java
@@ -22,13 +22,13 @@ import java.net.URLStreamHandlerFactory;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
-import org.apache.catalina.webresources.war.Handler;
-
+/**
+ * @deprecated Unused. Use the ServiceLoader mechanism to define additional
+ * handlers. Will be removed in Tomcat 11 onwards.
+ */
+@Deprecated
public class TomcatURLStreamHandlerFactory implements URLStreamHandlerFactory {
- private static final String WAR_PROTOCOL = "war";
- private static final String CLASSPATH_PROTOCOL = "classpath";
-
// Singleton instance
private static volatile TomcatURLStreamHandlerFactory instance = null;
@@ -153,13 +153,6 @@ public class TomcatURLStreamHandlerFactory implements URLStreamHandlerFactory {
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
- // Tomcat's handler always takes priority so applications can't override
- // it.
- if (WAR_PROTOCOL.equals(protocol)) {
- return new Handler();
- } else if (CLASSPATH_PROTOCOL.equals(protocol)) {
- return new ClasspathURLStreamHandler();
- }
// Application handlers
for (URLStreamHandlerFactory factory : userFactories) {
diff --git a/java/org/apache/catalina/webresources/TomcatURLStreamHandlerProvider.java b/java/org/apache/catalina/webresources/TomcatURLStreamHandlerProvider.java
new file mode 100644
index 0000000000..971e5ea4f8
--- /dev/null
+++ b/java/org/apache/catalina/webresources/TomcatURLStreamHandlerProvider.java
@@ -0,0 +1,47 @@
+/*
+ * 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.catalina.webresources;
+
+import java.net.URLStreamHandler;
+import java.net.spi.URLStreamHandlerProvider;
+
+import org.apache.catalina.webresources.war.Handler;
+
+@SuppressWarnings("deprecation")
+public class TomcatURLStreamHandlerProvider extends URLStreamHandlerProvider {
+
+ private static final String WAR_PROTOCOL = "war";
+ private static final String CLASSPATH_PROTOCOL = "classpath";
+
+ static {
+ // Create an instance without calling URL.setURLStreamHandlerFactory
+ TomcatURLStreamHandlerFactory.disable();
+ }
+
+
+ @Override
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ if (WAR_PROTOCOL.equals(protocol)) {
+ return new Handler();
+ } else if (CLASSPATH_PROTOCOL.equals(protocol)) {
+ return new ClasspathURLStreamHandler();
+ }
+
+ // Possible user handler defined via Tomcat's custom API
+ return TomcatURLStreamHandlerFactory.getInstance().createURLStreamHandler(protocol);
+ }
+}
diff --git a/res/META-INF/catalina.jar/services/java.net.spi.URLStreamHandlerProvider b/res/META-INF/catalina.jar/services/java.net.spi.URLStreamHandlerProvider
new file mode 100644
index 0000000000..60438bdb23
--- /dev/null
+++ b/res/META-INF/catalina.jar/services/java.net.spi.URLStreamHandlerProvider
@@ -0,0 +1,16 @@
+# 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.catalina.webresources.TomcatURLStreamHandlerProvider
\ No newline at end of file
diff --git a/res/META-INF/tomcat-embed-core.jar/services/java.net.spi.URLStreamHandlerProvider b/res/META-INF/tomcat-embed-core.jar/services/java.net.spi.URLStreamHandlerProvider
new file mode 100644
index 0000000000..60438bdb23
--- /dev/null
+++ b/res/META-INF/tomcat-embed-core.jar/services/java.net.spi.URLStreamHandlerProvider
@@ -0,0 +1,16 @@
+# 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.catalina.webresources.TomcatURLStreamHandlerProvider
\ No newline at end of file
diff --git a/test/META-INF/services/java.net.spi.URLStreamHandlerProvider b/test/META-INF/services/java.net.spi.URLStreamHandlerProvider
new file mode 100644
index 0000000000..e0b27f914f
--- /dev/null
+++ b/test/META-INF/services/java.net.spi.URLStreamHandlerProvider
@@ -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.
+
+# Handler required when running tests
+org.apache.catalina.webresources.TomcatURLStreamHandlerProvider
\ No newline at end of file
diff --git a/test/org/apache/catalina/webresources/TestClasspathUrlStreamHandler.java b/test/org/apache/catalina/webresources/TestClasspathUrlStreamHandler.java
index f1bb097b37..9df2b90fa3 100644
--- a/test/org/apache/catalina/webresources/TestClasspathUrlStreamHandler.java
+++ b/test/org/apache/catalina/webresources/TestClasspathUrlStreamHandler.java
@@ -22,16 +22,10 @@ import java.net.URL;
import java.util.Properties;
import org.junit.Assert;
-import org.junit.BeforeClass;
import org.junit.Test;
public class TestClasspathUrlStreamHandler {
- @BeforeClass
- public static void setup() {
- TomcatURLStreamHandlerFactory.getInstance();
- }
-
@Test
public void testClasspathURL01() throws IOException {
URL u = new URL("classpath:/org/apache/catalina/webresources/LocalStrings.properties");
diff --git a/test/org/apache/catalina/webresources/TestJarWarResourceSet.java b/test/org/apache/catalina/webresources/TestJarWarResourceSet.java
index be5d98f87a..ed5b29fd2f 100644
--- a/test/org/apache/catalina/webresources/TestJarWarResourceSet.java
+++ b/test/org/apache/catalina/webresources/TestJarWarResourceSet.java
@@ -19,7 +19,6 @@ package org.apache.catalina.webresources;
import java.io.File;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
import org.apache.catalina.Context;
@@ -30,12 +29,6 @@ import org.apache.catalina.startup.TomcatBaseTest;
public class TestJarWarResourceSet extends TomcatBaseTest {
- @Before
- public void register() {
- TomcatURLStreamHandlerFactory.register();
- }
-
-
@Test
public void testJarWarMetaInf() throws LifecycleException {
Tomcat tomcat = getTomcatInstance();
diff --git a/test/org/apache/catalina/webresources/TestTomcatURLStreamHandlerFactory.java b/test/org/apache/catalina/webresources/TestTomcatURLStreamHandlerFactory.java
index b999c8be71..ac5b6342ff 100644
--- a/test/org/apache/catalina/webresources/TestTomcatURLStreamHandlerFactory.java
+++ b/test/org/apache/catalina/webresources/TestTomcatURLStreamHandlerFactory.java
@@ -19,16 +19,14 @@ package org.apache.catalina.webresources;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
-import org.junit.Before;
import org.junit.Test;
+/**
+ * @deprecated Code under test is deprecated and will be removed in Tomcat 11
+ */
+@Deprecated
public class TestTomcatURLStreamHandlerFactory {
- @Before
- public void register() {
- TomcatURLStreamHandlerFactory.register();
- }
-
@Test
public void testUserFactory() throws Exception {
URLStreamHandlerFactory factory = new URLStreamHandlerFactory() {
diff --git a/test/org/apache/catalina/webresources/war/TestHandler.java b/test/org/apache/catalina/webresources/war/TestHandler.java
index c4b72bee15..0e3ac88a48 100644
--- a/test/org/apache/catalina/webresources/war/TestHandler.java
+++ b/test/org/apache/catalina/webresources/war/TestHandler.java
@@ -21,19 +21,10 @@ import java.net.URL;
import java.net.URLConnection;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
-import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
-
public class TestHandler {
- @Before
- public void register() {
- TomcatURLStreamHandlerFactory.register();
- }
-
-
@Test
public void testUrlFileInJarInWar() throws Exception {
doTestUrl("jar:war:", "*/WEB-INF/lib/test.jar!/META-INF/resources/index.html");
diff --git a/test/org/apache/catalina/webresources/war/TestWarURLConnection.java b/test/org/apache/catalina/webresources/war/TestWarURLConnection.java
index f005115824..1d82530ce9 100644
--- a/test/org/apache/catalina/webresources/war/TestWarURLConnection.java
+++ b/test/org/apache/catalina/webresources/war/TestWarURLConnection.java
@@ -21,19 +21,10 @@ import java.net.URL;
import java.net.URLConnection;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
-import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
-
public class TestWarURLConnection {
- @Before
- public void register() {
- TomcatURLStreamHandlerFactory.register();
- }
-
-
@Test
public void testContentLength() throws Exception {
File f = new File("test/webresources/war-url-connection.war");
diff --git a/test/org/apache/tomcat/util/buf/TesterUriUtilBase.java b/test/org/apache/tomcat/util/buf/TesterUriUtilBase.java
index b176788bf4..28a095bec9 100644
--- a/test/org/apache/tomcat/util/buf/TesterUriUtilBase.java
+++ b/test/org/apache/tomcat/util/buf/TesterUriUtilBase.java
@@ -23,15 +23,12 @@ import java.net.URL;
import org.junit.Assert;
import org.junit.Test;
-import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
-
public abstract class TesterUriUtilBase {
private final String separator;
protected TesterUriUtilBase(String separator) {
this.separator = separator;
- TomcatURLStreamHandlerFactory.register();
System.setProperty("org.apache.tomcat.util.buf.UriUtil.WAR_SEPARATOR", separator);
}
diff --git a/test/org/apache/tomcat/util/file/TestConfigFileLoader.java b/test/org/apache/tomcat/util/file/TestConfigFileLoader.java
index 5271e778da..d87c3de17f 100644
--- a/test/org/apache/tomcat/util/file/TestConfigFileLoader.java
+++ b/test/org/apache/tomcat/util/file/TestConfigFileLoader.java
@@ -27,13 +27,11 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.catalina.startup.CatalinaBaseConfigurationSource;
-import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
public class TestConfigFileLoader {
@BeforeClass
public static void setup() {
- TomcatURLStreamHandlerFactory.getInstance();
System.setProperty("catalina.base", "");
ConfigFileLoader.setSource(new CatalinaBaseConfigurationSource(new File(System.getProperty("catalina.base")), null));
}
diff --git a/test/org/apache/tomcat/util/scan/TestAbstractInputStreamJar.java b/test/org/apache/tomcat/util/scan/TestAbstractInputStreamJar.java
index b6f96e2b17..278ea23046 100644
--- a/test/org/apache/tomcat/util/scan/TestAbstractInputStreamJar.java
+++ b/test/org/apache/tomcat/util/scan/TestAbstractInputStreamJar.java
@@ -22,21 +22,13 @@ import java.io.InputStream;
import java.net.URL;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
import org.apache.catalina.util.IOTools;
-import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
import org.apache.tomcat.Jar;
public class TestAbstractInputStreamJar {
- @Before
- public void register() {
- TomcatURLStreamHandlerFactory.register();
- }
-
-
@Test
public void testNestedJarGetInputStream() throws Exception {
File f = new File("test/webresources/war-url-connection.war");
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index a5678489de..886dd1521a 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -115,6 +115,10 @@
<bug>66438</bug>: Correct names of Jakarta modules in JPMS metadata.
(markt)
</fix>
+ <update>
+ Switch to using the ServiceLoader mechanism to load the custom URL
+ protocol handlers that Tomcat uses. (markt)
+ </update>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org