Docker部署ZK+OKHttp3应用抛出NoClassDefFoundError错误求助
Docker部署ZK+OKHttp3应用时
sun.net.NetProperties初始化失败的解决方案 我之前处理过几乎一模一样的问题,这个错误的核心原因是你使用的java:8-jre Docker镜像(基于OpenJDK)和本地大概率用的Oracle JDK在sun系内部API的支持上存在差异,OKHttp初始化ProxySelector时会触发这个类的加载,而容器环境下的OpenJDK要么缺失相关类,要么没有足够权限完成初始化。
下面给你两个可行的解决方案,按优先级推荐:
方案一:添加JVM参数跳过代理自动检测
这个方法不需要更换镜像,能快速验证问题根源。因为错误是在初始化DefaultProxySelector时触发的,我们可以通过JVM参数禁用系统代理自动检测,跳过这部分逻辑:
修改你的Dockerfile的ENTRYPOINT部分:
FROM java:8-jre ADD target/my_file.jar my_file.jar EXPOSE 8080 ENTRYPOINT ["java","-Djava.net.useSystemProxies=false","-jar","my_file.jar"]
重新构建镜像并运行:
mvn clean package docker build -t my_image . sudo docker run -p 8080:8080 my_image
方案二:更换兼容性更好的Java镜像
java:8-jre是比较老旧的OpenJDK镜像,已经被官方标记为废弃,推荐更换为AdoptOpenJDK的镜像,它对Oracle JDK的API兼容性更好,能解决大部分内部类的问题:
修改Dockerfile为:
FROM adoptopenjdk:8-jre-hotspot ADD target/my_file.jar my_file.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","my_file.jar"]
同样重新构建运行即可。
问题根源补充说明
- 本地运行正常:因为你本地的JDK(几乎肯定是Oracle JDK)完整包含了
sun.net包下的内部类,并且有足够权限读取系统配置完成初始化。 - Docker环境出错:
java:8-jre镜像使用的OpenJDK对sun系内部API做了裁剪,同时容器环境下JVM尝试读取系统代理配置时可能遇到权限或配置缺失,导致sun.net.NetProperties类初始化失败,进而触发NoClassDefFoundError。
内容的提问来源于stack exchange,提问作者Nuni Telo
相关产品推荐
相关产品推荐

