Skip to content

Commit 135a559

Browse files
authored
Replace ClassLoadingStrategy with custom loading strategy (#38906)
* Replace ClassLoadingStrategy with custom loading strategy * Update findClassLoader calls to match * spotless * Generate subclasses in beam's package and loade them in the same classloader as ProtoByteBuddyUtils * Resolve classloader visibility issues in ProtoByteBuddyUtils
1 parent 61a7368 commit 135a559

1 file changed

Lines changed: 38 additions & 11 deletions

File tree

sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ProtoByteBuddyUtils.java

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.beam.sdk.extensions.protobuf;
1919

2020
import static org.apache.beam.sdk.extensions.protobuf.ProtoSchemaTranslator.getFieldNumber;
21+
import static org.apache.beam.sdk.util.ByteBuddyUtils.getClassLoadingStrategy;
2122

2223
import com.google.protobuf.BoolValue;
2324
import com.google.protobuf.ByteString;
@@ -55,7 +56,6 @@
5556
import net.bytebuddy.description.type.TypeDescription;
5657
import net.bytebuddy.description.type.TypeDescription.ForLoadedType;
5758
import net.bytebuddy.dynamic.DynamicType;
58-
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
5959
import net.bytebuddy.dynamic.scaffold.InstrumentedType;
6060
import net.bytebuddy.implementation.FixedValue;
6161
import net.bytebuddy.implementation.Implementation;
@@ -88,7 +88,6 @@
8888
import org.apache.beam.sdk.schemas.SchemaUserTypeCreator;
8989
import org.apache.beam.sdk.schemas.logicaltypes.EnumerationType;
9090
import org.apache.beam.sdk.schemas.logicaltypes.OneOfType;
91-
import org.apache.beam.sdk.schemas.utils.ByteBuddyUtils;
9291
import org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.ConvertType;
9392
import org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.ConvertValueForGetter;
9493
import org.apache.beam.sdk.schemas.utils.ByteBuddyUtils.ConvertValueForSetter;
@@ -511,8 +510,16 @@ public TypeConversion<StackManipulation> createSetterConversions(StackManipulati
511510

512511
int[] keys = getterMethodMap.keySet().stream().mapToInt(Integer::intValue).toArray();
513512

513+
Class<?> targetClass = getLoadingTarget(protoClass);
514+
@SuppressWarnings("unchecked")
514515
DynamicType.Builder<FieldValueGetter<@NonNull ProtoT, OneOfType.Value>> builder =
515-
ByteBuddyUtils.subclassGetterInterface(BYTE_BUDDY, protoClass, OneOfType.Value.class);
516+
(DynamicType.Builder<FieldValueGetter<@NonNull ProtoT, OneOfType.Value>>)
517+
BYTE_BUDDY
518+
.with(new InjectPackageStrategy(targetClass))
519+
.subclass(
520+
TypeDescription.Generic.Builder.parameterizedType(
521+
FieldValueGetter.class, protoClass, OneOfType.Value.class)
522+
.build());
516523
builder =
517524
builder
518525
.method(ElementMatchers.named("name"))
@@ -546,7 +553,7 @@ public TypeConversion<StackManipulation> createSetterConversions(StackManipulati
546553
return builder
547554
.visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES))
548555
.make()
549-
.load(ReflectHelpers.findClassLoader(), ClassLoadingStrategy.Default.INJECTION)
556+
.load(targetClass.getClassLoader(), getClassLoadingStrategy(targetClass))
550557
.getLoaded()
551558
.getDeclaredConstructor(List.class, OneOfType.class)
552559
.newInstance(getters, oneOfType);
@@ -568,9 +575,16 @@ FieldValueSetter<ProtoBuilderT, Object> createOneOfSetter(
568575
boolean contiguous = isContiguous(indices);
569576
int[] keys = setterMethodMap.keySet().stream().mapToInt(Integer::intValue).toArray();
570577

578+
Class<?> targetClass = getLoadingTarget(protoBuilderClass);
579+
@SuppressWarnings("unchecked")
571580
DynamicType.Builder<FieldValueSetter<ProtoBuilderT, Object>> builder =
572-
ByteBuddyUtils.subclassSetterInterface(
573-
BYTE_BUDDY, protoBuilderClass, OneOfType.Value.class);
581+
(DynamicType.Builder<FieldValueSetter<ProtoBuilderT, Object>>)
582+
BYTE_BUDDY
583+
.with(new InjectPackageStrategy(targetClass))
584+
.subclass(
585+
TypeDescription.Generic.Builder.parameterizedType(
586+
FieldValueSetter.class, protoBuilderClass, OneOfType.Value.class)
587+
.build());
574588
builder =
575589
builder
576590
.method(ElementMatchers.named("name"))
@@ -598,7 +612,7 @@ FieldValueSetter<ProtoBuilderT, Object> createOneOfSetter(
598612
return builder
599613
.visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES))
600614
.make()
601-
.load(ReflectHelpers.findClassLoader(), ClassLoadingStrategy.Default.INJECTION)
615+
.load(targetClass.getClassLoader(), getClassLoadingStrategy(targetClass))
602616
.getLoaded()
603617
.getDeclaredConstructor(List.class)
604618
.newInstance(setters);
@@ -1103,11 +1117,16 @@ static <ProtoBuilderT extends MessageLite.Builder> SchemaUserTypeCreator createB
11031117
List<FieldValueSetter<ProtoBuilderT, Object>> setters,
11041118
Schema schema) {
11051119
try {
1120+
Class<?> targetClass = getLoadingTarget(builderClass);
1121+
@SuppressWarnings("unchecked")
11061122
DynamicType.Builder<Supplier<ProtoBuilderT>> builder =
1107-
(DynamicType.Builder)
1123+
(DynamicType.Builder<Supplier<ProtoBuilderT>>)
11081124
BYTE_BUDDY
1109-
.with(new InjectPackageStrategy(builderClass))
1110-
.subclass(Supplier.class)
1125+
.with(new InjectPackageStrategy(targetClass))
1126+
.subclass(
1127+
TypeDescription.Generic.Builder.parameterizedType(
1128+
Supplier.class, builderClass)
1129+
.build())
11111130
.method(ElementMatchers.named("get"))
11121131
.intercept(new BuilderSupplier(protoClass));
11131132
Supplier<ProtoBuilderT> supplier =
@@ -1116,7 +1135,7 @@ static <ProtoBuilderT extends MessageLite.Builder> SchemaUserTypeCreator createB
11161135
new AsmVisitorWrapper.ForDeclaredMethods()
11171136
.writerFlags(ClassWriter.COMPUTE_FRAMES))
11181137
.make()
1119-
.load(ReflectHelpers.findClassLoader(), ClassLoadingStrategy.Default.INJECTION)
1138+
.load(targetClass.getClassLoader(), getClassLoadingStrategy(targetClass))
11201139
.getLoaded()
11211140
.getDeclaredConstructor()
11221141
.newInstance();
@@ -1190,4 +1209,12 @@ public ByteCodeAppender appender(final Target implementationTarget) {
11901209
};
11911210
}
11921211
}
1212+
1213+
private static Class<?> getLoadingTarget(Class<?> protoClass) {
1214+
ClassLoader loader = ReflectHelpers.findClassLoader(ProtoByteBuddyUtils.class, protoClass);
1215+
if (loader == ProtoByteBuddyUtils.class.getClassLoader()) {
1216+
return ProtoByteBuddyUtils.class;
1217+
}
1218+
return protoClass;
1219+
}
11931220
}

0 commit comments

Comments
 (0)