137

I am looking on how how to obtain the location of cacerts of the default java installation, when you do not have JAVA_HOME or JRE_HOME defined.

I need a solution that works at least for OS X and Linux.

Yes. java -v is assumed to work :)

sorin
  • 161,544
  • 178
  • 535
  • 806

8 Answers8

226

Under Linux, to find the location of $JAVA_HOME:

readlink -f /usr/bin/java | sed "s:bin/java::"

the cacerts are under lib/security/cacerts:

$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts

Under mac OS X , to find $JAVA_HOME run:

/usr/libexec/java_home

the cacerts are under Home/lib/security/cacerts:

$(/usr/libexec/java_home)/lib/security/cacerts

UPDATE: JDK 8 (or prior)

The code above was tested on a computer with a JRE installed. When using a JDK for Java 8 (or prior), as pR0Ps said, it's at

$(/usr/libexec/java_home)/jre/lib/security/cacerts

For Java 9 and above, both JRE and JDK use $(/usr/libexec/java_home)/lib/security/cacerts.

Community
  • 1
  • 1
Kuf
  • 17,318
  • 6
  • 67
  • 91
  • 9
    In OS X, the "official" way to find JAVA_HOME is running `/usr/libexec/java_home` – Daniel Serodio May 28 '13 at 16:43
  • 3
    @DanielSerodio, agreed. `/usr/libexec/java_home` gives me a different answer from the `readlink`-based command above, and the former seems to be correct, in that it contains the `cacerts` file. – Andrew Ferrier Mar 10 '14 at 15:32
  • 1
    @DanielSerodio and AndrewFerrier thanks guys, answer updated. – Kuf Mar 10 '14 at 15:51
  • 1
    @Kuf My JDK does not have this lib/security folder on Mac Yosemite. I am positive that i am in the right $JAVA_HOME – Brian Feb 03 '16 at 17:54
  • @BrianVanover answer updated. If it doesn't work for you please specify '/usr/libexec/java_home' output and JDK version – Kuf Feb 04 '16 at 21:47
  • 1
    On OSX 10.10.5 the security folder is under: Home/jre/lib/security – Sid Sarasvati Mar 23 '16 at 15:24
  • Your command on my Linux system says No such file or directory as there is no /usr/java/jdk1.8.0_162/lib/security/cacerts. Is the rule different for jre an jdk? – Lee Meador Oct 21 '19 at 16:25
  • I ran this just now on Mojave with Zulu installed via brew (basically the .dmg installer) and it didn't work. I had to remove `jre/` from the path: `$(/usr/libexec/java_home)/lib/security/cacerts` – atwright147 May 07 '20 at 14:12
  • how come the "/usr/libexec/java_home" is different than "echo $JAVA_HOME" ? shouldn't they be the same path? – ennth May 11 '21 at 17:34
  • On MacOS Big Sur this was at `$(/usr/libexec/java_home)/Contents/Home/jre/lib/security/cacerts` – S Raghav Nov 26 '21 at 06:28
  • This doesn't appear to work in Ubuntu – Bob Jul 08 '22 at 04:15
54

As of OS X 10.10.1 (Yosemite), the location of the cacerts file has been changed to

$(/usr/libexec/java_home)/jre/lib/security/cacerts
pR0Ps
  • 2,752
  • 2
  • 23
  • 26
15

If you need to access those certs programmatically it is best to not use the file at all, but access it via the trust manager. The following code is from a OpenJDK Test case (which makes sure the built cacerts collection is not empty):

TrustManagerFactory trustManagerFactory =
    TrustManagerFactory.getInstance("PKIX");
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers =
    trustManagerFactory.getTrustManagers();
X509TrustManager trustManager =
    (X509TrustManager) trustManagers[0];
X509Certificate[] acceptedIssuers =
    trustManager.getAcceptedIssuers();

So you don’t have to deal with file location or keystore password.

eckes
  • 10,103
  • 1
  • 59
  • 71
  • 1
    This is not reading the certificate installed in cacerts. i am able to if using file path and password – Somnath Singh Sep 21 '20 at 14:45
  • Yup @SomnathSingh is correct, this is definitely not reading the root cacerts. I have no idea what this is actually reading though. – Hunter Jackson Jan 29 '21 at 17:51
  • It reads the cacerts file in the same way the JDK implementation is using the default implementation. – eckes Jan 29 '21 at 19:58
  • Nice pointer, but I do not see how above code reveals the *location* of the cacerts file? It accesses the _content_, which is good to know, but does not answer the OP question. Or am I missing something? – mgaert Aug 10 '22 at 09:20
  • Yes the answer reads "not use the file at all" – eckes Aug 10 '22 at 15:21
13

For Java 9 onwards, it's in

${JAVA_HOME}/lib/security/cacerts

as opposed to the usual

${JAVA_HOME}/jre/lib/security/cacerts

jumping_monkey
  • 5,941
  • 2
  • 43
  • 58
12

In MacOS Mojave, the location is:

/Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/jre/lib/security/cacerts 

If using sdkman to manage java versions, the cacerts is in

~/.sdkman/candidates/java/current/jre/lib/security
snugghash
  • 450
  • 3
  • 13
Nish
  • 545
  • 5
  • 7
  • 2
    NOTE: For current versions of sdkman w/ JDK 11, the location is `~/.sdkman/candidates/java/current/lib/security` – Snekse Jan 30 '20 at 20:08
7

In High Sierra, the cacerts is located at : /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/security/cacerts

Azzabi Haythem
  • 2,318
  • 7
  • 26
  • 32
arpurush
  • 79
  • 1
  • 3
3

In Ubuntu 20.04.3 LTS, the cacerts is located at: /etc/ssl/certs/java/cacerts

$ java --version
openjdk 11.0.11 2021-04-20
OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04)
OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing)
$ ls -lah /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts*
/usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -> /etc/ssl/certs/java/cacerts
Felipe Windmoller
  • 1,528
  • 1
  • 12
  • 24
1

You can also consult readlink -f "which java". However it might not work for all binary wrappers. It is most likely better to actually start a Java class.

eckes
  • 10,103
  • 1
  • 59
  • 71