Skip to content

Commit 23197c3

Browse files
committed
Merge branch '2.4.x' into 2.5.x
Closes gh-28606
2 parents 5ba3a68 + c018788 commit 23197c3

File tree

5 files changed

+135
-1
lines changed

5 files changed

+135
-1
lines changed

spring-boot-project/spring-boot-autoconfigure/build.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ dependencies {
7373
optional("org.aspectj:aspectjweaver")
7474
optional("org.eclipse.jetty:jetty-webapp")
7575
optional("org.eclipse.jetty:jetty-reactive-httpclient")
76-
optional("org.eclipse.jetty.websocket:javax-websocket-server-impl")
76+
optional("org.eclipse.jetty.websocket:javax-websocket-server-impl") {
77+
exclude(group: "org.eclipse.jetty", module: "jetty-jndi")
78+
}
7779
optional("org.ehcache:ehcache")
7880
optional("org.elasticsearch.client:elasticsearch-rest-client")
7981
optional("org.elasticsearch.client:elasticsearch-rest-client-sniffer")
@@ -153,6 +155,7 @@ dependencies {
153155
testImplementation("ch.qos.logback:logback-classic")
154156
testImplementation("commons-fileupload:commons-fileupload")
155157
testImplementation("com.atomikos:transactions-jms")
158+
testImplementation("com.github.h-thurow:simple-jndi")
156159
testImplementation("com.ibm.db2:jcc")
157160
testImplementation("com.jayway.jsonpath:json-path")
158161
testImplementation("com.squareup.okhttp3:mockwebserver")

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@
1818

1919
import java.io.File;
2020
import java.nio.file.Path;
21+
import java.util.Arrays;
22+
import java.util.List;
23+
import java.util.Properties;
2124

2225
import javax.jms.ConnectionFactory;
2326
import javax.jms.TemporaryQueue;
2427
import javax.jms.XAConnection;
2528
import javax.jms.XAConnectionFactory;
2629
import javax.jms.XASession;
30+
import javax.naming.Context;
31+
import javax.naming.InitialContext;
32+
import javax.naming.NamingException;
2733
import javax.sql.DataSource;
2834
import javax.sql.XADataSource;
2935
import javax.transaction.UserTransaction;
@@ -34,7 +40,19 @@
3440
import com.atomikos.jms.AtomikosConnectionFactoryBean;
3541
import org.junit.jupiter.api.AfterEach;
3642
import org.junit.jupiter.api.Test;
43+
import org.junit.jupiter.api.extension.AfterEachCallback;
44+
import org.junit.jupiter.api.extension.BeforeEachCallback;
45+
import org.junit.jupiter.api.extension.ExtendWith;
46+
import org.junit.jupiter.api.extension.ExtensionContext;
47+
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
48+
import org.junit.jupiter.api.extension.ParameterContext;
49+
import org.junit.jupiter.api.extension.ParameterResolutionException;
50+
import org.junit.jupiter.api.extension.ParameterResolver;
3751
import org.junit.jupiter.api.io.TempDir;
52+
import org.junit.jupiter.params.ParameterizedTest;
53+
import org.junit.jupiter.params.provider.Arguments;
54+
import org.junit.jupiter.params.provider.MethodSource;
55+
import org.osjava.sj.loader.JndiLoader;
3856

3957
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
4058
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
@@ -49,6 +67,7 @@
4967
import org.springframework.context.annotation.Bean;
5068
import org.springframework.context.annotation.Configuration;
5169
import org.springframework.transaction.jta.JtaTransactionManager;
70+
import org.springframework.transaction.jta.UserTransactionAdapter;
5271

5372
import static org.assertj.core.api.Assertions.assertThat;
5473
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -76,6 +95,31 @@ void closeContext() {
7695
if (this.context != null) {
7796
this.context.close();
7897
}
98+
99+
}
100+
101+
@ParameterizedTest
102+
@ExtendWith(JndiExtension.class)
103+
@MethodSource("transactionManagerJndiEntries")
104+
void transactionManagerFromJndi(JndiEntry jndiEntry, InitialContext initialContext) throws NamingException {
105+
jndiEntry.register(initialContext);
106+
this.context = new AnnotationConfigApplicationContext(JtaAutoConfiguration.class);
107+
JtaTransactionManager transactionManager = this.context.getBean(JtaTransactionManager.class);
108+
if (jndiEntry.value instanceof UserTransaction) {
109+
assertThat(transactionManager.getUserTransaction()).isEqualTo(jndiEntry.value);
110+
assertThat(transactionManager.getTransactionManager()).isNull();
111+
}
112+
else {
113+
assertThat(transactionManager.getUserTransaction()).isInstanceOf(UserTransactionAdapter.class);
114+
assertThat(transactionManager.getTransactionManager()).isEqualTo(jndiEntry.value);
115+
}
116+
}
117+
118+
static List<Arguments> transactionManagerJndiEntries() {
119+
return Arrays.asList(Arguments.of(new JndiEntry("java:comp/UserTransaction", UserTransaction.class)),
120+
Arguments.of(new JndiEntry("java:appserver/TransactionManager", TransactionManager.class)),
121+
Arguments.of(new JndiEntry("java:pm/TransactionManager", TransactionManager.class)),
122+
Arguments.of(new JndiEntry("java:/TransactionManager", TransactionManager.class)));
79123
}
80124

81125
@Test
@@ -199,4 +243,79 @@ DataSource pooledDataSource(XADataSourceWrapper wrapper) throws Exception {
199243

200244
}
201245

246+
private static final class JndiEntry {
247+
248+
private final String name;
249+
250+
private final Class<?> type;
251+
252+
private final Object value;
253+
254+
private JndiEntry(String name, Class<?> type) {
255+
this.name = name;
256+
this.type = type;
257+
this.value = mock(type);
258+
}
259+
260+
private void register(InitialContext initialContext) throws NamingException {
261+
String[] components = this.name.split("/");
262+
String subcontextName = components[0];
263+
String entryName = components[1];
264+
Context javaComp = initialContext.createSubcontext(subcontextName);
265+
JndiLoader loader = new JndiLoader(initialContext.getEnvironment());
266+
Properties properties = new Properties();
267+
properties.setProperty(entryName + "/type", this.type.getName());
268+
properties.put(entryName + "/valueToConvert", this.value);
269+
loader.load(properties, javaComp);
270+
}
271+
272+
@Override
273+
public String toString() {
274+
return this.name;
275+
}
276+
277+
}
278+
279+
private static final class JndiExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver {
280+
281+
@Override
282+
public void beforeEach(ExtensionContext context) throws Exception {
283+
Namespace namespace = Namespace.create(getClass(), context.getUniqueId());
284+
context.getStore(namespace).getOrComputeIfAbsent(InitialContext.class, (k) -> createInitialContext(),
285+
InitialContext.class);
286+
}
287+
288+
private InitialContext createInitialContext() {
289+
try {
290+
return new InitialContext();
291+
}
292+
catch (Exception ex) {
293+
throw new RuntimeException();
294+
}
295+
}
296+
297+
@Override
298+
public void afterEach(ExtensionContext context) throws Exception {
299+
Namespace namespace = Namespace.create(getClass(), context.getUniqueId());
300+
InitialContext initialContext = context.getStore(namespace).remove(InitialContext.class,
301+
InitialContext.class);
302+
initialContext.removeFromEnvironment("org.osjava.sj.jndi.ignoreClose");
303+
initialContext.close();
304+
}
305+
306+
@Override
307+
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
308+
throws ParameterResolutionException {
309+
return InitialContext.class.isAssignableFrom(parameterContext.getParameter().getType());
310+
}
311+
312+
@Override
313+
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
314+
throws ParameterResolutionException {
315+
Namespace namespace = Namespace.create(getClass(), extensionContext.getUniqueId());
316+
return extensionContext.getStore(namespace).get(InitialContext.class);
317+
}
318+
319+
}
320+
202321
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
java.naming.factory.initial = org.osjava.sj.SimpleJndiContextFactory
2+
org.osjava.sj.delimiter = /
3+
org.osjava.sj.jndi.shared = true
4+
org.osjava.sj.root = src/test/resources/simple-jndi
5+
org.osjava.sj.jndi.ignoreClose = true

spring-boot-project/spring-boot-autoconfigure/src/test/resources/simple-jndi

Whitespace-only changes.

spring-boot-project/spring-boot-parent/build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ bom {
126126
]
127127
}
128128
}
129+
library("Simple JNDI", "0.23.0") {
130+
group("com.github.h-thurow") {
131+
modules = [
132+
"simple-jndi"
133+
]
134+
}
135+
}
129136
library("Sisu", "2.6.0") {
130137
group("org.sonatype.sisu") {
131138
modules = [

0 commit comments

Comments
 (0)