Skip to content

Commit 4043c0e

Browse files
geoandgsmet
authored andcommitted
Ensure ParameterConverter is loaded from the TCCL
This is needed because otherwise dev-mode could break in some cases Fixes: #39777 Follows up on: #39691 (cherry picked from commit 91a2f52)
1 parent 8cdead9 commit 4043c0e

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/scanning/ClassInjectorTransformer.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.jboss.resteasy.reactive.server.core.parameters.converters.DelegatingParameterConverterSupplier;
3737
import org.jboss.resteasy.reactive.server.core.parameters.converters.ParameterConverter;
3838
import org.jboss.resteasy.reactive.server.core.parameters.converters.ParameterConverterSupplier;
39+
import org.jboss.resteasy.reactive.server.core.parameters.converters.ParameterConverterSupport;
3940
import org.jboss.resteasy.reactive.server.core.parameters.converters.RuntimeResolvedConverter;
4041
import org.jboss.resteasy.reactive.server.injection.ResteasyReactiveInjectionContext;
4142
import org.jboss.resteasy.reactive.server.injection.ResteasyReactiveInjectionTarget;
@@ -77,6 +78,9 @@ public class ClassInjectorTransformer implements BiFunction<String, ClassVisitor
7778
private static final String INIT_CONVERTER_FIELD_NAME = "__quarkus_converter__";
7879
private static final String INIT_CONVERTER_METHOD_DESCRIPTOR = "(" + QUARKUS_REST_DEPLOYMENT_DESCRIPTOR + ")V";
7980

81+
private static final String PARAMETER_CONVERTER_SUPPORT_BINARY_NAME = ParameterConverterSupport.class.getName().replace('.',
82+
'/');
83+
8084
private static final String MULTIPART_SUPPORT_BINARY_NAME = MultipartSupport.class.getName().replace('.', '/');
8185

8286
private static final String OBJECT_BINARY_NAME = Object.class.getName().replace('.', '/');
@@ -457,18 +461,14 @@ private void generateConverterInitMethod(FieldInfo fieldInfo, ParameterConverter
457461
initConverterMethod.visitJumpInsn(Opcodes.IFNONNULL, notNull);
458462
// stack: [converter]
459463
initConverterMethod.visitInsn(Opcodes.POP);
460-
// stack: []
461-
// let's instantiate our delegate
462-
initConverterMethod.visitTypeInsn(Opcodes.NEW, delegateBinaryName);
463-
// stack: [converter]
464-
initConverterMethod.visitInsn(Opcodes.DUP);
465-
// stack: [converter, converter]
466-
initConverterMethod.visitMethodInsn(Opcodes.INVOKESPECIAL, delegateBinaryName, "<init>",
467-
"()V", false);
468-
// stack: [converter]
469-
// If we don't cast this to ParameterConverter, ASM in computeFrames will call getCommonSuperType
470-
// and try to load our generated class before we can load it, so we insert this cast to avoid that
471-
initConverterMethod.visitTypeInsn(Opcodes.CHECKCAST, PARAMETER_CONVERTER_BINARY_NAME);
464+
465+
// className param
466+
initConverterMethod.visitLdcInsn(delegateBinaryName.replace('/', '.'));
467+
initConverterMethod.visitMethodInsn(Opcodes.INVOKESTATIC, PARAMETER_CONVERTER_SUPPORT_BINARY_NAME,
468+
"create",
469+
"(" + STRING_DESCRIPTOR + ")" + PARAMETER_CONVERTER_DESCRIPTOR,
470+
false);
471+
472472
// end default delegate
473473
initConverterMethod.visitLabel(notNull);
474474
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.jboss.resteasy.reactive.server.core.parameters.converters;
2+
3+
/**
4+
* This class isn't used directly, it is however used by generated code meant to deal with {@link ParameterConverter}.
5+
*/
6+
@SuppressWarnings("unused")
7+
public final class ParameterConverterSupport {
8+
9+
private ParameterConverterSupport() {
10+
}
11+
12+
/**
13+
* Normally the reflective instantiation would not be needed, and we could just instantiate normally,
14+
* however that could break dev-mode when the converters are in a different module and non-standard Maven
15+
* configuration is used (see <a href="https://github.com/quarkusio/quarkus/issues/39773#issuecomment-2030493539">this</a>)
16+
*/
17+
public static ParameterConverter create(String className) {
18+
try {
19+
Class<?> clazz = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
20+
return (ParameterConverter) clazz.getConstructor().newInstance();
21+
} catch (Exception e) {
22+
throw new RuntimeException("Unable to create instance of " + className, e);
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)