Skip to content

Commit ff03cc3

Browse files
committed
Fix IllegalAccessException in MongoDbAtlasLocalContainerConnectionDetails.getSslBundle()
The original fix in commit 03d475e introduced a MethodHandles.unreflectSpecial() approach to resolve a StackOverflowError, but this caused IllegalAccessException due to incorrect usage of unreflectSpecial() for interface default methods. The unreflectSpecial() method is designed for superclass method calls, not interface default methods, and requires private access which caused: "IllegalAccessException: no private access for invokespecial: interface org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails" This fix replaces the complex reflection approach with simple interface delegation using 'MongoConnectionDetails.super.getSslBundle()'. This solution: - Eliminates IllegalAccessException by properly overriding with public access - Avoids StackOverflowError by delegating to interface default method - Removes all reflection code, making it simpler and more maintainable - Works across all Spring Boot versions without version-specific checks - Resolves access privilege conflict between interface and parent class The interface default method returns null, which is the desired behavior for SSL configuration when no custom SSL bundle is provided. Fixes: https://github.com/spring-projects/spring-ai/actions/runs/16981113833 Signed-off-by: Mark Pollack <[email protected]>
1 parent 8caffe8 commit ff03cc3

File tree

1 file changed

+3
-24
lines changed

1 file changed

+3
-24
lines changed

spring-ai-spring-boot-testcontainers/src/main/java/org/springframework/ai/testcontainers/service/connection/mongo/MongoDbAtlasLocalContainerConnectionDetailsFactory.java

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,13 @@
1616

1717
package org.springframework.ai.testcontainers.service.connection.mongo;
1818

19-
import java.lang.invoke.MethodHandles;
20-
import java.lang.reflect.Method;
21-
2219
import com.mongodb.ConnectionString;
2320
import org.testcontainers.mongodb.MongoDBAtlasLocalContainer;
2421

2522
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
2623
import org.springframework.boot.ssl.SslBundle;
2724
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
2825
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
29-
import org.springframework.util.ReflectionUtils;
3026

3127
/**
3228
* A {@link ContainerConnectionDetailsFactory} implementation that provides
@@ -51,12 +47,6 @@
5147
class MongoDbAtlasLocalContainerConnectionDetailsFactory
5248
extends ContainerConnectionDetailsFactory<MongoDBAtlasLocalContainer, MongoConnectionDetails> {
5349

54-
private static final Method GET_SSL_BUNDLE_METHOD;
55-
56-
static {
57-
GET_SSL_BUNDLE_METHOD = ReflectionUtils.findMethod(MongoConnectionDetails.class, "getSslBundle");
58-
}
59-
6050
@Override
6151
protected MongoConnectionDetails getContainerConnectionDetails(
6252
ContainerConnectionSource<MongoDBAtlasLocalContainer> source) {
@@ -79,21 +69,10 @@ public ConnectionString getConnectionString() {
7969
return new ConnectionString(getContainer().getConnectionString());
8070
}
8171

82-
// Conditional implementation based on whether the method exists
72+
@Override
8373
public SslBundle getSslBundle() {
84-
if (GET_SSL_BUNDLE_METHOD != null) { // Boot 3.5.x+
85-
try {
86-
return (SslBundle) MethodHandles.lookup()
87-
.in(GET_SSL_BUNDLE_METHOD.getDeclaringClass())
88-
.unreflectSpecial(GET_SSL_BUNDLE_METHOD, GET_SSL_BUNDLE_METHOD.getDeclaringClass())
89-
.bindTo(this)
90-
.invokeWithArguments();
91-
}
92-
catch (Throwable e) {
93-
throw new RuntimeException(e);
94-
}
95-
}
96-
return null; // Boot 3.4.x (No-Op)
74+
// Delegate to the interface default method by calling it explicitly
75+
return MongoConnectionDetails.super.getSslBundle();
9776
}
9877

9978
}

0 commit comments

Comments
 (0)