Skip to main content

GraalVM mongodb-reactive SpringNative: Java Runs Fine but Compiled Executable Can't Connect to MongoDB

Problem Reproduction

The dependency used is:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>

Added MongoConfig:

import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.gridfs.ReactiveGridFsTemplate;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;

@Configuration
@EnableReactiveMongoRepositories("run.runnable.xxx.repository")
public class MongoConfig extends AbstractReactiveMongoConfiguration {

@Value("${spring.data.mongodb.host}")
String host;

@Value("${spring.data.mongodb.port}")
String port;

@Value("${spring.data.mongodb.username}")
String username;

@Value("${spring.data.mongodb.password}")
String password;

@Value("${spring.data.mongodb.database}")
String database;

@Override
protected String getDatabaseName() {
return database;
}

@Override
public MongoClient reactiveMongoClient() {
String uri =
return MongoClients.create(uri);
}

@Bean
public ReactiveGridFsTemplate reactiveGridFsTemplate(MappingMongoConverter mappingMongoConverter) {
return new ReactiveGridFsTemplate(reactiveMongoDbFactory(), mappingMongoConverter, "attachments");
}

private MongoClient mongoClient;
@Autowired
public void setMongoClient(MongoClient mongoClient) {
this.mongoClient = mongoClient;
}

@Bean
public ReactiveMongoTemplate reactiveMongoTemplate() {
return new ReactiveMongoTemplate(mongoClient, getDatabaseName());
}
}

YAML configuration roughly as follows:

spring:
data:
mongodb:
host: host
username: username
password: password
database: database
port: 27017

Starting and connecting to the database with the Java version works fine, but after compiling to an executable, it throws an error on startup. The error message is:

Caused by: com.mongodb.MongoCommandException: Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server host. The full response is {"ok": 0.0, "errmsg": "Authentication failed.", "code": 18, "codeName": "AuthenticationFailed"}
at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:205) ~[na:na]
at com.mongodb.internal.connection.InternalStreamConnection.lambda$sendCommandMessageAsync$0(InternalStreamConnection.java:539) ~[na:na]
... 36 common frames omitted

Solution

After searching online without finding a solution, I guessed someone must have done this combination before. So I searched on GitHub and actually found one. I pulled down their code, updated to the latest SpringBoot version, switched the SpringBoot connection, and what! Theirs actually worked. I checked the difference between their configuration and mine, and found they didn't add any MongoConfig at all - they just wrote the connection URL directly in application.properties.

I made some changes to their code and pushed it back to GitHub. Address: https://github.com/MingGH/spring-native-demo You can pull it down directly and try configuring and starting it.

spring.data.mongodb.uri=mongodb://localhost:27017/blog
logging.level.root=INFO
logging.level.org.springframework.aot=TRACE

So I deleted my MongoConfig and configured in application.yaml:

spring:
data:
mongodb:
uri: mongodb://localhost:27017/blog

Compiled again, and it actually worked... I suspect SpringNative has made compatibility for auto-configuration, correctly injecting parameters, but using the MongoConfig form doesn't work.