java javax.net.ssl.keystore冲突解决?,为什么java使用JAVA_HOME / lib / security / cacerts的默认位置keystore / trusts...

In my java application I am running with supplied -Djavax.net.ssl.trustStore System properties as below.

-Djavax.net.ssl.trustStore=/myapp/app.jks -Djavax.net.ssl.trustStorePassword=XXXXX -Djavax.net.ssl.trustStoreType=jks -Djavax.net.debug=ssl

This is my Complete command line :

$JAVA_HOME/bin/java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Xms512m -Xmx1024m -XX:MaxPermSize=192m -Djavax.net.ssl.trustStore=/myapp/app.jks -Djavax.net.ssl.keyStore=/myapp/app.jks -Djavax.net.ssl.trustStorePassword=XXXXX -Djavax.net.ssl.keyStorePassword=XXXXX -Dweblogic.security.SSL.ignoreHostnameVerification=true -Djavax.net.debug=ssl -Djavax.net.ssl.trustStoreType=jks -cp /Oracle/Middleware/Oracle_Home/wlserver/server/lib/wlfullclient.jar:/myapp/stand‌​alone/lib/asm-5.0.3.jar:/myapp/standalone/lib/castor-1.3.2-core.jar:/myapp/standa‌​lone/lib/myAPP_final.jar

But java is not using that certificate from custom keyStore from the custom path. It is by default going to $JAVA_HOME/lib/security/cacerts with that I am getting below exception :

java.net.ConnectException: t3s://myapphost.com:7500: Destination 10.243.155.222, 7900 unreachable; nested exception is:

javax.net.ssl.SSLHandshakeException: General SSLEngine problem; No available router to destination

When i am importing and adding same certificate in the $JAVA_HOME/lib/security/cacerts it not giving any Exception.

I have refer and this post and try to configured same things in $JAVA_HOME/jre/lib/security/java.security and added following entry:

javax.net.ssl.trustStore=/myapp/app.jks

javax.net.ssl.trustStorePassword=XXXXX

javax.net.ssl.trustStoreType=jks

Still i am facing same problem.

My Question and problem here is, why java always goes java default keyStore location: $JAVA_HOME/lib/security/cacerts though i have supplied and configured my own custom keyStore using : -Djavax.net.ssl.trustStore=/myapp/app.jks -Djavax.net.ssl.trustStorePassword=XXXXX -Djavax.net.ssl.trustStoreType=jks -Djavax.net.debug=ssl

And if i am importing same certificate in default java keyStore loation it is working fine for me.

where and what all i need to change to configure different keystore to avoid to above exception.

解决方案

After seeing this Post I have configured and supplied following system properties -D option it resolved the problem for me. Hope it will help to others so i am posting it.

-Dweblogic.security.CustomTrustKeyStoreFileName=/myapp/app.jks

-Dweblogic.security.TrustKeyStore=CustomTrust

-Dweblogic.security.CustomTrustKeyStorePassPhrase=XXXXXPWD

-Dweblogic.security.CustomTrustKeyStoreType=jks

I have understood following things which i have kept in Note: of -Dweblogic.security.TrustKeyStore parameter.

Note 1: -**Dweblogic.security.TrustKeyStore** will have following options and internal interpretation

1: `-Dweblogic.security.TrustKeyStore=JavaStandardTrust` (**We should use when the trusted CAs in the JDK's cacerts, specify this**)

2: `-Dweblogic.security.TrustKeyStore=DemoTrust` (**We should use when the trusted CAs in DemoTrust.jks and in the JDK's cacerts, specify this**)

3: `-Dweblogic.security.TrustKeyStore=CustomTrust` (**We should use when the trusted CAs from another keystore, specify this**).

Note 2:

Any time if you got below Exception, it means your java application is not finding certificate in the specified trust-store.

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)

at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)

at sun.security.validator.Validator.validate(Validator.java:260)

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:unable to find valid certification path to requested target,It is telling the same.

Note 3:

Important things try to cogfigured -Djavax.net.debug=ssl for seeing more detail view of logs. Normally without that parameter we wont be able to see more details log.

<think>好的,用户现在遇到了一个问题,他们在容器内部使用服务名称`ocr_service`时出现了`java.net.UnknownHostException: ocr_service`异常,但之前通过`nslookup`确认DNS解析是正常的。需要分析问题原因并提供解决方案。 首先,回顾之前的分析:容器的网络配置正确,`ocr_service`在Docker的自定义网络`zjck-net`中,IP地址为`172.18.0.6`,并且容器内部的DNS服务器是Docker内置的`127.0.0.11`,`nslookup`可以成功解析`ocr_service`到正确的IP。同时,服务在容器内监听`8866`端口,绑定在`0.0.0.0`,说明服务本身配置正确,可以接受外部连接。 现在的问题是,当应用程序尝试通过主机名`ocr_service`进行连接时,却无法解析,导致异常。可能的几个原因需要逐一排查: 1. **DNS解析失败**:虽然`nslookup`可以解析,但应用程序使用的DNS解析方式可能不同。比如,Java应用可能使用了不同的DNS解析机制,或者存在缓存问题。 2. **JVM的DNS缓存**:Java虚拟机可能有DNS缓存,导致即使DNS配置正确,旧的缓存信息仍被使用,从而无法解析新的记录。 3. **应用程序配置问题**:可能在代码中硬编码了某些DNS设置,或者未正确配置使用系统的DNS解析器。 4. **Docker网络配置问题**:虽然网络配置看起来正确,但可能存在其他容器或网络设置导致的问题,如容器不在同一网络,或者DNS服务未正确运行。 **具体分析步骤**: - **检查应用程序的DNS解析机制**:确认应用程序是否使用了与`nslookup`相同的DNS服务器。`nslookup`使用的是系统配置的DNS,而Java应用默认可能使用不同的方式。可以检查Java的DNS设置,或者尝试在代码中强制指定DNS服务器。 - **验证JVM的DNS缓存**:Java默认会缓存DNS解析结果,可以通过设置`networkaddress.cache.ttl`来调整缓存时间,或者禁用缓存,以测试是否是缓存导致的问题。 - **检查容器是否在同一个Docker网络**:确保所有需要通信的容器都连接到同一个自定义网络`zjck-net`,这样Docker的内置DNS才能正确解析服务名称。 - **确认服务名称的正确性**:在代码中使用的服务名称是否与Docker容器名称或服务名称一致,是否存在拼写错误。 - **网络连接测试**:在容器内部使用`ping`或`curl`命令测试连接到`ocr_service`,确认网络层是否可达,而不仅仅是DNS解析正确。 - **检查防火墙或安全组设置**:虽然Docker通常会自动处理网络规则,但有时宿主机或容器内部的防火墙可能会阻止连接,需要确认相关端口是否开放。 **解决方案建议**: 1. **强制使用IPv4**:Java可能优先尝试IPv6解析,而Docker网络可能仅配置了IPv4。可以通过JVM参数`-Djava.net.preferIPv4Stack=true`强制使用IPv4。 2. **调整JVM DNS缓存设置**:在启动JVM时添加参数,如`-Dsun.net.inetaddr.ttl=0`来禁用DNS缓存,或者设置较短的TTL值,以便及时获取最新的DNS记录。 3. **检查容器网络连接**:确保发起请求的容器和`ocr_service`容器都连接到同一个Docker网络`zjck-net`,否则无法通过服务名称解析。 4. **使用Docker内部DNS**:在应用程序中,确保DNS解析使用的是Docker内置的DNS服务器`127.0.0.11`,而非外部DNS服务器。 5. **代码中直接使用IP地址测试**:作为临时解决方案,将`ocr_service`替换为`172.18.0.6`,如果连接成功,则问题确实出在DNS解析上,需进一步排查Java的DNS配置。 6. **查看Java应用的详细错误日志**:确认是否有更详细的错误信息,例如连接超时或其他网络问题,帮助进一步定位问题。 **验证步骤**: - 在应用程序所在的容器内部,运行`ping ocr_service`,确认是否能解析出正确的IP并收到响应。 - 使用`curl http://ocr_service:8866`或类似命令测试HTTP连接,确认服务是否可达。 - 检查Java应用的启动参数,确认是否有自定义的DNS设置或网络配置。 通过以上步骤,可以逐步缩小问题范围,最终找到导致`UnknownHostException`的具体原因,并采取相应的解决措施。</think>以下是针对您遇到的问题的详细分析和解决方案: --- ### **问题诊断** #### **现象描述** - 在容器内部通过`nslookup ocr_service`能正确解析到IP `172.18.0.6` - 服务端口`8866`监听正常(`0.0.0.0:8866`) - 但Java应用程序报错:`java.net.UnknownHostException: ocr_service: 未知的名称或服务` #### **根本原因** 1. **Java DNS解析机制与Docker的兼容性问题** - Java默认优先使用IPv6解析,而Docker自定义网络可能仅配置IPv4地址。 - Java的DNS缓存机制可能导致无法及时更新Docker动态分配的容器IP。 2. **容器间网络配置问题** - 发起请求的容器与`ocr_service`可能不在同一Docker网络(`zjck-net`)。 - 容器未正确使用Docker内置DNS服务器(`127.0.0.11`)。 --- ### **解决方案** #### 方法一:强制Java使用IPv4(推荐) 在Java启动命令中添加以下参数,强制使用IPv4协议: ```bash -Djava.net.preferIPv4Stack=true ``` **示例**: ```bash java -Djava.net.preferIPv4Stack=true -jar your_application.jar ``` #### 方法二:禁用JVM DNS缓存 调整DNS缓存时间,确保实时解析Docker动态IP: ```bash -Dsun.net.inetaddr.ttl=0 # 禁用缓存 -Dsun.net.inetaddr.negative.ttl=0 ``` **示例**: ```bash java -Dsun.net.inetaddr.ttl=0 -Dsun.net.inetaddr.negative.ttl=0 -jar your_application.jar ``` #### 方法三:检查容器网络配置 1. **确认容器在同一网络** 运行以下命令检查所有容器是否连接到`zjck-net`: ```bash docker network inspect zjck-net | grep "Containers" ``` 2. **显式指定容器网络** 启动其他容器时,需明确加入`zjck-net`网络: ```bash docker run --network zjck-net your_image ``` #### 方法四:直接使用容器IP(临时测试) 在代码中暂时将`ocr_service`替换为`172.18.0.6`,验证服务是否可达: ```java String serviceUrl = "http://172.18.0.6:8866"; ``` - 若测试成功,说明问题出在DNS解析环节。 --- ### **验证步骤** 1. **测试容器间连通性** 在发起请求的容器内执行: ```bash ping ocr_service # 应返回IP 172.18.0.6 curl http://ocr_service:8866 # 验证HTTP连接 ``` 2. **检查DNS解析日志** 在Java应用中启用DNS调试日志: ```bash -Djavax.net.debug=all ``` 3. **查看Docker DNS配置** 进入容器检查`/etc/resolv.conf`文件,确认DNS服务器为`127.0.0.11`: ```bash docker exec -it your_container cat /etc/resolv.conf ``` --- ### **配置示意图** ```plaintext Java应用容器 -> Docker DNS (127.0.0.11) -> 解析 ocr_service -> 172.18.0.6:8866 ``` --- ### **附加说明** - **Docker DNS工作原理** Docker为每个自定义网络维护一个内嵌DNS服务器(`127.0.0.11`),容器间通过服务名称通信时,需确保所有容器在同一网络。 - **Java与IPv6的兼容性** 若容器未启用IPv6,需强制Java使用IPv4协议,避免因协议不匹配导致解析失败。 通过上述方法,应能解决`UnknownHostException`问题。若仍不生效,请提供应用程序的完整错误日志及容器网络拓扑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值