diff --git a/extensions/narayana-jta/deployment/src/main/java/io/quarkus/narayana/jta/deployment/NarayanaJtaProcessor.java b/extensions/narayana-jta/deployment/src/main/java/io/quarkus/narayana/jta/deployment/NarayanaJtaProcessor.java index 959d6aa626a60..ef48f23452d5c 100644 --- a/extensions/narayana-jta/deployment/src/main/java/io/quarkus/narayana/jta/deployment/NarayanaJtaProcessor.java +++ b/extensions/narayana-jta/deployment/src/main/java/io/quarkus/narayana/jta/deployment/NarayanaJtaProcessor.java @@ -59,17 +59,20 @@ import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.deployment.builditem.NativeImageFeatureBuildItem; import io.quarkus.deployment.builditem.ShutdownContextBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem; import io.quarkus.deployment.logging.LogCleanupFilterBuildItem; +import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild; import io.quarkus.gizmo.ClassCreator; import io.quarkus.narayana.jta.runtime.NarayanaJtaProducers; import io.quarkus.narayana.jta.runtime.NarayanaJtaRecorder; import io.quarkus.narayana.jta.runtime.TransactionManagerBuildTimeConfig; import io.quarkus.narayana.jta.runtime.TransactionManagerConfiguration; import io.quarkus.narayana.jta.runtime.context.TransactionContext; +import io.quarkus.narayana.jta.runtime.graal.DisableLoggingFeature; import io.quarkus.narayana.jta.runtime.interceptor.TestTransactionInterceptor; import io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorMandatory; import io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorNever; @@ -97,7 +100,8 @@ public void build(NarayanaJtaRecorder recorder, BuildProducer reflectiveClass, BuildProducer runtimeInit, BuildProducer feature, - TransactionManagerConfiguration transactions, ShutdownContextBuildItem shutdownContextBuildItem) { + TransactionManagerConfiguration transactions, TransactionManagerBuildTimeConfig transactionManagerBuildTimeConfig, + ShutdownContextBuildItem shutdownContextBuildItem) { recorder.handleShutdown(shutdownContextBuildItem, transactions); feature.produce(new FeatureBuildItem(Feature.NARAYANA_JTA)); additionalBeans.produce(new AdditionalBeanBuildItem(NarayanaJtaProducers.class)); @@ -141,6 +145,10 @@ public void build(NarayanaJtaRecorder recorder, builder.addBeanClass(TransactionalInterceptorNotSupported.class); additionalBeans.produce(builder.build()); + if (transactionManagerBuildTimeConfig.allowUnsafeMultipleLastResources) { + recorder.logAllowUnsafeMultipleLastResources(); + } + //we want to force Arjuna to init at static init time Properties defaultProperties = PropertiesFactory.getDefaultProperties(); //we don't want to store the system properties here @@ -148,6 +156,7 @@ public void build(NarayanaJtaRecorder recorder, for (Object i : System.getProperties().keySet()) { defaultProperties.remove(i); } + recorder.setDefaultProperties(defaultProperties); // This must be done before setNodeName as the code in setNodeName will create a TSM based on the value of this property recorder.disableTransactionStatusManager(); @@ -160,9 +169,22 @@ public void build(NarayanaJtaRecorder recorder, @Record(STATIC_INIT) public void allowUnsafeMultipleLastResources(NarayanaJtaRecorder recorder, TransactionManagerBuildTimeConfig transactionManagerBuildTimeConfig, - Capabilities capabilities) { + Capabilities capabilities, BuildProducer logCleanupFilters, + BuildProducer nativeImageFeatures) { if (transactionManagerBuildTimeConfig.allowUnsafeMultipleLastResources) { recorder.allowUnsafeMultipleLastResources(capabilities.isPresent(Capability.AGROAL)); + + // we will handle these warnings ourselves at runtime init + logCleanupFilters.produce( + new LogCleanupFilterBuildItem("com.arjuna.ats.arjuna", "ARJUNA012139", "ARJUNA012141", "ARJUNA012142")); + } + } + + @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class) + public void nativeImageFeature(TransactionManagerBuildTimeConfig transactionManagerBuildTimeConfig, + BuildProducer nativeImageFeatures) { + if (transactionManagerBuildTimeConfig.allowUnsafeMultipleLastResources) { + nativeImageFeatures.produce(new NativeImageFeatureBuildItem(DisableLoggingFeature.class)); } } diff --git a/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/NarayanaJtaRecorder.java b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/NarayanaJtaRecorder.java index 2ef74ed9eda8a..1833d285e6d95 100644 --- a/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/NarayanaJtaRecorder.java +++ b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/NarayanaJtaRecorder.java @@ -111,17 +111,27 @@ public void setConfig(final TransactionManagerConfiguration transactions) { } /** - * This should be removed in 3.11. + * This should be removed in the future. */ @Deprecated(forRemoval = true) public void allowUnsafeMultipleLastResources(boolean agroalPresent) { arjPropertyManager.getCoreEnvironmentBean().setAllowMultipleLastResources(true); + arjPropertyManager.getCoreEnvironmentBean().setDisableMultipleLastResourcesWarning(true); if (agroalPresent) { jtaPropertyManager.getJTAEnvironmentBean() .setLastResourceOptimisationInterfaceClassName("io.agroal.narayana.LocalXAResource"); } } + /** + * This should be removed in the future. + */ + @Deprecated(forRemoval = true) + public void logAllowUnsafeMultipleLastResources() { + log.warn( + "Setting quarkus.transaction-manager.allow-unsafe-multiple-last-resources to true makes adding multiple resources to the same transaction unsafe."); + } + private void setObjectStoreDir(String name, TransactionManagerConfiguration config) { BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, name).setObjectStoreDir(config.objectStore.directory); } diff --git a/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/graal/DisableLoggingFeature.java b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/graal/DisableLoggingFeature.java new file mode 100644 index 0000000000000..64e88a65a9a28 --- /dev/null +++ b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/graal/DisableLoggingFeature.java @@ -0,0 +1,45 @@ +package io.quarkus.narayana.jta.runtime.graal; + +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.graalvm.nativeimage.hosted.Feature; + +/** + * Disables logging during the analysis phase + */ +public class DisableLoggingFeature implements Feature { + + private static final String[] CATEGORIES = { + "com.arjuna.ats.arjuna" + }; + + private final Map categoryMap = new HashMap<>(CATEGORIES.length); + + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + for (String category : CATEGORIES) { + Logger logger = Logger.getLogger(category); + categoryMap.put(category, logger.getLevel()); + logger.setLevel(Level.SEVERE); + } + } + + @Override + public void afterAnalysis(AfterAnalysisAccess access) { + for (String category : CATEGORIES) { + Level level = categoryMap.remove(category); + if (level != null) { + Logger logger = Logger.getLogger(category); + logger.setLevel(level); + } + } + } + + @Override + public String getDescription() { + return "Disables INFO and WARN logging during the analysis phase"; + } +}