Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I am using Tooling API to create a class. Used the following link as reference to create a class and it works fine. But if i try to make it bit more dynamic by putting Apex Class Name in string and using it in the Body it doesn't work. I am getting following Error : "unexpected token: 'MyNewClass'","errorCode":"INVALID_FIELD_FOR_INSERT_UPDATE".

**EDIT

Following is the code snippet which i ran from the developer console.

String salesforceHost = System.Url.getSalesforceBaseURL().toExternalForm();

String url =  salesforceHost + '/services/data/v28.0/tooling/sobjects/ApexClass';

String sampleClass = 'MyNewClass';

String classBody = 'public class ' + sampleClass + ' {\\n' 
        + ' public ' + sampleClass + ' {\\n'
        + '\\n' 
        + ' }\\n'
        + '}';


HttpRequest req = new HttpRequest();

req.setMethod('POST');
req.setEndpoint(url);
req.setHeader('Content-type', 'application/json');
req.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());        
req.setBody('{'+
    '"Body" : "' + classBody +'"'+
 '}');
Http http = new Http();
HTTPResponse res = http.send(req);
String resBody = res.getBody();

Note : if i change the first two lines of classBody it will work i.e.

String classBody = 'public class MyNewClass {\\n' 
        + ' public MyNewClass {\\n'

Did i miss anything?

UPDATE

Use Double Back Slash by default since it works all the time. if you want to format the body contents by providing space then single slash may not work at times.

Thanks

share|improve this question
    
I just tried and it works just fine. Can you post you full code that you're using? Also, make sure that a class by the name MyNewClass doesn't exist before executing this code? Even if it does it should give a DUPLICATE_VALUE errorCode and not the above one.. –  theGreatDanton Jan 10 at 10:20
    
@theGreatDanton Hi..Thanks for the reply...i edited the question also the class is not present in the org...Also i tried this in multiple orgs and its not working –  ForceDeveloper Jan 10 at 10:27
    
Change the authorization header from OAuth to Bearer and try again. It should look something like this : req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId()); –  theGreatDanton Jan 10 at 10:30

1 Answer 1

up vote 9 down vote accepted

I found two problems with your dynamically constructed Apex code which I have addressed below.

  • You only need one back slash to inject the carriage return character into the code
  • You had not declared the class constructor correctly, it needed the braces ()

After i made these changes and applied to my Apex Tooling API code below it worked.

// Create the ApexClass via Tooling REST API
String sampleClass = 'MyNewClass';
String classBody = 'public class ' + sampleClass + ' {\n' 
        + ' public ' + sampleClass + '() {\n'
        + '\n' 
        + ' }\n'
        + '}';
JSONGenerator body = JSON.createGenerator(false);
body.writeStartObject();
body.writeStringField('Name', sampleClass);
body.writeStringField('Body', classBody);
body.writeEndObject();
HttpRequest createReq = new HttpRequest();
createReq.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v29.0/tooling/sobjects/ApexClass');
createReq.setBody( body.getAsString() );
createReq.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());
createReq.setHeader('Content-Type', 'application/json');
createReq.setMethod('POST');
Http h = new Http();    
HttpResponse createRes = h.send(createReq);     
share|improve this answer
    
Wow ..@andrew you're awesome...That constructor stuff was typo...Thanks for pointing it out...Its working as expected but i thought i need to escape the backslash when i embed it in string? –  ForceDeveloper Jan 10 at 10:39
    
It works even with the double back slash...I totally messed it up by missing the constructor syntax...thanks –  ForceDeveloper Jan 10 at 10:57
    
Ha no worries, you do need the back slash, the double back slash is to escape the back slash, i suspect it works either way because the API unescapes again internally. –  Andrew Fawcett Jan 10 at 11:11
    
Good Work Andrew .. –  Vineeth Jan 10 at 12:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.