使用 DNS 记录(SRV 和 TXT)时,无法在 Spring 上下文中实例化 Mongo 相关 bean
Posted
技术标签:
【中文标题】使用 DNS 记录(SRV 和 TXT)时,无法在 Spring 上下文中实例化 Mongo 相关 bean【英文标题】:Unable to instantiate Mongo related beans in Spring context when DNS records (SRV and TXT) are being used 【发布时间】:2021-12-27 07:34:38 【问题描述】:我在没有任何 Mongo bean 实例化问题的情况下使用 Java 8 和 Spring Data MongoDb Reactive 的 Java maven 项目。目前,我正在尝试将同一个项目从 Java 8 项目升级到 Java 11 (jvm 11.0.8+10-LTS)。我更新的 Spring Boot 版本是 2.5.6,带有 Jetty 服务器(9.4.44.v20210927),对应的 Mongo 响应式版本是基于 2.5.6。当 Spring 尝试创建与 mongo 相关的 bean 以将它们添加到上下文中时,会出现以下错误:
Unable to support mongodb+srv// style connections as the ‘com.sun.jndi.dns.DnsContextFactory’ "
+ "class is not available in this JRE. A JNDI context is required for resolving SRV records
我尝试过以下方法:
添加设置属性的 jndi.properties 文件
java.naming.provider.url=dns:.
在 maven 编译器插件中添加 -exports 参数
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
<compilerArgs>
<arg>--add-exports</arg>
<arg>jdk.naming.dns/com.sun.jndi.dns=java.naming</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
升级到兼容 java 11 的最新 jetty server 版本
<jetty.version>9.4.44.v20210927</jetty.version>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>$jetty.version</version>
<scope>provided</scope>
</dependency>
你能告诉我一个解决方案吗?
【问题讨论】:
【参考方案1】:我认为您实际上不必添加--add-exports
。如果您查看 Mongodb Java 驱动程序代码,您会发现它已经添加了dns:
这是一个 PR https://github.com/mongodb/mongo-java-driver/pull/554
这可能与 JVM 有关,但很难证明这一点。您可以使用 OpenJDK 11 在 docker 容器上运行它并查看吗?还是不同的版本?
/*
It's unfortunate that we take a runtime dependency on com.sun.jndi.dns.DnsContextFactory.
This is not guaranteed to work on all JVMs but in practice is expected to work on most.
*/
private static InitialDirContext createDnsDirContext()
Hashtable<String, String> envProps = new Hashtable<String, String>();
envProps.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
envProps.put(Context.PROVIDER_URL, "dns:");
try
return new InitialDirContext(envProps);
catch (NamingException e)
throw new MongoClientException("Unable to support mongodb+srv// style connections as the 'com.sun.jndi.dns.DnsContextFactory' "
+ "class is not available in this JRE. A JNDI context is required for resolving SRV records.", e);
https://github.com/mongodb/mongo-java-driver/blob/master/driver-core/src/main/com/mongodb/internal/dns/DefaultDnsResolver.java
【讨论】:
我尝试使用 URI 的 DNS 样式表示法创建一个具有相同 Java 版本 (11) 和 mongo 依赖项的小项目,它可以正常工作。问题可能出在依赖项或其他地方。 @SocketM 最后,您可以为响应式 mongo 添加最新的驱动程序,看看是否能解决您的问题...否则,如果没有,则不要使用 SRV。https://mvnrepository.com/artifact/org.mongodb/mongodb-driver-reactivestreams/4.4.0
我试过了。我使用了 spring boot 最新版本,它还汇集了最新版本的 mongo db reactive。通常我使用 srv 表示法,因为我可以使用 DNS 服务器,并且我从 txt 中提取了一些配置。缺点是我必须对包括生产在内的所有主机和端口进行硬编码,而不是使用 DNS。以上是关于使用 DNS 记录(SRV 和 TXT)时,无法在 Spring 上下文中实例化 Mongo 相关 bean的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Strophe JS 获取 DNS SRV 记录?