I've been trying to troubleshoot a Netty connection exception when my Spring application is attempting to connect to a MongoDb TestContainer. If needed I can push the project to github (it's a sample project from udemy, the teacher of the course is using maven, but I prefer gradle so I inadvertently got myself in hot water), but here are the relevant test classes that are being used below. Before getting into the classes, I will mention that with a docker-compose.yaml, I'm able to have my application connect to the defined mongo service with no issue, but for some reason with the test container setup, I'm not able to. I have ensured to include the port mapping for the "spring.data.mongodb.uri".
The build.gradle:
plugins {
java
id("org.springframework.boot") version "3.4.1"
id("io.spring.dependency-management") version "1.1.7"
}
group = "com.omri"
version = "0.0.1-SNAPSHOT"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")
implementation("org.springframework.boot:spring-boot-starter-webflux")
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation("org.testcontainers:testcontainers:1.20.4")
testImplementation("org.testcontainers:junit-jupiter")
}
dependencyManagement {
imports {
mavenBom("org.testcontainers:testcontainers-bom:1.20.4")
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
The test base class where the mongodb container is defined and started:
public abstract class BaseTest {
private static final int MONGO_PORT = 27017;
private static final String INIT_JS = "/docker-entrypoint-initdb.d/init.js";
private static final String MONGO_URI_FORMAT = "mongodb://job_user:job_password@%s:%s/job";
@Container
protected static final GenericContainer<?> mongo = new GenericContainer<>(DockerImageName.parse("mongo"))
.withExposedPorts(MONGO_PORT)
.withClasspathResourceMapping("data/job-init.js", INIT_JS, BindMode.READ_ONLY)
.waitingFor(Wait.forListeningPort());
@DynamicPropertySource
static void mongoProperties(DynamicPropertyRegistry registry) {
mongo.start();
registry.add("spring.data.mongodb.uri", () -> String.format(MONGO_URI_FORMAT, mongo.getHost(), mongo.getFirstMappedPort()));
}
}
The test class itself (not much here currently):
@SpringBootTest
@AutoConfigureWebTestClient
class JobServiceIT extends BaseTest {
@Autowired
private WebTestClient webClient;
@Autowired
private Environment env;
@Test
public void allJobsTest() {
System.out.println(env.getProperty("spring.data.mongodb.uri"));
/*webClient.get().uri("/jobs/all").exchange()
.expectStatus()
.is2xxSuccessful()
.expectBody().jsonPath("$").isNotEmpty();*/
}
}
This is the exception that I am seeing:
com.mongodb.MongoSocketWriteException: Exception sending message
at com.mongodb.internal.connection.InternalStreamConnection.throwTranslatedWriteException(InternalStreamConnection.java:790) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendMessage(InternalStreamConnection.java:675) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.trySendMessage(InternalStreamConnection.java:507) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendCommandMessage(InternalStreamConnection.java:482) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceiveInternal(InternalStreamConnection.java:440) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.lambda$sendAndReceive$0(InternalStreamConnection.java:375) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:378) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:100) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:49) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:144) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.startHandshake(InternalStreamConnectionInitializer.java:79) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:235) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.2.1.jar:na]
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.2.1.jar:na]
Caused by: io.netty.channel.StacklessClosedChannelException: null
at io.netty.channel.AbstractChannel$AbstractUnsafe.write(Object, ChannelPromise)(Unknown Source) ~[netty-transport-4.1.116.Final.jar:4.1.116.Final]```
The exception was a red herring. I misspelled the "job/all" GET request as "jobs/all".
If anyone found this post with a similar error, I found this thread to be useful: https://github.com/testcontainers/testcontainers-java/issues/4695