title: Load java trust store at runtime - after jvm have been launched?
body: <p>In my java application I need to send POST requests to a server sitting behind https. On the machine where my java application is running there is a java trust store in: <code>/usr/local/comp.jks</code> that contains the certificate for the server I need to interact with (its already imported).</p>
  
  <p>The problem is that I cannot control how the JVM is started that will run my java application - e.g. by adding: </p>
  
  <p><code>-Djavax.net.ssl.trustStore=/usr/local/comp.jks</code> to the VM arguments.</p>
  
  <p>Is it possible to load the trust store in the above path at runtime from my application <strong><em>after</em></strong> the JVM has started so I can authenticate against the https site?</p>
  
  <p>I have only found guides on how to import certificates at runtime but that I cannot use - also since I don't have the password for <code>/usr/local/comp.jks</code></p>
  
  <p>Below my current implementation (in groovy):</p>
  
  <pre><code>import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.net.URL;
  import java.security.KeyManagementException;
  import java.security.KeyStore
  import java.security.NoSuchAlgorithmException;
  import java.security.cert.CertificateException
  import java.security.cert.X509Certificate
  import java.util.Base64;
  
  import javax.net.ssl.HostnameVerifier;
  import javax.net.ssl.HttpsURLConnection;
  import javax.net.ssl.SSLContext;
  import javax.net.ssl.SSLSession;
  import javax.net.ssl.TrustManager;
  import javax.net.ssl.X509TrustManager;
  
  
  public class HttpsClientImpl extends AbstractHttpClient  {
    private String username = null;
    private String password = null;
  
    public HttpsClientImpl (String username, String password)  {
      this.username=username;
      this.password=password;
  
    }
  
    @Override
    public String sendRequest(String request, String method) {
      System.setProperty( "javax.net.ssl.trustStore", "/usr/local/comp.jks" );
      URL url = new URL(request);
      HttpsURLConnection con = (HttpsURLConnection) url.openConnection()
      // Set auth
      byte[] name = (username + ":" + password).getBytes();
      String authStr = Base64.getEncoder().encodeToString(name);
      con.setRequestProperty("Authorization", "Basic " + authStr)
  
      con.setRequestMethod(method);
      writeResult(con);
      return con.getResponseCode();
    }
  
  
    private void writeResult(HttpsURLConnection con) throws IOException {
      if(con!=null){
        BufferedReader br = null;
        if (200 &lt;= con.getResponseCode() &amp;&amp; con.getResponseCode() &lt;= 299) {
          br = new BufferedReader(new InputStreamReader(con.getInputStream()));
        } else {
          br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
        }
        try {
          String input;
          while ((input = br.readLine()) != null){
            System.out.println(input);
          }
          br.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  </code></pre>
  
  <p>When I run that I get:</p>
  
  <pre><code>sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
      at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
      at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
      at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
      at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
  Caused: sun.security.validator.ValidatorException: PKIX path building failed
  </code></pre>