From 6164fc85010c90ea8747acda63c52d7397d23fcf Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 13 Sep 2022 08:51:37 -0700 Subject: [PATCH 01/12] Replace more uses of `ClassLoadingStrategy.Default.INJECTION` in preparation for Java 17+. Follow-up to: https://github.com/apache/beam/commit/98f1f75459ee300baa5574042149a65063239705. --- .../beam/sdk/coders/RowCoderGenerator.java | 28 ++++++++++++++- .../sdk/schemas/utils/AvroByteBuddyUtils.java | 5 +-- .../sdk/schemas/utils/ByteBuddyUtils.java | 27 ++++++++++++++- .../beam/sdk/schemas/utils/JavaBeanUtils.java | 11 +++--- .../beam/sdk/schemas/utils/POJOUtils.java | 10 +++--- .../schemas/utils/SelectByteBuddyHelpers.java | 4 +-- .../ByteBuddyOnTimerInvokerFactory.java | 34 +++++++++++++++---- 7 files changed, 98 insertions(+), 21 deletions(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java index 5ce7358d8824..b79401722129 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.BitSet; @@ -36,6 +37,7 @@ import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription.ForLoadedType; 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.implementation.FixedValue; @@ -172,7 +174,7 @@ public static Coder generate(Schema schema) { rowCoder = builder .make() - .load(Coder.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION) + .load(Coder.class.getClassLoader(), getClassLoadingStrategy(Coder.class)) .getLoaded() .getDeclaredConstructor(Coder[].class, int[].class) .newInstance((Object) componentCoders, (Object) encodingPosToRowIndex); @@ -187,6 +189,30 @@ public static Coder generate(Schema schema) { return rowCoder; } + private static ClassLoadingStrategy getClassLoadingStrategy(Class targetClass) { + try { + ClassLoadingStrategy 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 class GeneratedCoderConstructor implements Implementation { @Override public InstrumentedType prepare(InstrumentedType instrumentedType) { diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/AvroByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/AvroByteBuddyUtils.java index eb01b83c94fc..218d08967105 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/AvroByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/AvroByteBuddyUtils.java @@ -17,6 +17,8 @@ */ package org.apache.beam.sdk.schemas.utils; +import static org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.getClassLoadingStrategy; + import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; @@ -25,7 +27,6 @@ import net.bytebuddy.asm.AsmVisitorWrapper; import net.bytebuddy.description.type.TypeDescription.ForLoadedType; import net.bytebuddy.dynamic.DynamicType; -import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.implementation.MethodCall; import net.bytebuddy.implementation.bytecode.StackManipulation; import net.bytebuddy.implementation.bytecode.assign.TypeCasting; @@ -99,7 +100,7 @@ private static SchemaUserTypeCreator createCreator(Class clazz, Schema sc .make() .load( ReflectHelpers.findClassLoader(clazz.getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy(clazz)) .getLoaded() .getDeclaredConstructor() .newInstance(); diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java index bb0003c4d4dc..cef29a0df0ad 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java @@ -43,6 +43,7 @@ import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription.ForLoadedType; 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.implementation.Implementation; @@ -459,7 +460,7 @@ public InstrumentedType prepare(InstrumentedType instrumentedType) { .make() .load( ReflectHelpers.findClassLoader(((Class) fromType).getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy((Class) fromType)) .getLoaded(); } @@ -1503,4 +1504,28 @@ protected StackManipulation afterPushingParameters() { return new StackManipulation.Compound(); } } + + static ClassLoadingStrategy getClassLoadingStrategy(Class targetClass) { + try { + ClassLoadingStrategy 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); + } + } } diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/JavaBeanUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/JavaBeanUtils.java index ec0dba2c9421..ddefbac86ebe 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/JavaBeanUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/JavaBeanUtils.java @@ -17,6 +17,8 @@ */ package org.apache.beam.sdk.schemas.utils; +import static org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.getClassLoadingStrategy; + import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -28,7 +30,6 @@ import net.bytebuddy.asm.AsmVisitorWrapper; import net.bytebuddy.description.method.MethodDescription.ForLoadedMethod; import net.bytebuddy.dynamic.DynamicType; -import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.dynamic.scaffold.InstrumentedType; import net.bytebuddy.implementation.FixedValue; import net.bytebuddy.implementation.Implementation; @@ -162,7 +163,7 @@ public static FieldValueGetter createGetter( .load( ReflectHelpers.findClassLoader( typeInformation.getMethod().getDeclaringClass().getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy(typeInformation.getMethod().getDeclaringClass())) .getLoaded() .getDeclaredConstructor() .newInstance(); @@ -226,7 +227,7 @@ public static FieldValueSetter createSetter( .load( ReflectHelpers.findClassLoader( typeInformation.getMethod().getDeclaringClass().getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy(typeInformation.getMethod().getDeclaringClass())) .getLoaded() .getDeclaredConstructor() .newInstance(); @@ -290,7 +291,7 @@ public static SchemaUserTypeCreator createConstructorCreator( .make() .load( ReflectHelpers.findClassLoader(clazz.getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy(clazz)) .getLoaded() .getDeclaredConstructor() .newInstance(); @@ -338,7 +339,7 @@ public static SchemaUserTypeCreator createStaticCreator( .make() .load( ReflectHelpers.findClassLoader(clazz.getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy(clazz)) .getLoaded() .getDeclaredConstructor() .newInstance(); diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java index 46970c6bc4f6..10b9fb3c8488 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java @@ -17,6 +17,8 @@ */ package org.apache.beam.sdk.schemas.utils; +import static org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.getClassLoadingStrategy; + import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -156,7 +158,7 @@ private static SchemaUserTypeCreator createSetFieldCreator( .make() .load( ReflectHelpers.findClassLoader(clazz.getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy(clazz)) .getLoaded() .getDeclaredConstructor() .newInstance(); @@ -208,7 +210,7 @@ public static SchemaUserTypeCreator createConstructorCreator( .make() .load( ReflectHelpers.findClassLoader(clazz.getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy(clazz)) .getLoaded() .getDeclaredConstructor() .newInstance(); @@ -299,7 +301,7 @@ public static SchemaUserTypeCreator createStaticCreator( .make() .load( ReflectHelpers.findClassLoader(field.getDeclaringClass().getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy(field.getDeclaringClass())) .getLoaded() .getDeclaredConstructor() .newInstance(); @@ -379,7 +381,7 @@ private static FieldValueSetter createSetter( .make() .load( ReflectHelpers.findClassLoader(field.getDeclaringClass().getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + getClassLoadingStrategy(field.getDeclaringClass())) .getLoaded() .getDeclaredConstructor() .newInstance(); diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java index fd3b3735ee5c..031e79be98f1 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java @@ -17,6 +17,7 @@ */ package org.apache.beam.sdk.schemas.utils; +import static org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.getClassLoadingStrategy; import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; @@ -36,7 +37,6 @@ import net.bytebuddy.description.type.TypeDescription.ForLoadedType; import net.bytebuddy.description.type.TypeDescription.Generic; import net.bytebuddy.dynamic.DynamicType; -import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.dynamic.scaffold.InstrumentedType; import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.Implementation.Context; @@ -177,7 +177,7 @@ static RowSelector createRowSelector(SchemaAndDescriptor schemaAndDescriptor) { return builder .visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES)) .make() - .load(Row.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION) + .load(Row.class.getClassLoader(), getClassLoadingStrategy(Row.class)) .getLoaded() .getDeclaredConstructor(Schema.class) .newInstance(outputSchema); diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java index 49affe696e46..2105626ad6e5 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java @@ -21,12 +21,14 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.concurrent.ExecutionException; import net.bytebuddy.ByteBuddy; import net.bytebuddy.description.modifier.FieldManifestation; import net.bytebuddy.description.modifier.Visibility; import net.bytebuddy.description.type.TypeDescription; 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; @@ -225,9 +227,7 @@ public Constructor load(final OnTimerMethodSpecifier onTimerMethodSpecifier) Class> res = (Class>) unloaded - .load( - findClassLoader(fnClass.getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + .load(findClassLoader(fnClass.getClassLoader()), getClassLoadingStrategy(fnClass)) .getLoaded(); return res; } @@ -277,13 +277,35 @@ public Constructor load(final OnTimerMethodSpecifier onTimerMethodSpecifier) Class> res = (Class>) unloaded - .load( - findClassLoader(fnClass.getClassLoader()), - ClassLoadingStrategy.Default.INJECTION) + .load(findClassLoader(fnClass.getClassLoader()), getClassLoadingStrategy(fnClass)) .getLoaded(); return res; } + private static ClassLoadingStrategy getClassLoadingStrategy(Class targetClass) { + try { + ClassLoadingStrategy 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); + } + } + /** * An "invokeOnTimer" method implementation akin to @ProcessElement, but simpler because no * splitting-related parameters need to be handled. From 40bc89320a5aac904b1d919723e00d2ec9bb9e73 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 6 Feb 2023 12:03:52 -0800 Subject: [PATCH 02/12] Move helper method to a shared ByteBuddyUtils class --- .../beam/sdk/coders/RowCoderGenerator.java | 25 +-------- .../sdk/schemas/utils/AvroByteBuddyUtils.java | 2 +- .../sdk/schemas/utils/ByteBuddyUtils.java | 25 +-------- .../beam/sdk/schemas/utils/JavaBeanUtils.java | 2 +- .../beam/sdk/schemas/utils/POJOUtils.java | 2 +- .../schemas/utils/SelectByteBuddyHelpers.java | 2 +- .../ByteBuddyOnTimerInvokerFactory.java | 24 +------- .../apache/beam/sdk/util/ByteBuddyUtils.java | 55 +++++++++++++++++++ 8 files changed, 62 insertions(+), 75 deletions(-) create mode 100644 sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java index b79401722129..4781047571b5 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java @@ -18,6 +18,7 @@ package org.apache.beam.sdk.coders; import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions.checkState; +import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; import java.io.IOException; import java.io.InputStream; @@ -189,30 +190,6 @@ public static Coder generate(Schema schema) { return rowCoder; } - private static ClassLoadingStrategy getClassLoadingStrategy(Class targetClass) { - try { - ClassLoadingStrategy 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 class GeneratedCoderConstructor implements Implementation { @Override public InstrumentedType prepare(InstrumentedType instrumentedType) { diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/AvroByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/AvroByteBuddyUtils.java index 218d08967105..4c9055ba245c 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/AvroByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/AvroByteBuddyUtils.java @@ -17,7 +17,7 @@ */ package org.apache.beam.sdk.schemas.utils; -import static org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.getClassLoadingStrategy; +import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java index cef29a0df0ad..52785351fb4b 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java @@ -18,6 +18,7 @@ package org.apache.beam.sdk.schemas.utils; import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions.checkNotNull; +import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -1504,28 +1505,4 @@ protected StackManipulation afterPushingParameters() { return new StackManipulation.Compound(); } } - - static ClassLoadingStrategy getClassLoadingStrategy(Class targetClass) { - try { - ClassLoadingStrategy 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); - } - } } diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/JavaBeanUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/JavaBeanUtils.java index ddefbac86ebe..49d30f0e3454 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/JavaBeanUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/JavaBeanUtils.java @@ -17,7 +17,7 @@ */ package org.apache.beam.sdk.schemas.utils; -import static org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.getClassLoadingStrategy; +import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java index 10b9fb3c8488..47e2b4eec5f1 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java @@ -17,7 +17,7 @@ */ package org.apache.beam.sdk.schemas.utils; -import static org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.getClassLoadingStrategy; +import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; import java.lang.reflect.Constructor; import java.lang.reflect.Field; diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java index 031e79be98f1..e5c69a4c18eb 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java @@ -17,7 +17,7 @@ */ package org.apache.beam.sdk.schemas.utils; -import static org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.getClassLoadingStrategy; +import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions.checkNotNull; import com.google.auto.value.AutoValue; diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java index 2105626ad6e5..c61ef1d110ac 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java @@ -18,6 +18,7 @@ package org.apache.beam.sdk.transforms.reflect; import static org.apache.beam.sdk.util.common.ReflectHelpers.findClassLoader; +import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -282,29 +283,6 @@ public Constructor load(final OnTimerMethodSpecifier onTimerMethodSpecifier) return res; } - private static ClassLoadingStrategy getClassLoadingStrategy(Class targetClass) { - try { - ClassLoadingStrategy 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); - } - } /** * An "invokeOnTimer" method implementation akin to @ProcessElement, but simpler because no diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java new file mode 100644 index 000000000000..1877c08320a2 --- /dev/null +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.beam.sdk.util; + +import java.lang.reflect.Method; +import net.bytebuddy.dynamic.loading.ClassInjector; +import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; + +/** Utilities for working with Byte Buddy. */ +@SuppressWarnings({ + "nullness", // TODO(https://github.com/apache/beam/issues/20497) +}) +public final class ByteBuddyUtils { + private ByteBuddyUtils() {} // Non-instantiable + + /** Returns a class loading strategy that is compatible with Java 17+. */ + public static ClassLoadingStrategy getClassLoadingStrategy(Class targetClass) { + try { + ClassLoadingStrategy 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); + } + } +} From 37bc0fc1cfdadefc3d5df2b5b8665f49f89e3b28 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 7 Feb 2023 15:11:09 -0800 Subject: [PATCH 03/12] spotlessApply --- .../java/org/apache/beam/sdk/coders/RowCoderGenerator.java | 5 +---- .../org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java | 4 +--- .../transforms/reflect/ByteBuddyOnTimerInvokerFactory.java | 6 +----- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java index 4781047571b5..e2e3f7e1084f 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java @@ -17,14 +17,13 @@ */ package org.apache.beam.sdk.coders; -import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions.checkState; import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; +import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions.checkState; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.BitSet; @@ -38,8 +37,6 @@ import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription.ForLoadedType; 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.implementation.FixedValue; import net.bytebuddy.implementation.Implementation; diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java index 52785351fb4b..65eaffb9318f 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/ByteBuddyUtils.java @@ -17,8 +17,8 @@ */ package org.apache.beam.sdk.schemas.utils; -import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions.checkNotNull; import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; +import static org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions.checkNotNull; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -44,8 +44,6 @@ import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription.ForLoadedType; 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.implementation.Implementation; import net.bytebuddy.implementation.Implementation.Context; diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java index c61ef1d110ac..09e6212fa661 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/ByteBuddyOnTimerInvokerFactory.java @@ -17,20 +17,17 @@ */ package org.apache.beam.sdk.transforms.reflect; -import static org.apache.beam.sdk.util.common.ReflectHelpers.findClassLoader; import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy; +import static org.apache.beam.sdk.util.common.ReflectHelpers.findClassLoader; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.concurrent.ExecutionException; import net.bytebuddy.ByteBuddy; import net.bytebuddy.description.modifier.FieldManifestation; import net.bytebuddy.description.modifier.Visibility; import net.bytebuddy.description.type.TypeDescription; 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; import net.bytebuddy.implementation.Implementation; @@ -283,7 +280,6 @@ public Constructor load(final OnTimerMethodSpecifier onTimerMethodSpecifier) return res; } - /** * An "invokeOnTimer" method implementation akin to @ProcessElement, but simpler because no * splitting-related parameters need to be handled. From 95c749c583f936e24f0a1bae5d0417a9bfecbd6c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 9 Feb 2023 17:54:54 -0800 Subject: [PATCH 04/12] Apply suggestions from code review Co-authored-by: Lukasz Cwik --- .../main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java | 2 +- .../apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java index e2e3f7e1084f..f12a92871485 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java @@ -172,7 +172,7 @@ public static Coder generate(Schema schema) { rowCoder = builder .make() - .load(Coder.class.getClassLoader(), getClassLoadingStrategy(Coder.class)) + .load(ReflectHelpers.findClassLoader(schema.getClass().getClassLoader()), getClassLoadingStrategy(schema.getClass())) .getLoaded() .getDeclaredConstructor(Coder[].class, int[].class) .newInstance((Object) componentCoders, (Object) encodingPosToRowIndex); diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java index e5c69a4c18eb..c819431522d6 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java @@ -177,7 +177,7 @@ static RowSelector createRowSelector(SchemaAndDescriptor schemaAndDescriptor) { return builder .visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES)) .make() - .load(Row.class.getClassLoader(), getClassLoadingStrategy(Row.class)) + .load(ReflectHelpers.findClassLoader(schemaAndDescriptor.getClass().getClassLoader()), getClassLoadingStrategy(schemaAndDescriptor.getClass())) .getLoaded() .getDeclaredConstructor(Schema.class) .newInstance(outputSchema); From 267440f66d7a0f2229695ebb1992acb55829f101 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 9 Feb 2023 18:39:05 -0800 Subject: [PATCH 05/12] Fix nullness issues, add an overload that takes a custom classloader --- .../apache/beam/sdk/util/ByteBuddyUtils.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java index 1877c08320a2..233c996e28b2 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java @@ -17,31 +17,38 @@ */ package org.apache.beam.sdk.util; +import static java.util.Objects.requireNonNull; + import java.lang.reflect.Method; import net.bytebuddy.dynamic.loading.ClassInjector; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; +import org.checkerframework.checker.nullness.qual.Nullable; /** Utilities for working with Byte Buddy. */ -@SuppressWarnings({ - "nullness", // TODO(https://github.com/apache/beam/issues/20497) -}) public final class ByteBuddyUtils { private ByteBuddyUtils() {} // Non-instantiable /** Returns a class loading strategy that is compatible with Java 17+. */ public static ClassLoadingStrategy getClassLoadingStrategy(Class targetClass) { + return getClassLoadingStrategy(targetClass, ByteBuddyUtils.class.getClassLoader()); + } + + /** Returns a class loading strategy that is compatible with Java 17+. */ + public static ClassLoadingStrategy getClassLoadingStrategy( + Class targetClass, @Nullable ClassLoader classLoader) { try { ClassLoadingStrategy strategy; if (ClassInjector.UsingLookup.isAvailable()) { - Class methodHandles = Class.forName("java.lang.invoke.MethodHandles"); + Class methodHandles = Class.forName("java.lang.invoke.MethodHandles", true, classLoader); + @SuppressWarnings("nullness") // MethodHandles#lookup accepts null Object lookup = methodHandles.getMethod("lookup").invoke(null); + Class lookupClass = + Class.forName("java.lang.invoke.MethodHandles$Lookup", true, classLoader); 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); + methodHandles.getMethod("privateLookupIn", Class.class, lookupClass); + @SuppressWarnings("nullness") // this is a static method, the receiver can be null + Object privateLookup = requireNonNull(privateLookupIn.invoke(null, targetClass, lookup)); + strategy = ClassLoadingStrategy.UsingLookup.of(requireNonNull(privateLookup)); } else if (ClassInjector.UsingReflection.isAvailable()) { strategy = ClassLoadingStrategy.Default.INJECTION; } else { From f5ae913ef86c4d3c4de1fe5da7c3b78654a2c977 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 9 Feb 2023 18:39:54 -0800 Subject: [PATCH 06/12] spotless apply --- .../java/org/apache/beam/sdk/coders/RowCoderGenerator.java | 4 +++- .../apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java index f12a92871485..7fe05acb4588 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java @@ -172,7 +172,9 @@ public static Coder generate(Schema schema) { rowCoder = builder .make() - .load(ReflectHelpers.findClassLoader(schema.getClass().getClassLoader()), getClassLoadingStrategy(schema.getClass())) + .load( + ReflectHelpers.findClassLoader(schema.getClass().getClassLoader()), + getClassLoadingStrategy(schema.getClass())) .getLoaded() .getDeclaredConstructor(Coder[].class, int[].class) .newInstance((Object) componentCoders, (Object) encodingPosToRowIndex); diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java index c819431522d6..c5d180ce104b 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java @@ -177,7 +177,9 @@ static RowSelector createRowSelector(SchemaAndDescriptor schemaAndDescriptor) { return builder .visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES)) .make() - .load(ReflectHelpers.findClassLoader(schemaAndDescriptor.getClass().getClassLoader()), getClassLoadingStrategy(schemaAndDescriptor.getClass())) + .load( + ReflectHelpers.findClassLoader(schemaAndDescriptor.getClass().getClassLoader()), + getClassLoadingStrategy(schemaAndDescriptor.getClass())) .getLoaded() .getDeclaredConstructor(Schema.class) .newInstance(outputSchema); From e376095c3190e6fcf385ea3845f10cd29d404d33 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 10 Feb 2023 10:07:21 -0800 Subject: [PATCH 07/12] Fix imports --- .../main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java | 1 + .../apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java | 1 + 2 files changed, 2 insertions(+) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java index 7fe05acb4588..5a37a22e22dc 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/RowCoderGenerator.java @@ -55,6 +55,7 @@ import org.apache.beam.sdk.schemas.Schema.Field; import org.apache.beam.sdk.schemas.Schema.FieldType; import org.apache.beam.sdk.schemas.SchemaCoder; +import org.apache.beam.sdk.util.common.ReflectHelpers; import org.apache.beam.sdk.values.Row; import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions; import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.Maps; diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java index c5d180ce104b..ec3db9b3cce4 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/SelectByteBuddyHelpers.java @@ -66,6 +66,7 @@ import org.apache.beam.sdk.schemas.Schema.FieldType; import org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.IfNullElse; import org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.ShortCircuitReturnNull; +import org.apache.beam.sdk.util.common.ReflectHelpers; import org.apache.beam.sdk.values.Row; import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.base.Preconditions; import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.Lists; From 44532904d157df14959daff4d3ec15ba83d167cf Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 10 Feb 2023 11:54:53 -0800 Subject: [PATCH 08/12] Update sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java Co-authored-by: Lukasz Cwik --- .../main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java index 233c996e28b2..ae4d04008cc5 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java @@ -30,15 +30,10 @@ private ByteBuddyUtils() {} // Non-instantiable /** Returns a class loading strategy that is compatible with Java 17+. */ public static ClassLoadingStrategy getClassLoadingStrategy(Class targetClass) { - return getClassLoadingStrategy(targetClass, ByteBuddyUtils.class.getClassLoader()); - } - - /** Returns a class loading strategy that is compatible with Java 17+. */ - public static ClassLoadingStrategy getClassLoadingStrategy( - Class targetClass, @Nullable ClassLoader classLoader) { try { ClassLoadingStrategy strategy; if (ClassInjector.UsingLookup.isAvailable()) { + ClassLoader classLoader = ReflectHelpers.getClassLoader(targetClass.getClassLoader()); Class methodHandles = Class.forName("java.lang.invoke.MethodHandles", true, classLoader); @SuppressWarnings("nullness") // MethodHandles#lookup accepts null Object lookup = methodHandles.getMethod("lookup").invoke(null); From 9943d723158ff3ffed0c184bd04162109ee4f442 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 10 Feb 2023 11:55:25 -0800 Subject: [PATCH 09/12] Use ISE instead of LinkageError --- .../src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java index ae4d04008cc5..ef6ffa3fa123 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java @@ -51,7 +51,7 @@ public static ClassLoadingStrategy getClassLoadingStrategy(Class } return strategy; } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); + throw new IllegalStateException("No code generation strategy available", e); } } } From e666a9804731b08860aa260ba195a3dc47e27ddc Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 13 Feb 2023 14:38:46 -0800 Subject: [PATCH 10/12] Add a missing import --- .../src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java index ef6ffa3fa123..f821da913f14 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java @@ -20,6 +20,7 @@ import static java.util.Objects.requireNonNull; import java.lang.reflect.Method; +import org.apache.beam.sdk.util.common.ReflectHelpers; import net.bytebuddy.dynamic.loading.ClassInjector; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import org.checkerframework.checker.nullness.qual.Nullable; From fbd11b674ffca0f8e9346c14f56dc178d403a5f6 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 13 Feb 2023 14:43:07 -0800 Subject: [PATCH 11/12] s/getClassLoader/findClassLoader --- .../main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java index f821da913f14..c03f0f70d62b 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java @@ -20,10 +20,9 @@ import static java.util.Objects.requireNonNull; import java.lang.reflect.Method; -import org.apache.beam.sdk.util.common.ReflectHelpers; import net.bytebuddy.dynamic.loading.ClassInjector; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.apache.beam.sdk.util.common.ReflectHelpers; /** Utilities for working with Byte Buddy. */ public final class ByteBuddyUtils { @@ -34,7 +33,7 @@ public static ClassLoadingStrategy getClassLoadingStrategy(Class try { ClassLoadingStrategy strategy; if (ClassInjector.UsingLookup.isAvailable()) { - ClassLoader classLoader = ReflectHelpers.getClassLoader(targetClass.getClassLoader()); + ClassLoader classLoader = ReflectHelpers.findClassLoader(targetClass.getClassLoader()); Class methodHandles = Class.forName("java.lang.invoke.MethodHandles", true, classLoader); @SuppressWarnings("nullness") // MethodHandles#lookup accepts null Object lookup = methodHandles.getMethod("lookup").invoke(null); From d4b5dabf96ccefbf3888a3b5d038fd4aacbce6f6 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 13 Feb 2023 14:45:38 -0800 Subject: [PATCH 12/12] fix Checker Framework error --- .../src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java index c03f0f70d62b..3a7dd889d958 100644 --- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java +++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/ByteBuddyUtils.java @@ -33,7 +33,7 @@ public static ClassLoadingStrategy getClassLoadingStrategy(Class try { ClassLoadingStrategy strategy; if (ClassInjector.UsingLookup.isAvailable()) { - ClassLoader classLoader = ReflectHelpers.findClassLoader(targetClass.getClassLoader()); + ClassLoader classLoader = ReflectHelpers.findClassLoader(targetClass); Class methodHandles = Class.forName("java.lang.invoke.MethodHandles", true, classLoader); @SuppressWarnings("nullness") // MethodHandles#lookup accepts null Object lookup = methodHandles.getMethod("lookup").invoke(null);