2

So I have the following code:

 @HttpPost
 global static void execute(){
     String json = RestContext.request.requestBody.toString();
     JSON.deserialize(json, List<DTO>.class);
 }

but when I try to do it with a try catch, I need to do the following:

@HttpPost
global static void execute(){
    String json = RestContext.request.requestBody.toString();
    try{
        System.JSON.deserialize(json, List<DTO>.class);
    }
    catch(Exception ex){}
}

I don't understand why inside a try/catch block it won't compile unless I write the System namespace. Is it a bug?

  • 1
    Is that your actual code? Seems like it shouldn't compile because I'd think you need to assign the result of deserializing your JSON to some variable. – Derek F Jan 31 '18 at 16:24
  • @DerekF no, it isn't. It's a snippet I extracted for clarity of concept. – Javier García Manzano Jan 31 '18 at 16:26
3

The code that you wrote may have been an over-simplification. It does not compile in either of my orgs. If it does happen to compile, you may have stumbled across a compiler bug.

However, it is possible to end up constructing code like the following:

String json = JSON.deserialize(RestContext.request.requestBody.toString());

This works because "json" has not been defined until after the current statement executes, so it resolves without causing an error. However, once defined, you can no longer refer to the system library as JSON, but instead have to refer to it as System.JSON to disambiguate the token.

As a general rule, you should not use any standard library name (e.g. Schema, Account, Test, JSON, EncodingUtil, etc), unless you want to break your code in spectacularly amazing ways. For example, a top-level class named Test will cause practically all of your well-written unit tests to fail.

Since, as far as I can tell, the first code example should not compile, do not use it, because one day in the future, if and/or when this bug is fixed, your code will automatically fail to compile one day. In fact, your code may prevent salesforce.com from fixing the bug, since it will likely fail the Hammer Test.

1

I'm surprised the first one compiles.

Apex is case insensitive so the token json which is a String variable takes precedence over the type JSON. Introducing the System namespace points the compiler to the type JSON which is in that namespace.

Generally I try to avoid using type names as variable names: it's annoying but can save some pain.

  • So it's just an issue with case sensitivity lmao... I'll recheck it at home. Thanks for the heads up! – Javier García Manzano Jan 31 '18 at 16:00
  • 1
    @JavierGarcíaManzano Nothing to do with case sensitivity. – sfdcfox Jan 31 '18 at 16:34
  • @sfdcfox Why not in that in case sensitive languages json and JSON are separate tokens but not in Apex? – Keith C Jan 31 '18 at 16:37
  • 1
    @KeithC I suspect it has to do with some obscure rule being triggered in Type Resolution and System Namespace for Types, possibly version dependent. This code does not compile when copied to my org (with an appropriate substitution for DTO). Apex Code does not case-sensitively compare variable or class names in any situation. – sfdcfox Jan 31 '18 at 16:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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