This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push: new 6c4d98d17e Fix BZ 69559 - Avoid 24 warning when not relevant 6c4d98d17e is described below commit 6c4d98d17e986c030773bcc66b7fbfcad8bf5796 Author: Mark Thomas <ma...@apache.org> AuthorDate: Mon Feb 3 15:40:36 2025 +0000 Fix BZ 69559 - Avoid 24 warning when not relevant Ensure that the Java 24 warning regarding the of sun.misc.Unsafe::invokeCleaner is only reported by the JRE when the code will be used. https://bz.apache.org/bugzilla/show_bug.cgi?id=69559 --- .../apache/tomcat/util/buf/ByteBufferUtils.java | 78 +--------------------- ...BufferUtils.java => ByteBufferUtilsUnsafe.java} | 50 +++----------- webapps/docs/changelog.xml | 5 ++ 3 files changed, 17 insertions(+), 116 deletions(-) diff --git a/java/org/apache/tomcat/util/buf/ByteBufferUtils.java b/java/org/apache/tomcat/util/buf/ByteBufferUtils.java index e082fb36a4..3ad2b51864 100644 --- a/java/org/apache/tomcat/util/buf/ByteBufferUtils.java +++ b/java/org/apache/tomcat/util/buf/ByteBufferUtils.java @@ -16,66 +16,10 @@ */ package org.apache.tomcat.util.buf; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.ByteBuffer; -import org.apache.juli.logging.Log; -import org.apache.juli.logging.LogFactory; -import org.apache.tomcat.util.compat.JreCompat; -import org.apache.tomcat.util.res.StringManager; - public class ByteBufferUtils { - private static final StringManager sm = StringManager.getManager(ByteBufferUtils.class); - private static final Log log = LogFactory.getLog(ByteBufferUtils.class); - - private static final Object unsafe; - private static final Method cleanerMethod; - private static final Method cleanMethod; - private static final Method invokeCleanerMethod; - - static { - ByteBuffer tempBuffer = ByteBuffer.allocateDirect(0); - Method cleanerMethodLocal = null; - Method cleanMethodLocal = null; - Object unsafeLocal = null; - Method invokeCleanerMethodLocal = null; - if (JreCompat.isJre9Available()) { - try { - Class<?> clazz = Class.forName("sun.misc.Unsafe"); - Field theUnsafe = clazz.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - unsafeLocal = theUnsafe.get(null); - invokeCleanerMethodLocal = clazz.getMethod("invokeCleaner", ByteBuffer.class); - invokeCleanerMethodLocal.invoke(unsafeLocal, tempBuffer); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | - NoSuchMethodException | SecurityException | ClassNotFoundException | NoSuchFieldException e) { - log.warn(sm.getString("byteBufferUtils.cleaner"), e); - unsafeLocal = null; - invokeCleanerMethodLocal = null; - } - } else { - try { - cleanerMethodLocal = tempBuffer.getClass().getMethod("cleaner"); - cleanerMethodLocal.setAccessible(true); - Object cleanerObject = cleanerMethodLocal.invoke(tempBuffer); - cleanMethodLocal = cleanerObject.getClass().getMethod("clean"); - cleanMethodLocal.invoke(cleanerObject); - } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | - InvocationTargetException e) { - log.warn(sm.getString("byteBufferUtils.cleaner"), e); - cleanerMethodLocal = null; - cleanMethodLocal = null; - } - } - cleanerMethod = cleanerMethodLocal; - cleanMethod = cleanMethodLocal; - unsafe = unsafeLocal; - invokeCleanerMethod = invokeCleanerMethodLocal; - } - private ByteBufferUtils() { // Hide the default constructor since this is a utility class. } @@ -118,28 +62,10 @@ public class ByteBufferUtils { /** * Clean specified direct buffer. This will cause an unavoidable warning on Java 24 and newer. + * * @param buf the buffer to clean */ public static void cleanDirectBuffer(ByteBuffer buf) { - if (cleanMethod != null) { - try { - cleanMethod.invoke(cleanerMethod.invoke(buf)); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | - SecurityException e) { - if (log.isDebugEnabled()) { - log.debug(sm.getString("byteBufferUtils.cleaner"), e); - } - } - } else if (invokeCleanerMethod != null) { - try { - invokeCleanerMethod.invoke(unsafe, buf); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | - SecurityException e) { - if (log.isDebugEnabled()) { - log.debug(sm.getString("byteBufferUtils.cleaner"), e); - } - } - } + ByteBufferUtilsUnsafe.cleanDirectBuffer(buf); } - } diff --git a/java/org/apache/tomcat/util/buf/ByteBufferUtils.java b/java/org/apache/tomcat/util/buf/ByteBufferUtilsUnsafe.java similarity index 79% copy from java/org/apache/tomcat/util/buf/ByteBufferUtils.java copy to java/org/apache/tomcat/util/buf/ByteBufferUtilsUnsafe.java index e082fb36a4..67e77b0001 100644 --- a/java/org/apache/tomcat/util/buf/ByteBufferUtils.java +++ b/java/org/apache/tomcat/util/buf/ByteBufferUtilsUnsafe.java @@ -26,10 +26,14 @@ import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.compat.JreCompat; import org.apache.tomcat.util.res.StringManager; -public class ByteBufferUtils { +/* + * This functionality is in a separate class so it is only loaded if cleanDirectBuffer() is called. This is because the + * use of unsafe triggers an unavoidable warning with Java 24. + */ +class ByteBufferUtilsUnsafe { - private static final StringManager sm = StringManager.getManager(ByteBufferUtils.class); - private static final Log log = LogFactory.getLog(ByteBufferUtils.class); + private static final StringManager sm = StringManager.getManager(ByteBufferUtilsUnsafe.class); + private static final Log log = LogFactory.getLog(ByteBufferUtilsUnsafe.class); private static final Object unsafe; private static final Method cleanerMethod; @@ -76,51 +80,17 @@ public class ByteBufferUtils { invokeCleanerMethod = invokeCleanerMethodLocal; } - private ByteBufferUtils() { + private ByteBufferUtilsUnsafe() { // Hide the default constructor since this is a utility class. } - /** - * Expands buffer to the given size unless it is already as big or bigger. Buffers are assumed to be in 'write to' - * mode since there would be no need to expand a buffer while it was in 'read from' mode. - * - * @param in Buffer to expand - * @param newSize The size t which the buffer should be expanded - * - * @return The expanded buffer with any data from the input buffer copied in to it or the original buffer if there - * was no need for expansion - */ - public static ByteBuffer expand(ByteBuffer in, int newSize) { - if (in.capacity() >= newSize) { - return in; - } - - ByteBuffer out; - boolean direct = false; - if (in.isDirect()) { - out = ByteBuffer.allocateDirect(newSize); - direct = true; - } else { - out = ByteBuffer.allocate(newSize); - } - - // Copy data - in.flip(); - out.put(in); - - if (direct) { - cleanDirectBuffer(in); - } - - return out; - } - /** * Clean specified direct buffer. This will cause an unavoidable warning on Java 24 and newer. + * * @param buf the buffer to clean */ - public static void cleanDirectBuffer(ByteBuffer buf) { + static void cleanDirectBuffer(ByteBuffer buf) { if (cleanMethod != null) { try { cleanMethod.invoke(cleanerMethod.invoke(buf)); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 798fa5cf24..b3ddd8eb8c 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -227,6 +227,11 @@ Improve the performance of repeated calls to <code>getHeader()</code>. Pull request <pr>813</pr> provided by Adwait Kumar Singh. (markt) </fix> + <fix> + <bug>69559</bug>: Ensure that the Java 24 warning regarding the use of + <code> sun.misc.Unsafe::invokeCleaner</code> is only reported by the JRE + when the code will be used. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org