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
The following commit(s) were added to refs/heads/main by this push: new 592bc75020 Refactor JreCompat for minimum Java version of Java 21 592bc75020 is described below commit 592bc75020589df542320ae0a55cf7ff400bd45f Author: Mark Thomas <ma...@apache.org> AuthorDate: Thu May 11 17:09:03 2023 +0100 Refactor JreCompat for minimum Java version of Java 21 --- java/org/apache/catalina/core/StandardContext.java | 20 ---- .../catalina/loader/WebappClassLoaderBase.java | 132 ++++++++++----------- .../org/apache/tomcat/util/compat/Jre19Compat.java | 84 ------------- java/org/apache/tomcat/util/compat/JreCompat.java | 80 +------------ .../tomcat/util/compat/LocalStrings.properties | 16 --- .../tomcat/util/compat/LocalStrings_fr.properties | 16 --- .../tomcat/util/compat/LocalStrings_ja.properties | 16 --- .../tomcat/util/compat/LocalStrings_ko.properties | 16 --- .../util/compat/LocalStrings_zh_CN.properties | 16 --- .../servlet/http/HttpServletDoHeadBaseTest.java | 37 ++---- webapps/docs/config/context.xml | 15 --- 11 files changed, 81 insertions(+), 367 deletions(-) diff --git a/java/org/apache/catalina/core/StandardContext.java b/java/org/apache/catalina/core/StandardContext.java index 888aa53e0e..5d1cc905ad 100644 --- a/java/org/apache/catalina/core/StandardContext.java +++ b/java/org/apache/catalina/core/StandardContext.java @@ -705,12 +705,6 @@ public class StandardContext extends ContainerBase implements Context, Notificat */ private boolean renewThreadsWhenStoppingContext = true; - /** - * Should Tomcat attempt to clear references to classes loaded by the web application class loader from the - * ObjectStreamClass caches? - */ - private boolean clearReferencesObjectStreamClassCaches = true; - /** * Should Tomcat attempt to clear references to classes loaded by this class loader from ThreadLocals? */ @@ -2648,19 +2642,6 @@ public class StandardContext extends ContainerBase implements Context, Notificat } - public boolean getClearReferencesObjectStreamClassCaches() { - return clearReferencesObjectStreamClassCaches; - } - - - public void setClearReferencesObjectStreamClassCaches(boolean clearReferencesObjectStreamClassCaches) { - boolean oldClearReferencesObjectStreamClassCaches = this.clearReferencesObjectStreamClassCaches; - this.clearReferencesObjectStreamClassCaches = clearReferencesObjectStreamClassCaches; - support.firePropertyChange("clearReferencesObjectStreamClassCaches", oldClearReferencesObjectStreamClassCaches, - this.clearReferencesObjectStreamClassCaches); - } - - public boolean getClearReferencesThreadLocals() { return clearReferencesThreadLocals; } @@ -4745,7 +4726,6 @@ public class StandardContext extends ContainerBase implements Context, Notificat cl.setClearReferencesStopThreads(getClearReferencesStopThreads()); cl.setClearReferencesStopTimerThreads(getClearReferencesStopTimerThreads()); cl.setClearReferencesHttpClientKeepAliveThread(getClearReferencesHttpClientKeepAliveThread()); - cl.setClearReferencesObjectStreamClassCaches(getClearReferencesObjectStreamClassCaches()); cl.setClearReferencesThreadLocals(getClearReferencesThreadLocals()); cl.setSkipMemoryLeakChecksOnJvmShutdown(getSkipMemoryLeakChecksOnJvmShutdown()); } diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/java/org/apache/catalina/loader/WebappClassLoaderBase.java index b637fdd323..fede505739 100644 --- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java +++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java @@ -352,12 +352,6 @@ public abstract class WebappClassLoaderBase extends URLClassLoader */ private boolean clearReferencesHttpClientKeepAliveThread = true; - /** - * Should Tomcat attempt to clear references to classes loaded by this class - * loader from the ObjectStreamClass caches? - */ - private boolean clearReferencesObjectStreamClassCaches = true; - /** * Should Tomcat attempt to clear references to classes loaded by this class * loader from ThreadLocals? @@ -539,17 +533,6 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } - public boolean getClearReferencesObjectStreamClassCaches() { - return clearReferencesObjectStreamClassCaches; - } - - - public void setClearReferencesObjectStreamClassCaches( - boolean clearReferencesObjectStreamClassCaches) { - this.clearReferencesObjectStreamClassCaches = clearReferencesObjectStreamClassCaches; - } - - public boolean getClearReferencesThreadLocals() { return clearReferencesThreadLocals; } @@ -1518,11 +1501,6 @@ public abstract class WebappClassLoaderBase extends URLClassLoader // Stop any threads the web application started clearReferencesThreads(); - // Clear any references retained in the serialization caches - if (clearReferencesObjectStreamClassCaches && !JreCompat.isGraalAvailable()) { - clearReferencesObjectStreamClassCaches(); - } - // Check for leaks triggered by ThreadLocals loaded by this class loader if (clearReferencesThreadLocals && !JreCompat.isGraalAvailable()) { checkThreadLocalsForLeaks(); @@ -1669,7 +1647,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader // shutting down the executor boolean usingExecutor = false; try { - Object executor = JreCompat.getInstance().getExecutor(thread); + Object executor = getExecutor(thread); if (executor instanceof ThreadPoolExecutor) { ((ThreadPoolExecutor) executor).shutdownNow(); usingExecutor = true; @@ -1726,6 +1704,70 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } + private Object getExecutor(Thread thread) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + + Object result = null; + + // Runnable wrapped by Thread + // "target" in Sun/Oracle JDK + // "runnable" in IBM JDK + // "action" in Apache Harmony + Object target = null; + for (String fieldName : new String[] { "target", "runnable", "action" }) { + try { + Field targetField = thread.getClass().getDeclaredField(fieldName); + targetField.setAccessible(true); + target = targetField.get(thread); + break; + } catch (NoSuchFieldException nfe) { + continue; + } + } + + // "java.util.concurrent" code is in public domain, + // so all implementations are similar including our + // internal fork. + if (target != null && target.getClass().getCanonicalName() != null && + (target.getClass().getCanonicalName().equals( + "org.apache.tomcat.util.threads.ThreadPoolExecutor.Worker") || + target.getClass().getCanonicalName().equals( + "java.util.concurrent.ThreadPoolExecutor.Worker"))) { + Field executorField = target.getClass().getDeclaredField("this$0"); + executorField.setAccessible(true); + result = executorField.get(target); + } + + if (result == null) { + Object holder = null; + Object task = null; + try { + Field holderField = thread.getClass().getDeclaredField("holder"); + holderField.setAccessible(true); + holder = holderField.get(thread); + + Field taskField = holder.getClass().getDeclaredField("task"); + taskField.setAccessible(true); + task = taskField.get(holder); + } catch (NoSuchFieldException nfe) { + return null; + } + + if (task!= null && task.getClass().getCanonicalName() != null && + (task.getClass().getCanonicalName().equals( + "org.apache.tomcat.util.threads.ThreadPoolExecutor.Worker") || + task.getClass().getCanonicalName().equals( + "java.util.concurrent.ThreadPoolExecutor.Worker"))) { + Field executorField = task.getClass().getDeclaredField("this$0"); + executorField.setAccessible(true); + result = executorField.get(task); + } + } + + return result; + } + + /* * Look at a threads stack trace to see if it is a request thread or not. It * isn't perfect, but it should be good-enough for most cases. @@ -2110,27 +2152,6 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } - private void clearReferencesObjectStreamClassCaches() { - if (JreCompat.isJre19Available()) { - // The memory leak this fixes has been fixed in Java 19 onwards, - // 17.0.4 onwards and 11.0.16 onwards - // See https://bugs.openjdk.java.net/browse/JDK-8277072 - return; - } - try { - Class<?> clazz = Class.forName("java.io.ObjectStreamClass$Caches"); - clearCache(clazz, "localDescs"); - clearCache(clazz, "reflectors"); - } catch (ReflectiveOperationException | SecurityException | ClassCastException e) { - log.warn(sm.getString( - "webappClassLoader.clearObjectStreamClassCachesFail", getContextName()), e); - } catch (InaccessibleObjectException e) { - // Must be running on without the necessary command line options. - log.warn(sm.getString("webappClassLoader.addExportsJavaIo", getCurrentModuleName())); - } - } - - private String getCurrentModuleName() { String moduleName = this.getClass().getModule().getName(); if (moduleName == null) { @@ -2140,29 +2161,6 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } - private void clearCache(Class<?> target, String mapName) - throws ReflectiveOperationException, SecurityException, ClassCastException { - Field f = target.getDeclaredField(mapName); - f.setAccessible(true); - Object map = f.get(null); - // Avoid trying to clear references if Tomcat is running on a JRE that - // includes the fix for this memory leak - // See https://bugs.openjdk.java.net/browse/JDK-8277072 - if (map instanceof Map<?,?>) { - Iterator<?> keys = ((Map<?,?>) map).keySet().iterator(); - while (keys.hasNext()) { - Object key = keys.next(); - if (key instanceof Reference) { - Object clazz = ((Reference<?>) key).get(); - if (loadedByThisOrChild(clazz)) { - keys.remove(); - } - } - } - } - } - - /** * Find specified class in local repositories. * diff --git a/java/org/apache/tomcat/util/compat/Jre19Compat.java b/java/org/apache/tomcat/util/compat/Jre19Compat.java deleted file mode 100644 index 60ee0c2dc1..0000000000 --- a/java/org/apache/tomcat/util/compat/Jre19Compat.java +++ /dev/null @@ -1,84 +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. - */ -package org.apache.tomcat.util.compat; - -import java.lang.reflect.Field; - -import org.apache.juli.logging.Log; -import org.apache.juli.logging.LogFactory; -import org.apache.tomcat.util.res.StringManager; - -public class Jre19Compat extends JreCompat { - - private static final Log log = LogFactory.getLog(Jre19Compat.class); - private static final StringManager sm = StringManager.getManager(Jre19Compat.class); - - private static final boolean supported; - - static { - // Don't need any Java 19 specific classes (yet) so just test for one of - // the new ones for now. - Class<?> c1 = null; - try { - c1 = Class.forName("java.lang.WrongThreadException"); - } catch (ClassNotFoundException cnfe) { - // Must be pre-Java 19 - log.debug(sm.getString("jre19Compat.javaPre19"), cnfe); - } - - supported = (c1 != null); - } - - static boolean isSupported() { - return supported; - } - - @Override - public Object getExecutor(Thread thread) - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - - Object result = super.getExecutor(thread); - - if (result == null) { - Object holder = null; - Object task = null; - try { - Field holderField = thread.getClass().getDeclaredField("holder"); - holderField.setAccessible(true); - holder = holderField.get(thread); - - Field taskField = holder.getClass().getDeclaredField("task"); - taskField.setAccessible(true); - task = taskField.get(holder); - } catch (NoSuchFieldException nfe) { - return null; - } - - if (task!= null && task.getClass().getCanonicalName() != null && - (task.getClass().getCanonicalName().equals( - "org.apache.tomcat.util.threads.ThreadPoolExecutor.Worker") || - task.getClass().getCanonicalName().equals( - "java.util.concurrent.ThreadPoolExecutor.Worker"))) { - Field executorField = task.getClass().getDeclaredField("this$0"); - executorField.setAccessible(true); - result = executorField.get(task); - } - } - - return result; - } -} diff --git a/java/org/apache/tomcat/util/compat/JreCompat.java b/java/org/apache/tomcat/util/compat/JreCompat.java index 3de6908893..334115acc3 100644 --- a/java/org/apache/tomcat/util/compat/JreCompat.java +++ b/java/org/apache/tomcat/util/compat/JreCompat.java @@ -16,18 +16,15 @@ */ package org.apache.tomcat.util.compat; -import java.lang.reflect.Field; - /** * This is the base implementation class for JRE compatibility and provides an - * implementation based on Java 17. Sub-classes may extend this class and provide + * implementation based on Java 21. Sub-classes may extend this class and provide * alternative implementations for later JRE versions */ public class JreCompat { private static final JreCompat instance; private static final boolean graalAvailable; - private static final boolean jre19Available; static { boolean result = false; @@ -41,15 +38,8 @@ public class JreCompat { } graalAvailable = result || System.getProperty("org.graalvm.nativeimage.imagecode") != null; - // This is Tomcat 11.0.x with a minimum Java version of Java 17. - // Look for the highest supported JVM first - if (Jre19Compat.isSupported()) { - instance = new Jre19Compat(); - jre19Available = true; - } else { - instance = new JreCompat(); - jre19Available = false; - } + // This is Tomcat 11.0.x with a minimum Java version of Java 21. + instance = new JreCompat(); } @@ -61,68 +51,4 @@ public class JreCompat { public static boolean isGraalAvailable() { return graalAvailable; } - - - public static boolean isJre19Available() { - return jre19Available; - } - - - // Java 17 implementations of Java 19 methods - - /** - * Obtains the executor, if any, used to create the provided thread. - * - * @param thread The thread to examine - * - * @return The executor, if any, that created the provided thread - * - * @throws NoSuchFieldException - * If a field used via reflection to obtain the executor cannot - * be found - * @throws SecurityException - * If a security exception occurs while trying to identify the - * executor - * @throws IllegalArgumentException - * If the instance object does not match the class of the field - * when obtaining a field value via reflection - * @throws IllegalAccessException - * If a field is not accessible due to access restrictions - */ - public Object getExecutor(Thread thread) - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - - Object result = null; - - // Runnable wrapped by Thread - // "target" in Sun/Oracle JDK - // "runnable" in IBM JDK - // "action" in Apache Harmony - Object target = null; - for (String fieldName : new String[] { "target", "runnable", "action" }) { - try { - Field targetField = thread.getClass().getDeclaredField(fieldName); - targetField.setAccessible(true); - target = targetField.get(thread); - break; - } catch (NoSuchFieldException nfe) { - continue; - } - } - - // "java.util.concurrent" code is in public domain, - // so all implementations are similar including our - // internal fork. - if (target != null && target.getClass().getCanonicalName() != null && - (target.getClass().getCanonicalName().equals( - "org.apache.tomcat.util.threads.ThreadPoolExecutor.Worker") || - target.getClass().getCanonicalName().equals( - "java.util.concurrent.ThreadPoolExecutor.Worker"))) { - Field executorField = target.getClass().getDeclaredField("this$0"); - executorField.setAccessible(true); - result = executorField.get(target); - } - - return result; - } } diff --git a/java/org/apache/tomcat/util/compat/LocalStrings.properties b/java/org/apache/tomcat/util/compat/LocalStrings.properties deleted file mode 100644 index a3d30954e7..0000000000 --- a/java/org/apache/tomcat/util/compat/LocalStrings.properties +++ /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. - -jre19Compat.javaPre19=Class not found so assuming code is running on a pre-Java 19 JVM diff --git a/java/org/apache/tomcat/util/compat/LocalStrings_fr.properties b/java/org/apache/tomcat/util/compat/LocalStrings_fr.properties deleted file mode 100644 index ee07dd61d3..0000000000 --- a/java/org/apache/tomcat/util/compat/LocalStrings_fr.properties +++ /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. - -jre19Compat.javaPre19=Classe non trouvée donc le code est exécutée sur une JVM antérieure à Java 19 diff --git a/java/org/apache/tomcat/util/compat/LocalStrings_ja.properties b/java/org/apache/tomcat/util/compat/LocalStrings_ja.properties deleted file mode 100644 index 2246b19e0e..0000000000 --- a/java/org/apache/tomcat/util/compat/LocalStrings_ja.properties +++ /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. - -jre19Compat.javaPre19=クラスが見つからないため、Java 19より前のJVMでコードが実行されていると仮定します diff --git a/java/org/apache/tomcat/util/compat/LocalStrings_ko.properties b/java/org/apache/tomcat/util/compat/LocalStrings_ko.properties deleted file mode 100644 index 42a25ed603..0000000000 --- a/java/org/apache/tomcat/util/compat/LocalStrings_ko.properties +++ /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. - -jre19Compat.javaPre19=클래스가 발견되지 않으므로, 코드가 자바 19 이전 버전의 JVM에서 실행 중이라고 가정합니다. diff --git a/java/org/apache/tomcat/util/compat/LocalStrings_zh_CN.properties b/java/org/apache/tomcat/util/compat/LocalStrings_zh_CN.properties deleted file mode 100644 index 571a2bffd2..0000000000 --- a/java/org/apache/tomcat/util/compat/LocalStrings_zh_CN.properties +++ /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. - -jre19Compat.javaPre19=该类未找到,因此推测当前代码运行在Java 19版本之前的虚拟机上 diff --git a/test/jakarta/servlet/http/HttpServletDoHeadBaseTest.java b/test/jakarta/servlet/http/HttpServletDoHeadBaseTest.java index d34cafa0db..8dea5e7f84 100644 --- a/test/jakarta/servlet/http/HttpServletDoHeadBaseTest.java +++ b/test/jakarta/servlet/http/HttpServletDoHeadBaseTest.java @@ -42,7 +42,6 @@ import org.apache.catalina.startup.Tomcat; import org.apache.coyote.http2.Http2TestBase; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.collections.CaseInsensitiveKeyMap; -import org.apache.tomcat.util.compat.JreCompat; /* * Split into multiple tests as a single test takes so long it impacts the time @@ -244,13 +243,12 @@ public class HttpServletDoHeadBaseTest extends Http2TestBase { boolean resetBufferSize = false; if (Boolean.parseBoolean(getServletConfig().getInitParameter(LEGACY_DO_HEAD)) && - JreCompat.isJre19Available() && "HEAD".equals(req.getMethod()) && useWriter && - resetType != ResetType.NONE) { + "HEAD".equals(req.getMethod()) && useWriter && resetType != ResetType.NONE) { /* - * Using legacy HEAD handling with a Writer on Java 19+. + * Using legacy HEAD handling with a Writer. + * * HttpServlet wraps the response. The test is sensitive to - * buffer sizes. The size of the buffer HttpServlet uses varies - * with Java version. For the tests to pass the number of + * buffer sizes. For the tests to pass the number of * characters that can be written before the response is * committed needs to be the same. * @@ -258,14 +256,8 @@ public class HttpServletDoHeadBaseTest extends Http2TestBase { * bytes. When a Writer is used, an additional 8192 byte buffer * is used for char->byte. * - * With Java <19, the char->byte buffer used by HttpServlet - * processing HEAD requests in legacy mode is created as a 8192 - * byte buffer which is consistent with the buffer Tomcat uses - * internally. - * - * With Java 19+, the char->byte buffer used by HttpServlet - * processing HEAD requests in legacy mode is created as a 512 - * byte buffer. + * The char->byte buffer used by HttpServlet processing HEAD + * requests in legacy mode is created as a 512 byte buffer. * * If the response isn't reset, none of this matters as it is * just the size of the response buffer and the size of the @@ -273,13 +265,12 @@ public class HttpServletDoHeadBaseTest extends Http2TestBase { * However, if the response is reset then things get interesting * as the amount of response data that can be written before * committing the response is the combination of the char->byte - * buffer and the response buffer. Because the char->byte buffer - * size in legacy mode varies with Java version, the size of the - * response buffer needs to be adjusted to compensate so that - * both GET and HEAD can write the same amount of data before - * committing the response. To make matters worse, to obtain the - * correct behaviour the response buffer size needs to be reset - * back to 8192 after the reset. + * buffer and the response buffer. The size of the response + * buffer needs to be adjusted so that both GET and HEAD can + * write the same amount of data before committing the response. + * To make matters worse, to obtain the correct behaviour the + * response buffer size needs to be reset back to 8192 after the + * reset. * * This is why the legacy mode is problematic and the new * approach of the container handling HEAD is better. @@ -290,9 +281,7 @@ public class HttpServletDoHeadBaseTest extends Http2TestBase { adjustedBufferSize = originalBufferSize; } - // Adjust for smaller initial char -> byte buffer in Java 19+ - // originalBufferSize initial size in Java <19 - // 512 initial size in Java 19+ + // Adjust for smaller initial char -> byte buffer adjustedBufferSize = adjustedBufferSize + originalBufferSize - 512; resetBufferSize = true; diff --git a/webapps/docs/config/context.xml b/webapps/docs/config/context.xml index e5aa73f86d..0f3798bfde 100644 --- a/webapps/docs/config/context.xml +++ b/webapps/docs/config/context.xml @@ -789,21 +789,6 @@ not specified, the default value of <code>true</code> will be used.</p> </attribute> - <attribute name="clearReferencesObjectStreamClassCaches" required="false"> - <p>If <code>true</code>, when the web application is stopped Tomcat - looks for <code>SoftReference</code>s to classes loaded by the web - application in the <code>ObjectStreamClass</code> class used for - serialization and clears any <code>SoftReference</code>s it finds. This - feature uses reflection to identify the <code>SoftReference</code>s and - therefore requires that the command line option - <code>-XaddExports:java.base/java.io=ALL-UNNAMED</code> is set. If not - specified, the default value of <code>true</code> will be used.</p> - <p>The memory leak associated with <code>ObjectStreamClass</code> has - been fixed in Java 19 onwards, Java 17.0.4 onwards and Java 11.0.16 - onwards. The check will be disabled when running on a version - of Java that contains the fix.</p> - </attribute> - <attribute name="clearReferencesRmiTargets" required="false"> <p>If <code>true</code>, Tomcat looks for memory leaks associated with RMI Targets and clears any it finds. This feature uses reflection to --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org