function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
toddnewmantoddnewman 

login - trustAnchors parameter must be non-empty

Hi all,

 

I am trying to run a query over SOAP using Java.  I am using the Javaforce tool which bascially packages up the partner WSDL into an axis wrapper for you.  So far so good.

 

I put it all together in Eclipse, run a test class.  All looks good.  Deploy to tomcat and that's where the fun begins.

 

(1) When I start tomcat, the call errors every time I navigate to the page (detail below)

(2) If I rebuild the WAR and restart tomcat it works perfectly every time (so far)

(3) If I do the same but also clean out the tomcat work directory, it fails every time again.

 

The error occurs on the login call.  The error string is java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty.  From what I can see, this occurs when tomcat can't find a valid cacerts file.  I would believe that is the problem except that it works sometimes.  Unfortunately, building and starting twice is not a valid workaround for reasons too boring to detail here.

 

This occurs on both Tomcat 5.5 and 7.0, Java 6.  I hope someone has seen this!

 

From com.sforce.soap.partner.SoapBindingStub

==============

        org.apache.axis.client.Call _call = createCall();
        _call.setOperation(_operations[0]);
        _call.setUseSOAPAction(true);
        _call.setSOAPActionURI("");
        _call.setEncodingStyle(null);
        _call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
        _call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
        _call.setOperationName(new javax.xml.namespace.QName("urn:partner.soap.sforce.com", "login"));

        setRequestHeaders(_call);
        setAttachments(_call);
  try {        java.lang.Object _resp = _call.invoke(new java.lang.Object[] {username, password});
/////////// error occurs on the above line

 

Here's more of the response from Salesforce

============================


<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server.userException</faultcode>

<faultstring>javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty</faultstring>

<detail><ns1:stackTrace xmlns:ns1="http://xml.apache.org/axis/">javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1612)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1595)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1172)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
    at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:186)
    at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
    at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
    at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
    at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
    at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
    at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
    at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
    at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
    at org.apache.axis.client.Call.invoke(Call.java:2767)
    at org.apache.axis.client.Call.invoke(Call.java:2443)
    at org.apache.axis.client.Call.invoke(Call.java:2366)
    at org.apache.axis.client.Call.invoke(Call.java:1812)
    at com.sforce.soap.partner.SoapBindingStub.login(SoapBindingStub.java:2257)
[snip]
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:183)
    at java.security.cert.PKIXParameters.&lt;init&gt;(PKIXParameters.java:103)
    at java.security.cert.PKIXBuilderParameters.&lt;init&gt;(PKIXBuilderParameters.java:87)
    at sun.security.validator.PKIXValidator.&lt;init&gt;(PKIXValidator.java:55)
    ... 134 more
</ns1:stackTrace>
<ns2:hostname xmlns:ns2="http://xml.apache.org/axis/">sveltedaddy.local</ns2:hostname></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>


Best Answer chosen by Admin (Salesforce Developers) 
manimmanim

Hi,

I had faced this issue while I was trying to authenticate using LDAP in tomcat.I was setting my key store path i.e. "cacerts" file path using system property as below:

 System.setProperty("javax.net.ssl.trustStore",keystorePath);

 

To find out what's happening I did below:

String keystore = "cacerts";

 File keyStoreFile = new File (keystorePath);

 

if(keyStoreFile.exists()){
             System.out.println("KeyStore file exists :abs path = "+ keyStoreFile.getAbsolutePath());
         }else{
             System.out.println("KeyStore file does not exist :abs path = "+ keyStoreFile.getAbsolutePath());
         }

 

This printed the path where it was trying to look for cacerts file.In my case cacerts file was not present at that path.After putting it there it worked.

 

All Answers

manimmanim

Hi,

I had faced this issue while I was trying to authenticate using LDAP in tomcat.I was setting my key store path i.e. "cacerts" file path using system property as below:

 System.setProperty("javax.net.ssl.trustStore",keystorePath);

 

To find out what's happening I did below:

String keystore = "cacerts";

 File keyStoreFile = new File (keystorePath);

 

if(keyStoreFile.exists()){
             System.out.println("KeyStore file exists :abs path = "+ keyStoreFile.getAbsolutePath());
         }else{
             System.out.println("KeyStore file does not exist :abs path = "+ keyStoreFile.getAbsolutePath());
         }

 

This printed the path where it was trying to look for cacerts file.In my case cacerts file was not present at that path.After putting it there it worked.

 

This was selected as the best answer
toddnewmantoddnewman

Thanks for that, you got me going down the right path.

 

I logged out the current trustStore value and found it was "C:\sun\app\..."  I'm on Mac OS X so that couldn't have been a default.  A bit of grepping around and I found it.

 

Turns out there is a System.setProperty("javax.net.ssl.trustStore", xxxx) call in our code already where xxxx is stored in a config file.  I was unaware of this file or call.

 

Thanks!