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
David Bailey 16David Bailey 16 

Force.com WSC Metadata API Java Sample Syntax Errors

In the original Salesforce article "Introduction to the Force.com Web Services Connector" by Jeff Douglas, Developer Advocate, everything works just fine code-wise, until one gets to the WCS Metadata API Java code sample.   That sample code generates two syntax errors ...

Line 54: AsyncResult[] ars = metadataConnection.create(new CustomObject[] { co });
- The method create(CustomObject[]) is undefined for the type MetadataConnection

Line 72: arsStatus = metadataConnection.checkStatus(ids);
- The method checkStatus(String[]) is undefined for the type MetadataConnection

This currently occurs using the "force-wsc-38.0.0-uber.jar" jar file.  Can you kindly tell me what I need to do to fix these errors?  Cheers,

David
 
Best Answer chosen by David Bailey 16
David Bailey 16David Bailey 16
Okay.  So, I looked inside the "force-wsc-38.0.0-uber.jar" jar file.  There are obviously no longer create() and checkStatus() methods in it.  There are now createMetadata(), createMetadataResponse(), checkRetrieveStatus() and checkRetrieveStatusResponse(), CheckDeployStatus(), and CheckDeployStatusResponse() methods in it.

Uh, replacing the create() method with the createMetadata() method eliminated the "The method create(CustomObject[]) is undefined for the type MetadataConnection" error, but created the "Type mismatch: cannot convert from SaveResult[] to AsyncResult[]" error.  Likewise, replacing the checkStatus() method with checkRetrieveStatus() method, eliminated the "The method checkStatus(String[]) is undefined for the type MetadataConnection" error, but created the "The method checkRetrieveStatus(String, boolean) in the type MetadataConnection is not applicable for the arguments (String[])" error.  So, it seems like making these arbitrary substutitions without understanding what the methods are actually supposed to do will start a game of "whack a mole", which could go on indefinitely.

So, here's my question, where is the documentation for the WSC Metadata API classes kept, so I can try to figure out what's going on?  It's been a long time since I've programmed in Java, so I'm way, way rusty.  So, if there are any SFDC Java "heavies" out there reading this, please steer me to where the WSC Metaata API Java docs live, and toss me a hint about what should be done to replace the create() and checkStatus() methods.

I'm pretty sure that SFDC doesn't want errant code hanging around in examples that are supposed to be teaching new developers stuff.  But I can't seem to get in touch with the author of this code, Jeff Douglas.  Hey, maybe he'll see this discussion and "step up".  Or, maybe one of his "homies" will see it and pass it along to him.

Thanks,

David

All Answers

David Bailey 16David Bailey 16
Um, for reference:

 • Jeff Douglas' Introduction to the Force.com Web Services Connector article link:
   - https://developer.salesforce.com/page/Introduction_to_the_Force.com_Web_Services_Connector

And, here's the WSC Metadata API Sample Java Code from the article (that contains the two syntax errors on lines 54 and 72) ...
 
package wsc;

import com.sforce.soap.metadata.*;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;

public class Main {

  static final String USERNAME = "YOUR-USERNAME";
  static final String PASSWORD = "YOUR-PASSWORD&SECURITY-TOKEN";
  static PartnerConnection connection;

  public static void main(String[] args) throws ConnectionException {
  
    ConnectorConfig partnerConfig = new ConnectorConfig();
    ConnectorConfig metadataConfig = new ConnectorConfig();
    
    partnerConfig.setUsername(USERNAME);
    partnerConfig.setPassword(PASSWORD);
    //partnerConfig.setTraceMessage(true);
    
    @SuppressWarnings("unused")
    PartnerConnection partnerConnection = com.sforce.soap.partner.Connector.newConnection(partnerConfig);
    
    // shove the partner's session id into the metadata configuration then connect
    metadataConfig.setSessionId(partnerConnection.getSessionHeader().getSessionId());
    MetadataConnection metadataConnection = com.sforce.soap.metadata.Connector.newConnection(metadataConfig);
  
    // create a new custom object
    String objectName = "WSCCustomObject";
    String displayName = "WSC Custom Object";
    
    CustomObject co = new CustomObject();
    co.setFullName(objectName+"__c");
    co.setDeploymentStatus(DeploymentStatus.Deployed);
    co.setDescription("Created by the WSC using the Metadata API");
    co.setLabel(displayName);
    co.setPluralLabel(displayName+"s");
    co.setSharingModel(SharingModel.ReadWrite);
    co.setEnableActivities(true);
    
    // create the text id field
    CustomField field = new CustomField();
    field.setType(FieldType.Text);
    field.setDescription("The custom object identifier field");
    field.setLabel(displayName);
    field.setFullName(objectName+"__c");
    // add the field to the custom object
    co.setNameField(field);

    try {
      // submit the custom object to salesforce
      AsyncResult[] ars = metadataConnection.create(new CustomObject[] { co });
      if (ars == null) {
          System.out.println("The object was not created successfully");
          return;
      }
      
      String createdObjectId = ars[0].getId();
      String[] ids = new String[] {createdObjectId};
      boolean done = false;
      long waitTimeMilliSecs = 1000;
      AsyncResult[] arsStatus = null;
      
      /**
       * After the create() call completes, we must poll the results
       * of the checkStatus() call until it indicates that the create
       * operation is completed.
       */  
      while (!done) {
          arsStatus = metadataConnection.checkStatus(ids);
          if (arsStatus == null) {
              System.out.println("The object status cannot be retrieved");
              return;
          }
          done = arsStatus[0].isDone();
          if (arsStatus[0].getStatusCode() != null )  {
              System.out.println("Error status code: "+arsStatus[0].getStatusCode());
              System.out.println("Error message: "+arsStatus[0].getMessage());
          }
          Thread.sleep(waitTimeMilliSecs);
          // double the wait time for the next iteration  
          waitTimeMilliSecs *= 2;
          System.out.println("The object state is "+arsStatus[0].getState());
      }
      
      System.out.println("The ID for the created object is "+arsStatus[0].getId());
    }
    catch (Exception ex) {
        System.out.println("\nFailed to create object, error message was: \n" +ex.getMessage());
    }
  
  }
    
}

Uh, the metadataConnection class does not contain a create() method (line 54) and a checkStatus() method (line 72).
David Bailey 16David Bailey 16
Okay.  So, I looked inside the "force-wsc-38.0.0-uber.jar" jar file.  There are obviously no longer create() and checkStatus() methods in it.  There are now createMetadata(), createMetadataResponse(), checkRetrieveStatus() and checkRetrieveStatusResponse(), CheckDeployStatus(), and CheckDeployStatusResponse() methods in it.

Uh, replacing the create() method with the createMetadata() method eliminated the "The method create(CustomObject[]) is undefined for the type MetadataConnection" error, but created the "Type mismatch: cannot convert from SaveResult[] to AsyncResult[]" error.  Likewise, replacing the checkStatus() method with checkRetrieveStatus() method, eliminated the "The method checkStatus(String[]) is undefined for the type MetadataConnection" error, but created the "The method checkRetrieveStatus(String, boolean) in the type MetadataConnection is not applicable for the arguments (String[])" error.  So, it seems like making these arbitrary substutitions without understanding what the methods are actually supposed to do will start a game of "whack a mole", which could go on indefinitely.

So, here's my question, where is the documentation for the WSC Metadata API classes kept, so I can try to figure out what's going on?  It's been a long time since I've programmed in Java, so I'm way, way rusty.  So, if there are any SFDC Java "heavies" out there reading this, please steer me to where the WSC Metaata API Java docs live, and toss me a hint about what should be done to replace the create() and checkStatus() methods.

I'm pretty sure that SFDC doesn't want errant code hanging around in examples that are supposed to be teaching new developers stuff.  But I can't seem to get in touch with the author of this code, Jeff Douglas.  Hey, maybe he'll see this discussion and "step up".  Or, maybe one of his "homies" will see it and pass it along to him.

Thanks,

David
This was selected as the best answer