I use Spring Boot 1.4.0. And I find that tomcat can't read the keystore conatined in a jar. But how can I load the keystore in a jar.

The configuration about SSL:

server:
  port: 8443
  ssl:
    enabled: true
    key-store: classpath:keystore.jks
    key-store-password: pass
    key-alias: pass
    #protocol: TSL
    enabled-protocols: TLSv1,TLSv1.1,TLSv1.2

The Exception:

java.io.FileNotFoundException: class path resource [xx.jks] cannot be resolved to absolute file path because it does not reside in the file system:jar:file:/C:/xx/xx/xx/xx/xx/target/xx-1.0-SNAPSHOT.jar!/xx.jks

Comment From: wilkinsona

This works fine in our Tomcat SSL sample. Please try with the latest 1.4.x release (1.4.6.RELEASE) and, if that doesn't help, please provide a small sample that reproduces the problem.

Comment From: momo159

it works fine in IntelliJ IDEA. If I build it as a jar and run this jar, it will show this Exception

Comment From: wilkinsona

it works fine in IntelliJ IDEA. If I build it as a jar and run this jar. It will show this Exception

I already understood that from your original description when you said it can't read the keystore from a jar file. As I said above, it works fine in our sample so we're going to need to see a sample from you that reproduces the problem.

Comment From: momo159

Thanks. I fixed it by your samples.

Comment From: GursharanKhalsa

@wilkinsona I'm facing the same problem and I've already followed your SSL sample but it doesn't work for me. In elicpse it works fine but if I build its as a JAR then it will throw an exception.

Properties:

server.port=1019
server.ssl.enabled=true
server.ssl.key-alias=springboot_pk
server.ssl.key-store-type=JKS
server.ssl.key-password=springboot
server.ssl.key-store=classpath:springboot.JKS

Exception:

elling 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: class path resource [springboot.JKS] cannot be resolved to URL because it does not exist
2018-10-31 11:10:05.823  INFO 9736 --- [           main] ConditionEvaluationReportLoggingListener 
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-10-31 11:10:05.829 ERROR 9736 --- [           main] o.s.boot.SpringApplication               : Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Could not load key store: class path resource [springboot.JKS] cannot be resolved to URL because it does not exist
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155) ~[spring-boot-2.0.4.RELEASE.jar!/:2.0.4.RELEASE]

Comment From: wilkinsona

@GursharanKhalsa Please see my comments above. If you’d like someone to spend some time trying to help you, please provide a small sample that reproduces the problem. Before doing that, I’d check that you have a file named springboot.JKS (with matching case) in src/main/resources.

Comment From: GursharanKhalsa

@wilkinsona Thanks for the reply but this problem occur because of classpath resource when I run in eclipse it would easily find the .jks file but after building the project into single.jar. The .jks file would not find as a classpath resource so I resolved it by replacing classpath:springboot.jks to ./springboot.jks and place .jks file parallel to.jar file and it worked.

But I would like to know about if we add some required resources insrc/main/resources parallel to application.properties then why spring throws these kinds of exceptions at runtime after build and What is an appropriate solution to add the resources which we need at runtime?

Comment From: wilkinsona

@GursharanKhalsa Loading a keystore from a jar file should work. As I’ve already said above, if you’d like someone to spend some time trying to help you, please provide a small sample that reproduces the problem.

Comment From: Pmenasigi

Hi While enabling HTTPS for spring boot project i am getting like this please need help Caused by: org.springframework.boot.context.embedded.tomcat.ConnectorStartFailedException: Connector configured to listen on port 8477 failed to start my ssl configuration

The format used for the keystore. It could be set to JKS in case it is a JKS file

server.ssl.key-store-type=PKCS12

The path to the keystore containing the certificate

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

The password used to generate the certificate

server.ssl.key-store-password=domain

The alias mapped to the certificate

server.ssl.key-alias=domain

trust store location

trust.store=classpath:keystore/ssl-servercert.p12

trust store password

trust.store.password=domain

server.http.port=9000

security.require-ssl=true server.ssl.enabled=true server.port=8477 http.port=8442

need help please

Comment From: wilkinsona

@Pmenasigi If you're looking for some help, please ask on Gitter or Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

Comment From: HimanshuMamodiya

@wilkinsona Thanks for the reply but this problem occur because of classpath resource when I run in eclipse it would easily find the .jks file but after building the project into single.jar. The .jks file would not find as a classpath resource so I resolved it by replacing classpath:springboot.jks to ./springboot.jks and place .jks file parallel to.jar file and it worked.

But I would like to know about if we add some required resources insrc/main/resources parallel to application.properties then why spring throws these kinds of exceptions at runtime after build and What is an appropriate solution to add the resources which we need at runtime?

I am also facing the same issue

Comment From: onlyhuman

I think it is a bit more general problem, try to load a resource from a spring boot jar as an URL instead of a File. Like this way: @Value("${server.ssl.key-store}") private Resource keyStore; Then later: keyStore.getURL()

Comment From: Brice-D

i had the same problem and i just solved it like that: server.ssl.key-store=src/main/resources/keystore.p12

no "/" for the "src"

Comment From: wilkinsona

Thanks for trying to help out, @Brice-D. Please be aware that pointing to src/main/resources will only work when running the app with the source code available and the root of the source repository as the current working directory. It won't work if you launch the app from another directory or you deploy the jar to another machine.

Comment From: Brice-D

Thanks. It's working now for some reason Screenshot 2021-01-21 at 13 12 07 with the configuration from your sample

Comment From: priyanka28-lang

My application files has :

stargate-filter.truststore=standard_trusts.jks

and I can't even change the code for getResource as I am importing some dependency ..

ks = KeyStore.getInstance(KeyStore.getDefaultType());
URL resource = this.getClass().getClassLoader().getResource(config.getTruststore());
if(resource == null) { 
    System.out.println("Could not find the truststore located at [" + config.getTruststore()+ "]");
} else {
    File file = new File(resource.toURI());
    FileInputStream fis = new FileInputStream(file);
    ks.load(fis, config.getTruststorePassword().toCharArray());
}

In my local it works fine, but deploying it to any external server (k8) I get this as URI is not hierarchical .. and if i copy it o some location and provide the path .. I get exception "System.out.println("Could not find the truststore located at [" + config.getTruststore()+ "]");"...

Any suggestions ..