Recently, fellow Opensource.com scribe James Farrell wrote a wonderful article entitled How Ansible brought peace to my home. In addition to the great article, I really liked the title, one of those unexpected phrases that I’m sure brought a smile to many faces.
I recently had a weird but positive experience of my own that begs a similar sort of unexpected label. I’ve been grappling with a difficult problem that arose when upgrading some server and networking infrastructure that broke a Java application I’ve been supporting since the early 2000s. Strangely enough, I found the solution in what appears to be a very informative and excellent article on Kubernetes, of all things.
Without further ado, here is my problem:
I’m guessing that most readers will look at that message and think things like, "I hope there’s more info in the log file," or "I’m really glad I’ve never received a message like that."
Unfortunately, there isn’t a lot of info in the log file, just the same message, in fact. In an effort to debug this, I did three things:
I searched online for the message. Interestingly, or perhaps ominously, there were only 200 or so hits on this string, one of which suggested turning on more debugging output, which involved adding the setting
to the java command running the application.
I tried that suggestion, which resulted in a lot of output (good), most of which only vaguely made sense to me as I’m no kind of expert in the underlying bits of stuff like SSL. But one thing I did notice is that there was no information regarding a response from the server in the midst of all of that output;
So I searched some more.
Another interesting part of this problem is that the code ran fine when executed by the Java command bundled in the OpenJDK, but failed with this error when using a customized runtime created from the same OpenJDK in this way. So the relatively modest number of apparently similar problems turned up from search #1 above were actually not all that relevant since they all seemed to be dealing mostly with bad SSL certificates on the server in conjunction with the PostgreSQL JDBC’s ability to check the server’s credentials.
More on Kubernetes
- What is Kubernetes?
- eBook: Storage Patterns for Kubernetes
- Test drive OpenShift hands-on
- eBook: Getting started with Kubernetes
- An introduction to enterprise Kubernetes
- How to explain Kubernetes in plain terms
- eBook: Running Kubernetes on your Raspberry Pi homelab
- Kubernetes cheat sheet
- eBook: A guide to Kubernetes for SREs and sysadmins
- Latest Kubernetes articles
I should also mention that it took me quite some time to realize that the problem was introduced by using the custom Java runtime, as I managed to check many other possibilities along the way (and indeed, I did fix a few minor bugs while I was at it). My efforts included things like getting the latest OpenJDK, checking and re-checking all the URLs in case one had a typo, and so forth.
As often happens, after putting the problem aside for a few hours, an idea occurred to me—perhaps I was missing some module in the customized Java runtime. While I didn’t receive any errors directly suggesting that problem, the observable fact that the standard OpenJDK environment worked while the custom one failed seemed to hint at that possibility. I took a quick look in the jmods/ folder in the OpenJDK installation, but there are some 70 modules there and nothing jumped out at me.
But again, what seemed odd was, with debugging turned on (see #1 above), there was no indication of what the server would accept, just what the client mostly couldn’t offer, many lines like this:
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
So I was at least thinking by this time that maybe what was missing was the module that offered those kinds of cipher suites. So I started searching with strings like "jdbc crypto," and in the midst of that, the most unlikely article showed up: Optimizing Kubernetes Services—Part 2: Spring Web, written by Juan Medina. Midway down the article, I spotted the following:
Huh! Imagine that, his script is creating a custom Java runtime, just like mine. But he says he needs to add in manually the module jdk.crypto.ec in order to connect via SSL to his PostgreSQL environment. Sure sounded familiar.
In fact, this was the solution to my problem as well; the missing module was jdk.crypto.ec, and I was able to add it into my build as follows:
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
(I’m cross-building a Windows Java runtime here; see my earlier article on this topic for more info).
This was a big bullet to dodge for someone like me who doesn’t know much about crypto. And once again, open source, and more than that, the willingness to share that goes with open source, is huge. And wow, using Kubernetes to fix a Java desktop application, that’s pretty huge too! Thanks again to Juan Medina!