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/02/27 17:02:12 UTC
[tomcat] 01/03: Revert "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 main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 6e83c093f2b674dfcdb06151392d0651a8b880ff
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Feb 27 16:01:22 2023 +0000
Revert "Refactcor custom URL handler to use ServiceLoader"
This reverts commits:
4c70a12e8aac4081a11f200a7e70f0db30a6c79b.
3a2db66ffd4efb9f9d8f5c7b916477f62f32441c.
6b4d6ba0fad9f233e492618ea0bbcbaa307605fc.
f949ac1cd08004d1a149d3a411b079c7712e44bb.
0782f0b919b5131a9423c91333f7c557954336a3.
---
bin/catalina.bat | 3 +
bin/catalina.sh | 3 +
build.xml | 2 -
.../catalina/loader/WebappClassLoaderBase.java | 4 +
.../apache/catalina/webresources/StandardRoot.java | 11 +-
.../TomcatURLStreamHandlerFactory.java | 176 +++++++++++++++++++++
.../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 | 35 ++--
.../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 | 5 +
18 files changed, 260 insertions(+), 72 deletions(-)
diff --git a/bin/catalina.bat b/bin/catalina.bat
index 068cd283bc..ce73b88044 100755
--- a/bin/catalina.bat
+++ b/bin/catalina.bat
@@ -203,6 +203,9 @@ set "JSSE_OPTS=-Djdk.tls.ephemeralDHKeySize=2048"
:gotJsseOpts
set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS%"
+rem Register custom URL handlers
+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 a7b14b6957..d987738b27 100755
--- a/bin/catalina.sh
+++ b/bin/catalina.sh
@@ -251,6 +251,9 @@ if [ -z "$JSSE_OPTS" ] ; then
fi
JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS"
+# Register custom URL handlers
+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 d51f3045cf..9070c52281 100644
--- a/build.xml
+++ b/build.xml
@@ -1169,7 +1169,6 @@
<jarIt jarfile="${catalina.jar}"
filesDir="${tomcat.classes}"
filesId="files.catalina"
- meta-inf="${tomcat.manifests}/catalina.jar"
addOSGi="true" />
<!-- Catalina Cluster/HA JAR File -->
@@ -1699,7 +1698,6 @@
filesId="files.tomcat-embed-core"
notice="${tomcat.manifests}/servlet-api.jar.notice"
license="${tomcat.manifests}/servlet-api.jar.license"
- meta-inf="${tomcat.manifests}/tomcat-embed-core.jar"
addOSGi="true"
addGraal="true"
graalPrefix="org.apache.tomcat.embed/tomcat-embed-core"
diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
index 2addcb83c8..b637fdd323 100644
--- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
@@ -61,6 +61,7 @@ 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;
@@ -1542,6 +1543,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
// Clear the classloader reference in the VM's bean introspector
java.beans.Introspector.flushCaches();
+
+ // Clear any custom URLStreamHandlers
+ TomcatURLStreamHandlerFactory.release(this);
}
diff --git a/java/org/apache/catalina/webresources/StandardRoot.java b/java/org/apache/catalina/webresources/StandardRoot.java
index 3609e2c368..2cb98e277a 100644
--- a/java/org/apache/catalina/webresources/StandardRoot.java
+++ b/java/org/apache/catalina/webresources/StandardRoot.java
@@ -45,6 +45,7 @@ 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;
@@ -691,12 +692,12 @@ public class StandardRoot extends LifecycleMBeanBase implements WebResourceRoot
}
}
- /**
- * @deprecated Unused. Will be removed in Tomcat 11 onwards.
- */
- @Deprecated
protected void registerURLStreamHandlerFactory() {
- // NO-OP
+ if (!JreCompat.isGraalAvailable()) {
+ // Ensure support for jar:war:file:/ URLs will be available (required
+ // for resource JARs in packed WAR files).
+ TomcatURLStreamHandlerFactory.register();
+ }
}
@Override
diff --git a/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java b/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java
new file mode 100644
index 0000000000..d58f9d3fef
--- /dev/null
+++ b/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java
@@ -0,0 +1,176 @@
+/*
+ * 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.URL;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.catalina.webresources.war.Handler;
+
+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;
+
+ /**
+ * Obtain a reference to the singleton instance. It is recommended that
+ * callers check the value of {@link #isRegistered()} before using the
+ * returned instance.
+ *
+ * @return A reference to the singleton instance
+ */
+ public static TomcatURLStreamHandlerFactory getInstance() {
+ getInstanceInternal(true);
+ return instance;
+ }
+
+
+ private static TomcatURLStreamHandlerFactory getInstanceInternal(boolean register) {
+ // Double checked locking. OK because instance is volatile.
+ if (instance == null) {
+ synchronized (TomcatURLStreamHandlerFactory.class) {
+ if (instance == null) {
+ instance = new TomcatURLStreamHandlerFactory(register);
+ }
+ }
+ }
+ return instance;
+ }
+
+
+ private final boolean registered;
+
+ // List of factories for application defined stream handler factories.
+ private final List<URLStreamHandlerFactory> userFactories =
+ new CopyOnWriteArrayList<>();
+
+ /**
+ * Register this factory with the JVM. May be called more than once. The
+ * implementation ensures that registration only occurs once.
+ *
+ * @return <code>true</code> if the factory is already registered with the
+ * JVM or was successfully registered as a result of this call.
+ * <code>false</code> if the factory was disabled prior to this
+ * call.
+ */
+ public static boolean register() {
+ return getInstanceInternal(true).isRegistered();
+ }
+
+
+ /**
+ * Prevent this this factory from registering with the JVM. May be called
+ * more than once.
+ *
+ * @return <code>true</code> if the factory is already disabled or was
+ * successfully disabled as a result of this call.
+ * <code>false</code> if the factory was already registered prior
+ * to this call.
+ */
+ public static boolean disable() {
+ return !getInstanceInternal(false).isRegistered();
+ }
+
+
+ /**
+ * Release references to any user provided factories that have been loaded
+ * using the provided class loader. Called during web application stop to
+ * prevent memory leaks.
+ *
+ * @param classLoader The class loader to release
+ */
+ public static void release(ClassLoader classLoader) {
+ if (instance == null) {
+ return;
+ }
+ List<URLStreamHandlerFactory> factories = instance.userFactories;
+ for (URLStreamHandlerFactory factory : factories) {
+ ClassLoader factoryLoader = factory.getClass().getClassLoader();
+ while (factoryLoader != null) {
+ if (classLoader.equals(factoryLoader)) {
+ // Implementation note: userFactories is a
+ // CopyOnWriteArrayList, so items are removed with
+ // List.remove() instead of usual Iterator.remove()
+ factories.remove(factory);
+ break;
+ }
+ factoryLoader = factoryLoader.getParent();
+ }
+ }
+ }
+
+
+ private TomcatURLStreamHandlerFactory(boolean register) {
+ // Hide default constructor
+ // Singleton pattern to ensure there is only one instance of this
+ // factory
+ this.registered = register;
+ if (register) {
+ URL.setURLStreamHandlerFactory(this);
+ }
+ }
+
+
+ public boolean isRegistered() {
+ return registered;
+ }
+
+
+ /**
+ * Since the JVM only allows a single call to
+ * {@link URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)} and
+ * Tomcat needs to register a handler, provide a mechanism to allow
+ * applications to register their own handlers.
+ *
+ * @param factory The user provided factory to add to the factories Tomcat
+ * has already registered
+ */
+ public void addUserFactory(URLStreamHandlerFactory factory) {
+ userFactories.add(factory);
+ }
+
+
+ @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) {
+ URLStreamHandler handler =
+ factory.createURLStreamHandler(protocol);
+ if (handler != null) {
+ return handler;
+ }
+ }
+
+ // Unknown protocol
+ return null;
+ }
+}
diff --git a/res/META-INF/catalina.jar/services/java.net.spi.URLStreamHandlerProvider b/res/META-INF/catalina.jar/services/java.net.spi.URLStreamHandlerProvider
deleted file mode 100644
index 60438bdb23..0000000000
--- a/res/META-INF/catalina.jar/services/java.net.spi.URLStreamHandlerProvider
+++ /dev/null
@@ -1,16 +0,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.
-
-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
deleted file mode 100644
index 60438bdb23..0000000000
--- a/res/META-INF/tomcat-embed-core.jar/services/java.net.spi.URLStreamHandlerProvider
+++ /dev/null
@@ -1,16 +0,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.
-
-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
deleted file mode 100644
index e0b27f914f..0000000000
--- a/test/META-INF/services/java.net.spi.URLStreamHandlerProvider
+++ /dev/null
@@ -1,17 +0,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.
-
-# 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 9df2b90fa3..f1bb097b37 100644
--- a/test/org/apache/catalina/webresources/TestClasspathUrlStreamHandler.java
+++ b/test/org/apache/catalina/webresources/TestClasspathUrlStreamHandler.java
@@ -22,10 +22,16 @@ 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 ed5b29fd2f..be5d98f87a 100644
--- a/test/org/apache/catalina/webresources/TestJarWarResourceSet.java
+++ b/test/org/apache/catalina/webresources/TestJarWarResourceSet.java
@@ -19,6 +19,7 @@ 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;
@@ -29,6 +30,12 @@ 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/java/org/apache/catalina/webresources/TomcatURLStreamHandlerProvider.java b/test/org/apache/catalina/webresources/TestTomcatURLStreamHandlerFactory.java
similarity index 56%
rename from java/org/apache/catalina/webresources/TomcatURLStreamHandlerProvider.java
rename to test/org/apache/catalina/webresources/TestTomcatURLStreamHandlerFactory.java
index 6be9781506..b999c8be71 100644
--- a/java/org/apache/catalina/webresources/TomcatURLStreamHandlerProvider.java
+++ b/test/org/apache/catalina/webresources/TestTomcatURLStreamHandlerFactory.java
@@ -17,24 +17,27 @@
package org.apache.catalina.webresources;
import java.net.URLStreamHandler;
-import java.net.spi.URLStreamHandlerProvider;
+import java.net.URLStreamHandlerFactory;
-import org.apache.catalina.webresources.war.Handler;
+import org.junit.Before;
+import org.junit.Test;
-public class TomcatURLStreamHandlerProvider extends URLStreamHandlerProvider {
-
- private static final String WAR_PROTOCOL = "war";
- private static final String CLASSPATH_PROTOCOL = "classpath";
-
- @Override
- public URLStreamHandler createURLStreamHandler(String protocol) {
- if (WAR_PROTOCOL.equals(protocol)) {
- return new Handler();
- } else if (CLASSPATH_PROTOCOL.equals(protocol)) {
- return new ClasspathURLStreamHandler();
- }
+public class TestTomcatURLStreamHandlerFactory {
+ @Before
+ public void register() {
+ TomcatURLStreamHandlerFactory.register();
+ }
- return null;
+ @Test
+ public void testUserFactory() throws Exception {
+ URLStreamHandlerFactory factory = new URLStreamHandlerFactory() {
+ @Override
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ return null;
+ }
+ };
+ TomcatURLStreamHandlerFactory.getInstance().addUserFactory(factory);
+ TomcatURLStreamHandlerFactory.release(factory.getClass().getClassLoader());
}
-}
+}
\ No newline at end of file
diff --git a/test/org/apache/catalina/webresources/war/TestHandler.java b/test/org/apache/catalina/webresources/war/TestHandler.java
index 0e3ac88a48..c4b72bee15 100644
--- a/test/org/apache/catalina/webresources/war/TestHandler.java
+++ b/test/org/apache/catalina/webresources/war/TestHandler.java
@@ -21,10 +21,19 @@ 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 1d82530ce9..f005115824 100644
--- a/test/org/apache/catalina/webresources/war/TestWarURLConnection.java
+++ b/test/org/apache/catalina/webresources/war/TestWarURLConnection.java
@@ -21,10 +21,19 @@ 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 bad8b2f685..9980669aa2 100644
--- a/test/org/apache/tomcat/util/buf/TesterUriUtilBase.java
+++ b/test/org/apache/tomcat/util/buf/TesterUriUtilBase.java
@@ -23,12 +23,15 @@ 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 d87c3de17f..5271e778da 100644
--- a/test/org/apache/tomcat/util/file/TestConfigFileLoader.java
+++ b/test/org/apache/tomcat/util/file/TestConfigFileLoader.java
@@ -27,11 +27,13 @@ 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 278ea23046..b6f96e2b17 100644
--- a/test/org/apache/tomcat/util/scan/TestAbstractInputStreamJar.java
+++ b/test/org/apache/tomcat/util/scan/TestAbstractInputStreamJar.java
@@ -22,13 +22,21 @@ 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 3f3e4e70e2..feaabd8985 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -129,6 +129,11 @@
so that the provider configuration file required by Tomcat's custom URL
protocol for WAR files is retained when adding OSGi meta-data. (markt)
</fix>
+ <update>
+ Revert switch to using the ServiceLoader mechanism to load the custom URL
+ protocol handlers that Tomcat uses. The original system property based
+ approach has been restored. (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