diff options
author | Ed Merks | 2021-12-14 08:43:54 +0000 |
---|---|---|
committer | Ed Merks | 2021-12-14 08:43:54 +0000 |
commit | 3287652aeb4ae5fcb72687e2806ac4a21cfa14ea (patch) | |
tree | c645524898b8859ba1e0ab7fc8bab21f96377401 /plugins/org.eclipse.oomph.util | |
parent | ab309666319bd4ce51e6668befb1b0319ce0cdaa (diff) | |
download | org.eclipse.oomph-3287652aeb4ae5fcb72687e2806ac4a21cfa14ea.tar.gz org.eclipse.oomph-3287652aeb4ae5fcb72687e2806ac4a21cfa14ea.tar.xz org.eclipse.oomph-3287652aeb4ae5fcb72687e2806ac4a21cfa14ea.zip |
[577783] org.eclipse.oomph.util.AccessUtil doesn't work for Java 17
https://bugs.eclipse.org/bugs/show_bug.cgi?id=577783
Diffstat (limited to 'plugins/org.eclipse.oomph.util')
-rw-r--r-- | plugins/org.eclipse.oomph.util/META-INF/MANIFEST.MF | 8 | ||||
-rw-r--r-- | plugins/org.eclipse.oomph.util/pom.xml | 2 | ||||
-rw-r--r-- | plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/AccessUtil.java | 43 |
3 files changed, 45 insertions, 8 deletions
diff --git a/plugins/org.eclipse.oomph.util/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.util/META-INF/MANIFEST.MF index 0206b1ad7..f45f4abf7 100644 --- a/plugins/org.eclipse.oomph.util/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.util/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.oomph.util;singleton:=true -Bundle-Version: 1.17.0.qualifier +Bundle-Version: 1.18.0.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -13,8 +13,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.apache.httpcomponents.httpclient;bundle-version="[4.0.0,5.0.0)", org.eclipse.emf.common;bundle-version="[2.10.0,3.0.0)";visibility:=reexport Import-Package: org.osgi.framework;version="[1.3.0,2.0.0)" -Export-Package: org.eclipse.oomph.internal.util;version="1.17.0";x-internal:=true, - org.eclipse.oomph.internal.util.table;version="1.17.0";x-internal:=true, - org.eclipse.oomph.util;version="1.17.0";x-internal:=true +Export-Package: org.eclipse.oomph.internal.util;version="1.18.0";x-internal:=true, + org.eclipse.oomph.internal.util.table;version="1.18.0";x-internal:=true, + org.eclipse.oomph.util;version="1.18.0";x-internal:=true Eclipse-BuddyPolicy: registered Automatic-Module-Name: org.eclipse.oomph.util diff --git a/plugins/org.eclipse.oomph.util/pom.xml b/plugins/org.eclipse.oomph.util/pom.xml index aeefad2d3..194f5842b 100644 --- a/plugins/org.eclipse.oomph.util/pom.xml +++ b/plugins/org.eclipse.oomph.util/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.util</artifactId> - <version>1.17.0-SNAPSHOT</version> + <version>1.18.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/AccessUtil.java b/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/AccessUtil.java index d2cf1fcf8..cffa28a4c 100644 --- a/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/AccessUtil.java +++ b/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/AccessUtil.java @@ -11,7 +11,10 @@ package org.eclipse.oomph.util; import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -2193,6 +2196,12 @@ final class AccessUtil private static final Method DEFINE_ANONYMOUS_CLASS_METHOD; + private static final Method DEFINE_HIDDEN_CLASS_METHOD; + + private static final MethodHandles.Lookup LOOKUP; + + private static final Object CLASS_OPTIONS; + private static final Method ALLOCATE_INSTANCE_METHOD; private static final Method CONSUMER_ACCEPT_METHOD; @@ -2201,6 +2210,9 @@ final class AccessUtil { Object unsafeInstance = null; Method defineAnonymousClassMethod = null; + Method defineHiddenClassMethod = null; + MethodHandles.Lookup lookup = null; + Object classOptions = null; Method allocateInstanceMethod = null; Method consumerAcceptMethod = null; @@ -2220,8 +2232,20 @@ final class AccessUtil // Get the singleton from the static field. unsafeInstance = theUnsafeField.get(null); - // We will use the Unsafe.defineAnonymousClass method to a create class that will be able to make an AccessibleObject accessible. - defineAnonymousClassMethod = unsafeClass.getMethod("defineAnonymousClass", Class.class, byte[].class, Object[].class); + try + { + // We will use the Unsafe.defineAnonymousClass method to a create class that will be able to make an AccessibleObject accessible. + defineAnonymousClassMethod = unsafeClass.getMethod("defineAnonymousClass", Class.class, byte[].class, Object[].class); + } + catch (NoSuchMethodException ex) + { + long offset = (Long)unsafeClass.getMethod("staticFieldOffset", Field.class).invoke(unsafeInstance, + MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP")); + lookup = (MethodHandles.Lookup)unsafeClass.getMethod("getObject", Object.class, long.class).invoke(unsafeInstance, MethodHandles.Lookup.class, offset); + Class<?> classOption = Class.forName("java.lang.invoke.MethodHandles$Lookup$ClassOption"); + classOptions = Array.newInstance(classOption, 0); + defineHiddenClassMethod = Lookup.class.getMethod("defineHiddenClass", byte[].class, boolean.class, classOptions.getClass()); + } allocateInstanceMethod = unsafeClass.getDeclaredMethod("allocateInstance", Class.class); @@ -2238,6 +2262,9 @@ final class AccessUtil UNSAFE_INSTANCE = unsafeInstance; DEFINE_ANONYMOUS_CLASS_METHOD = defineAnonymousClassMethod; + DEFINE_HIDDEN_CLASS_METHOD = defineHiddenClassMethod; + LOOKUP = lookup; + CLASS_OPTIONS = classOptions; ALLOCATE_INSTANCE_METHOD = allocateInstanceMethod; CONSUMER_ACCEPT_METHOD = consumerAcceptMethod; } @@ -2376,7 +2403,17 @@ final class AccessUtil // Define an anonymous class in the declaring class' package // using the computed class bytes. - Class<?> theAnonymousClass = (Class<?>)DEFINE_ANONYMOUS_CLASS_METHOD.invoke(UNSAFE_INSTANCE, declaringClass, bytes, null); + Class<?> theAnonymousClass; + if (DEFINE_ANONYMOUS_CLASS_METHOD != null) + { + theAnonymousClass = (Class<?>)DEFINE_ANONYMOUS_CLASS_METHOD.invoke(UNSAFE_INSTANCE, declaringClass, bytes, null); + } + else + { + MethodHandles.Lookup lookup = LOOKUP.in(declaringClass); + lookup = (Lookup)DEFINE_HIDDEN_CLASS_METHOD.invoke(lookup, bytes, Boolean.FALSE, CLASS_OPTIONS); + theAnonymousClass = lookup.lookupClass(); + } // Because the template bytes were computed class local to this // file, the class isn't public and we're not allowed by Java 9 |