Spring SAML Sample application returns Could not initialize class org.apache.commons.ssl.TrustMaterial

You're most likely hitting a bug in the underlying OpenSAML and SSL library which presumes that file JAVA_HOME/lib/security/cacerts or JAVA_HOME/lib/security/jssecacerts is present and can be read as a JKS or PKCS12 keystore. In your case the file is probably corrupted.

Please try updating the cacerts file in your JDK with the file from the original installation. Make sure you can read it using keytool -list -keystore cacerts with either an empty password or password "changeit".


Same issue, upgraded to not-yet-commons-ssl-0.3.16.jar from the bundled 3.9 of saml-sample and it worked.


I'm on a mac with Java 1.6 - here's what I found:

TrustMaterial.java is running static init code ->

    String pathToCacerts = javaHome + "/lib/security/cacerts";
    String pathToJSSECacerts = javaHome + "/lib/security/jssecacerts";
    TrustMaterial cacerts = null;
    TrustMaterial jssecacerts = null;
    try {
        File f = new File(pathToCacerts);
        if (f.exists()) {
            cacerts = new TrustMaterial(pathToCacerts);
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    try {
        File f = new File(pathToJSSECacerts);
        if (f.exists()) {
            jssecacerts = new TrustMaterial(pathToJSSECacerts);
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }

    CACERTS = cacerts;
    JSSE_CACERTS = jssecacerts;
    if (JSSE_CACERTS != null) {
        DEFAULT = JSSE_CACERTS;
    } else {
        DEFAULT = CACERTS;
    }

Now, above there is a bug mentioned about assuming JAVA_HOME/lib/security/... files are valid keystores. If neither of these files are valid keystores both CACERTS and JSSE_CACERTS are null and this line at line 127 causes the NPE because JSSE_CACERTS is null:

this.jks = CACERTS != null ? CACERTS.jks : JSSE_CACERTS.jks;

So, why are both null?

When I look at mine on my filesystem:

file /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts

I get this:

/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts: broken symbolic link to /System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security/cacerts

That's a symlink to an invalid cacerts keystore. What I did was get a good copy of a JDK1.6 keystore via this command:

sudo find / -name 'cacerts' 2>/dev/null

/some/other/path/to/cacerts

Then, do file /some/other/path/to/cacerts to make sure you get a valid file:

/some/other/path/to/cacerts: Java KeyStore

Copy that to /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts to replace your broken symlink and verify it's good:

file /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts

/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts: Java KeyStore

Once that's a valid keystore, this code will work.

What a pain in the ass.