Java Command Line App Using the Salesforce WSC

May 17th, 2010

The Force.com Web Service Connector (WSC) is a high performance web services stack that is much easier to implement than the “tried and true” Force.com Web Services API. Here’s a quick command line app you can use as a starter application. This class simply creates a new Account and then queries for the 5 newest Accounts by created date.

To get started, download wsc-18.jar from the WSC project’s download page to your desktop (any location will do). Now log into your Developer org and download the Partner WSDL (Setup -> App Setup -> Develop -> API) to your desktop as “partner.wsdl”. Now we’ll need to generate the stub code from the Partner WSDL. Make sure you have Java 1.6 installed and open a command prompt. Now run wsdlc on the Partner WSDL you just downloaded (detailed instruction are here):

java -classpath wsc-18.jar com.sforce.ws.tools.wsdlc partner.wsdl partner.jar

This will create a “partner.jar” file on your desktop. If you are using a Sandbox instead of a Developer or Production org, here are instructions for running wsdlc as there are a few issues. Your console should look similar to:

Note: You can also simply download the partner-18.jar and bypass the steps above to generate the partner.jar.

Now create a new Java project in Eclipse, add the wsc-18.jar and partner.jar files to your build path and copy the code below. You’ll need to add your username and password/security token before you run the code. Running the code should produce output similar to:

Here’s the starter code for the application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.jeffdouglas;
 
import com.sforce.soap.partner.*;
import com.sforce.soap.partner.sobject.*;
import com.sforce.ws.*;
 
public class Main {
 
  public static void main(String[] args) {
 
    ConnectorConfig config = new ConnectorConfig();
    config.setUsername("YOUR-USERNAME");
    config.setPassword("YOUR-PASSWORD-AND-SECURITYTOKEN");
 
    PartnerConnection connection = null;
 
    try {
 
      // create a connection object with the credentials
      connection = Connector.newConnection(config);
 
      // create a new account
      System.out.println("Creating a new Account...");
      SObject account = new SObject();
      account.setType("Account");
      account.setField("Name", "ACME Account 1");
      SaveResult[] results = connection.create(new SObject[] { account });
      System.out.println("Created Account: " + results[0].getId());
 
      // query for the 5 newest accounts
      System.out.println("Querying for the 5 newest Accounts...");
      QueryResult queryResults = connection.query("SELECT Id, Name from Account " +
          "ORDER BY CreatedDate DESC LIMIT 5");
      if (queryResults.getSize() > 0) {
        for (SObject s: queryResults.getRecords()) {
          System.out.println("Id: " + s.getField("Id") + " - Name: "+s.getField("Name"));
        }
      }
 
    } catch (ConnectionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
 
  }
 
}

Categories: Code Sample, Java, Salesforce

Leave a comment

Comments Feed8 Comments

  1. Jd

    Hmm, Jeff, that doesn’t look like Ubuntu

  2. Fabian Off

    Hey Jeff,

    thank’s for your great tutorial!
    As I just wanted to test generating a .jar I executed your code and encountered the following problem:

    “java -classpath wsc-18.jar com.sforce.ws.tools.wdlc partner.wsdl partner.jar”
    should instead read

    “java -classpath wsc-18.jar com.sforce.ws.tools.wsdlc partner.wsdl partner.jar”

    Notice the *s* in wsdlc?
    Nevertheless, great work, once again!

  3. Jeff Douglas

    Thanks Fabian! I updated the code. Appreciate the help.

  4. Umut Dogan

    Also put -Dpackage-prefix=wsc before classpath for fixing class cast exceptions related to Axis.
    Source: http://www.tgerm.com/2010/08/wsc-apache-axis-classcastexception.html

  5. Siva

    Jeff,

    Tried it exactly they way you suggested. I am always getting java.lang.NoClassDefFoundError: com/sforce/ws/ConnectionException

    Here is trace

    HTTP ERROR 500

    Problem accessing /helloworld/greet. Reason:

    com/sforce/ws/ConnectionException

    Caused by:

    java.lang.NoClassDefFoundError: com/sforce/ws/ConnectionException
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
    at java.lang.Class.getConstructor0(Class.java:2699)
    at java.lang.Class.newInstance0(Class.java:326)
    at java.lang.Class.newInstance(Class.java:308)
    at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
    at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:428)
    at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:58)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:351)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
    Caused by: java.lang.ClassNotFoundException: com.sforce.ws.ConnectionException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:176)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    … 33 more

    Caused by:

    java.lang.ClassNotFoundException: com.sforce.ws.ConnectionException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:176)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
    at java.lang.Class.getConstructor0(Class.java:2699)
    at java.lang.Class.newInstance0(Class.java:326)
    at java.lang.Class.newInstance(Class.java:308)
    at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
    at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:428)
    at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:58)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:351)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

  6. Alan Davies

    WSC is very good, but I have been unable to find out how to dynamically set the service endpoint to either ‘https://login…” or “https://test…”, to enable me to talk to Prod or Sandbox Orgs as required. The WSC code seems to use the service endpoint hard-wired into the Enterprise.jar which I generate from the Enterprise.wsdl.
    Ideas?

  7. Bryan Gilbert

    Hi Alan,
    I wanted to also connect to the sandbox and traced the code to verify that, by default, the service end point is the login.salesforce.com. To get to test try this:

    config.setAuthEndpoint(“https://test.salesforce.com/services/Soap/c/21.0″);
    config.setServiceEndpoint(“https://test.salesforce.com/services/Soap/c/21.0″);

  8. vijay

    quick question using the code above where do I set the loginscopheader for the portal login

Leave a comment

Feed

http://blog.jeffdouglas.com / Java Command Line App Using the Salesforce WSC

WordPress Appliance - Powered by TurnKey Linux