Force.com: Resolving the Destination URL not reset exception

Salesforce provides a number of methods for integrating Java and/or .NET applications using SOAP APIs. Depending on the type of application you will be writing will determine which WSDL(s) you will need to generate and consume. These WSDLs are located in Your Name | Setup | Develop | API.

Earlier today I was writing a Java client to connect via the Web Services API through the Enterprise WSDL. Using the Force.com Web Services Connector (WSC), I generated the stub code from the wsdl and included the jar files in my project. These details can be found by clicking the link above.

Connecting to Salesforce seemed pretty straightforward. In my case, I needed to use the Connector.newConnection() method. So I did this:

package com.rickross;

import com.sforce.soap.enterprise.Connector;
import com.sforce.soap.enterprise.EnterpriseConnection;
import com.sforce.soap.enterprise.LoginResult;
import com.sforce.soap.enterprise.sobject.Account;
import com.sforce.soap.enterprise.sobject.SObject;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;

public class BrokenDemo 
{
	public static void main(String[] args) 
		throws ConnectionException 
	{
		System.out.println("Starting Broken Demo");
		ConnectorConfig config = new ConnectorConfig();
		config.setManualLogin(true);	
		EnterpriseConnection conn = 
			Connector.newConnection(config);
		LoginResult result = 
			conn.login("username", "pwd+token");
		if (!result.getPasswordExpired())
		{
			Account account = new Account();
			account.setName("Test from Java");
			// Won't work.. this will throw 
			/*
			 * [UnexpectedErrorFault 
			 * [ApiFault  exceptionCode='UNKNOWN_EXCEPTION'
 				exceptionMessage='Destination URL not reset. 
 				The URL returned from login must be set in 
 				the SforceService'
			   ]
			 */
			conn.create(new SObject[]{ account });

			conn.logout();
		}
	}
}
But this did not work. Searching for this issue gave solutions that were not applicable when using the Force.com Web Services Connector. I talked to a colleague who had used .NET to communicate with the force.com APIs and he showed me code that required him to override a URL property, which did not exist in Java.

After some time experimenting, I discovered a solution which required the creation of another EnterpriseConnection but instead of using the user name and password, to use the session ID and server URL that is found from the results of the previous login. The following code demonstrates a successful test:

public class WorkingDemo 
{
	public static void main(String[] args) 
		throws ConnectionException 
	{
		System.out.println("Starting Working Demo");
		ConnectorConfig config = new ConnectorConfig();
		config.setManualLogin(true);	
		EnterpriseConnection conn = 
			Connector.newConnection(config);
		LoginResult loginResult = 
			conn.login("username", "pwd+token");
		if (!loginResult.getPasswordExpired())
		{
			System.out.println("Logged in");
			
			// once you log in, you need to create a new 
			// config and get the session and server 
			// details from the login results and 
			// create a new connection with this info
			ConnectorConfig newConfig = new ConnectorConfig();
			newConfig.setSessionId(
					loginResult.getSessionId());
			newConfig.setServiceEndpoint(
					loginResult.getServerUrl());
			conn = Connector.newConnection(newConfig);
	        
			Account account = new Account();
			account.setName("Test from Java");

			conn.create(new SObject[]{ account });
			
			System.out.println("The account has been created!");
			
			conn.logout();
		}
	}
}
I hope that this will save someone a few minutes or hours trying to figure out how to solve this exception when using the Enterprise WSDL. Please let me know if you know of any other solutions that will work.
Posted in Java, PaaS, Salesforce.com, Software Development, Tips & Tricks, Web Services | 3 Comments

Improving Enterprise Development in the Cloud – Part 3

Hourglass

Thou Shall Maximize Developer Productivity

Software craftsmen are equally concerned with the code they craft and the tools that they use. They arm themselves with Integrated Development Environments (IDEs) like Eclipse or Visual Studio; build tools like Ant and Maven, and unit testing tools like JUnit and NUnit; database tools like Toad, and MySQL Workbench to help them produce reliable software faster than ever before.

When I am intensely directed and focus on writing software where the world around me fades into the background and I am writing code as fast as I can type, I notice when a tool disrupts my ability to stay focused on whatever I am producing. Good tools help you to automate time consuming tasks, great tools work to keep you focused.

The Force.com platform is more than just click and configure. Custom classes and triggers can be written in a language called Apex, which is loosely based on Java, when click and configure does not provide the functionality that you desire. Using an Eclipse Plugin enables the open source IDE to communicate with a specific Force.com organization and give you the ability to write, test and debug your Apex code.

As you write your code in Eclipse, saving a file will trigger the Force.com IDE to save your changes back to the Force.com instance. (You can change this option by turning off the Build Automatically found in the Project Menu, just remember to save your changes to the server later using the Force.com | Save to Server option by right clicking on a specific file or the src folder).

What I have noticed is that the time it takes for the save operation to complete can vary greatly. Sometimes the save operation is quick, maybe 1 second, and other times it can take an excruciating long time of 45 seconds or more. And while I don’t know exactly what causes these delays, I speculate that the longer save times occur within Force.com organizations that have a large number of custom classes and triggers.

Part of this delay is due to the strict requirement for having code coverage of 75% or more in production organizations. Saving a file triggers the unit tests to be executed and if you have a large number of files, it makes logical sense that it would take some time to execute the tests.

Unfortunately, I find these lengthy delays disruptive to my ability to stay “in the zone”. It forces me to think more about the tool and not on the problem at hand. A tool that gets in the way of writing code does not help developer productivity, it hinders it.

My intention here is not to just state a problem but also provide additional thinking on how to solve this productivity issue. I don’t know how feasible this is, but what I would love to see is the ability to bring the force.com cloud down to my laptop. A local sandbox if you will.

Think about this for a moment.

Give us the ability to work offline, on our laptops. Perhaps a virtual machine image that functions just like a Force.com instance in the cloud. A local sandbox. Certain functionality may need to be limited and/or disabled because it wouldn’t make sense. That is understandable.

Not only could that help developer productivity, it would also offload some of the processing required to save, compile and execute the tests on the Salesforce.com servers. And while I don’t know the feasibility for this option, it would certainly be interesting to explore.

What ideas and or practices do you have for increasing developer productivity in the cloud?

Posted in Commentary, PaaS, Salesforce.com, Sandbox, Software Development | Leave a comment