I am attempting to run and test a Spring Boot application that I have packaged into a zip file and unpacked on a Linux VM. The zip contains everything the application needs (at least to my knowledge). When I attempt to execute the application, it starts but quickly fails because it cannot load a keystore needed for SSH/TLS secure communications.
I have the following in my application.yml:
server:
port: 8091
ssl:
enabled: true
protocol: TLS
trust-store-type: JKS
trust-store: classpath:keystore/server.keystore
trust-store-password: <hidden>
key-store-type: JKS
key-store: classpath:keystore/ra/server.keystore
key-store-password: <hidden>
The directory structure on the test system is as follows:
[centos@route-assessor route-assessor]$ ls -R
.:
config elastic-apm-agent-1.10.0.jar lib run-route-assessor.sh services-0.0.1-SNAPSHOT.jar
./config:
application.yml keystore log4j2.xml
./config/keystore:
mp ra rg server.keystore
./config/keystore/mp:
server.keystore
./config/keystore/ra:
server.keystore
./config/keystore/rg:
server.keystore
./lib
<dependency jars>
Here is the exception thrown:
[2019-10-23 13:21:31.419] main WARN : context.AnnotationConfigServletWebServerApplicationContext:557 - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Could not load key store 'classpath:keystore/server.keystore'
The Spring Boot “runtime” obviously sees and accesses the config
directory, but doesn’t seem to see the keystore
directory contained within. Do I need to specify the paths differently in application.yml or do I need to put the keystore files somewhere else?
Note: I can run this application with the application.yml configured as shown from eclipse without any problem. Granted, all resources are located in src/main/resources
for that situation.
UPDATE:
As per @borban’s suggestion, I modified the application.yml as follows:
key-store: file:config/keystore/ra/server.keystore
trust-store: file:config/keystore/server.keystore
That seems to have solved one problem, but I’m not out of the woods yet:
[2019-10-23 15:07:17.671] main ERROR: boot.SpringApplication:821 - Application run failed
org.springframework.boot.web.server.WebServerException: Unable to start embedded Jetty server
...
Caused by: java.lang.IllegalStateException: no valid keystore
...
As far as I know, my keystore files are valid and correct (I’ve been using them on my Windows development box for months). They are copied over as part of the zip distribution. Is there something maybe I’m missing?
I’m also a little concerned with a few other messages in the log. I’m not sure if they’re related, but it seems that they could be:
[2019-10-23 15:07:10.153] main WARN : resource.Resource:126 - java.lang.IllegalArgumentException: URI is not hierarchical
[2019-10-23 15:07:10.155] main WARN : resource.Resource:126 - java.lang.IllegalArgumentException: URI is not hierarchical
I don’t recall seeing them before.
2
Answers
Are you are trying to access this keystore outside of the classpath and from the filesystem itself? From the folder structure you are giving, that seems to be the case. If you remove the “classpath” prefix and then update your path appropriately, it should work.
From this post, it looks like you have to prefix with “file”
https://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html
You can use maven resource plugin to add the folders you need to the plugin:
https://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html
then use without classpath??