You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by ki...@apache.org on 2022/09/09 16:08:07 UTC

[beam] branch master updated: Use a ClassLoadingStrategy that is compatible with Java 17+

This is an automated email from the ASF dual-hosted git repository.

kileysok pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git


The following commit(s) were added to refs/heads/master by this push:
     new 98f1f75459e Use a ClassLoadingStrategy that is compatible with Java 17+
     new ef0bb6d1cbf Merge pull request #23055 from cushon/b243697303
98f1f75459e is described below

commit 98f1f75459ee300baa5574042149a65063239705
Author: Liam Miller-Cushon <cu...@google.com>
AuthorDate: Tue Sep 6 15:16:17 2022 -0700

    Use a ClassLoadingStrategy that is compatible with Java 17+
    
    See "Supporting proxies on Java versions prior to 9 and past 10" in
    http://mydailyjava.blogspot.com/2018/04/jdk-11-and-proxies-in-world-past.html
---
 .../reflect/ByteBuddyDoFnInvokerFactory.java       | 29 +++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyDoFnInvokerFactory.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyDoFnInvokerFactory.java
index 7b453678f1d..8e84828fd42 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyDoFnInvokerFactory.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyDoFnInvokerFactory.java
@@ -35,6 +35,7 @@ import net.bytebuddy.description.type.TypeDescription;
 import net.bytebuddy.description.type.TypeDescription.ForLoadedType;
 import net.bytebuddy.description.type.TypeList;
 import net.bytebuddy.dynamic.DynamicType;
+import net.bytebuddy.dynamic.loading.ClassInjector;
 import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
 import net.bytebuddy.dynamic.scaffold.InstrumentedType;
 import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
@@ -519,13 +520,35 @@ class ByteBuddyDoFnInvokerFactory implements DoFnInvokerFactory {
     Class<? extends DoFnInvoker<?, ?>> res =
         (Class<? extends DoFnInvoker<?, ?>>)
             unloaded
-                .load(
-                    findClassLoader(fnClass.getClassLoader()),
-                    ClassLoadingStrategy.Default.INJECTION)
+                .load(findClassLoader(fnClass.getClassLoader()), getClassLoadingStrategy(fnClass))
                 .getLoaded();
     return res;
   }
 
+  private static ClassLoadingStrategy<ClassLoader> getClassLoadingStrategy(Class<?> targetClass) {
+    try {
+      ClassLoadingStrategy<ClassLoader> strategy;
+      if (ClassInjector.UsingLookup.isAvailable()) {
+        Class<?> methodHandles = Class.forName("java.lang.invoke.MethodHandles");
+        Object lookup = methodHandles.getMethod("lookup").invoke(null);
+        Method privateLookupIn =
+            methodHandles.getMethod(
+                "privateLookupIn",
+                Class.class,
+                Class.forName("java.lang.invoke.MethodHandles$Lookup"));
+        Object privateLookup = privateLookupIn.invoke(null, targetClass, lookup);
+        strategy = ClassLoadingStrategy.UsingLookup.of(privateLookup);
+      } else if (ClassInjector.UsingReflection.isAvailable()) {
+        strategy = ClassLoadingStrategy.Default.INJECTION;
+      } else {
+        throw new IllegalStateException("No code generation strategy available");
+      }
+      return strategy;
+    } catch (ReflectiveOperationException e) {
+      throw new LinkageError(e.getMessage(), e);
+    }
+  }
+
   private static Implementation getRestrictionCoderDelegation(
       TypeDescription doFnType, DoFnSignature signature) {
     if (signature.processElement().isSplittable()) {