You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2017/01/20 13:09:56 UTC
svn commit: r1779622 - in /tomcat/trunk:
java/org/apache/tomcat/util/buf/ByteBufferUtils.java
webapps/docs/changelog.xml
Author: remm
Date: Fri Jan 20 13:09:56 2017
New Revision: 1779622
URL: http://svn.apache.org/viewvc?rev=1779622&view=rev
Log:
Restore Java 9 direct byte buffer cleanup code, for now. The last way to access it is through the private Unsafe singleton, which will likely stop working at some point :(
Modified:
tomcat/trunk/java/org/apache/tomcat/util/buf/ByteBufferUtils.java
tomcat/trunk/webapps/docs/changelog.xml
Modified: tomcat/trunk/java/org/apache/tomcat/util/buf/ByteBufferUtils.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/buf/ByteBufferUtils.java?rev=1779622&r1=1779621&r2=1779622&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/buf/ByteBufferUtils.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/buf/ByteBufferUtils.java Fri Jan 20 13:09:56 2017
@@ -16,6 +16,7 @@
*/
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;
@@ -31,38 +32,57 @@ 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;
- try {
- cleanerMethodLocal = tempBuffer.getClass().getMethod("cleaner");
- cleanerMethodLocal.setAccessible(true);
- Object cleanerObject = cleanerMethodLocal.invoke(tempBuffer);
- if (cleanerObject instanceof Runnable) {
- cleanMethodLocal = Runnable.class.getMethod("run");
- } else {
- cleanMethodLocal = cleanerObject.getClass().getMethod("clean");
+ 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;
}
- cleanMethodLocal.invoke(cleanerObject);
- } catch (Throwable t) {
- JreCompat jreCompat = JreCompat.getInstance();
- if (jreCompat.isInstanceOfInaccessibleObjectException(t)) {
- // Must be running on Java 9 without the necessary command line
- // options.
- log.warn(sm.getString("byteBufferUtils.addExportsCleaner"));
- } else {
- ExceptionUtils.handleThrowable(t);
+ } else {
+ try {
+ cleanerMethodLocal = tempBuffer.getClass().getMethod("cleaner");
+ cleanerMethodLocal.setAccessible(true);
+ Object cleanerObject = cleanerMethodLocal.invoke(tempBuffer);
+ cleanMethodLocal = cleanerObject.getClass().getMethod("clean");
+ cleanMethodLocal.invoke(cleanerObject);
+ } catch (Throwable t) {
+ JreCompat jreCompat = JreCompat.getInstance();
+ if (jreCompat.isInstanceOfInaccessibleObjectException(t)) {
+ // Must be running on Java 9 without the necessary command line
+ // options.
+ log.warn(sm.getString("byteBufferUtils.addExportsCleaner"));
+ } else {
+ ExceptionUtils.handleThrowable(t);
+ }
+ log.warn(sm.getString("byteBufferUtils.cleaner"), t);
+ cleanerMethodLocal = null;
+ cleanMethodLocal = null;
}
- log.warn(sm.getString("byteBufferUtils.cleaner"), t);
- cleanerMethodLocal = null;
- cleanMethodLocal = null;
}
cleanerMethod = cleanerMethodLocal;
cleanMethod = cleanMethodLocal;
+ unsafe = unsafeLocal;
+ invokeCleanerMethod = invokeCleanerMethodLocal;
}
private ByteBufferUtils() {
@@ -114,6 +134,14 @@ public class ByteBufferUtils {
| InvocationTargetException | SecurityException e) {
// Ignore
}
+ } else if (invokeCleanerMethod != null) {
+ try {
+ invokeCleanerMethod.invoke(unsafe, buf);
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException | SecurityException e) {
+ // Ignore
+ e.printStackTrace();
+ }
}
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1779622&r1=1779621&r2=1779622&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Fri Jan 20 13:09:56 2017
@@ -60,6 +60,9 @@
connectors when using the JSSE implementation for TLS when running on
Java 9. (markt)
</add>
+ <fix>
+ Restore Java 9 direct byte buffer compatibility. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Cluster">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org