From 8c69a5917668520005ca09bc471e7713a5e98078 Mon Sep 17 00:00:00 2001 From: Andrej Shadura Date: Fri, 1 Mar 2019 13:16:32 +0100 Subject: Port to Java 11 --- debian/patches/cleaner.patch | 271 +++++++++++++++++++++++++++++++++++++++++++ debian/patches/java11.patch | 20 ++++ debian/patches/series | 2 + 3 files changed, 293 insertions(+) create mode 100644 debian/patches/cleaner.patch create mode 100644 debian/patches/java11.patch create mode 100644 debian/patches/series diff --git a/debian/patches/cleaner.patch b/debian/patches/cleaner.patch new file mode 100644 index 0000000..a5f06c7 --- /dev/null +++ b/debian/patches/cleaner.patch @@ -0,0 +1,271 @@ +Bug-Debian: https://bugs.debian.org/893495 +Bug-Debian: https://bugs.debian.org/917727 +Forwarded: no +Last-Update: 2019-02-28 + +--- a/lang/src/main/java/net/openhft/lang/io/AbstractMappedStore.java ++++ b/lang/src/main/java/net/openhft/lang/io/AbstractMappedStore.java +@@ -28,7 +28,7 @@ + + import net.openhft.lang.io.serialization.ObjectSerializer; + import net.openhft.lang.model.constraints.NotNull; +-import sun.misc.Cleaner; ++import java.lang.ref.Cleaner; + import sun.nio.ch.FileChannelImpl; + + abstract class AbstractMappedStore implements BytesStore, Closeable { +@@ -39,7 +39,8 @@ + // retain to prevent GC. + private final File file; + private final RandomAccessFile raf; +- private final Cleaner cleaner; ++ private final static Cleaner cleaner = Cleaner.create(); ++ private Cleaner.Cleanable cleanable; + private final AtomicInteger refCount = new AtomicInteger(1); + private final FileChannel.MapMode mode; + protected final MmapInfoHolder mmapInfoHolder; +@@ -59,7 +60,7 @@ + this.raf = new RandomAccessFile(file, accesModeFor(mode)); + resizeIfNeeded(startInFile, size); + map(startInFile); +- this.cleaner = Cleaner.create(this, new Unmapper(mmapInfoHolder, raf)); ++ this.cleanable = cleaner.register(this, new Unmapper(mmapInfoHolder, raf)); + } catch (Exception e) { + throw wrap(e); + } +@@ -173,7 +174,7 @@ + + @Override + public final void free() { +- cleaner.clean(); ++ cleanable.clean(); + } + + @Override +--- a/lang/src/main/java/net/openhft/lang/io/ByteBufferReuse.java ++++ b/lang/src/main/java/net/openhft/lang/io/ByteBufferReuse.java +@@ -117,12 +117,15 @@ + + final byte[] impl = cw.toByteArray(); + +- final Unsafe unsafe = NativeBytes.UNSAFE; + Class clazz = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Class run() { + ClassLoader cl = MAGIC_CLASS_LOADER; +- return unsafe.defineClass(reuseImplClassName, impl, 0, impl.length, cl, null); ++ try { ++ return (Class) NativeBytes.defineClassMethodHandle.bindTo(cl).invokeWithArguments(reuseImplClassName, impl, 0, impl.length); ++ } catch (Throwable e) { ++ throw new RuntimeException(e); ++ } + } + }); + try { +--- a/lang/src/main/java/net/openhft/lang/io/CharBufferReuse.java ++++ b/lang/src/main/java/net/openhft/lang/io/CharBufferReuse.java +@@ -102,12 +102,15 @@ + + final byte[] impl = cw.toByteArray(); + +- final Unsafe unsafe = NativeBytes.UNSAFE; + Class clazz = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Class run() { + ClassLoader cl = MAGIC_CLASS_LOADER; +- return unsafe.defineClass(reuseImplClassName, impl, 0, impl.length, cl, null); ++ try { ++ return (Class) NativeBytes.defineClassMethodHandle.bindTo(cl).invokeWithArguments(reuseImplClassName, impl, 0, impl.length); ++ } catch (Throwable e) { ++ throw new RuntimeException(e); ++ } + } + }); + try { +--- a/lang/src/main/java/net/openhft/lang/io/DirectStore.java ++++ b/lang/src/main/java/net/openhft/lang/io/DirectStore.java +@@ -22,7 +22,7 @@ + import net.openhft.lang.io.serialization.ObjectSerializer; + import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory; + import net.openhft.lang.model.constraints.NotNull; +-import sun.misc.Cleaner; ++import java.lang.ref.Cleaner; + + import java.io.File; + import java.util.concurrent.atomic.AtomicInteger; +@@ -32,7 +32,8 @@ + */ + public class DirectStore implements BytesStore, AutoCloseable { + private final ObjectSerializer objectSerializer; +- private final Cleaner cleaner; ++ private final static Cleaner cleaner = Cleaner.create(); ++ private Cleaner.Cleanable cleanable; + private final Deallocator deallocator; + private long address; + private long size; +@@ -62,7 +63,7 @@ + + this.size = size; + deallocator = new Deallocator(address); +- cleaner = Cleaner.create(this, deallocator); ++ cleanable = cleaner.register(this, deallocator); + } + + @Override +@@ -123,7 +124,7 @@ + } + + public void free() { +- cleaner.clean(); ++ cleanable.clean(); + } + + public long size() { +--- a/lang/src/main/java/net/openhft/lang/io/IOTools.java ++++ b/lang/src/main/java/net/openhft/lang/io/IOTools.java +@@ -19,8 +19,8 @@ + import net.openhft.lang.model.constraints.NotNull; + import net.openhft.lang.model.constraints.Nullable; + import org.slf4j.LoggerFactory; +-import sun.misc.Cleaner; + import sun.nio.ch.DirectBuffer; ++import sun.misc.Unsafe; + + import java.io.Closeable; + import java.io.File; +@@ -28,6 +28,8 @@ + import java.nio.ByteBuffer; + import java.nio.charset.Charset; + ++import java.lang.reflect.Method; ++ + /** + * @author peter.lawrey + */ +@@ -35,6 +37,19 @@ + ; + public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); + public static final Charset UTF_8 = Charset.forName("UTF-8"); ++ private static final Unsafe unsafe = NativeBytes.UNSAFE; ++ private static final Method invokeCleaner; ++ ++ static { ++ Method tmpCleaner; ++ try { ++ tmpCleaner = unsafe.getClass().getDeclaredMethod("invokeCleaner", ByteBuffer.class); ++ tmpCleaner.setAccessible(true); ++ } catch (Throwable t) { ++ tmpCleaner = null; ++ } ++ invokeCleaner = tmpCleaner; ++ } + + public static void close(@Nullable Closeable closeable) { + if (closeable == null) return; +@@ -82,9 +97,13 @@ + + public static void clean(ByteBuffer bb) { + if (bb instanceof DirectBuffer) { +- Cleaner cl = ((DirectBuffer) bb).cleaner(); +- if (cl != null) +- cl.clean(); ++ if (invokeCleaner != null) { ++ try { ++ invokeCleaner.invoke(unsafe, bb); ++ } catch (Throwable e) { ++ ++ } ++ } + } + } + } +--- a/lang/src/main/java/net/openhft/lang/io/NativeBytes.java ++++ b/lang/src/main/java/net/openhft/lang/io/NativeBytes.java +@@ -21,6 +21,10 @@ + import org.jetbrains.annotations.NotNull; + import sun.misc.Unsafe; + ++import java.lang.invoke.MethodHandle; ++import java.lang.invoke.MethodHandles; ++import java.lang.invoke.MethodType; ++ + import java.io.EOFException; + import java.io.IOException; + import java.lang.reflect.Field; +@@ -41,6 +45,7 @@ + @NotNull + @SuppressWarnings("ALL") + public static final Unsafe UNSAFE; ++ public static final MethodHandle defineClassMethodHandle; + protected static final long NO_PAGE; + static final int BYTES_OFFSET; + static final int CHARS_OFFSET; +@@ -57,6 +62,14 @@ + throw new AssertionError(e); + } + NO_PAGE = UNSAFE.allocateMemory(UNSAFE.pageSize()); ++ try { ++ MethodHandles.Lookup baseLookup = MethodHandles.lookup(); ++ MethodType defineClassMethodType = MethodType.methodType(Class.class, new Class[]{String.class, byte[].class, int.class, int.class}); ++ MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(ClassLoader.class, baseLookup); ++ defineClassMethodHandle = lookup.findVirtual(ClassLoader.class, "defineClass", defineClassMethodType); ++ } catch (Throwable e) { ++ throw new RuntimeException(e); ++ } + } + + protected long startAddr; +--- a/lang/src/main/java/net/openhft/lang/io/VanillaMappedBytes.java ++++ b/lang/src/main/java/net/openhft/lang/io/VanillaMappedBytes.java +@@ -15,7 +15,6 @@ + */ + package net.openhft.lang.io; + +-import sun.misc.Cleaner; + import sun.nio.ch.DirectBuffer; + + import java.io.File; +@@ -23,6 +22,7 @@ + import java.nio.ByteBuffer; + import java.nio.MappedByteBuffer; + import java.nio.channels.FileChannel; ++import java.lang.reflect.Method; + + public class VanillaMappedBytes extends NativeBytes { + private final File path; +@@ -31,6 +31,18 @@ + private final FileLifecycleListener fileLifecycleListener; + private final long index; + private boolean unmapped; ++ private static final Method invokeCleaner; ++ ++ static { ++ Method tmpCleaner; ++ try { ++ tmpCleaner = UNSAFE.getClass().getDeclaredMethod("invokeCleaner", ByteBuffer.class); ++ tmpCleaner.setAccessible(true); ++ } catch (Throwable t) { ++ tmpCleaner = null; ++ } ++ invokeCleaner = tmpCleaner; ++ } + + public VanillaMappedBytes(final File path, final MappedByteBuffer buffer) { + this(path, buffer, -1, null, FileLifecycleListener.FileLifecycleListeners.IGNORE); +@@ -92,10 +104,13 @@ + @Override + protected synchronized void cleanup() { + if(!this.unmapped) { +- Cleaner cl = ((DirectBuffer)this.buffer).cleaner(); +- if (cl != null) { ++ if (invokeCleaner != null) { + long start = System.nanoTime(); +- cl.clean(); ++ try { ++ invokeCleaner.invoke(UNSAFE, this.buffer); ++ } catch (Throwable e) { ++ ++ } + + fileLifecycleListener.onEvent( + FileLifecycleListener.EventType.UNMAP, diff --git a/debian/patches/java11.patch b/debian/patches/java11.patch new file mode 100644 index 0000000..d20eb99 --- /dev/null +++ b/debian/patches/java11.patch @@ -0,0 +1,20 @@ +--- a/lang/pom.xml ++++ b/lang/pom.xml +@@ -149,9 +149,15 @@ + org.apache.maven.plugins + maven-compiler-plugin + +- 1.6 +- 1.6 ++ 1.9 ++ 1.9 ++ true + UTF-8 ++ ++ --add-exports=java.base/jdk.internal.ref=ALL-UNNAMED ++ --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED ++ --add-exports=java.base/sun.nio.ch=ALL-UNNAMED ++ + + + diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..a2dcc79 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,2 @@ +java11.patch +cleaner.patch -- cgit v1.2.3