GraalVM mongodb-reactive SpringNative,Java能正常运行,但是编译出的可执行文件无法连接到mongo
问题复现
依赖中选用的是:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
增加了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配置大概如下
spring:
data:
mongodb:
host: host
username: username
password: password
database: database
port: 27017
使用Java版进行启动和连接操作数据库都没问题,但是编译成可执行文件后启动便会抛错,错误信息如下:
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
解决办法
在我网上搜了一圈但是都没有找到解决办法,我猜测肯定以前是有人这样已经缝合玩过了,我便去github上搜,还真让我找到一个,把他的代码拉下来,更新一下最新版本的SpringBoot,切换一下SpringBoot连接,什么!他的竟然是可以的,我检查了一下他的配置和我的配置区别,才发现人家根本没增加什么MongoConfig,直接在application.properties中写了连接的url
这里我对他的代码做了一下更改,然后重新推到了github,地址:https://github.com/MingGH/spring-native-demo 你可以直接拉下来尝试配置启动
spring.data.mongodb.uri=mongodb://localhost:27017/blog
logging.level.root=INFO
logging.level.org.springframework.aot=TRACE
于是我便删除了我的MongoConfig, 在application.yaml中配置
spring:
data:
mongodb:
uri: mongodb://localhost:27017/blog
再进行编译,没想到还真的可以了。。。猜测是SpringNative对自动装配做了兼容,能把参数正确注入,但是使用MongoConfig的形式便不行