Spring Boot集成PulsarClient遇DNS TTL访问权限错误求助
问题描述
使用Java 20、Spring Boot 3.1.0、Pulsar 3.0.0组合初始化PulsarClient时,出现模块访问权限错误,具体信息如下:
依赖版本配置:
<properties> <java.version>20</java.version> <pulsar.version>3.0.0</pulsar.version> <spring.boot.version>3.1.0</spring.boot.version> </properties>
初始化PulsarClient的配置类代码:
@Configuration public class PulsarConfiguration { @Bean public PulsarClient pulsarClient() throws PulsarClientException { return PulsarClient.builder().serviceUrl("pulsar://localhost:6650").build(); } }
抛出的错误日志:
Cannot get DNS TTL settings from sun.net.InetAddressCachePolicy class java.lang.IllegalAccessException: class org.apache.pulsar.common.util.netty.DnsResolverUtil cannot access class sun.net.InetAddressCachePolicy (in module java.base) because module java.base does not export sun.net to unnamed module @6069db50 at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:394) ~[na:na] at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:709) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na] at org.apache.pulsar.common.util.netty.DnsResolverUtil.<clinit>(DnsResolverUtil.java:46) ~[pulsar-client-3.0.0.jar:3.0.0] at org.apache.pulsar.client.impl.ConnectionPool.createAddressResolver(ConnectionPool.java:159) ~[pulsar-client-3.0.0.jar:3.0.0] at org.apache.pulsar.client.impl.ConnectionPool.lambda$new$1(ConnectionPool.java:126) ~[pulsar-client-3.0.0.jar:3.0.0] at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na] at org.apache.pulsar.client.impl.ConnectionPool.<init>(ConnectionPool.java:126) ~[pulsar-client-3.0.0.jar:3.0.0] at org.apache.pulsar.client.impl.ConnectionPool.<init>(ConnectionPool.java:95) ~[pulsar-client-3.0.0.jar:3.0.0] at org.apache.pulsar.client.impl.ConnectionPool.<init>(ConnectionPool.java:90) ~[pulsar-client-3.0.0.jar:3.0.0] at org.apache.pulsar.client.impl.PulsarClientImpl.<init>(PulsarClientImpl.java:196) ~[pulsar-client-3.0.0.jar:3.0.0] at org.apache.pulsar.client.impl.PulsarClientImpl.<init>(PulsarClientImpl.java:153) ~[pulsar-client-3.0.0.jar:3.0.0] at org.apache.pulsar.client.impl.ClientBuilderImpl.build(ClientBuilderImpl.java:63) ~[pulsar-client-3.0.0.jar:3.0.0] at in.silentsudo.springbootmongodbdatagenerator.PulsarConfiguration.pulsarClient(PulsarConfiguration.java:16) ~[classes/:na]
拒绝降级方案,寻求其他解决途径。
解决方案
方案1:添加JVM参数开放模块访问权限
启动应用时加入以下JVM参数,允许Pulsar客户端访问Java基础模块中的sun.net包:
--add-exports java.base/sun.net=ALL-UNNAMED
- 若使用Maven插件启动,在
pom.xml的spring-boot-maven-plugin中配置:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <jvmArguments>--add-exports java.base/sun.net=ALL-UNNAMED</jvmArguments> </configuration> </plugin>
- 若使用IDEA启动,直接在Run/Debug配置的VM options中添加该参数。
方案2:升级Pulsar版本至3.1.0及以上
该问题已在Pulsar 3.1.0版本中修复,修改pom.xml中的Pulsar版本即可:
<properties> <java.version>20</java.version> <pulsar.version>3.1.0</pulsar.version> <spring.boot.version>3.1.0</spring.boot.version> </properties>
升级后无需额外配置,客户端会自动使用兼容Java模块系统的DNS缓存策略获取方式。
方案3:自定义DNS解析器(进阶)
通过PulsarClientBuilder指定自定义DNS解析器,绕过默认的DNS处理逻辑:
import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Collections; import org.apache.pulsar.client.api.DnsResolver; import org.apache.pulsar.client.api.PulsarClient; import org.apache.pulsar.client.api.PulsarClientException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class PulsarConfiguration { @Bean public PulsarClient pulsarClient() throws PulsarClientException { return PulsarClient.builder() .serviceUrl("pulsar://localhost:6650") .dnsResolver((DnsResolver) host -> { try { return Collections.singletonList(InetAddress.getByName(host)); } catch (UnknownHostException e) { throw new RuntimeException(e); } }) .build(); } }
这种方式需要自行实现DNS解析逻辑,适合有特殊DNS需求的场景。
内容的提问来源于stack exchange,提问作者silentsudo
相关产品推荐
相关产品推荐

