[SalesForce] INVALID_SESSION_ID when calling Salesforce services from Java

We have a Java application running on glassfish that makes callouts to WebServices hosted on our SF sandbox using the Partner WSDL and the SF Web Service Connector (wsc).

Yesterday it was working just fine. Today, after we did an Instance Refresh it stopped working. Whenever the Java tries to make the callout to a SF web method, we get the following error.

INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session. Session not found, missing session hash: D78G6B4m/rAhFmb5LxHR/jNoDfMCMBPWY0jIrCGnxyE= This error usually occurs after a session expires or a user logs out. 

Relevant information:

  • The login on SF from the Java application is successful. I can look at the information it returns (I can see it is connecting to the correct sandbox URL) and it's all correct. The login is done in the following way:

    ConnectorConfig connectorConfig = new ConnectorConfig();
    config.setAuthEndpoint("https://test.salesforce.com/services/Soap/u/34.0");
    config.setUsername("user@email.com.sandboxname");
    config.setPassword("passwordtoken");

    PartnerConnection partnerConnection = new PartnerConnection(config);

    I can also see on the SF user page that the login was successful, and a user session is created on Session Management.

  • The sandbox refresh caused the sandbox instance and URL to be changed.
    (The number after CS was changed: company–preprod.cs108.my.salesforce.com)

  • I have tried to reset the token and modify the java code accordingly, to no avail. As I said, the login is successful, it's just the session ID that is messing things up.

In short, what I need to understand is why the login is returning an invalid session ID.

Any help is appreciated.

Best Answer

This is a pretty common problem.

After you call the login method you get a LoginResult back in the response.

That response includes the sessionId that you then need to include in the in the SessionHeader for all the subsequent API calls.

However, the LoginResult also includes a serverUrl, which is critically important to get any subsequent API calls to work.

From the docs:

serverUrl

URL of the endpoint that will process subsequent API calls. Your client application needs to set the endpoint.

That serverUrl becomes your new endpoint for any subsequent API calls.

That your code was working and is now failing after refreshing the sandbox suggests you had some fixed coding to work against the old sandbox.


The sample code in Examples Using the Partner WSDL shows this explicitly in the .NET example code with the line:

// Set the returned service endpoint URL
binding.Url = lr.serverUrl;

Yet the equivalent is conspicuously absent in the Java sample. That implies it should almost be handled implicitly by the PartnerConnection.

If you look at the source of PartnerConnection you can see that it should be doing the following with the LoginResult.

config.setServiceEndpoint(result.getServerUrl());

Maybe try a getServiceEndpoint() on the PartnerConnection after you created it to confirm it is pointing to the correct sandbox pod instance.