+ Start a Discussion
iKnowSFDCiKnowSFDC 

Method does not exist error when calling method from a static method

I'm using an @future (callout=true) method to make a callout to a webservice for an xml file. If I remove the @future annotation and make the method not static it compiles with no problem and calls the readResponse method. If I keep it as a static method, I'm unable to call the readResponse or the getValueFromTag method. I know I'm missing something obvious but am just not finding it in the documentation, hoping   

My code is using the example posted on the developer relations blog this summer at http://blogs.developerforce.com/developer-relations/2013/08/integrating-force-com-using-xml-in-apex.html

public class parseExample{
    public Policy_Information__c polInfo{get;set;}
    public List<Policy_Information__c> polInfoToInsert = new List<Policy_Information__c>();
   
    @future(callout=true)
    public static void requestIvans(){
        Http h = new Http();
      HttpRequest req = new HttpRequest();
  HttpResponse res = new HttpResponse();
        String url = 'https://s3.amazonaws.com/XXX/XXXX.xml';
        req.setEndPoint(url);
        req.setMethod('GET');
  res = h.send(req);
        String response = res.getBody();
  XmlStreamReader reader = new XmlStreamReader(response);
        system.debug('reader response is>>>'+response.left(25));
     readResponse(reader);  
    }

    public void readResponse(XmlStreamReader reader) {
     // Is there any element next?
        while (reader.hasNext()) {
            // Is the next element an opening tag?
            if (reader.getEventType() == XmlTag.START_ELEMENT) {
                // Set Account Details
                if ('CommercialName' == reader.getLocalName()) {
                    // if opening tag of account is found initialize polInfo Record
                    polInfo = new Policy_Information__c();
                } else if ('CommercialName' == reader.getLocalName()) {
                    polInfo.Insured_Name__c = getValueFromTag(reader);
                } else if ('Addr1' == reader.getLocalName()) {
                    polInfo.Address1__c = getValueFromTag(reader);
                }else if ('City' == reader.getLocalName()){
                    polInfo.City__c = getValueFromTag(reader);
                } else if('StateProvCd' == reader.getLocalName()){
                    polInfo.State__c = getValueFromTag(reader);
                }else if('PostalCode' == reader.getLocalName()){
                    polInfo.Zip__c = getValueFromTag(reader);
                }
                system.debug('polInfo record details>>>'+polInfo);
                //set policy information
               
            } else if (reader.getEventType() == XmlTag.END_ELEMENT) {
                // Is the next element an end tag? If yes is it an Account or an Accounts tag?
                if ('PolicyDetail' == reader.getLocalName()) {
                    // If you find end tag called account, push the account record in list
                    polInfoToInsert.add(polInfo);
                    system.debug('number of polstoInsert>>>'+polInfoToInsert.size());
                } else if ('IVANSExtract' == reader.getLocalName()) {
                    // We have reached end of file, just exit
                    break;
                }
            }
        }
          insert polInfoToInsert;
    }

// This is an extra function to read data between opening and closing tag.
// It will return the string of value from between tags
public string getValueFromTag(XMLStreamReader reader) {
    String DataValue;

    while (reader.hasNext()) {
        if (reader.getEventType() == XmlTag.END_ELEMENT) {
            break;
        } else if (reader.getEventType() == XmlTag.CHARACTERS) {
            DataValue = reader.getText();
        }
        reader.next();
    }

    return DataValue;
}
}


sfdcfoxsfdcfox
There are two types of methods: static and instance methods. With instance methods, you have access to "this", referring to the current instance, plus you can access all static methods. The inverse is not true, as static methods have no "this", because there is no instance to refer to. In fact, there may be zero, one, or many instances of the class available at any given time in memory. As an aside, future methods wouldn't work anyways, because they run outside of the current context where they were invoked from. Most likely, what you are intending to do is to make readResponse static so that the future method can use it.
iKnowSFDCiKnowSFDC

My understanding was that the @future method could only be executed on a static method when it was a call out - would you recommend making the read response static and using the @future method there and leaving the requestIvans method static? So essentially - the readResponse method would be as follows: 

@future
public static void readResponse(){
requestIvans();
/*the rest of the code*/
}

And the requestIvans would be as follows: 

public XMLStreamReader requestIvans(){
/*callout code*/
return reader;

}

iKnowSFDCiKnowSFDC
@sfdcfox - thanks - once I got my head wrapped around how to use a static method it worked. Thanks for your direction.