From a16b87565607a8d1ef4b737ce201aa0aa7b12b2d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 16 May 2017 15:54:10 +0300 Subject: [PATCH] avoid NoSuchMethodError under jdk9 --- .../codeInspection/ex/QuickFixAction.java | 2 +- .../com/intellij}/ReviseWhenPortedToJDK.java | 4 +-- .../intellij/util/io/DirectBufferWrapper.java | 32 ++++++++++++++++--- 3 files changed, 31 insertions(+), 7 deletions(-) rename platform/{lang-impl/src/com/intellij/internal => util/src/com/intellij}/ReviseWhenPortedToJDK.java (95%) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java index 3adfc6181f54..19608f346ea0 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java @@ -28,7 +28,7 @@ import com.intellij.codeInspection.ui.InspectionResultsView; import com.intellij.codeInspection.ui.InspectionTree; import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; -import com.intellij.internal.ReviseWhenPortedToJDK; +import com.intellij.ReviseWhenPortedToJDK; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.CustomComponentAction; import com.intellij.openapi.application.ApplicationManager; diff --git a/platform/lang-impl/src/com/intellij/internal/ReviseWhenPortedToJDK.java b/platform/util/src/com/intellij/ReviseWhenPortedToJDK.java similarity index 95% rename from platform/lang-impl/src/com/intellij/internal/ReviseWhenPortedToJDK.java rename to platform/util/src/com/intellij/ReviseWhenPortedToJDK.java index b411c87d5bfb..7ed160dd5cd1 100644 --- a/platform/lang-impl/src/com/intellij/internal/ReviseWhenPortedToJDK.java +++ b/platform/util/src/com/intellij/ReviseWhenPortedToJDK.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.internal; +package com.intellij; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -26,5 +26,5 @@ import java.lang.annotation.Target; @Target({ElementType.METHOD,ElementType.TYPE,ElementType.TYPE_USE,ElementType.ANNOTATION_TYPE,ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.PARAMETER,ElementType.LOCAL_VARIABLE,ElementType.PACKAGE,ElementType.TYPE_PARAMETER}) @Retention(RetentionPolicy.SOURCE) public @interface ReviseWhenPortedToJDK { - String value(); + String value(); // JDK major version } diff --git a/platform/util/src/com/intellij/util/io/DirectBufferWrapper.java b/platform/util/src/com/intellij/util/io/DirectBufferWrapper.java index f99218473015..6054e71fb1f5 100644 --- a/platform/util/src/com/intellij/util/io/DirectBufferWrapper.java +++ b/platform/util/src/com/intellij/util/io/DirectBufferWrapper.java @@ -15,13 +15,16 @@ */ package com.intellij.util.io; +import com.intellij.ReviseWhenPortedToJDK; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; import org.jetbrains.annotations.Nullable; import sun.misc.Cleaner; import sun.nio.ch.DirectBuffer; import java.io.File; import java.io.IOException; +import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.security.AccessController; import java.security.PrivilegedAction; @@ -58,15 +61,37 @@ public abstract class DirectBufferWrapper extends ByteBufferWrapper { myBuffer = null; } - static boolean disposeDirectBuffer(final ByteBuffer buffer) { + @ReviseWhenPortedToJDK("9") + static boolean disposeDirectBuffer(final ByteBuffer buffer) { return AccessController.doPrivileged(new PrivilegedAction() { @Override @Nullable public Object run() { try { if (buffer instanceof DirectBuffer) { - Cleaner cleaner = ((DirectBuffer)buffer).cleaner(); - if (cleaner != null) cleaner.clean(); // Already cleaned otherwise + if (SystemInfo.IS_AT_LEAST_JAVA9) { + // in JDK9 DirectBuffer.cleaner() returns jdk.internal.ref.Cleaner instead of sun.misc.Cleaner + // since we have to target both jdk 8 and 9 we have to use reflection + try { + Method cleanerMethod = buffer.getClass().getMethod("cleaner"); + cleanerMethod.setAccessible(true); + Object cleaner = cleanerMethod.invoke(buffer); + if (cleaner != null) { + Method cleanMethod = cleaner.getClass().getMethod("clean"); + cleanMethod.setAccessible(true); + cleanMethod.invoke(cleaner); + } + } + catch (Exception e) { + // something serious, needs to be logged + LOG.error(e); + throw e; + } + } + else { + Cleaner cleaner = ((DirectBuffer)buffer).cleaner(); + if (cleaner != null) cleaner.clean(); // Already cleaned otherwise + } } return null; } @@ -76,5 +101,4 @@ public abstract class DirectBufferWrapper extends ByteBufferWrapper { } }) == null; } - }