最近,Opensource.com的同事James Farrell写了一篇精彩的文章,题为Ansible如何为我的家带来和平。除了这篇文章很棒之外,我真的很喜欢这个标题,这是一个意想不到的短语,我相信它给很多人带来了微笑。
我最近也有一个奇怪但积极的经历,它要求有一个类似的意想不到的标签。我一直在努力解决一个难题,这个问题是在升级一些服务器和网络基础设施时出现的,这些基础设施破坏了一个自2000年代初以来我一直在支持的Java应用程序。奇怪的是,我在一篇关于Kubernetes的非常有信息量和优秀的文章中找到了解决方案,真是出乎意料。
事不宜迟,这就是我的问题

我猜大多数读者看到这条消息会想到这样的话,“我希望日志文件中能有更多信息”,或者“我真的很高兴我从未收到过这样的消息。”
不幸的是,日志文件中没有太多信息,实际上只是相同的消息。 为了调试这个问题,我做了三件事
-
我在网上搜索了这条消息。有趣的是,或者说是不祥的是,只有200个左右的结果包含这个字符串,其中一个建议打开更多的调试输出,这涉及到添加设置
-Djavax.net.debug=ssl:handshake:verbose
到运行该应用程序的 **java** 命令。
-
我尝试了那个建议,结果产生了很多输出(很好),但由于我不是SSL等底层东西的专家,所以大多数输出对我来说都只是隐约有意义。但我确实注意到的一件事是,在所有这些输出中,没有关于服务器响应的信息;
-
所以我搜索了更多。
这个问题的另一个有趣之处是,当由OpenJDK中捆绑的Java命令执行时,代码运行良好,但是当使用以这种方式从同一OpenJDK创建的自定义运行时时,则会报错。因此,从上面第#1次搜索中出现的相对较少的类似问题实际上并不那么相关,因为它们似乎主要处理的是服务器上的错误SSL证书以及PostgreSQL JDBC检查服务器凭据的能力。
我还应该提到,我花了相当长的时间才意识到这个问题是由使用自定义Java运行时引起的,因为我设法检查了沿途的许多其他可能性(而且,我确实在同时修复了一些小错误)。我的努力包括获取最新的OpenJDK,检查和重新检查所有URL以防有错别字等等。
通常情况是,在将问题搁置几个小时后,我产生了一个想法——也许我的自定义Java运行时缺少一些模块。虽然我没有收到任何直接提示该问题的错误,但标准OpenJDK环境有效而自定义环境失败这一可观察的事实似乎暗示了这种可能性。我快速浏览了OpenJDK安装中的 **jmods/** 文件夹,但是那里有大约70个模块,没有任何模块跳出来。
但同样,似乎奇怪的是,在打开调试(参见上面的#1)的情况下,没有迹象表明服务器会接受什么,只是客户端主要不能提供什么,很多行像这样
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
所以至少这个时候我在想,也许缺少的是提供这些密码套件的模块。所以我开始搜索诸如“jdbc crypto”之类的字符串,在搜索过程中,最不可能的文章出现了:优化Kubernetes服务 - 第2部分:Spring Web,由Juan Medina撰写。在文章的中途,我发现了以下内容

哈!想象一下,他的脚本正在创建一个自定义Java运行时,就像我的。 但是他说他需要手动添加模块 **jdk.crypto.ec** 才能通过SSL连接到他的PostgreSQL环境。 听起来很熟悉。
事实上,这也是我问题的解决方案; 缺少的模块是 **jdk.crypto.ec**,我可以按如下方式将其添加到我的构建中
DEPS=$(JAVA_HOME)/bin/jdeps --print-module-deps $(TEST_HOME)/MyApp.jar \ $(TEST_HOME)/lib/*.jar,jdk.crypto.ec;
$(JAVA_HOME)/bin/jlink --module-path $(W64_JAVA_HOME)/jmods
–no-header-files --no-man-pages --compress=2 –strip-debug
–add-modules $$DEPS --output $(TEST_HOME)/java-runtime
(我在这里交叉编译Windows Java运行时;有关更多信息,请参阅我之前关于此主题的文章)。
结论
对于像我这样对密码学知之甚少的人来说,这是一个很大的进步。再次强调,开源,以及伴随开源的乐于分享的精神,都是非常重要的。哇,使用 Kubernetes 来修复 Java 桌面应用程序,这也很厉害!再次感谢 Juan Medina!
6 条评论