|
4 | 4 | package org.xerial.snappy;
|
5 | 5 |
|
6 | 6 | import java.io.IOException;
|
| 7 | +import java.lang.invoke.LambdaMetafactory; |
7 | 8 | import java.lang.invoke.MethodHandle;
|
8 | 9 | import java.lang.invoke.MethodHandles;
|
9 | 10 | import java.lang.invoke.MethodType;
|
@@ -37,21 +38,27 @@ final class SnappyFramed
|
37 | 38 | Supplier<Checksum> supplier = null;
|
38 | 39 | try
|
39 | 40 | {
|
40 |
| - final Class crc32cClazz = Class.forName("java.util.zip.CRC32C"); |
41 |
| - final MethodHandles.Lookup lookup = MethodHandles.publicLookup(); |
42 |
| - |
43 |
| - final MethodHandle conHandle = lookup.findConstructor(crc32cClazz, MethodType.methodType(void.class)) |
44 |
| - .asType(MethodType.methodType(Checksum.class)); |
45 |
| - supplier = () -> { |
46 |
| - try |
47 |
| - { |
48 |
| - return (Checksum) conHandle.invokeExact(); |
49 |
| - } |
50 |
| - catch (Throwable e) |
51 |
| - { |
52 |
| - throw new IllegalStateException(e); |
53 |
| - } |
54 |
| - }; |
| 41 | + final Class<?> crc32cClazz = Class.forName("java.util.zip.CRC32C"); |
| 42 | + // using LambdaMetafactory requires a caller sensitive lookup |
| 43 | + final MethodHandles.Lookup lookup = MethodHandles.lookup(); |
| 44 | + final MethodHandle conHandle = lookup.findConstructor(crc32cClazz, MethodType.methodType(void.class)); |
| 45 | + |
| 46 | + // use LambdaMetafactory to generate an implementation of Supplier<Checksum> which invokes |
| 47 | + // the java.util.zip.CRC32C default constructor |
| 48 | + supplier = (Supplier<Checksum>) LambdaMetafactory.metafactory(lookup, |
| 49 | + // method name on Supplier |
| 50 | + "get", |
| 51 | + // functional interface to be created by factory |
| 52 | + MethodType.methodType(Supplier.class), |
| 53 | + // type of the functional interface |
| 54 | + // uses a generic, so erasure to Object |
| 55 | + MethodType.methodType(Object.class), |
| 56 | + // the method handle to call |
| 57 | + conHandle, |
| 58 | + // type as used at call site |
| 59 | + MethodType.methodType(Checksum.class)) |
| 60 | + .getTarget() |
| 61 | + .invoke(); |
55 | 62 | }
|
56 | 63 | catch(Throwable t)
|
57 | 64 | {
|
|
0 commit comments