Spring Java app not finding the keystore file

spring boot keystore location
spring boot load keystore from file
spring boot load keystore from file location
spring boot keystore yml
spring boot resource keystore
spring boot disable ssl
spring boot both http and https
jks file not found java

I am trying to set up a simple Spring application to use SSL and host it on Digital Ocean. Why is my app not finding the keystore file?

The droplet I've set up is based on Ubuntu 18.04. I used Letsencrypt to get a certificate and this guide to generate a PKCS file. I've set up my application.properties file to look in the jar file's current directory like so:

security.require-ssl:true
server.ssl.key-store:keystore.p12
server.ssl.key-store-password:<password>
server.ssl.key-store-type:PKCS12
server.ssl.key-alias:<alias>

I would expect this to run and start a web server on the configured port. However, what I get in the stack trace is this:

Caused by: java.io.FileNotFoundException: /root/software/gimmememe/target/keystore.p12  (No such file or directory)

Weirdly enough when I run the same jar with the same keystore.p12 file on my own Windows machine it runs fine:

o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 9123 (https) with context path ''
meme.Application                         : Started Application in 4.985 seconds (JVM running for 5.464)

I don't think it's a permissions issue on the Ubuntu machine as I tried setting the permissions on the keystore file like so:

-rw-r--r-- 1 root root     4274 Mar 26 18:44 keystore.p12

I am running my jar file with the following command (tried with sudo infront as well):

java -jar gimme-meme-1.0.0.war

Spring loads the file from the classpath, which allows, so you should prefix the path with that classpath:, e.g.

server.ssl.key-store : classpath:keystore.p12

Or if you use the = symbol as a key/value delimiter:

server.ssl.key-store = classpath:keystore.p12

Bear in mind that the value is only trimmed on the left side, so you can not have any trailing whitespace after the value.

Why is my Java app not finding the keystore file?, 问题: I am trying to set up a simple Spring application to use SSL and host it on Digital Ocean. Why is my app not finding the keystore file? Most likely, you need to tell Spring Boot that the file is in the jar. For example, if you keep the file at src/main/resources, gradle & maven will place that file at the root of the classpath. To convey this information to the spring boot app, you'll want to tell it the file is on the classpath. That means you need to set server.ssl.key-store to classpath:keystore.p12, so that Spring knows it needs to load the keystore from within the archive's classpath.

I had exactly the same issues and could resolve it. I stored the keystore file in src/main/resources/keystore.p12, but in the jar file it was under classes/ directly. My solution was:

server.ssl.key-store=classpath:keystore.p12   

Can't find the location of file keystore when running as jar � Issue , And I find that tomcat can't read the keystore conatined in a jar. java.io. FileNotFoundException: class path resource [xx.jks] cannot be resolved The . jks file would not find as a classpath resource so I resolved it by replacing in src /main/resources parallel to application.properties then why spring throws� The Kafka client requires the keystore to be on the file system (it doesn't understand class path resources, and it can't read files in the jar). KeyStore load () { try (FileInputStream in = new FileInputStream (path)) { It works with mvn spring-boot:run because maven runs the exploded project, not the jar.

It looks like your app is just looking in the current directory for the keystore.p12 file, as indicated by:

Caused by: java.io.FileNotFoundException: /root/software/gimmememe/target/keystore.p12 (No such file or directory)

Most likely, you need to tell Spring Boot that the file is in the jar.

For example, if you keep the file at src/main/resources, gradle & maven will place that file at the root of the classpath. To convey this information to the spring boot app, you'll want to tell it the file is on the classpath.

That means you need to set server.ssl.key-store to classpath:keystore.p12, so that Spring knows it needs to load the keystore from within the archive's classpath.

-- EDIT --

Here's an example of someone having a similar problem that illustrates this fix.

Github Issue of Similar Problem

Why am I not able to start a Java application with SSL?, I am trying to set up a simple Spring application to use SSL and host it on Digital Ocean. Why is my app not finding the keystore file The droplet� Starting with Spring Boot 1.2, you can configure SSL using application.properties or application.yml.Here's an example for application.properties:. server.port = 8443 server.ssl.key-store = classpath:keystore.jks server.ssl.key-store-password = secret server.ssl.key-password = another-secret

How to enable HTTPS in a Spring Boot Java application, How to enable HTTPS in a Spring Boot Java application The first thing to do is placing the keystore file inside the Spring Boot project. If you want to find out which properties are available to configure SSL, you can refer our browser won 't trust our application and will warn the user that it's not secure. I am using springBootVersion 1.2.0.RELEASE.I'm trying to have my keystore and truststore configured through application.properties.. When I add the following settings, I can get the keystore to work, but not the truststore.

How To Enable HTTPS In Spring Boot Application, Spring Boot provides a configurable and programmatic way to enable HTTPS The two most common formats used for keystores are JKS, specific for Java, and PKCS12, notNull(ssl, "Ssl configuration should not be null"); Let's open our application.properties file (or application.yml) and define the following properties: server.port=8443 server.ssl.key-store-type=PKCS12 server.ssl.key-store=classpath:keystore.p12 server.ssl.key-store-password=password server.ssl.key-alias=tomcat security.require-ssl=true application.properties (Spring Boot 1)

Spring Boot - Enabling HTTPS, Spring Boot - Enabling HTTPS - By default, Spring Boot application uses HTTP 8080 To create a self-signed certificate, Java Run Time environment comes This code will generate a PKCS12 keystore file named as keystore.p12 and the� $ keytool -export -alias ftpKey -file certfile.cer -keystore privateKey.store Enter keystore password: foobar Certificate stored in file <certfile.cer> As you can see, you don't have to do too much there, but you must know the password for your private key keystore (the privateKey.store file).

Comments
  • Your tomcat is running as root? In the target directory.
  • I am only using the embedded tomcat within Spring. I am not sure if that's exactly how it works but I'm just running the jar from the command line. Also I will not be running as root when this is all set up.
  • There is no such thing as 'the JAR file's curremt directory'. There is the current working directory, and the directory where the JAR file is located, and they aren't necessarily the same thing, especially in a WEB container.
  • Sorry for the confusion then. I mean the directory where the JAR is located and that's where I also place the keystore.p12 file
  • So then you have to name it completely, because that's not where the container is looking. You only provided the filename, so it looks in its current working directory, and you can see what that is from the error message. So, err, put it there.
  • It appears that on the Ubuntu machine Spring was not cleaning trailing whitespace.
  • 'In the JAR file's current directory' does not mean 'in the JAR file'.
  • Thanks for the suggestion. I tried putting the keystore.p12 file in src/main/resources and it is indeed included in the output jar. I added classpath: in front of the file name too and I got the following error: FileNotFoundException: class path resource [keystore.p12 ] cannot be resolved to URL because it does not exist I believe this has to be an environment issue given that it runs fine on my Windows machine.
  • @MZokov, if you try running the same java -jar command from your windows machine, with the file in the jar, does it work? If we can get that to work, then it should port to wherever you deploy the application. Another option is to just copy the .p12 file to wherever you are deploying the app and place it right next to the running jar. I personally prefer bundling it in so that the jar is portable and can work anywhere.
  • Also, if you're running the project as a war, src/main/resources might not actually end up on the root of the classpath - you might need to put it at src/main/resources/WEB-INF, I'm not sure if it needs to be further nested, but wars are treated differently than pure spring boot jars.
  • I am actually getting the same error on my Windows machine. FileNotFoundException: class path resource [keystore.p12 ] cannot be resolved to URL because it does not exist . I will try a regular jar instead of a war as well. I'm not sure I need it to necessarily be a war.