Do not use uninterruptible file channels in FileChannelUtil
To avoid illegal access errors from incremental compilation on JDK 16+. #KT-45689 Fixed #KT-47152 Fixed
This commit is contained in:
@@ -1,66 +1,13 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.util.io;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
final class FileChannelUtil {
|
||||
private static final Logger LOG = Logger.getInstance(FileChannelUtil.class);
|
||||
|
||||
private static final Class<?> sunNioChFileChannelImpl = setupFileChannelImpl();
|
||||
private static final MethodHandle setUnInterruptible = setupUnInterruptibleHandle();
|
||||
|
||||
private static Class<?> setupFileChannelImpl() {
|
||||
try {
|
||||
return Class.forName("sun.nio.ch.FileChannelImpl");
|
||||
public final class FileChannelUtil {
|
||||
@NotNull
|
||||
static FileChannel unInterruptible(@NotNull FileChannel channel) {
|
||||
return channel;
|
||||
}
|
||||
catch (ClassNotFoundException ignored) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static MethodHandle setupUnInterruptibleHandle() {
|
||||
MethodHandle setUnInterruptible = null;
|
||||
try {
|
||||
if (sunNioChFileChannelImpl != null) {
|
||||
// noinspection SpellCheckingInspection
|
||||
setUnInterruptible = MethodHandles
|
||||
.lookup()
|
||||
.findVirtual(sunNioChFileChannelImpl, "setUninterruptible", MethodType.methodType(void.class));
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
LOG.info("interruptible FileChannels will be used for indexes");
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
if (setUnInterruptible != null) {
|
||||
LOG.info("uninterruptible FileChannels will be used for indexes");
|
||||
}
|
||||
else {
|
||||
LOG.info("interruptible FileChannels will be used for indexes");
|
||||
}
|
||||
return setUnInterruptible;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static FileChannel unInterruptible(@NotNull FileChannel channel) {
|
||||
try {
|
||||
if (setUnInterruptible != null && sunNioChFileChannelImpl != null && sunNioChFileChannelImpl.isInstance(channel)) {
|
||||
setUnInterruptible.invoke(channel);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
ExceptionUtil.rethrow(e);
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user