From 7c815c1a67b20c9e4a992216630def983d10389d Mon Sep 17 00:00:00 2001 From: Aleksandr Nikolaev <> Date: Mon, 22 Jun 2026 18:33:56 +0300 Subject: [PATCH 1/6] IGNITE-28588 update Spring --- checkstyle/checkstyle.xml | 2 +- .../misc/springbean/SpringBeanExample.java | 12 +++--------- modules/calcite/pom.xml | 6 ++++++ .../ignite/internal/IgniteComponentType.java | 4 ++-- .../processors/rest/GridRestProcessor.java | 4 ++++ .../uri/tasks/GarHelloWorldTask.java | 7 ++++--- .../uri/tasks/GridUriDeploymentTestTask1.java | 7 +++++-- .../uri/tasks/GridUriDeploymentTestTask2.java | 6 ++++-- .../uri/tasks/GridUriDeploymentTestTask9.java | 6 ++++-- modules/jta/pom.xml | 12 +++++++++--- .../apache/ignite/cache/jta/CacheTmLookup.java | 2 +- .../cache/jta/jndi/CacheJndiTmFactory.java | 2 +- .../cache/jta/jndi/CacheJndiTmLookup.java | 2 +- .../jta/reflect/CacheReflectionTmLookup.java | 2 +- .../websphere/WebSphereLibertyTmFactory.java | 2 +- .../jta/websphere/WebSphereTmFactory.java | 18 +++++++++--------- .../processors/cache/jta/CacheJtaManager.java | 8 ++++---- .../processors/cache/jta/CacheJtaResource.java | 4 ++-- .../cache/CacheJndiTmFactorySelfTest.java | 16 ++++++++-------- ...acheJtaConfigurationValidationSelfTest.java | 2 +- ...acheJtaFactoryConfigValidationSelfTest.java | 2 +- .../cache/GridJtaLifecycleAwareSelfTest.java | 2 +- .../GridJtaTransactionManagerSelfTest.java | 4 ++-- .../cache/jta/AbstractCacheJtaSelfTest.java | 4 ++-- ...GridPartitionedCacheJtaFactorySelfTest.java | 2 +- ...itionedCacheJtaLookupClassNameSelfTest.java | 2 +- .../http/jetty/GridJettyRestHandler.java | 6 +++--- .../GridResourceSpringBeanInjector.java | 6 +++--- .../GridResourceProcessorSelfTest.java | 2 +- .../uri/GridUriDeploymentSpringDocument.java | 6 +++--- .../uri/GridUriDeploymentSpringParser.java | 10 ++++++---- modules/web/ignite-websphere-test/pom.xml | 12 ++++++++++++ .../ignite/webtest/TestJtaTxServlet.java | 6 +++--- .../cache/websession/WebSessionFilter.java | 8 ++++---- parent/pom.xml | 14 +++++++++++++- 35 files changed, 127 insertions(+), 83 deletions(-) diff --git a/checkstyle/checkstyle.xml b/checkstyle/checkstyle.xml index d1423237dadf6..7bb56603bc603 100644 --- a/checkstyle/checkstyle.xml +++ b/checkstyle/checkstyle.xml @@ -64,7 +64,7 @@ - + diff --git a/examples/src/main/java/org/apache/ignite/examples/misc/springbean/SpringBeanExample.java b/examples/src/main/java/org/apache/ignite/examples/misc/springbean/SpringBeanExample.java index 66b22fa8681a9..d514db2512c0b 100644 --- a/examples/src/main/java/org/apache/ignite/examples/misc/springbean/SpringBeanExample.java +++ b/examples/src/main/java/org/apache/ignite/examples/misc/springbean/SpringBeanExample.java @@ -53,11 +53,9 @@ public static void main(String[] args) throws Exception { System.out.println(); System.out.println(">>> Spring bean example started."); - // Initialize Spring factory. - ClassPathXmlApplicationContext ctx = - new ClassPathXmlApplicationContext("org/apache/ignite/examples/misc/springbean/spring-bean.xml"); - - try { + // Initialize Spring factory (closed automatically, which stops the local cluster node). + try (ClassPathXmlApplicationContext ctx = + new ClassPathXmlApplicationContext("org/apache/ignite/examples/misc/springbean/spring-bean.xml")) { // Get ignite from Spring (note that local cluster node is already started). Ignite ignite = (Ignite)ctx.getBean("mySpringBean"); @@ -81,9 +79,5 @@ public static void main(String[] args) throws Exception { System.out.println(">>> Check all nodes for output (this node is also part of the cluster)."); System.out.println(">>>"); } - finally { - // Stop local cluster node. - ctx.destroy(); - } } } diff --git a/modules/calcite/pom.xml b/modules/calcite/pom.xml index 945451239f846..8abb473c21d41 100644 --- a/modules/calcite/pom.xml +++ b/modules/calcite/pom.xml @@ -69,6 +69,12 @@ org.apache.calcite calcite-core ${calcite.version} + + + org.apache.commons + commons-dbcp2 + + diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java index 8e9e483af45ef..6a895088bf711 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java @@ -208,7 +208,7 @@ public T createIfInClassPath(GridKernalContext ctx, boolean mandatory) try { Class.forName(cls); } - catch (ClassNotFoundException e) { + catch (ClassNotFoundException | LinkageError e) { if (mandatory) throw componentException(e); @@ -263,7 +263,7 @@ private T createOptional0(@Nullable GridKernalContext ctx) throws IgniteChec try { cls = Class.forName(clsName); } - catch (ClassNotFoundException ignored) { + catch (ClassNotFoundException | LinkageError ignored) { try { cls = Class.forName(noOpClsName); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java index a7e0cc58d9d27..0f4f56b855b18 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java @@ -1017,6 +1017,10 @@ private void startHttpProtocol() throws IgniteCheckedException { log.debug("Failed to initialize HTTP REST protocol (consider adding ignite-rest-http " + "module to classpath)."); } + catch (LinkageError e) { + U.warn(log, "Failed to initialize HTTP REST protocol (consider adding ignite-rest-http " + + "module and its dependencies to classpath): " + e); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { throw new IgniteCheckedException("Failed to initialize HTTP REST protocol.", e); } diff --git a/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GarHelloWorldTask.java b/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GarHelloWorldTask.java index df71641a54255..1bcb94160f011 100644 --- a/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GarHelloWorldTask.java +++ b/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GarHelloWorldTask.java @@ -29,8 +29,8 @@ import org.apache.ignite.compute.ComputeTaskName; import org.apache.ignite.compute.ComputeTaskSplitAdapter; import org.jetbrains.annotations.Nullable; -import org.springframework.beans.factory.support.AbstractBeanFactory; -import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.ClassPathResource; /** @@ -43,7 +43,8 @@ public class GarHelloWorldTask extends ComputeTaskSplitAdapter { /** {@inheritDoc} */ @Override public Collection split(int gridSize, String arg) throws IgniteException { // Create Spring context. - AbstractBeanFactory fac = new XmlBeanFactory( + DefaultListableBeanFactory fac = new DefaultListableBeanFactory(); + new XmlBeanDefinitionReader(fac).loadBeanDefinitions( new ClassPathResource("org/apache/ignite/spi/deployment/uri/tasks/gar-spring-bean.xml", getClass().getClassLoader())); fac.setBeanClassLoader(getClass().getClassLoader()); diff --git a/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestTask1.java b/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestTask1.java index d95c411e74c23..1348d7f8066ba 100644 --- a/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestTask1.java +++ b/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestTask1.java @@ -23,7 +23,8 @@ import org.apache.ignite.compute.ComputeJob; import org.apache.ignite.compute.ComputeJobResult; import org.apache.ignite.compute.ComputeTaskSplitAdapter; -import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.ClassPathResource; /** @@ -32,7 +33,9 @@ public class GridUriDeploymentTestTask1 extends ComputeTaskSplitAdapter { /** */ public GridUriDeploymentTestTask1() { - XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring1.xml", getClass().getClassLoader())); + DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); + new XmlBeanDefinitionReader(factory).loadBeanDefinitions( + new ClassPathResource("spring1.xml", getClass().getClassLoader())); factory.setBeanClassLoader(getClass().getClassLoader()); diff --git a/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestTask2.java b/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestTask2.java index 1325efd17aa6e..cf661982b4a0e 100644 --- a/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestTask2.java +++ b/modules/extdata/uri/src/main/java/org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestTask2.java @@ -23,7 +23,8 @@ import org.apache.ignite.compute.ComputeJob; import org.apache.ignite.compute.ComputeJobResult; import org.apache.ignite.compute.ComputeTaskSplitAdapter; -import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.ClassPathResource; /** @@ -35,7 +36,8 @@ public class GridUriDeploymentTestTask2 extends ComputeTaskSplitAdapterhttp://ignite.apache.org + + + + true + + ${project.groupId} @@ -41,9 +47,9 @@ - javax.transaction - jta - 1.1 + jakarta.transaction + jakarta.transaction-api + 2.0.1 diff --git a/modules/jta/src/main/java/org/apache/ignite/cache/jta/CacheTmLookup.java b/modules/jta/src/main/java/org/apache/ignite/cache/jta/CacheTmLookup.java index 7f973848a8417..8a0659e2a9cf0 100644 --- a/modules/jta/src/main/java/org/apache/ignite/cache/jta/CacheTmLookup.java +++ b/modules/jta/src/main/java/org/apache/ignite/cache/jta/CacheTmLookup.java @@ -17,7 +17,7 @@ package org.apache.ignite.cache.jta; -import javax.transaction.TransactionManager; +import jakarta.transaction.TransactionManager; import org.apache.ignite.IgniteException; import org.apache.ignite.configuration.TransactionConfiguration; import org.jetbrains.annotations.Nullable; diff --git a/modules/jta/src/main/java/org/apache/ignite/cache/jta/jndi/CacheJndiTmFactory.java b/modules/jta/src/main/java/org/apache/ignite/cache/jta/jndi/CacheJndiTmFactory.java index 10f3f86c77960..b6c778c7ba641 100644 --- a/modules/jta/src/main/java/org/apache/ignite/cache/jta/jndi/CacheJndiTmFactory.java +++ b/modules/jta/src/main/java/org/apache/ignite/cache/jta/jndi/CacheJndiTmFactory.java @@ -20,10 +20,10 @@ import java.util.Arrays; import java.util.Hashtable; import java.util.Map; +import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; import javax.naming.InitialContext; import javax.naming.NamingException; -import javax.transaction.TransactionManager; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.util.typedef.internal.U; diff --git a/modules/jta/src/main/java/org/apache/ignite/cache/jta/jndi/CacheJndiTmLookup.java b/modules/jta/src/main/java/org/apache/ignite/cache/jta/jndi/CacheJndiTmLookup.java index dfd8b5e3cca65..db01b36d48440 100644 --- a/modules/jta/src/main/java/org/apache/ignite/cache/jta/jndi/CacheJndiTmLookup.java +++ b/modules/jta/src/main/java/org/apache/ignite/cache/jta/jndi/CacheJndiTmLookup.java @@ -18,9 +18,9 @@ package org.apache.ignite.cache.jta.jndi; import java.util.List; +import jakarta.transaction.TransactionManager; import javax.naming.InitialContext; import javax.naming.NamingException; -import javax.transaction.TransactionManager; import org.apache.ignite.IgniteException; import org.apache.ignite.cache.jta.CacheTmLookup; import org.jetbrains.annotations.Nullable; diff --git a/modules/jta/src/main/java/org/apache/ignite/cache/jta/reflect/CacheReflectionTmLookup.java b/modules/jta/src/main/java/org/apache/ignite/cache/jta/reflect/CacheReflectionTmLookup.java index 25b06de220152..96cf03de0d61a 100644 --- a/modules/jta/src/main/java/org/apache/ignite/cache/jta/reflect/CacheReflectionTmLookup.java +++ b/modules/jta/src/main/java/org/apache/ignite/cache/jta/reflect/CacheReflectionTmLookup.java @@ -18,7 +18,7 @@ package org.apache.ignite.cache.jta.reflect; import java.lang.reflect.InvocationTargetException; -import javax.transaction.TransactionManager; +import jakarta.transaction.TransactionManager; import org.apache.ignite.IgniteException; import org.apache.ignite.cache.jta.CacheTmLookup; import org.apache.ignite.internal.util.typedef.internal.A; diff --git a/modules/jta/src/main/java/org/apache/ignite/cache/jta/websphere/WebSphereLibertyTmFactory.java b/modules/jta/src/main/java/org/apache/ignite/cache/jta/websphere/WebSphereLibertyTmFactory.java index aa579ade02f99..581078a97e2a5 100644 --- a/modules/jta/src/main/java/org/apache/ignite/cache/jta/websphere/WebSphereLibertyTmFactory.java +++ b/modules/jta/src/main/java/org/apache/ignite/cache/jta/websphere/WebSphereLibertyTmFactory.java @@ -18,8 +18,8 @@ package org.apache.ignite.cache.jta.websphere; import java.lang.reflect.InvocationTargetException; +import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; -import javax.transaction.TransactionManager; import org.apache.ignite.IgniteException; /** diff --git a/modules/jta/src/main/java/org/apache/ignite/cache/jta/websphere/WebSphereTmFactory.java b/modules/jta/src/main/java/org/apache/ignite/cache/jta/websphere/WebSphereTmFactory.java index 85886df7eed0c..7276e12932fc6 100644 --- a/modules/jta/src/main/java/org/apache/ignite/cache/jta/websphere/WebSphereTmFactory.java +++ b/modules/jta/src/main/java/org/apache/ignite/cache/jta/websphere/WebSphereTmFactory.java @@ -21,16 +21,16 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import jakarta.transaction.HeuristicMixedException; +import jakarta.transaction.HeuristicRollbackException; +import jakarta.transaction.InvalidTransactionException; +import jakarta.transaction.NotSupportedException; +import jakarta.transaction.RollbackException; +import jakarta.transaction.Synchronization; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; -import javax.transaction.HeuristicMixedException; -import javax.transaction.HeuristicRollbackException; -import javax.transaction.InvalidTransactionException; -import javax.transaction.NotSupportedException; -import javax.transaction.RollbackException; -import javax.transaction.Synchronization; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; import org.apache.ignite.IgniteException; diff --git a/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaManager.java b/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaManager.java index b98a7f8b006b4..854773ad259cf 100644 --- a/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaManager.java +++ b/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaManager.java @@ -18,11 +18,11 @@ package org.apache.ignite.internal.processors.cache.jta; import java.util.concurrent.atomic.AtomicReference; +import jakarta.transaction.RollbackException; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; -import javax.transaction.RollbackException; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.jta.CacheTmLookup; import org.apache.ignite.configuration.CacheConfiguration; diff --git a/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaResource.java b/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaResource.java index 5b1b37a15db5f..81edfc40833d4 100644 --- a/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaResource.java +++ b/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaResource.java @@ -18,9 +18,9 @@ package org.apache.ignite.internal.processors.cache.jta; import java.util.concurrent.atomic.AtomicReference; +import jakarta.transaction.Status; +import jakarta.transaction.Synchronization; import javax.cache.CacheException; -import javax.transaction.Status; -import javax.transaction.Synchronization; import javax.transaction.xa.XAException; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/CacheJndiTmFactorySelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/CacheJndiTmFactorySelfTest.java index f3781d4af58e3..8f3ba7014403e 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/CacheJndiTmFactorySelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/CacheJndiTmFactorySelfTest.java @@ -18,16 +18,16 @@ package org.apache.ignite.internal.processors.cache; import java.util.concurrent.Callable; +import jakarta.transaction.HeuristicMixedException; +import jakarta.transaction.HeuristicRollbackException; +import jakarta.transaction.InvalidTransactionException; +import jakarta.transaction.NotSupportedException; +import jakarta.transaction.RollbackException; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; import javax.naming.Context; import javax.naming.InitialContext; -import javax.transaction.HeuristicMixedException; -import javax.transaction.HeuristicRollbackException; -import javax.transaction.InvalidTransactionException; -import javax.transaction.NotSupportedException; -import javax.transaction.RollbackException; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; import org.apache.ignite.IgniteException; import org.apache.ignite.cache.jta.jndi.CacheJndiTmFactory; import org.apache.ignite.testframework.GridTestUtils; diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheJtaConfigurationValidationSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheJtaConfigurationValidationSelfTest.java index db41a0cd4e7e8..c79578918361c 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheJtaConfigurationValidationSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheJtaConfigurationValidationSelfTest.java @@ -18,7 +18,7 @@ package org.apache.ignite.internal.processors.cache; import java.util.concurrent.Callable; -import javax.transaction.TransactionManager; +import jakarta.transaction.TransactionManager; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.jta.CacheTmLookup; import org.apache.ignite.configuration.CacheConfiguration; diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheJtaFactoryConfigValidationSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheJtaFactoryConfigValidationSelfTest.java index ffb08e7da9145..e7617f531bc0c 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheJtaFactoryConfigValidationSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheJtaFactoryConfigValidationSelfTest.java @@ -18,8 +18,8 @@ package org.apache.ignite.internal.processors.cache; import java.util.concurrent.Callable; +import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; -import javax.transaction.TransactionManager; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java index 695e9953298d6..c655cfaebe2c7 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java @@ -17,8 +17,8 @@ package org.apache.ignite.internal.processors.cache; +import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; -import javax.transaction.TransactionManager; import org.apache.ignite.Ignite; import org.apache.ignite.cache.CacheMode; import org.apache.ignite.cache.jta.CacheTmLookup; diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java index e85d196880f75..ecace1bbd0d8b 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java @@ -19,9 +19,9 @@ import java.util.Arrays; import java.util.Collection; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; import org.apache.ignite.IgniteCache; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.TransactionConfiguration; diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java index 8fb9f1e7b6c62..d6e3971dca60a 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java @@ -19,8 +19,8 @@ import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; -import javax.transaction.Status; -import javax.transaction.UserTransaction; +import jakarta.transaction.Status; +import jakarta.transaction.UserTransaction; import org.apache.ignite.IgniteCache; import org.apache.ignite.cache.CacheMode; import org.apache.ignite.configuration.CacheConfiguration; diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaFactorySelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaFactorySelfTest.java index ec9f8e8761def..0324e9bb74236 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaFactorySelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaFactorySelfTest.java @@ -17,8 +17,8 @@ package org.apache.ignite.internal.processors.cache.jta; +import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; -import javax.transaction.TransactionManager; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.TransactionConfiguration; diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaLookupClassNameSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaLookupClassNameSelfTest.java index 573a543318988..979f42c82ff75 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaLookupClassNameSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaLookupClassNameSelfTest.java @@ -18,7 +18,7 @@ package org.apache.ignite.internal.processors.cache.jta; import java.util.concurrent.Callable; -import javax.transaction.TransactionManager; +import jakarta.transaction.TransactionManager; import org.apache.ignite.IgniteException; import org.apache.ignite.cache.CacheAtomicityMode; import org.apache.ignite.cache.jta.CacheTmLookup; diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java index dcb5d1d6e4bf5..6e1948bcf9500 100644 --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java @@ -31,13 +31,13 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.InjectableValues; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.ServletRequest; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.InjectableValues; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.IgniteSystemProperties; diff --git a/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java b/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java index 876e79fc09313..9980bf9598e27 100644 --- a/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java +++ b/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java @@ -21,12 +21,12 @@ import java.lang.reflect.Modifier; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.managers.deployment.GridDeployment; +import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.resources.SpringResource; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.context.ApplicationContext; -import org.springframework.util.StringUtils; /** * Spring bean injector implementation works with resources provided @@ -111,7 +111,7 @@ private Object getBeanByResourceAnnotation(SpringResource annotation) throws Ign String beanName = annotation.resourceName(); Class beanCls = annotation.resourceClass(); - boolean oneParamSet = !StringUtils.isEmpty(beanName) ^ beanCls != SpringResource.DEFAULT.class; + boolean oneParamSet = !F.isEmpty(beanName) ^ beanCls != SpringResource.DEFAULT.class; if (!oneParamSet) { throw new IgniteCheckedException("Either bean name or its class must be specified in @SpringResource, " + @@ -119,7 +119,7 @@ private Object getBeanByResourceAnnotation(SpringResource annotation) throws Ign } try { - return !StringUtils.isEmpty(beanName) ? springCtx.getBean(beanName) : springCtx.getBean(beanCls); + return !F.isEmpty(beanName) ? springCtx.getBean(beanName) : springCtx.getBean(beanCls); } catch (NoUniqueBeanDefinitionException e) { throw e; diff --git a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridResourceProcessorSelfTest.java b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridResourceProcessorSelfTest.java index 828bf600bb5ef..15e9e3240634e 100644 --- a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridResourceProcessorSelfTest.java +++ b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridResourceProcessorSelfTest.java @@ -406,7 +406,7 @@ public void testInjectResourceGridTaskAndJob() throws Exception { try { // Should not be null if task has been completed successfully (meaning all resources have been injected). - Assert.notNull(g.compute().execute(TestTask.class, null)); + Assert.notNull(g.compute().execute(TestTask.class, null), "must not be null"); } finally { stopGrid(); diff --git a/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/GridUriDeploymentSpringDocument.java b/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/GridUriDeploymentSpringDocument.java index 0143537c52258..0a3159013515a 100644 --- a/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/GridUriDeploymentSpringDocument.java +++ b/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/GridUriDeploymentSpringDocument.java @@ -24,7 +24,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.spi.IgniteSpiException; import org.springframework.beans.BeansException; -import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; /** * Helper class which helps to read deployer and tasks information from @@ -32,7 +32,7 @@ */ class GridUriDeploymentSpringDocument { /** Initialized springs beans factory. */ - private final XmlBeanFactory factory; + private final DefaultListableBeanFactory factory; /** List of tasks from package description. */ private List>> tasks; @@ -42,7 +42,7 @@ class GridUriDeploymentSpringDocument { * * @param factory Configuration factory. */ - GridUriDeploymentSpringDocument(XmlBeanFactory factory) { + GridUriDeploymentSpringDocument(DefaultListableBeanFactory factory) { assert factory != null; this.factory = factory; diff --git a/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/GridUriDeploymentSpringParser.java b/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/GridUriDeploymentSpringParser.java index 842a8cf9be07c..f62ce2a146a33 100644 --- a/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/GridUriDeploymentSpringParser.java +++ b/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/GridUriDeploymentSpringParser.java @@ -24,7 +24,8 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.spi.IgniteSpiException; import org.springframework.beans.BeansException; -import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.InputStreamResource; @@ -52,8 +53,8 @@ private GridUriDeploymentSpringParser() { * @param log Logger * @return Grid wrapper for the input stream. * @throws org.apache.ignite.spi.IgniteSpiException Thrown if incoming input stream could not be - * read or parsed by {@code Spring} {@link XmlBeanFactory}. - * @see XmlBeanFactory + * read or parsed by {@code Spring} {@link DefaultListableBeanFactory}. + * @see DefaultListableBeanFactory */ static GridUriDeploymentSpringDocument parseTasksDocument(InputStream in, IgniteLogger log) throws IgniteSpiException { @@ -65,7 +66,8 @@ static GridUriDeploymentSpringDocument parseTasksDocument(InputStream in, Ignite try { U.copy(in, out); - XmlBeanFactory factory = new XmlBeanFactory(new ByteArrayResource(out.toByteArray())); + DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); + new XmlBeanDefinitionReader(factory).loadBeanDefinitions(new ByteArrayResource(out.toByteArray())); return new GridUriDeploymentSpringDocument(factory); } diff --git a/modules/web/ignite-websphere-test/pom.xml b/modules/web/ignite-websphere-test/pom.xml index 84dad0d4b6cff..859531decb414 100644 --- a/modules/web/ignite-websphere-test/pom.xml +++ b/modules/web/ignite-websphere-test/pom.xml @@ -33,6 +33,12 @@ http://ignite.apache.org + + + true + true + + ${project.groupId} @@ -50,6 +56,12 @@ com.ibm.websphere.appserver.api.transaction 1.1.113 + + + jakarta.transaction + jakarta.transaction-api + 2.0.1 + diff --git a/modules/web/ignite-websphere-test/src/main/java/org/apache/ignite/webtest/TestJtaTxServlet.java b/modules/web/ignite-websphere-test/src/main/java/org/apache/ignite/webtest/TestJtaTxServlet.java index e7f33aa3fc31e..c0559a2da0946 100644 --- a/modules/web/ignite-websphere-test/src/main/java/org/apache/ignite/webtest/TestJtaTxServlet.java +++ b/modules/web/ignite-websphere-test/src/main/java/org/apache/ignite/webtest/TestJtaTxServlet.java @@ -19,13 +19,13 @@ import java.io.IOException; import java.io.PrintWriter; -import javax.transaction.RollbackException; -import javax.transaction.TransactionManager; -import com.ibm.tx.jta.TransactionManagerFactory; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import jakarta.transaction.RollbackException; +import jakarta.transaction.TransactionManager; +import com.ibm.tx.jta.TransactionManagerFactory; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.Ignition; diff --git a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java index f4ce1f55a2fe6..c297f5c5c53fe 100644 --- a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java +++ b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java @@ -21,10 +21,6 @@ import java.util.Collection; import java.util.Map; import java.util.Objects; -import javax.cache.CacheException; -import javax.cache.expiry.Duration; -import javax.cache.expiry.ExpiryPolicy; -import javax.cache.expiry.ModifiedExpiryPolicy; import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; import jakarta.servlet.FilterConfig; @@ -35,6 +31,10 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequestWrapper; import jakarta.servlet.http.HttpSession; +import javax.cache.CacheException; +import javax.cache.expiry.Duration; +import javax.cache.expiry.ExpiryPolicy; +import javax.cache.expiry.ModifiedExpiryPolicy; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteClientDisconnectedException; diff --git a/parent/pom.xml b/parent/pom.xml index 864cf9378b8e0..b0f435d3615e6 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -107,7 +107,7 @@ 42.7.3 2.0.17 1.1.10.7 - 5.3.39 + 6.2.19 3.5.6 10.0.27 0.8.3 @@ -683,6 +683,18 @@ [3.9.6,) + + + javax.transaction:jta + javax.transaction:javax.transaction-api + jakarta.transaction:jakarta.transaction-api:(,2.0.0) + + + Use jakarta.transaction:jakarta.transaction-api:2.0.1+ only. + Add <exclusions> to the transitive source if this fails. + + + From f718e04331216de05b6711c284d109033ca973d4 Mon Sep 17 00:00:00 2001 From: Dmitry Werner Date: Tue, 23 Jun 2026 12:33:55 +0500 Subject: [PATCH 2/6] IGNITE-28807 Fix tests in jta after update Spring#2 --- modules/jta/pom.xml | 27 +-- .../cache/GridJtaLifecycleAwareSelfTest.java | 4 +- .../GridJtaTransactionManagerSelfTest.java | 28 +-- .../cache/jta/AbstractCacheJtaSelfTest.java | 27 ++- ...ridPartitionedCacheJtaFactorySelfTest.java | 2 +- ...tionedCacheJtaLookupClassNameSelfTest.java | 2 +- .../cache/jta/TransactionManagerWrapper.java | 220 ++++++++++++++++++ parent/pom.xml | 3 +- 8 files changed, 261 insertions(+), 52 deletions(-) create mode 100644 modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/TransactionManagerWrapper.java diff --git a/modules/jta/pom.xml b/modules/jta/pom.xml index 3c8d1d244d1bd..21909a7f7948a 100644 --- a/modules/jta/pom.xml +++ b/modules/jta/pom.xml @@ -34,12 +34,6 @@ http://ignite.apache.org - - - - true - - ${project.groupId} @@ -59,16 +53,16 @@ - org.ow2.jotm - jotm-core - ${jotm.version} + org.jboss.narayana.jta + narayana-jta + ${narayana.version} test - javax.resource - connector-api - 1.5 + org.jboss.logging + jboss-logging + ${jboss.logging.version} test @@ -106,15 +100,6 @@ test - - - - org.jboss.spec.javax.rmi - jboss-rmi-api_1.0_spec - ${jboss.rmi.version} - test - - diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java index c655cfaebe2c7..9e56daf44efeb 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java @@ -142,8 +142,8 @@ public static class TestTxFactory extends GridAbstractLifecycleAwareSelfTest.Tes /** {@inheritDoc} */ @Test - @Override public void testLifecycleAware() throws Exception { - // No-op, see anothre tests. + @Override public void testLifecycleAware() { + // No-op, see another tests. } /** */ diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java index ecace1bbd0d8b..6d496f1662d2f 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java @@ -22,18 +22,17 @@ import jakarta.transaction.Transaction; import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; + import org.apache.ignite.IgniteCache; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.TransactionConfiguration; +import org.apache.ignite.internal.processors.cache.jta.TransactionManagerWrapper; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.apache.ignite.transactions.TransactionConcurrency; import org.apache.ignite.transactions.TransactionIsolation; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import org.objectweb.jotm.Current; -import org.objectweb.jotm.Jotm; -import org.objectweb.jotm.rmi.RmiLocalConfiguration; import static org.apache.ignite.cache.CacheMode.PARTITIONED; import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC; @@ -45,8 +44,12 @@ */ @RunWith(Parameterized.class) public class GridJtaTransactionManagerSelfTest extends GridCommonAbstractTest { - /** Java Open Transaction Manager facade. */ - private static Jotm jotm; + /** + * Thread-local wrapper so each test thread (OPTIMISTIC/PESSIMISTIC) gets its own TransactionManager and + * doesn't interfere with the other. + */ + private static final ThreadLocal TRANSACTION_MANAGER = + ThreadLocal.withInitial(TransactionManagerWrapper::new); /** * @return Test parameters. @@ -77,18 +80,9 @@ public static Collection parameters() { @Override protected void beforeTestsStarted() throws Exception { super.beforeTestsStarted(); - jotm = new Jotm(true, false, new RmiLocalConfiguration()); - - Current.setAppServer(false); - startGrid(); } - /** {@inheritDoc} */ - @Override protected void afterTestsStopped() throws Exception { - jotm.stop(); - } - /** * Test for switching tx context by JTA Manager. * @@ -102,7 +96,7 @@ public void testJtaTxContextSwitch() throws Exception { cfg.setDefaultTxConcurrency(txConcurrency); cfg.setDefaultTxIsolation(isolation); - TransactionManager jtaTm = jotm.getTransactionManager(); + TransactionManager jtaTm = TRANSACTION_MANAGER.get(); IgniteCache cache = jcache(); @@ -177,7 +171,7 @@ public void testJtaTxContextSwitchWithExistingTx() throws Exception { cfg.setDefaultTxConcurrency(txConcurrency); cfg.setDefaultTxIsolation(isolation); - TransactionManager jtaTm = jotm.getTransactionManager(); + TransactionManager jtaTm = TRANSACTION_MANAGER.get(); IgniteCache cache = jcache(); @@ -231,7 +225,7 @@ static class TestTxManagerFactory implements Factory { /** {@inheritDoc} */ @Override public TransactionManager create() { - return jotm.getTransactionManager(); + return TRANSACTION_MANAGER.get(); } } } diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java index d6e3971dca60a..5b4b69873c883 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java @@ -21,6 +21,8 @@ import java.util.concurrent.CountDownLatch; import jakarta.transaction.Status; import jakarta.transaction.UserTransaction; + +import com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple; import org.apache.ignite.IgniteCache; import org.apache.ignite.cache.CacheMode; import org.apache.ignite.configuration.CacheConfiguration; @@ -30,8 +32,6 @@ import org.apache.ignite.testframework.GridTestSafeThreadFactory; import org.apache.ignite.transactions.Transaction; import org.junit.Test; -import org.objectweb.jotm.Jotm; -import org.objectweb.jotm.rmi.RmiLocalConfiguration; import static org.apache.ignite.cache.CacheMode.PARTITIONED; import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC; @@ -45,12 +45,16 @@ public abstract class AbstractCacheJtaSelfTest extends GridCacheAbstractSelfTest /** */ private static final int GRID_CNT = 1; - /** Java Open Transaction Manager facade. */ - protected static Jotm jotm; + /** Transaction manager. */ + protected static TransactionManagerWrapper txMgr; + + /** User transaction. */ + protected static UserTransaction userTx; /** {@inheritDoc} */ @Override protected void beforeTestsStarted() throws Exception { - jotm = new Jotm(true, false, new RmiLocalConfiguration()); + txMgr = new TransactionManagerWrapper(); + userTx = new UserTransactionImple(); super.beforeTestsStarted(); } @@ -59,7 +63,12 @@ public abstract class AbstractCacheJtaSelfTest extends GridCacheAbstractSelfTest @Override protected void afterTestsStopped() throws Exception { super.afterTestsStopped(); - jotm.stop(); + if (txMgr != null) { + jakarta.transaction.Transaction tx = txMgr.getTransaction(); + + if (tx != null && tx.getStatus() == Status.STATUS_ACTIVE) + txMgr.rollback(); + } } /** {@inheritDoc} */ @@ -101,7 +110,7 @@ public abstract class AbstractCacheJtaSelfTest extends GridCacheAbstractSelfTest */ @Test public void testJta() throws Exception { - UserTransaction jtaTx = jotm.getUserTransaction(); + UserTransaction jtaTx = userTx; IgniteCache cache = jcache(); @@ -145,7 +154,7 @@ public void testJta() throws Exception { */ @Test public void testJtaTwoCaches() throws Exception { - UserTransaction jtaTx = jotm.getUserTransaction(); + UserTransaction jtaTx = userTx; IgniteEx ignite = grid(0); @@ -205,7 +214,7 @@ public void testAsyncOpAwait() throws Exception { @Override public Object call() throws Exception { assertNull(grid(0).transactions().tx()); - UserTransaction jtaTx = jotm.getUserTransaction(); + UserTransaction jtaTx = userTx; jtaTx.begin(); diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaFactorySelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaFactorySelfTest.java index 0324e9bb74236..df090fc0fd097 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaFactorySelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaFactorySelfTest.java @@ -42,7 +42,7 @@ static class TestTxManagerFactory implements Factory { /** {@inheritDoc} */ @Override public TransactionManager create() { - return jotm.getTransactionManager(); + return txMgr; } } } diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaLookupClassNameSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaLookupClassNameSelfTest.java index 979f42c82ff75..09bc63a0d3b3b 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaLookupClassNameSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/GridPartitionedCacheJtaLookupClassNameSelfTest.java @@ -66,7 +66,7 @@ public void testIncompatibleTmLookup() { public static class TestTmLookup implements CacheTmLookup { /** {@inheritDoc} */ @Override public TransactionManager getTm() { - return jotm.getTransactionManager(); + return txMgr; } } diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/TransactionManagerWrapper.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/TransactionManagerWrapper.java new file mode 100644 index 0000000000000..062f1760a7ad3 --- /dev/null +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/TransactionManagerWrapper.java @@ -0,0 +1,220 @@ +/* + * 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.ignite.internal.processors.cache.jta; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import jakarta.transaction.HeuristicMixedException; +import jakarta.transaction.HeuristicRollbackException; +import jakarta.transaction.InvalidTransactionException; +import jakarta.transaction.NotSupportedException; +import jakarta.transaction.RollbackException; +import jakarta.transaction.SystemException; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple; +import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple; +import com.arjuna.ats.internal.jta.xa.TxInfo; + +/** + * Narayana TransactionManager wrapper that simulates JOTM-style suspend/resume. + *

+ * Each wrapper instance has its own state (not shared between parallel tests). + */ +public class TransactionManagerWrapper implements TransactionManager { + /** Narayana transaction manager. */ + private final TransactionManagerImple delegate = new TransactionManagerImple(); + + /** Stores saved XA resources per suspended JTA Transaction (instance). */ + private final Map> txRsrcMap = new ConcurrentHashMap<>(); + + /** Narayana TransactionImple._resources field (Hashtable). */ + private static final Field RESOURCES_FIELD; + + /** Narayana TxInfo._xid field. */ + private static final Field TXINFO_XID_FIELD; + + static { + Field f; + + try { + f = TransactionImple.class.getDeclaredField("_resources"); + + f.setAccessible(true); + } + catch (Exception e) { + throw new RuntimeException("Failed to access Narayana TransactionImple._resources", e); + } + + RESOURCES_FIELD = f; + + try { + f = TxInfo.class.getDeclaredField("_xid"); + + f.setAccessible(true); + } + catch (Exception e) { + throw new RuntimeException("Failed to access Narayana TxInfo._xid", e); + } + + TXINFO_XID_FIELD = f; + } + + /** {@inheritDoc} */ + @Override public void setRollbackOnly() throws IllegalStateException, SecurityException, SystemException { + delegate.setRollbackOnly(); + } + + /** {@inheritDoc} */ + @Override public void setTransactionTimeout(int seconds) throws SystemException { + delegate.setTransactionTimeout(seconds); + } + + /** {@inheritDoc} */ + @Override public int getStatus() throws SystemException { + return delegate.getStatus(); + } + + /** {@inheritDoc} */ + @Override public Transaction getTransaction() throws SystemException { + return delegate.getTransaction(); + } + + /** {@inheritDoc} */ + @Override public void begin() throws NotSupportedException, SystemException { + delegate.begin(); + } + + /** {@inheritDoc} */ + @Override public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, + SecurityException, IllegalStateException, SystemException { + delegate.commit(); + } + + /** {@inheritDoc} */ + @Override public void rollback() throws IllegalStateException, SecurityException, SystemException { + delegate.rollback(); + } + + /** {@inheritDoc} */ + @Override public Transaction suspend() throws SystemException { + Transaction tx = delegate.getTransaction(); + + if (tx instanceof TransactionImple) + saveAndRemoveResources(tx, (TransactionImple)tx); + + return delegate.suspend(); + } + + /** {@inheritDoc} */ + @Override public void resume(Transaction tobj) throws InvalidTransactionException, IllegalStateException, SystemException { + delegate.resume(tobj); + + // Restore XA resources first + Transaction curTx = delegate.getTransaction(); + + if (curTx instanceof TransactionImple) + restoreResourcesAndResume(tobj, (TransactionImple)curTx); + } + + /** Calls end (TMSUSPEND) and removes resources from Narayana's internal map. */ + private void saveAndRemoveResources(Transaction jtaTx, TransactionImple tx) { + List saved = new ArrayList<>(); + + try { + Hashtable resources = (Hashtable)RESOURCES_FIELD.get(tx); + + if (resources != null && !resources.isEmpty()) { + Enumeration resEnum = resources.keys(); + List toRemove = new ArrayList<>(); + + while (resEnum.hasMoreElements()) { + XAResource res = resEnum.nextElement(); + Object txInfo = resources.get(res); + + Xid xid = null; + + if (txInfo != null) { + try { + xid = (Xid)TXINFO_XID_FIELD.get(txInfo); + } + catch (Exception ignored) { + // No-op. + } + } + + saved.add(new ResourceTxInfoPair(res, txInfo, xid)); + toRemove.add(res); + + try { + res.end(xid, XAResource.TMSUSPEND); + } + catch (Exception ignored) { + // No-op. + } + } + + for (XAResource res : toRemove) + resources.remove(res); + } + } + catch (Exception ignored) { + // No-op. + } + + txRsrcMap.put(jtaTx, saved); + } + + /** Restores resources and calls start (TMRESUME). */ + private void restoreResourcesAndResume(Transaction jtaTx, TransactionImple tx) { + List saved = txRsrcMap.remove(jtaTx); + + if (saved == null) + return; + + try { + Hashtable resources = (Hashtable)RESOURCES_FIELD.get(tx); + + for (ResourceTxInfoPair pair : saved) { + if (pair.txInfo != null) + resources.put(pair.res, pair.txInfo); + + try { + pair.res.start(pair.xid, XAResource.TMRESUME); + } + catch (Exception ignored) { + // No-op. + } + } + } + catch (Exception ignored) { + // No-op. + } + } + + /** Simple pair of XAResource, TxInfo and Xid. */ + private record ResourceTxInfoPair(XAResource res, Object txInfo, Xid xid) { } +} diff --git a/parent/pom.xml b/parent/pom.xml index b0f435d3615e6..a1d66ba1fb790 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -83,7 +83,7 @@ 1.0.0_1 1.1.1 1.0.0 - 1.0.6.Final + 3.6.3.Final 26.1.0 11.0.25 5.0.2 @@ -117,6 +117,7 @@ 3.20.0 1.0.0 1.4.17 + 7.3.4.Final 3.12.0 From d10d3ac254063381450b22753fc311b1bc51c71a Mon Sep 17 00:00:00 2001 From: Aleksandr Nikolaev <> Date: Tue, 23 Jun 2026 12:56:40 +0300 Subject: [PATCH 3/6] IGNITE-28765 update Jetty --- .../jetty/rest-jetty-ssl-client-auth.xml | 13 +---- .../test/resources/jetty/rest-jetty-ssl.xml | 17 +------ .../src/test/resources/jetty/rest-jetty.xml | 14 +----- .../test/resources/jetty/router-jetty-ssl.xml | 17 +------ .../src/test/resources/jetty/router-jetty.xml | 14 +----- modules/core/pom.xml | 8 +-- modules/core/src/test/webapp/WEB-INF/web.xml | 8 +-- modules/rest-http/pom.xml | 12 +++-- .../http/jetty/GridJettyRestHandler.java | 16 +++--- .../http/jetty/GridJettyRestProtocol.java | 50 +++++++++---------- .../http/jetty/IgniteRestExtension.java | 2 +- .../protocols/http/jetty/WelcomeHandler.java | 11 ++-- .../http/jetty/IgniteRestExtensionTest.java | 4 +- .../http/GridHttpDeploymentSelfTest.java | 5 +- .../src/main/webapp/WEB-INF/web.xml | 10 ++-- modules/web/ignite-websphere-test/pom.xml | 18 +++---- .../ignite/webtest/TestJtaTxServlet.java | 6 +-- .../src/main/webapp/WEB-INF/web.xml | 10 ++-- modules/web/pom.xml | 12 ++--- .../websession/WebSessionSelfTest.java | 11 ++-- .../websession/WebSessionServerStart.java | 4 +- modules/web/src/test/webapp2/WEB-INF/web.xml | 8 +-- parent/pom.xml | 4 +- 23 files changed, 103 insertions(+), 171 deletions(-) diff --git a/modules/clients/src/test/resources/jetty/rest-jetty-ssl-client-auth.xml b/modules/clients/src/test/resources/jetty/rest-jetty-ssl-client-auth.xml index 00158a85cc226..b95d81dd1ef29 100644 --- a/modules/clients/src/test/resources/jetty/rest-jetty-ssl-client-auth.xml +++ b/modules/clients/src/test/resources/jetty/rest-jetty-ssl-client-auth.xml @@ -19,7 +19,7 @@ - + 5 10 @@ -76,17 +76,6 @@ - - - - - - - - - - - false diff --git a/modules/clients/src/test/resources/jetty/rest-jetty-ssl.xml b/modules/clients/src/test/resources/jetty/rest-jetty-ssl.xml index d84df0d48b3e8..d34d2c9ada2a8 100644 --- a/modules/clients/src/test/resources/jetty/rest-jetty-ssl.xml +++ b/modules/clients/src/test/resources/jetty/rest-jetty-ssl.xml @@ -20,7 +20,7 @@ - + 10 @@ -38,7 +38,7 @@ - + /src/test/keystore/server.jks 123456 123456 @@ -77,18 +77,5 @@ - - - - - - - - - - - - - false diff --git a/modules/clients/src/test/resources/jetty/rest-jetty.xml b/modules/clients/src/test/resources/jetty/rest-jetty.xml index d84bf8ae49c17..c4dcc0f37afe2 100644 --- a/modules/clients/src/test/resources/jetty/rest-jetty.xml +++ b/modules/clients/src/test/resources/jetty/rest-jetty.xml @@ -20,7 +20,7 @@ - + 20 @@ -61,17 +61,5 @@ - - - - - - - - - - - - false diff --git a/modules/clients/src/test/resources/jetty/router-jetty-ssl.xml b/modules/clients/src/test/resources/jetty/router-jetty-ssl.xml index 093fa181535cc..85081526a7d33 100644 --- a/modules/clients/src/test/resources/jetty/router-jetty-ssl.xml +++ b/modules/clients/src/test/resources/jetty/router-jetty-ssl.xml @@ -20,7 +20,7 @@ - + 10 @@ -38,7 +38,7 @@ - + /src/test/keystore/server.jks 123456 123456 @@ -77,18 +77,5 @@ - - - - - - - - - - - - - false diff --git a/modules/clients/src/test/resources/jetty/router-jetty.xml b/modules/clients/src/test/resources/jetty/router-jetty.xml index 8815431069b75..eecb262972c17 100644 --- a/modules/clients/src/test/resources/jetty/router-jetty.xml +++ b/modules/clients/src/test/resources/jetty/router-jetty.xml @@ -20,7 +20,7 @@ - + 20 @@ -61,17 +61,5 @@ - - - - - - - - - - - - false diff --git a/modules/core/pom.xml b/modules/core/pom.xml index 54de1b5d825da..080d157a21104 100644 --- a/modules/core/pom.xml +++ b/modules/core/pom.xml @@ -156,15 +156,15 @@ - org.eclipse.jetty - jetty-servlets + org.eclipse.jetty.ee11 + jetty-ee11-servlets ${jetty.version} test - org.eclipse.jetty - jetty-webapp + org.eclipse.jetty.ee11 + jetty-ee11-webapp ${jetty.version} test diff --git a/modules/core/src/test/webapp/WEB-INF/web.xml b/modules/core/src/test/webapp/WEB-INF/web.xml index e3523c76af007..a1451584cc434 100644 --- a/modules/core/src/test/webapp/WEB-INF/web.xml +++ b/modules/core/src/test/webapp/WEB-INF/web.xml @@ -17,11 +17,11 @@ limitations under the License. --> - + xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee + https://jakarta.ee/xml/ns/jakartaee/web-app_6_1.xsd" + version="6.1"> diff --git a/modules/rest-http/pom.xml b/modules/rest-http/pom.xml index 24610347ac09d..0125e003c89af 100644 --- a/modules/rest-http/pom.xml +++ b/modules/rest-http/pom.xml @@ -82,9 +82,15 @@ ${jetty.version} + + org.eclipse.jetty.ee11 + jetty-ee11-servlet + ${jetty.version} + + org.eclipse.jetty - jetty-servlet + jetty-session ${jetty.version} @@ -95,8 +101,8 @@ - org.eclipse.jetty.toolchain - jetty-jakarta-servlet-api + jakarta.servlet + jakarta.servlet-api ${jetty-jakarta-servlet-api.version} diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java index 6e1948bcf9500..c91ed3ec58762 100644 --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java @@ -33,6 +33,7 @@ import java.util.UUID; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import com.fasterxml.jackson.core.JsonProcessingException; @@ -72,8 +73,6 @@ import org.apache.ignite.lang.IgniteClosure; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.plugin.security.SecurityCredentials; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.AbstractHandler; import org.jetbrains.annotations.Nullable; import static java.lang.String.format; @@ -93,7 +92,7 @@ /** * Jetty REST handler. The following URL format is supported: {@code /ignite?cmd=cmdName¶m1=abc¶m2=123} */ -public class GridJettyRestHandler extends AbstractHandler { +public class GridJettyRestHandler extends HttpServlet { /** */ public static final String IGNITE_CMD_PATH = "/ignite"; @@ -270,16 +269,13 @@ private static int intValue(String key, Map params, int dfltVal) } /** {@inheritDoc} */ - @Override public void handle(String target, Request req, HttpServletRequest srvReq, HttpServletResponse res) { - if (log.isDebugEnabled()) - log.debug("Handling request [target=" + target + ", req=" + req + ", srvReq=" + srvReq + ']'); + @Override protected void service(HttpServletRequest srvReq, HttpServletResponse res) { + String target = srvReq.getRequestURI(); - if (!target.startsWith(IGNITE_CMD_PATH)) - return; + if (log.isDebugEnabled()) + log.debug("Handling request [target=" + target + ", srvReq=" + srvReq + ']'); processRequest(target, srvReq, res); - - req.setHandled(true); } /** diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestProtocol.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestProtocol.java index 2631840cc0b22..5bdad0701d9f7 100644 --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestProtocol.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestProtocol.java @@ -44,20 +44,20 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.spi.IgniteSpiException; +import org.eclipse.jetty.ee11.servlet.FilterHolder; +import org.eclipse.jetty.ee11.servlet.ServletContextHandler; +import org.eclipse.jetty.ee11.servlet.ServletHolder; import org.eclipse.jetty.server.AbstractNetworkConnector; import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.server.handler.HandlerList; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.util.MultiException; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.xml.XmlConfiguration; import org.jetbrains.annotations.Nullable; @@ -238,17 +238,6 @@ private boolean startJetty() throws IgniteCheckedException { catch (Exception e) { boolean failedToBind = e instanceof SocketException; - if (e instanceof MultiException) { - if (log.isDebugEnabled()) - log.debug("Caught multi exception: " + e); - - failedToBind = true; - - for (Object obj : ((MultiException)e).getThrowables()) - if (!(obj instanceof SocketException)) - failedToBind = false; - } - if (e instanceof IOException && X.hasCause(e, SocketException.class)) failedToBind = true; @@ -309,7 +298,7 @@ private void loadJettyConfiguration(@Nullable URL cfgUrl) throws IgniteCheckedEx XmlConfiguration cfg; try { - Resource rsrc = Resource.newResource(cfgUrl); + Resource rsrc = ResourceFactory.root().newResource(cfgUrl.toURI()); cfg = new XmlConfiguration(rsrc); } @@ -336,18 +325,27 @@ private void loadJettyConfiguration(@Nullable URL cfgUrl) throws IgniteCheckedEx assert httpSrv != null; - Handler extsHnd = loadExtensions(); - WelcomeHandler welcomeHnd = new WelcomeHandler(log); + ContextHandlerCollection hnds = new ContextHandlerCollection(); - httpSrv.setHandler(new HandlerList(jettyHnd, extsHnd, welcomeHnd)); + loadExtensions(hnds); + + // Main context serves the REST command endpoint and the welcome page. + // Its root context path ("/") is matched last, after the more specific extension contexts. + ServletContextHandler mainCtx = new ServletContextHandler(ServletContextHandler.NO_SESSIONS); + + mainCtx.setContextPath("/"); + mainCtx.addServlet(new ServletHolder(jettyHnd), IGNITE_CMD_PATH + "/*"); + mainCtx.addServlet(new ServletHolder(new WelcomeHandler(log)), "/"); + + hnds.addHandler(mainCtx); + + httpSrv.setHandler(hnds); override(getJettyConnector()); } - /** */ - private Handler loadExtensions() throws IgniteCheckedException { - HandlerList extsHnd = new HandlerList(); - + /** Discovers REST extensions and registers a dedicated servlet context for each one. */ + private void loadExtensions(ContextHandlerCollection hnds) throws IgniteCheckedException { CommonUtils.loadService(IgniteRestExtension.class).forEach(exts::add); Set paths = new HashSet<>(); @@ -372,13 +370,11 @@ private Handler loadExtensions() throws IgniteCheckedException { A.ensure(!extCtx.isContextPathDefault(), "The context path must be configured: " + ext.getClass().getName()); A.ensure(paths.add(extCtx.getContextPath()), "Duplicate REST context path: " + extCtx.getContextPath()); - extsHnd.addHandler(extCtx); + hnds.addHandler(extCtx); if (log.isInfoEnabled()) log.info("Configured REST extension: " + ext.getClass().getName()); } - - return extsHnd; } /** diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/IgniteRestExtension.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/IgniteRestExtension.java index 275cac62c2274..ee4b749a4f9b2 100644 --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/IgniteRestExtension.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/IgniteRestExtension.java @@ -17,7 +17,7 @@ package org.apache.ignite.internal.processors.rest.protocols.http.jetty; -import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.ee11.servlet.ServletContextHandler; /** * Extension point for registering custom HTTP REST endpoints in the Jetty REST protocol. diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/WelcomeHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/WelcomeHandler.java index 72b162b467ab6..bab9870add8d6 100644 --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/WelcomeHandler.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/WelcomeHandler.java @@ -19,16 +19,15 @@ import java.io.IOException; import java.io.InputStream; +import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.apache.ignite.IgniteLogger; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.AbstractHandler; /** * Handles welcome page. */ -public class WelcomeHandler extends AbstractHandler { +public class WelcomeHandler extends HttpServlet { /** Default page. */ private final byte[] dfltPage; @@ -51,14 +50,15 @@ public WelcomeHandler(IgniteLogger log) { } /** {@inheritDoc} */ - @Override public void handle(String target, Request req, HttpServletRequest srvReq, HttpServletResponse res) throws IOException { + @Override protected void service(HttpServletRequest req, HttpServletResponse res) throws IOException { if (dfltPage == null || favicon == null || logo == null) { res.setStatus(HttpServletResponse.SC_NOT_FOUND); - req.setHandled(true); return; } + String target = req.getRequestURI(); + if (target.startsWith("/favicon.ico")) { res.setContentType("image/x-icon"); res.getOutputStream().write(favicon); @@ -75,7 +75,6 @@ else if (target.startsWith("/logo.svg")) { res.getOutputStream().flush(); res.setStatus(HttpServletResponse.SC_OK); - req.setHandled(true); } /** */ diff --git a/modules/rest-http/src/test/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/IgniteRestExtensionTest.java b/modules/rest-http/src/test/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/IgniteRestExtensionTest.java index c057aa5644362..7ea3a27cda535 100644 --- a/modules/rest-http/src/test/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/IgniteRestExtensionTest.java +++ b/modules/rest-http/src/test/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/IgniteRestExtensionTest.java @@ -29,8 +29,8 @@ import org.apache.ignite.plugin.security.SecurityException; import org.apache.ignite.resources.IgniteInstanceResource; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.ee11.servlet.ServletContextHandler; +import org.eclipse.jetty.ee11.servlet.ServletHolder; import org.junit.Test; import static org.apache.ignite.cluster.ClusterState.INACTIVE; diff --git a/modules/urideploy/src/test/java/org/apache/ignite/spi/deployment/uri/scanners/http/GridHttpDeploymentSelfTest.java b/modules/urideploy/src/test/java/org/apache/ignite/spi/deployment/uri/scanners/http/GridHttpDeploymentSelfTest.java index b366d4fe2fa93..b7d7fb4c7ab06 100644 --- a/modules/urideploy/src/test/java/org/apache/ignite/spi/deployment/uri/scanners/http/GridHttpDeploymentSelfTest.java +++ b/modules/urideploy/src/test/java/org/apache/ignite/spi/deployment/uri/scanners/http/GridHttpDeploymentSelfTest.java @@ -30,6 +30,7 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.ResourceHandler; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.junit.Test; /** @@ -86,7 +87,7 @@ public class GridHttpDeploymentSelfTest extends GridUriDeploymentAbstractSelfTes ResourceHandler hnd = new ResourceHandler(); - hnd.setDirectoriesListed(true); + hnd.setDirAllowed(true); String garPathTmp = GridTestProperties.getProperty("urideployment.path.tmp"); @@ -100,7 +101,7 @@ public class GridHttpDeploymentSelfTest extends GridUriDeploymentAbstractSelfTes rsrcBase = resourseBaseDir.getPath(); - hnd.setResourceBase(rsrcBase); + hnd.setBaseResource(ResourceFactory.root().newResource(rsrcBase)); srv.setHandler(hnd); diff --git a/modules/web/ignite-appserver-test/src/main/webapp/WEB-INF/web.xml b/modules/web/ignite-appserver-test/src/main/webapp/WEB-INF/web.xml index 6fe7358724e75..44b1dd498edb6 100644 --- a/modules/web/ignite-appserver-test/src/main/webapp/WEB-INF/web.xml +++ b/modules/web/ignite-appserver-test/src/main/webapp/WEB-INF/web.xml @@ -15,11 +15,11 @@ ~ limitations under the License. --> - - - + Archetype Created Web Application diff --git a/modules/web/ignite-websphere-test/pom.xml b/modules/web/ignite-websphere-test/pom.xml index 859531decb414..6495420328842 100644 --- a/modules/web/ignite-websphere-test/pom.xml +++ b/modules/web/ignite-websphere-test/pom.xml @@ -33,12 +33,6 @@ http://ignite.apache.org - - - true - true - - ${project.groupId} @@ -49,12 +43,12 @@ ${project.groupId} ignite-jta - - - - com.ibm.websphere.appserver.api - com.ibm.websphere.appserver.api.transaction - 1.1.113 + + + jakarta.transaction + jakarta.transaction-api + + diff --git a/modules/web/ignite-websphere-test/src/main/java/org/apache/ignite/webtest/TestJtaTxServlet.java b/modules/web/ignite-websphere-test/src/main/java/org/apache/ignite/webtest/TestJtaTxServlet.java index c0559a2da0946..f859bfdab58ae 100644 --- a/modules/web/ignite-websphere-test/src/main/java/org/apache/ignite/webtest/TestJtaTxServlet.java +++ b/modules/web/ignite-websphere-test/src/main/java/org/apache/ignite/webtest/TestJtaTxServlet.java @@ -24,8 +24,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.transaction.RollbackException; -import jakarta.transaction.TransactionManager; -import com.ibm.tx.jta.TransactionManagerFactory; +import jakarta.transaction.UserTransaction; +import javax.naming.InitialContext; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.Ignition; @@ -56,7 +56,7 @@ public class TestJtaTxServlet extends HttpServlet { final IgniteCache cache = ignite.cache("tx"); - TransactionManager tmMgr = TransactionManagerFactory.getTransactionManager(); + UserTransaction tmMgr = (UserTransaction)new InitialContext().lookup("java:comp/UserTransaction"); tmMgr.begin(); diff --git a/modules/web/ignite-websphere-test/src/main/webapp/WEB-INF/web.xml b/modules/web/ignite-websphere-test/src/main/webapp/WEB-INF/web.xml index 94cb0cf6b6d3f..c4d24ea9bd316 100644 --- a/modules/web/ignite-websphere-test/src/main/webapp/WEB-INF/web.xml +++ b/modules/web/ignite-websphere-test/src/main/webapp/WEB-INF/web.xml @@ -15,11 +15,11 @@ ~ limitations under the License. --> - - - + Archetype Created Web Application diff --git a/modules/web/pom.xml b/modules/web/pom.xml index d75e7d4542091..26c082bb43df7 100644 --- a/modules/web/pom.xml +++ b/modules/web/pom.xml @@ -47,8 +47,8 @@ - org.eclipse.jetty.toolchain - jetty-jakarta-servlet-api + jakarta.servlet + jakarta.servlet-api ${jetty-jakarta-servlet-api.version} @@ -65,15 +65,15 @@ - org.eclipse.jetty - jetty-servlets + org.eclipse.jetty.ee11 + jetty-ee11-servlets ${jetty.version} test - org.eclipse.jetty - jetty-webapp + org.eclipse.jetty.ee11 + jetty-ee11-webapp ${jetty.version} test diff --git a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java index 45b4ecf838fdf..c5c6e69902d73 100644 --- a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java +++ b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java @@ -57,12 +57,13 @@ import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.eclipse.jetty.ee11.servlet.ServletHolder; +import org.eclipse.jetty.ee11.webapp.WebAppContext; import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.security.Constraint; -import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.jetbrains.annotations.Nullable; import org.junit.Ignore; import org.junit.Test; @@ -998,10 +999,10 @@ private Server startServerWithLoginService( HashLoginService hashLoginSrvc = new HashLoginService(); hashLoginSrvc.setName("Test Realm"); createRealm(); - hashLoginSrvc.setConfig("/tmp/realm.properties"); + hashLoginSrvc.setConfig(ResourceFactory.root().newResource("/tmp/realm.properties")); SecurityHandler securityHnd = ctx.getSecurityHandler(); // DefaultAuthenticatorFactory doesn't default to basic auth anymore. - securityHnd.setAuthMethod(Constraint.__BASIC_AUTH); + securityHnd.setAuthenticator(new BasicAuthenticator()); securityHnd.setLoginService(hashLoginSrvc); srv.setHandler(ctx); diff --git a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionServerStart.java b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionServerStart.java index b620085e09e16..a2d0ca6cd39ac 100644 --- a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionServerStart.java +++ b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionServerStart.java @@ -25,9 +25,9 @@ import jakarta.servlet.http.HttpSession; import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.internal.util.typedef.internal.U; +import org.eclipse.jetty.ee11.servlet.ServletHolder; +import org.eclipse.jetty.ee11.webapp.WebAppContext; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.webapp.WebAppContext; /** * Server starter for web sessions caching test. diff --git a/modules/web/src/test/webapp2/WEB-INF/web.xml b/modules/web/src/test/webapp2/WEB-INF/web.xml index d51b87d27a621..bb1e5ee85d85a 100644 --- a/modules/web/src/test/webapp2/WEB-INF/web.xml +++ b/modules/web/src/test/webapp2/WEB-INF/web.xml @@ -17,11 +17,11 @@ ~ limitations under the License. --> - + xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee + https://jakarta.ee/xml/ns/jakartaee/web-app_6_1.xsd" + version="6.1"> diff --git a/parent/pom.xml b/parent/pom.xml index a1d66ba1fb790..53faff2cec2bb 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -85,8 +85,8 @@ 1.0.0 3.6.3.Final 26.1.0 - 11.0.25 - 5.0.2 + 12.1.10 + 6.1.0 1.37 4.5.2 3.1.15 From 65b2092569dfdd031bd0ef89d78ca6944e935151 Mon Sep 17 00:00:00 2001 From: Aleksandr Nikolaev <> Date: Wed, 8 Jul 2026 22:19:42 +0300 Subject: [PATCH 4/6] IGNITE-28588 minor fix --- .../ignite/internal/processors/rest/GridRestProcessor.java | 2 +- .../processors/cache/GridJtaLifecycleAwareSelfTest.java | 2 +- .../processors/rest/protocols/http/jetty/WelcomeHandler.java | 4 ++-- parent/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java index 0f4f56b855b18..e417ede2f6e99 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java @@ -1019,7 +1019,7 @@ private void startHttpProtocol() throws IgniteCheckedException { } catch (LinkageError e) { U.warn(log, "Failed to initialize HTTP REST protocol (consider adding ignite-rest-http " + - "module and its dependencies to classpath): " + e); + "module and its dependencies to classpath).", e); } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { throw new IgniteCheckedException("Failed to initialize HTTP REST protocol.", e); diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java index 9e56daf44efeb..9a4658e98d5a6 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaLifecycleAwareSelfTest.java @@ -143,7 +143,7 @@ public static class TestTxFactory extends GridAbstractLifecycleAwareSelfTest.Tes /** {@inheritDoc} */ @Test @Override public void testLifecycleAware() { - // No-op, see another tests. + // No-op, see other tests. } /** */ diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/WelcomeHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/WelcomeHandler.java index bab9870add8d6..ed137e252cb64 100644 --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/WelcomeHandler.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/WelcomeHandler.java @@ -59,6 +59,8 @@ public WelcomeHandler(IgniteLogger log) { String target = req.getRequestURI(); + res.setStatus(HttpServletResponse.SC_OK); + if (target.startsWith("/favicon.ico")) { res.setContentType("image/x-icon"); res.getOutputStream().write(favicon); @@ -73,8 +75,6 @@ else if (target.startsWith("/logo.svg")) { } res.getOutputStream().flush(); - - res.setStatus(HttpServletResponse.SC_OK); } /** */ diff --git a/parent/pom.xml b/parent/pom.xml index 53faff2cec2bb..c84d05e9d54ef 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -688,7 +688,7 @@ javax.transaction:jta javax.transaction:javax.transaction-api - jakarta.transaction:jakarta.transaction-api:(,2.0.0) + jakarta.transaction:jakarta.transaction-api:(,2.0.1) Use jakarta.transaction:jakarta.transaction-api:2.0.1+ only. From d50525c34fb47c185fbb50fb5765febd0ac1074d Mon Sep 17 00:00:00 2001 From: Dmitry Werner Date: Thu, 9 Jul 2026 15:46:32 +0500 Subject: [PATCH 5/6] cleanup --- .../GridJtaTransactionManagerSelfTest.java | 42 +++- .../cache/jta/AbstractCacheJtaSelfTest.java | 19 +- .../cache/jta/TransactionManagerWrapper.java | 220 ------------------ 3 files changed, 35 insertions(+), 246 deletions(-) delete mode 100644 modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/TransactionManagerWrapper.java diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java index 6d496f1662d2f..aba7af5fe7c0b 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java @@ -22,14 +22,13 @@ import jakarta.transaction.Transaction; import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; - import org.apache.ignite.IgniteCache; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.TransactionConfiguration; -import org.apache.ignite.internal.processors.cache.jta.TransactionManagerWrapper; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.apache.ignite.transactions.TransactionConcurrency; import org.apache.ignite.transactions.TransactionIsolation; +import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -44,12 +43,8 @@ */ @RunWith(Parameterized.class) public class GridJtaTransactionManagerSelfTest extends GridCommonAbstractTest { - /** - * Thread-local wrapper so each test thread (OPTIMISTIC/PESSIMISTIC) gets its own TransactionManager and - * doesn't interfere with the other. - */ - private static final ThreadLocal TRANSACTION_MANAGER = - ThreadLocal.withInitial(TransactionManagerWrapper::new); + /** Transaction manager. */ + private static TransactionManager txMgr; /** * @return Test parameters. @@ -80,6 +75,8 @@ public static Collection parameters() { @Override protected void beforeTestsStarted() throws Exception { super.beforeTestsStarted(); + txMgr = new TransactionManagerImple(); + startGrid(); } @@ -96,7 +93,7 @@ public void testJtaTxContextSwitch() throws Exception { cfg.setDefaultTxConcurrency(txConcurrency); cfg.setDefaultTxIsolation(isolation); - TransactionManager jtaTm = TRANSACTION_MANAGER.get(); + TransactionManager jtaTm = txMgr; IgniteCache cache = jcache(); @@ -114,8 +111,21 @@ public void testJtaTxContextSwitch() throws Exception { assertEquals(Integer.toString(1), cache.get(1)); + org.apache.ignite.transactions.Transaction igniteTx = grid().transactions().tx(); + jtaTm.suspend(); + // Narayana's TransactionManagerImple.suspend() only detaches the JTA transaction from the + // current thread context without calling XAResource.end(xid, TMSUSPEND) on enlisted + // XA resources. This behavior is fully compliant with the JTA specification: the spec + // defines TransactionManager.suspend() as "suspend the current transaction and return + // it" without requiring end() callbacks on XA resources. + // The previous JTA provider (JOTM) called end(TMSUSPEND) as an implementation detail + // (not because the spec required it), which is why this test worked out of the box + // with JOTM. To compensate for Narayana's spec-compliant behavior, we must explicitly + // suspend the Ignite transaction to detach it from the thread. + igniteTx.suspend(); + assertNull(grid().transactions().tx()); assertNull(cache.get(1)); @@ -142,6 +152,16 @@ public void testJtaTxContextSwitch() throws Exception { jtaTm.resume(tx1); + // Narayana's TransactionManagerImple.resume() only reattaches the JTA transaction to the + // current thread context without calling XAResource.start(xid, TMRESUME) on previously + // enlisted XA resources. This is also fully compliant with the JTA specification: + // TransactionManager.resume() is defined as "resume a previously suspended transaction" + // without requiring start() callbacks on XA resources. + // Similarly to suspend(), JOTM called start(TMRESUME) as an implementation detail, + // not because the spec required it. To compensate for Narayana's behavior, we must + // explicitly resume the Ignite transaction to reattach it to the thread. + igniteTx.resume(); + assertNotNull(grid().transactions().tx()); assertEquals(ACTIVE, grid().transactions().tx().state()); @@ -171,7 +191,7 @@ public void testJtaTxContextSwitchWithExistingTx() throws Exception { cfg.setDefaultTxConcurrency(txConcurrency); cfg.setDefaultTxIsolation(isolation); - TransactionManager jtaTm = TRANSACTION_MANAGER.get(); + TransactionManager jtaTm = txMgr; IgniteCache cache = jcache(); @@ -225,7 +245,7 @@ static class TestTxManagerFactory implements Factory { /** {@inheritDoc} */ @Override public TransactionManager create() { - return TRANSACTION_MANAGER.get(); + return txMgr; } } } diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java index 5b4b69873c883..0a2e9a4b421ff 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/AbstractCacheJtaSelfTest.java @@ -20,8 +20,9 @@ import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import jakarta.transaction.Status; +import jakarta.transaction.TransactionManager; import jakarta.transaction.UserTransaction; - +import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple; import com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple; import org.apache.ignite.IgniteCache; import org.apache.ignite.cache.CacheMode; @@ -46,31 +47,19 @@ public abstract class AbstractCacheJtaSelfTest extends GridCacheAbstractSelfTest private static final int GRID_CNT = 1; /** Transaction manager. */ - protected static TransactionManagerWrapper txMgr; + protected static TransactionManager txMgr; /** User transaction. */ protected static UserTransaction userTx; /** {@inheritDoc} */ @Override protected void beforeTestsStarted() throws Exception { - txMgr = new TransactionManagerWrapper(); + txMgr = new TransactionManagerImple(); userTx = new UserTransactionImple(); super.beforeTestsStarted(); } - /** {@inheritDoc} */ - @Override protected void afterTestsStopped() throws Exception { - super.afterTestsStopped(); - - if (txMgr != null) { - jakarta.transaction.Transaction tx = txMgr.getTransaction(); - - if (tx != null && tx.getStatus() == Status.STATUS_ACTIVE) - txMgr.rollback(); - } - } - /** {@inheritDoc} */ @Override protected int gridCount() { return GRID_CNT; diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/TransactionManagerWrapper.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/TransactionManagerWrapper.java deleted file mode 100644 index 062f1760a7ad3..0000000000000 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/jta/TransactionManagerWrapper.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 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.ignite.internal.processors.cache.jta; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import jakarta.transaction.HeuristicMixedException; -import jakarta.transaction.HeuristicRollbackException; -import jakarta.transaction.InvalidTransactionException; -import jakarta.transaction.NotSupportedException; -import jakarta.transaction.RollbackException; -import jakarta.transaction.SystemException; -import jakarta.transaction.Transaction; -import jakarta.transaction.TransactionManager; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.Xid; - -import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple; -import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple; -import com.arjuna.ats.internal.jta.xa.TxInfo; - -/** - * Narayana TransactionManager wrapper that simulates JOTM-style suspend/resume. - *

- * Each wrapper instance has its own state (not shared between parallel tests). - */ -public class TransactionManagerWrapper implements TransactionManager { - /** Narayana transaction manager. */ - private final TransactionManagerImple delegate = new TransactionManagerImple(); - - /** Stores saved XA resources per suspended JTA Transaction (instance). */ - private final Map> txRsrcMap = new ConcurrentHashMap<>(); - - /** Narayana TransactionImple._resources field (Hashtable). */ - private static final Field RESOURCES_FIELD; - - /** Narayana TxInfo._xid field. */ - private static final Field TXINFO_XID_FIELD; - - static { - Field f; - - try { - f = TransactionImple.class.getDeclaredField("_resources"); - - f.setAccessible(true); - } - catch (Exception e) { - throw new RuntimeException("Failed to access Narayana TransactionImple._resources", e); - } - - RESOURCES_FIELD = f; - - try { - f = TxInfo.class.getDeclaredField("_xid"); - - f.setAccessible(true); - } - catch (Exception e) { - throw new RuntimeException("Failed to access Narayana TxInfo._xid", e); - } - - TXINFO_XID_FIELD = f; - } - - /** {@inheritDoc} */ - @Override public void setRollbackOnly() throws IllegalStateException, SecurityException, SystemException { - delegate.setRollbackOnly(); - } - - /** {@inheritDoc} */ - @Override public void setTransactionTimeout(int seconds) throws SystemException { - delegate.setTransactionTimeout(seconds); - } - - /** {@inheritDoc} */ - @Override public int getStatus() throws SystemException { - return delegate.getStatus(); - } - - /** {@inheritDoc} */ - @Override public Transaction getTransaction() throws SystemException { - return delegate.getTransaction(); - } - - /** {@inheritDoc} */ - @Override public void begin() throws NotSupportedException, SystemException { - delegate.begin(); - } - - /** {@inheritDoc} */ - @Override public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, - SecurityException, IllegalStateException, SystemException { - delegate.commit(); - } - - /** {@inheritDoc} */ - @Override public void rollback() throws IllegalStateException, SecurityException, SystemException { - delegate.rollback(); - } - - /** {@inheritDoc} */ - @Override public Transaction suspend() throws SystemException { - Transaction tx = delegate.getTransaction(); - - if (tx instanceof TransactionImple) - saveAndRemoveResources(tx, (TransactionImple)tx); - - return delegate.suspend(); - } - - /** {@inheritDoc} */ - @Override public void resume(Transaction tobj) throws InvalidTransactionException, IllegalStateException, SystemException { - delegate.resume(tobj); - - // Restore XA resources first - Transaction curTx = delegate.getTransaction(); - - if (curTx instanceof TransactionImple) - restoreResourcesAndResume(tobj, (TransactionImple)curTx); - } - - /** Calls end (TMSUSPEND) and removes resources from Narayana's internal map. */ - private void saveAndRemoveResources(Transaction jtaTx, TransactionImple tx) { - List saved = new ArrayList<>(); - - try { - Hashtable resources = (Hashtable)RESOURCES_FIELD.get(tx); - - if (resources != null && !resources.isEmpty()) { - Enumeration resEnum = resources.keys(); - List toRemove = new ArrayList<>(); - - while (resEnum.hasMoreElements()) { - XAResource res = resEnum.nextElement(); - Object txInfo = resources.get(res); - - Xid xid = null; - - if (txInfo != null) { - try { - xid = (Xid)TXINFO_XID_FIELD.get(txInfo); - } - catch (Exception ignored) { - // No-op. - } - } - - saved.add(new ResourceTxInfoPair(res, txInfo, xid)); - toRemove.add(res); - - try { - res.end(xid, XAResource.TMSUSPEND); - } - catch (Exception ignored) { - // No-op. - } - } - - for (XAResource res : toRemove) - resources.remove(res); - } - } - catch (Exception ignored) { - // No-op. - } - - txRsrcMap.put(jtaTx, saved); - } - - /** Restores resources and calls start (TMRESUME). */ - private void restoreResourcesAndResume(Transaction jtaTx, TransactionImple tx) { - List saved = txRsrcMap.remove(jtaTx); - - if (saved == null) - return; - - try { - Hashtable resources = (Hashtable)RESOURCES_FIELD.get(tx); - - for (ResourceTxInfoPair pair : saved) { - if (pair.txInfo != null) - resources.put(pair.res, pair.txInfo); - - try { - pair.res.start(pair.xid, XAResource.TMRESUME); - } - catch (Exception ignored) { - // No-op. - } - } - } - catch (Exception ignored) { - // No-op. - } - } - - /** Simple pair of XAResource, TxInfo and Xid. */ - private record ResourceTxInfoPair(XAResource res, Object txInfo, Xid xid) { } -} From 8d78bb04ea8c26ca8f4d6039260ba55c2a36b219 Mon Sep 17 00:00:00 2001 From: Aleksandr Nikolaev <> Date: Thu, 9 Jul 2026 14:38:01 +0300 Subject: [PATCH 6/6] IGNITE-28588 fix checkstyle --- .../processors/cache/GridJtaTransactionManagerSelfTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java index aba7af5fe7c0b..cab956e9f0fa4 100644 --- a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java +++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java @@ -22,13 +22,13 @@ import jakarta.transaction.Transaction; import jakarta.transaction.TransactionManager; import javax.cache.configuration.Factory; +import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple; import org.apache.ignite.IgniteCache; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.TransactionConfiguration; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.apache.ignite.transactions.TransactionConcurrency; import org.apache.ignite.transactions.TransactionIsolation; -import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized;