I have been trying to connect to the tooling API using SOAP and Java, but so far I have not been able to get it to work. I have a Java project with the tooling.jar and wsc-23.jar present, and I have a build script that generates the necessary code. The environment seems to be fine, but I am pretty sure the initialization code for the connection is wrong.
I have not been able to find a tutorial that shows how to set up this connection. However, I did download the Force.com plugin code from GitHub and used this as a guide.
Here is my code:
private static void doStuff() throws Exception {
Properties props = new Properties();
try (Reader r = new FileReader("connection.properties")) {
props.load(r);
}
// 1. Establish partner connection.
ConnectorConfig partnerConfig = new ConnectorConfig();
partnerConfig.setUsername(props.getProperty("force.user"));
partnerConfig.setPassword(props.getProperty("force.password") + props.getProperty("force.token"));
partnerConfig.setAuthEndpoint(props.getProperty("force.url.u"));
partnerConfig.setServiceEndpoint(props.getProperty("force.url.u"));
PartnerConnection partnerConnection = com.sforce.soap.partner.Connector.newConnection(partnerConfig);
// 2. Establish tooling connection.
ConnectorConfig toolingConfig = new ConnectorConfig();
toolingConfig.setSessionId(partnerConnection.getSessionHeader().getSessionId());
toolingConfig.setAuthEndpoint(partnerConfig.getAuthEndpoint());
toolingConfig.setServiceEndpoint(props.getProperty("force.url.t"));
SoapConnection toolingConnection = com.sforce.soap.tooling.Connector.newConnection(toolingConfig);
// 3. Use tooling connection. THIS IS THE LINE THAT FAILS
DescribeGlobalResult res = toolingConnection.describeGlobal();
}
This is the referenced properties file containing configurable settings:
force.user=<nope>
force.password=<nope>
force.token=<nope>
force.url.u=https://login.salesforce.com/services/Soap/u/30.0/
force.url.t=https://login.salesforce.com/services/Soap/T/30.0/
Finally, here is the Java exception including stack trace:
[UnexpectedErrorFault [ApiFault exceptionCode='UNKNOWN_EXCEPTION'
exceptionMessage='Destination URL not reset. The URL returned from login must be set in the SforceService'
]
]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at java.lang.Class.newInstance(Class.java:433)
at com.sforce.ws.bind.TypeMapper.readSingle(TypeMapper.java:628)
at com.sforce.ws.bind.TypeMapper.readObject(TypeMapper.java:505)
at com.sforce.ws.transport.SoapConnection.parseDetail(SoapConnection.java:228)
at com.sforce.ws.transport.SoapConnection.createException(SoapConnection.java:202)
at com.sforce.ws.transport.SoapConnection.receive(SoapConnection.java:148)
at com.sforce.ws.transport.SoapConnection.send(SoapConnection.java:110)
at com.sforce.soap.tooling.SoapConnection.describeGlobal(SoapConnection.java:392)
at Main.doStuff(Main.java:65) <--- This is the line above where I mentioned it blows up
at Main.main(Main.java:34)
What do I need to change in my code so it will successfully login and initialize correctly so I can use the tooling API?