This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch spring6
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/spring6 by this push:
     new 97766d3590 Bump resteasy-spring 3.1.0.Final -> 3.1.1.Final (also 
workaround regressions)
97766d3590 is described below

commit 97766d3590c1aaadf9d3b69b3f7bd34a01fd014d
Author: Andi Huber <ahu...@apache.org>
AuthorDate: Wed Jan 24 15:07:05 2024 +0100

    Bump resteasy-spring 3.1.0.Final -> 3.1.1.Final (also workaround
    regressions)
---
 bom/pom.xml                                        |   2 +-
 .../integtests/OutboxRestClient_IntegTest.java     |  63 ++++----
 .../SpringBeanProcessorRegressionWorkaround.java   | 167 +++++++++++++++++++++
 3 files changed, 202 insertions(+), 30 deletions(-)

diff --git a/bom/pom.xml b/bom/pom.xml
index 0b5bd0bc45..efef3135ca 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -162,7 +162,7 @@ It is therefore a copy of org.apache:apache, with 
customisations clearly identif
         <quartz-scheduler.version>2.3.2</quartz-scheduler.version>
 
         
<resteasy-spring-boot.version>6.0.0.Alpha2</resteasy-spring-boot.version>
-        <resteasy-spring.version>3.1.0.Final</resteasy-spring.version>
+        <resteasy-spring.version>3.1.1.Final</resteasy-spring.version>
         <resteasy.version>6.2.7.Final</resteasy.version> <!-- be awre of 
potential clashes with 
https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-spring-boot-starter
 -->
         
<resteasy-jaxb-provider.version>6.2.2.Final</resteasy-jaxb-provider.version>
 
diff --git 
a/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/OutboxRestClient_IntegTest.java
 
b/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/OutboxRestClient_IntegTest.java
index c0d8cf07e5..d3133be5db 100644
--- 
a/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/OutboxRestClient_IntegTest.java
+++ 
b/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/OutboxRestClient_IntegTest.java
@@ -32,7 +32,6 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.web.server.LocalServerPort;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.PropertySource;
 import org.springframework.context.annotation.PropertySources;
 import org.springframework.test.context.ActiveProfiles;
@@ -55,14 +54,35 @@ import 
org.apache.causeway.extensions.executionoutbox.applib.integtest.model.Cou
 import 
org.apache.causeway.extensions.executionoutbox.jpa.CausewayModuleExtExecutionOutboxPersistenceJpa;
 import 
org.apache.causeway.extensions.executionoutbox.jpa.integtests.model.Counter;
 import 
org.apache.causeway.extensions.executionoutbox.restclient.api.OutboxClient;
-import 
org.apache.causeway.persistence.jpa.eclipselink.CausewayModulePersistenceJpaEclipselink;
 import org.apache.causeway.schema.ixn.v2.InteractionDto;
 import org.apache.causeway.security.bypass.CausewayModuleSecurityBypass;
 import 
org.apache.causeway.testing.fixtures.applib.CausewayModuleTestingFixturesApplib;
-import 
org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.CausewayModuleViewerRestfulObjectsJaxrsResteasy;
+import 
org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.conneg.RestfulObjectsJaxbWriterForXml;
+import 
org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.webmodule.WebModuleJaxrsResteasy;
+import 
org.apache.causeway.viewer.restfulobjects.viewer.CausewayModuleViewerRestfulObjectsViewer;
 
 @SpringBootTest(
-        classes = OutboxRestClient_IntegTest.AppManifest.class,
+        classes = {
+                OutboxRestClient_IntegTest.TestManifest.class,
+                CausewayModuleCoreRuntimeServices.class,
+                CausewayModuleSecurityBypass.class,
+
+                CausewayModuleTestingFixturesApplib.class,
+                CausewayModuleExtExecutionOutboxPersistenceJpa.class,
+
+                // RESTEASY013015: could not find the type for bean named 
jpaSharedEM_entityManagerFactory
+                //CausewayModuleViewerRestfulObjectsJaxrsResteasy.class, // 
replaced
+                SpringBeanProcessorRegressionWorkaround.class,
+                CausewayModuleViewerRestfulObjectsViewer.class,
+                WebModuleJaxrsResteasy.class,
+                RestfulObjectsJaxbWriterForXml.class,
+                // ---
+
+                CausewayModuleCoreWebapp.class,
+                // mixins
+                Counter_bumpUsingMixin.class,
+                Counter_bumpUsingMixinWithExecutionPublishingDisabled.class,
+        },
         webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
 )
 @ActiveProfiles("test")
@@ -70,27 +90,22 @@ public class OutboxRestClient_IntegTest  {
 
     @EnableAutoConfiguration
     @Configuration
-    @Import({
-            CausewayModuleCoreRuntimeServices.class,
-            CausewayModuleSecurityBypass.class,
-            CausewayModulePersistenceJpaEclipselink.class,
-            CausewayModuleTestingFixturesApplib.class,
-            CausewayModuleExtExecutionOutboxPersistenceJpa.class,
-            CausewayModuleViewerRestfulObjectsJaxrsResteasy.class,
-            CausewayModuleCoreWebapp.class,
-
-            // mixins
-            Counter_bumpUsingMixin.class,
-            Counter_bumpUsingMixinWithExecutionPublishingDisabled.class,
-    })
     @PropertySources({
             @PropertySource(CausewayPresets.UseLog4j2Test)
     })
     @EntityScan(basePackageClasses = {Counter.class})
-    @ComponentScan(basePackageClasses = {AppManifest.class, Counter.class})
-    public static class AppManifest {
+    @ComponentScan(basePackageClasses = {TestManifest.class, Counter.class})
+    public static class TestManifest {
     }
 
+    @Inject ExecutionOutboxEntryRepository executionOutboxEntryRepository;
+    @Inject InteractionService interactionService;
+    @Inject RepositoryService repositoryService;
+    @Inject CounterRepository<Counter> counterRepository;
+    @Inject WrapperFactory wrapperFactory;
+    @Inject TransactionService transactionService;
+    @Inject RestEndpointService restEndpointService;
+
     @LocalServerPort
     protected int port;
 
@@ -243,14 +258,4 @@ public class OutboxRestClient_IntegTest  {
         });
     }
 
-
-    @Inject RestEndpointService restEndpointService;
-
-    @Inject ExecutionOutboxEntryRepository executionOutboxEntryRepository;
-    @Inject InteractionService interactionService;
-    @Inject RepositoryService repositoryService;
-    @Inject CounterRepository<Counter> counterRepository;
-    @Inject WrapperFactory wrapperFactory;
-    @Inject TransactionService transactionService;
-
 }
diff --git 
a/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/SpringBeanProcessorRegressionWorkaround.java
 
b/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/SpringBeanProcessorRegressionWorkaround.java
new file mode 100644
index 0000000000..3aa897dc71
--- /dev/null
+++ 
b/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/SpringBeanProcessorRegressionWorkaround.java
@@ -0,0 +1,167 @@
+/*
+ *  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.causeway.extensions.executionoutbox.restclient.integtests;
+
+import java.util.List;
+
+import jakarta.persistence.EntityManagerFactory;
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletContextEvent;
+import jakarta.servlet.ServletContextListener;
+
+import org.jboss.resteasy.core.AsynchronousDispatcher;
+import org.jboss.resteasy.core.ResourceMethodRegistry;
+import org.jboss.resteasy.core.ResteasyContext;
+import org.jboss.resteasy.core.SynchronousDispatcher;
+import org.jboss.resteasy.plugins.server.servlet.ListenerBootstrap;
+import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap;
+import org.jboss.resteasy.plugins.spring.SpringBeanProcessor;
+import org.jboss.resteasy.spi.Dispatcher;
+import org.jboss.resteasy.spi.Registry;
+import org.jboss.resteasy.spi.ResteasyDeployment;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import 
org.jboss.resteasy.springboot.JAXRSResourcesAndProvidersScannerPostProcessor;
+import org.jboss.resteasy.springboot.ResteasyApplicationBuilder;
+import org.jboss.resteasy.springboot.ResteasyEmbeddedServletInitializer;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import 
org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import 
org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.CausewayModuleViewerRestfulObjectsJaxrsResteasy;
+
+/**
+ * RESTEASY013015: could not find the type for bean named 
jpaSharedEM_entityManagerFactory
+ * <p>
+ * Overrides {@link org.jboss.resteasy.springboot.ResteasyAutoConfiguration}
+ * and fixes regression with {@link SpringBeanProcessor}.
+ * <p>
+ * If seeing this in production, we need to propagate the workaround to
+ * {@link CausewayModuleViewerRestfulObjectsJaxrsResteasy}.
+ */
+@Configuration
+class SpringBeanProcessorRegressionWorkaround {
+
+    @Bean @Primary
+    @Qualifier("ResteasyProviderFactory")
+    public static BeanFactoryPostProcessor springBeanProcessor() {
+        var blackListed = List.of("jpaSharedEM_entityManagerFactory", 
"jpaSharedEM_AWC_entityManagerFactory");
+
+        ResteasyProviderFactory resteasyProviderFactory = 
ResteasyProviderFactory.newInstance();
+        ResourceMethodRegistry resourceMethodRegistry = new 
ResourceMethodRegistry(resteasyProviderFactory);
+
+        SpringBeanProcessor springBeanProcessor = new SpringBeanProcessor() {
+
+            @Override
+            protected Class<?> processBean(final 
ConfigurableListableBeanFactory beanFactory,
+                    final List<String> dependsOnProviders, final String name, 
final BeanDefinition beanDef) {
+
+                if(blackListed.contains(name)) {
+                    return EntityManagerFactory.class;
+                }
+
+                return super.processBean(beanFactory, dependsOnProviders, 
name, beanDef);
+            }
+
+        };
+        springBeanProcessor.setProviderFactory(resteasyProviderFactory);
+        springBeanProcessor.setRegistry(resourceMethodRegistry);
+
+        return springBeanProcessor;
+    }
+
+    @Bean
+    @ConditionalOnProperty(name="resteasy.jaxrs.scan-packages")
+    public static JAXRSResourcesAndProvidersScannerPostProcessor 
providerScannerPostProcessor() {
+        return new JAXRSResourcesAndProvidersScannerPostProcessor();
+    }
+
+    /**
+     * This is a modified version of {@link ResteasyBootstrap}
+     *
+     * @return a ServletContextListener object that configures and start a 
ResteasyDeployment
+     */
+    @Bean
+    public ServletContextListener 
resteasyBootstrapListener(@Qualifier("ResteasyProviderFactory") final 
BeanFactoryPostProcessor beanFactoryPostProcessor) {
+        ServletContextListener servletContextListener = new 
ServletContextListener() {
+
+            private SpringBeanProcessor springBeanProcessor = 
(SpringBeanProcessor) beanFactoryPostProcessor;
+
+            protected ResteasyDeployment deployment;
+
+            @Override
+            public void contextInitialized(final ServletContextEvent sce) {
+                ServletContext servletContext = sce.getServletContext();
+                ResteasyContext.pushContext(ServletContext.class, 
servletContext);
+                ListenerBootstrap config = new 
ListenerBootstrap(servletContext);
+
+                ResteasyProviderFactory resteasyProviderFactory = 
springBeanProcessor.getProviderFactory();
+                ResourceMethodRegistry resourceMethodRegistry = 
(ResourceMethodRegistry) springBeanProcessor.getRegistry();
+
+                deployment = config.createDeployment();
+
+                deployment.setProviderFactory(resteasyProviderFactory);
+                deployment.setRegistry(resourceMethodRegistry);
+
+                if (deployment.isAsyncJobServiceEnabled()) {
+                    AsynchronousDispatcher dispatcher = new 
AsynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
+                    deployment.setDispatcher(dispatcher);
+                } else {
+                    SynchronousDispatcher dispatcher = new 
SynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
+                    deployment.setDispatcher(dispatcher);
+                }
+
+                deployment.start();
+
+                
servletContext.setAttribute(ResteasyProviderFactory.class.getName(), 
deployment.getProviderFactory());
+                servletContext.setAttribute(Dispatcher.class.getName(), 
deployment.getDispatcher());
+                servletContext.setAttribute(Registry.class.getName(), 
deployment.getRegistry());
+            }
+
+            @Override
+            public void contextDestroyed(final ServletContextEvent sce) {
+                try {
+                    if (deployment != null) {
+                        deployment.stop();
+                    }
+                } finally {
+                    ResteasyContext.popContextData(ServletContext.class);
+                }
+            }
+        };
+
+        return servletContextListener;
+    }
+
+    @Bean(name = ResteasyApplicationBuilder.BEAN_NAME)
+    public ResteasyApplicationBuilder resteasyApplicationBuilder() {
+        return new ResteasyApplicationBuilder();
+    }
+
+    @Bean
+    public static ResteasyEmbeddedServletInitializer 
resteasyEmbeddedServletInitializer() {
+        return new ResteasyEmbeddedServletInitializer();
+    }
+
+
+}

Reply via email to