8

In Salesforce if you try and do this:

JSON.serialize(data);

where data is an instance of a global Apex class in another managed package it will fail.

This seems like a completely arbitrary and pointless limitation, since all the global fields can be accessed anyway. So why did Salesforce do this, and is there any alternative?

1
  • 2
    What error message does it throw when it fails?
    – Mark Pond
    Apr 27, 2018 at 16:19

3 Answers 3

8

There is a @JsonAccess annotation. Check this:

https://releasenotes.docs.salesforce.com/en-us/summer20/release-notes/rn_apex_JsonAccessAnnotation.htm

This annotation has 2 parameters: serializable & deserializable with this 4 options:

  • never: never allowed
  • sameNamespace: allowed only for Apex code in the same namespace
  • samePackage: allowed only for Apex code in the same package (impacts only second-generation packages)
  • always: always allowed for any Apex code

Example:

@JsonAccess(serializable='never' deserializable='sameNamespace')

public class Foo {}

2
  • 1
    As links often break please post a summary of the linked content so that this answer will not become invalid if the link no longer works.
    – Dave Humm
    Aug 28, 2020 at 11:13
  • This is very welcome! Should have been in from the start!
    – NickJ
    Aug 29, 2020 at 11:43
3

If the error message is:

System.JSONException: Cannot serialize type from package: ...

then a Google leads you to Dan Watt's post Salesforce: Serializing Objects from a Managed Package that includes:

Only custom objects, which are sObject types, of managed packages can be serialized from code that is external to the managed package. Objects that are instances of Apex classes defined in the managed package can’t be serialized. (JSON Support)

Why? Who knows...

The only alternative that comes to mind is to duplicate the data structure using local Apex classes or build nested Map<String, Object> with matching names. Pretty horrible if the structure is complex.

2

I also got this error. Optionally you can ask from the package to expose it, with the annotation

@JsonAccess(serializable='always' deserializable='always')

Just will add that in case the class contains subclass, then both should be exposed with this annotation, otherwise you will get similar error on the inner class

@JsonAccess(serializable='always' deserializable='always')
public class DemoClass1{
    
    @JsonAccess(serializable='always' deserializable='always')
    public class MyInnerClass{
    
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .