From e19f1d680d45c5d003624ff36f28939b812c237e Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Wed, 15 Apr 2020 10:46:45 +0200 Subject: [PATCH] Reactive routes - fix race condition in generated handlers - follows up on https://github.com/quarkusio/quarkus/pull/8536 --- .../web/deployment/VertxWebProcessor.java | 35 +++++++++---------- .../vertx/web/runtime/RouteHandler.java | 5 --- .../vertx/web/runtime/VertxWebRecorder.java | 14 +------- 3 files changed, 17 insertions(+), 37 deletions(-) diff --git a/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/VertxWebProcessor.java b/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/VertxWebProcessor.java index 7a4162993ff96..392ba1b13b76b 100644 --- a/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/VertxWebProcessor.java +++ b/extensions/vertx-web/deployment/src/main/java/io/quarkus/vertx/web/deployment/VertxWebProcessor.java @@ -40,7 +40,6 @@ import io.quarkus.arc.InjectableReferenceProvider; import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem; import io.quarkus.arc.deployment.BeanArchiveIndexBuildItem; -import io.quarkus.arc.deployment.BeanContainerBuildItem; import io.quarkus.arc.deployment.CustomScopeAnnotationsBuildItem; import io.quarkus.arc.deployment.UnremovableBeanBuildItem; import io.quarkus.arc.deployment.UnremovableBeanBuildItem.BeanClassAnnotationExclusion; @@ -130,6 +129,7 @@ class VertxWebProcessor { private static final MethodDescriptor INJECTABLE_BEAN_DESTROY = MethodDescriptor.ofMethod(InjectableBean.class, "destroy", void.class, Object.class, CreationalContext.class); + static final MethodDescriptor OBJECT_CONSTRUCTOR = MethodDescriptor.ofConstructor(Object.class); @BuildStep FeatureBuildItem feature() { @@ -328,12 +328,6 @@ void addAdditionalRoutes( detectConflictingRoutes(matchers); } - @BuildStep - @Record(ExecutionTime.RUNTIME_INIT) - void initRouteHandlers(VertxWebRecorder recorder, BeanContainerBuildItem container) { - recorder.initHandlers(); - } - @BuildStep AnnotationsTransformerBuildItem annotationTransformer(CustomScopeAnnotationsBuildItem scopes) { return new AnnotationsTransformerBuildItem(new AnnotationsTransformer() { @@ -418,34 +412,37 @@ private String generateHandler(BeanInfo bean, MethodInfo method, ClassOutput cla .setModifiers(ACC_PRIVATE | ACC_FINAL); } - implementInitialize(bean, invokerCreator, beanField, contextField, containerField); + implementConstructor(bean, invokerCreator, beanField, contextField, containerField); implementInvoke(bean, method, invokerCreator, beanField, contextField, containerField); invokerCreator.close(); return generatedName.replace('/', '.'); } - void implementInitialize(BeanInfo bean, ClassCreator invokerCreator, FieldCreator beanField, FieldCreator contextField, + void implementConstructor(BeanInfo bean, ClassCreator invokerCreator, FieldCreator beanField, FieldCreator contextField, FieldCreator containerField) { - MethodCreator initialize = invokerCreator.getMethodCreator("initialize", void.class); - ResultHandle containerHandle = initialize + MethodCreator constructor = invokerCreator.getMethodCreator("", void.class); + // Invoke super() + constructor.invokeSpecialMethod(OBJECT_CONSTRUCTOR, constructor.getThis()); + + ResultHandle containerHandle = constructor .invokeStaticMethod(ARC_CONTAINER); - ResultHandle beanHandle = initialize.invokeInterfaceMethod( + ResultHandle beanHandle = constructor.invokeInterfaceMethod( ARC_CONTAINER_BEAN, - containerHandle, initialize.load(bean.getIdentifier())); - initialize.writeInstanceField(beanField.getFieldDescriptor(), initialize.getThis(), beanHandle); + containerHandle, constructor.load(bean.getIdentifier())); + constructor.writeInstanceField(beanField.getFieldDescriptor(), constructor.getThis(), beanHandle); if (contextField != null) { - initialize.writeInstanceField(contextField.getFieldDescriptor(), initialize.getThis(), - initialize.invokeInterfaceMethod( + constructor.writeInstanceField(contextField.getFieldDescriptor(), constructor.getThis(), + constructor.invokeInterfaceMethod( ARC_CONTAINER_GET_ACTIVE_CONTEXT, - containerHandle, initialize + containerHandle, constructor .invokeInterfaceMethod( BEAN_GET_SCOPE, beanHandle))); } else { - initialize.writeInstanceField(containerField.getFieldDescriptor(), initialize.getThis(), containerHandle); + constructor.writeInstanceField(containerField.getFieldDescriptor(), constructor.getThis(), containerHandle); } - initialize.returnValue(null); + constructor.returnValue(null); } void implementInvoke(BeanInfo bean, MethodInfo method, ClassCreator invokerCreator, FieldCreator beanField, diff --git a/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/RouteHandler.java b/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/RouteHandler.java index ae1b2c53a2159..87befc01397b8 100644 --- a/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/RouteHandler.java +++ b/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/RouteHandler.java @@ -14,11 +14,6 @@ */ public interface RouteHandler extends Handler { - /** - * Initialize the handler instance before it is put into service. - */ - void initialize(); - /** * Invokes the route method. * diff --git a/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/VertxWebRecorder.java b/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/VertxWebRecorder.java index 8efc269d3c7f8..716a29b5a22b6 100644 --- a/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/VertxWebRecorder.java +++ b/extensions/vertx-web/runtime/src/main/java/io/quarkus/vertx/web/runtime/VertxWebRecorder.java @@ -1,8 +1,6 @@ package io.quarkus.vertx.web.runtime; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; import java.util.function.Function; import io.quarkus.runtime.annotations.Recorder; @@ -15,8 +13,6 @@ @Recorder public class VertxWebRecorder { - static volatile List handlers = new ArrayList<>(); - @SuppressWarnings("unchecked") public Handler createHandler(String handlerClassName) { try { @@ -27,7 +23,6 @@ public Handler createHandler(String handlerClassName) { Class> handlerClazz = (Class>) cl .loadClass(handlerClassName); RouteHandler handler = (RouteHandler) handlerClazz.getDeclaredConstructor().newInstance(); - handlers.add(handler); return handler; } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException e) { @@ -35,13 +30,6 @@ public Handler createHandler(String handlerClassName) { } } - public void initHandlers() { - for (RouteHandler routeHandler : handlers) { - routeHandler.initialize(); - } - handlers.clear(); - } - public Function createRouteFunction(RouteMatcher matcher, Handler bodyHandler) { return new Function() { @@ -81,4 +69,4 @@ public io.vertx.ext.web.Route apply(Router router) { }; } -} \ No newline at end of file +}