Skip to content

Commit

Permalink
Ensure ParameterConverter is loaded from the TCCL
Browse files Browse the repository at this point in the history
This is needed because otherwise dev-mode could break
in some cases

Fixes: quarkusio#39777
Follows up on: quarkusio#39691

(cherry picked from commit 91a2f52)
  • Loading branch information
geoand authored and gsmet committed Apr 3, 2024
1 parent 8cdead9 commit 4043c0e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.jboss.resteasy.reactive.server.core.parameters.converters.DelegatingParameterConverterSupplier;
import org.jboss.resteasy.reactive.server.core.parameters.converters.ParameterConverter;
import org.jboss.resteasy.reactive.server.core.parameters.converters.ParameterConverterSupplier;
import org.jboss.resteasy.reactive.server.core.parameters.converters.ParameterConverterSupport;
import org.jboss.resteasy.reactive.server.core.parameters.converters.RuntimeResolvedConverter;
import org.jboss.resteasy.reactive.server.injection.ResteasyReactiveInjectionContext;
import org.jboss.resteasy.reactive.server.injection.ResteasyReactiveInjectionTarget;
Expand Down Expand Up @@ -77,6 +78,9 @@ public class ClassInjectorTransformer implements BiFunction<String, ClassVisitor
private static final String INIT_CONVERTER_FIELD_NAME = "__quarkus_converter__";
private static final String INIT_CONVERTER_METHOD_DESCRIPTOR = "(" + QUARKUS_REST_DEPLOYMENT_DESCRIPTOR + ")V";

private static final String PARAMETER_CONVERTER_SUPPORT_BINARY_NAME = ParameterConverterSupport.class.getName().replace('.',
'/');

private static final String MULTIPART_SUPPORT_BINARY_NAME = MultipartSupport.class.getName().replace('.', '/');

private static final String OBJECT_BINARY_NAME = Object.class.getName().replace('.', '/');
Expand Down Expand Up @@ -457,18 +461,14 @@ private void generateConverterInitMethod(FieldInfo fieldInfo, ParameterConverter
initConverterMethod.visitJumpInsn(Opcodes.IFNONNULL, notNull);
// stack: [converter]
initConverterMethod.visitInsn(Opcodes.POP);
// stack: []
// let's instantiate our delegate
initConverterMethod.visitTypeInsn(Opcodes.NEW, delegateBinaryName);
// stack: [converter]
initConverterMethod.visitInsn(Opcodes.DUP);
// stack: [converter, converter]
initConverterMethod.visitMethodInsn(Opcodes.INVOKESPECIAL, delegateBinaryName, "<init>",
"()V", false);
// stack: [converter]
// If we don't cast this to ParameterConverter, ASM in computeFrames will call getCommonSuperType
// and try to load our generated class before we can load it, so we insert this cast to avoid that
initConverterMethod.visitTypeInsn(Opcodes.CHECKCAST, PARAMETER_CONVERTER_BINARY_NAME);

// className param
initConverterMethod.visitLdcInsn(delegateBinaryName.replace('/', '.'));
initConverterMethod.visitMethodInsn(Opcodes.INVOKESTATIC, PARAMETER_CONVERTER_SUPPORT_BINARY_NAME,
"create",
"(" + STRING_DESCRIPTOR + ")" + PARAMETER_CONVERTER_DESCRIPTOR,
false);

// end default delegate
initConverterMethod.visitLabel(notNull);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.jboss.resteasy.reactive.server.core.parameters.converters;

/**
* This class isn't used directly, it is however used by generated code meant to deal with {@link ParameterConverter}.
*/
@SuppressWarnings("unused")
public final class ParameterConverterSupport {

private ParameterConverterSupport() {
}

/**
* Normally the reflective instantiation would not be needed, and we could just instantiate normally,
* however that could break dev-mode when the converters are in a different module and non-standard Maven
* configuration is used (see <a href="https://github.com/quarkusio/quarkus/issues/39773#issuecomment-2030493539">this</a>)
*/
public static ParameterConverter create(String className) {
try {
Class<?> clazz = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
return (ParameterConverter) clazz.getConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("Unable to create instance of " + className, e);
}
}
}

0 comments on commit 4043c0e

Please sign in to comment.