SSL error when trying to run Java/Groovy application as a service

I’ve been working on a Groovy Spring Boot application using Snap and have been trying to get it to run as a service so that we can be sure it will run on startup.

It runs without issue as a normal command but when run as a service it throws an exception when it tries to open an SSL connection. Specifically when it calls javax.net.ssl.SSLContext.init() it throws a error like this:

java.security.KeyManagementException: java.security.KeyStoreException: initialization failed
         at org.bouncycastle.jsse.provider.ProvSSLContextSpi.selectTrustManager(Unknown Source)
         at org.bouncycastle.jsse.provider.ProvSSLContextSpi.engineInit(Unknown Source)
         at javax.net.ssl.SSLContext.init(SSLContext.java:282)
         at javax.net.ssl.SSLContext$init$0.call(Unknown Source)
         ...
Caused by: java.security.KeyStoreException: initialization failed
         at org.bouncycastle.jsse.provider.ProvTrustManagerFactorySpi.engineInit(Unknown Source)
         at javax.net.ssl.TrustManagerFactory.init(TrustManagerFactory.java:250)
         ...
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
         at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
         at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
         at java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
         at org.bouncycastle.jsse.provider.ProvX509TrustManagerImpl.<init>(Unknown Source)
         ...

Googling around after this error seems to suggest that it’s caused by missing ca certs:
https://stackoverflow.com/questions/6784463/error-trustanchors-parameter-must-be-non-empty
https://stackoverflow.com/questions/4764611/java-security-invalidalgorithmparameterexception-the-trustanchors-parameter-mus

But the cacerts file seem to be present in the snap directory after installation in multiple places:

etc/default/cacerts
etc/ssl/certs/java/cacerts
usr/lib/jvm/java-8-openjdk-armhf/jre/lib/security/cacerts

This seems to be picked up fine when the snap is run as a normal command, but when it’s running as a service it either doesn’t seem to be able to find them or it can’t read them.

Is there any difference in environment when running a snap as a service that would account for this?

Other info: My snapcraft.yml file is quite simple and looks like this:

name: foo
version: '1.1'
summary: bar
description: foobar
confinement: devmode
grade: devel

apps:
  service:
    command: java -Dspring.config.location=/config/dir/ -Dspring.config.name=foo -jar $SNAP/jar/foo-1.1.jar
    daemon: simple
    plugs:
    - home
    - network-bind
    - network-observe
    - serial-port

parts:
  local:
    plugin: gradle
    source: .
    gradle-options: [build]

The only difference with the non-service version of the project (that works fine) is “daemon: simple” line is removed from snapcraft.yml

We’re also setting the following ssl settings via the Spring Boot properties file:

 server.port
 server.ssl.enabled
 server.ssl.key-store
 server.ssl.key-store-password
 server.ssl.key-password
 server.ssl.key-alias
 server.ssl.key-store-type
 server.ssl.ciphers

It’s also probably worth noting that the environment it’s running in does not have its own Java runtime other than what is bundled in the snap.

Well it turned out this was a simple mistake caused by a Spring Boot misconfiguration and nothing to do with snapcraft. It seems the -Dspring.config.name=foo argument was not working the way I thought it was and the service was reading from the wrong config file, causing it to look in the wrong place for the keystore. Sorry to bother.