Search code examples
javassljava-11java-http-client

Is it possible to build a Java 11 HttpClient that uses SSL/TLS JAVA_OPTS as its SSLContext?


I know with Apache's HttpClientBuilder you can call useSystemProperties() and it will create a client with an SSLContext configured from the javax.net.ssl.keyStore (and truststore) if passed as JAVA_OPTS:

try (CloseableHttpClient client = HttpClientBuilder.create().useSystemProperties.build()) {
  // If javax.net.ssl props are set, make requests that require client auth
  // Otherwise make regular requests
}

I want to do something similar with the Java 11 HttpClient. The reason for this is in my use-case, I am treating key stores and trust stores as optional and it would be nice to not have to check their existence in my code. Basically, I want to set an SSLContext based on JAVA_OPTS if they exist; otherwise just use the "Default" context.


Solution

  • TLDR: you don't need to do anything

    New java.net.http.HttpClient, like older HttpsURLConnection and also plain SSL[Server]Socket and other things, defaults to SSLContext.getDefault() which by default uses the system properties javax.net.ssl.{key,trust}Store* -- reading them only once, the first time it is referenced in a given JVM; any settings made after that (necessarily by code) are ignored.

    The initial values of these system properties (like others input to the JVM, rather than automatically set like java.version) can be set by the -D option on the command line or in the _JAVA_OPTIONS environment variable; both of these can also be used to set other system properties that have nothing to do with SSL/TLS and other options that are not system properties. Java itself does not use env var JAVA_OPTS, but some things that run Java as a subordinate (like service monitors, IDEs, toolchains, etc, etc) may use (the contents of) that env var as part of the created command line.

    Note if you don't specify the sysprops, the truststore defaults to JRE/lib/security/cacerts (which is normally supplied with 'standard' public CAs like Verisign/Symantec/Digicert, GoDaddy, etc) but the keystore has no default, i.e. no client authentication is done.