+ Start a Discussion
ShiztasticShiztastic 

Schema.getGlobalDescribe

Is there any reason the Schema.getGlobalDescribe() method would suddenly stop returning anything?  I have noticed this strange intermittent behavior seems to start when I run test cases.  Sometimes the getGlobalDescribe will just stop returning anything for a day or so and then it just magically starts back up again.
 
Any info on why this happens would be much appreciated.  Thanks.
 
 
Shiztastic


Message Edited by Shiztastic on 10-21-2008 02:45 PM
Best Answer chosen by Admin (Salesforce Developers) 
CliffACliffA

For closure, it looks like Spring 09 addressed this issue.  From the release notes:

 

API Access Change for Dynamic Apex Scripts
Prior to Spring '09, when the API Access for a package was set to Unrestricted, dynamic Apex scripts only had access to the custom objects contained in that package. Now, when API Access for a package is set to Unrestricted, dynamic pex scripts have access to the custom objects contained in the package as well as all standard and custom objects in the ubscriber's organization.

All Answers

jpizzalajpizzala
I'm experiencing a (possibly) related issue.  When I run the Schema.getGlobalDescribe() through the System Log, it returns everything just fine.  However, when I run it through my Apex code, I get nothing.

I don't understand how there could be a difference between the two methods.  Are there multiple sets of compilers operating on different components?  Seems like everything would be compiled and run on the same code base.

Here is what my code looks like:

Code:
 public List<SelectOption> getTestOptions() {
  
  List<SelectOption> options = new List<SelectOption>();
     
  options.add( new SelectOption( 'test', 'test' ) );
      
  Map<String, Schema.SObjectField> accountFieldMap = Schema.getGlobalDescribe().get( 'Account' ).getDescribe().fields.getMap();
  
  System.assert( accountFieldMap != null );
          
  for( String fieldName : accountFieldMap.keySet() ) {
      
   Schema.DescribeFieldResult field = accountFieldMap.get( fieldName ).getDescribe();

   String fieldType = ( '' + field.getType() ).replace( 'Schema.DisplayType.', '' );

   // Add field name to the list options if it is an email type
   if( fieldType.equals( 'EMAIL' ) ) {
       
    options.add( new SelectOption( field.getLocalName(), field.getLabel() ) );
       
   }
      
     }
     
  System.debug( 'options values: ' + options );
     
  return options;
  
 }

 Running the above in the System Log's "Execute Apex" box, the "options values: " debug line returns the following:

Code:
20081022000418.359:AnonymousBlock: line 24, column 9: options values: (System.SelectOption[value="test", label="test", disabled="false"], System.SelectOption[value="FooEmailField__c", label="Foo Email Field", disabled="false"]) 

 Everything is working just fine.  However, when I try to execute the code in Apex (via a Visualforce page), I get this:

Code:
Visualforce Page: /apex/addeditsend

System.NullPointerException: Attempt to de-reference a null object

Class.TestClass.getTestOptions: line 12, column 87 External entry point

Debug Log:

***Begining Page Log for /apex/addeditsend
20081022001210.782:External entry point:     returning from end of method public TestClass<Constructor>(CommunicationSystemControl) in 0 ms
20081022001210.782:External entry point:     returning from end of method public AttachmentExtension<Constructor>(CommunicationSystemControl) in 0 ms
20081022001210.782:Class.CommunicationSystemControl.loadSend: line 70, column 9:     returning from end of method public void setActiveSend(SOBJECT:CommunicationCampaignSend__c) in 0 ms
20081022001210.782:Class.CommunicationSystemControl.loadSend: line 71, column 9:     returning from end of method public void setActiveCampaign(SOBJECT:CommunicationCampaign__c) in 0 ms
20081022001210.782:Class.CommunicationSystemControl.loadSend: line 72, column 9:     returning from end of method public void setActiveMergeContent(SOBJECT:CommunicationCampaignContent__c) in 0 ms
20081022001210.782:Class.CommunicationSystemControl.initializeAddEditSend: line 27, column 9:     returning from end of method private void loadSend() in 0 ms
20081022001210.782:External entry point:     returning from end of method public void initializeAddEditSend() in 0 ms

Element j_id0 called method {!initializeAddEditSend} returned type PageReference: none20081022001210.782:External entry point:     returning SOBJECT:CommunicationCampaignSend__c from method public SOBJECT:CommunicationCampaignSend__c getActiveSend() in 0 ms

 Which points at line 12 in the TestClass:

Code:
Map<String, Schema.SObjectField> accountFieldMap = Schema.getGlobalDescribe().get( 'Account' ).getDescribe().fields.getMap();

 Communication between the Visualforce page and this Apex TestClass (added as an extension in the Visualforce page) is valid (previous tests affirmed this).

I'm at a loss for a solution.  I've been trying to debug this for some time, yet nothing makes sense.

Could this be a temporary bug from the Winter '09 update?

CliffACliffA
I've been wrestling with this same problem today and it appears to be related to packaging.  To test my theory I created a test class:
Code:
public class DynamicApexTest {

    public static void descObj() {
        
        Map<String, Schema.SObjectType> globalSchemaDesc = Schema.getGlobalDescribe();
        Set<String> objNames = globalSchemaDesc.keySet();
        System.debug('How many objects do we see? ' + globalSchemaDesc.size());
        for (String objName : objNames) {
            System.debug('Object Name=' + objName);
        }
    }
    
    static testmethod void testQueryLimitNewDonation(){
        descObj();
    }

}

 
If I package this class and run tests then globalSchemaDesc.size() == 0, it can't see any objects

If I take the class out of the package and run tests then globalSchemaDesc.size() == 161, it sees all objects

The documentation references limitations for packaged describe statements (http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dynamic_describe_objects_understanding.htm):

Understanding Describe Information Permissions

Apex generally runs in system mode. All classes and triggers that are not included in a package, that is, are native to your organization, have no restrictions on the sObjects that they can look up dynamically. This means that with a native script, you can generate a map of all the sObjects for your organization, regardless of the current user's permission.

Dynamic Apex scripts, contained in managed packages created by certified Apex partners, that are installed from Force.com AppExchange, have restricted access to any sObject outside the managed package. Partners can set the API Access value within the package to grant access to standard sObjects not included as part of the managed package. While Partners can request access to standard objects, custom objects not included as part of the managed package and can never be referenced or accessed by dynamic Apex scripts that are packaged.


The behavior I'm seeing, however, does not appear to match SF's description.  I would expect the packaged class to at least see the custom objects that are in the package.  In addition, my package is setup with "API Access    Unrestricted [Package contains S-Controls]" so I would also expect to see standard objects too. 

Can someone at SF shed some light on this?

mshelmanmshelman
There have been numerous posts describing similar issues since inception of Winter 09. I attempted to reference them in this post:  Is anybody out there?

While Salesforce has been strangely silent on this it appears that the problem has to do with the API Access field on the package. My understanding is that in order to reference standard objects in any form of Dynamic Apex or Describe calls then the "restrictions" must  be enabled for the standard objects. However, I experienced similar errors with a custom object that is included in the package. Such behavior seems like a bug. When I enabled Read permissions for all the standard objects listed the errors for my custom object ceased.

Apart from everything else the nomenclature seems backward. To permit accessing the objects then we "Enable Restrictions" and if we don't want to allow access then it's "Disable Restrictions"
jpizzalajpizzala
I have removed the SControl from this package, which has allowed me to manually specify the restrictions.  I set the API Restrictions to Read on the Account object.  This kinda works - now I can get fields from the Account record - but only the standard fields.  None of the custom fields show in the describe.

Anyone else experiencing this?
jpizzalajpizzala
Also, with the restrictions enabled, I can no longer access my Apex controller's webservice methods via Javascript.  Here is the error message I get from the Firefox JS console when I try to execute the webservice call:

Code:
Error: uncaught exception: {faultcode:'sf:INSUFFICIENT_ACCESS', faultstring:'CommunicationSystemControlExternal: no access allowed to this class.', }
 
Yet when I disable restrictions, all is fine and the communication lanes are open.

Actually, when I think about it, this functionality is most likely intended.  It is the previously mentioned global describe functionality that seems to work backwards with the restrictions.

Hopefully a SF admin will be able to shed some light on this.
mshelmanmshelman
Mr Wilburn's states that "I was just informed that this is a known issue and the fix is a few weeks out.
The work-around appears to be to avoid using packages with dynamic apex/SOQL until that fix is out."

System.QueryException: object is not accessible in query due to package restrictions
gjsgjs
There are a number of issues around dynamic covered by a number of bugs:
 
Bug #210020 covers:
 
1) PAC does not allow access to subscriber created custom field extensions. EG:

Namespaced(fRecruit) Dynamic code has access to fRecruit__Canidate__c sobject. But if the subscriber adds a field to the object, Dynamic code cannot operate on this custom field.

2) By default, namespaced code should have complete dynamic access on the namespaced objects/fields - regardless of whether PAC is enabled.
 
We plan to fix this in a Summer 08 patch.
Bug #215860 covers:
 
PAC must be enabled in order for dynamic apex to work, but if your package contains an scontrol, we don't allow you to set PAC on the package.
 
This bug is under consideration for Winter 09.
 
Bug #208274 covers:
 
Dynamic Apex Describe Intermittently Not Return Field Names.
 
This bug has been closed out as "Not reproducible". We'd love to get a repro case.
 
ShiztasticShiztastic
I am not sure if this will help, but this problem seems linked to creating a package.  I don't have a problem with the getGlobalDescribe() until I create a package.  I usually have to delete the package in order to get the function to start working again.  It's impossible to recompile the package (new Managed Package Version) because the global function fails which makes the test cases fail as well.  The only solution is to delete the package, wait for the function to start working, recreate the package.
JakesterJakester

Hi Greg,

Shiztastic and I could probably reproduce this for you. It happens intermittently, but pretty (annoyingly!) frequently, too. We could do a web meeting, and sure would love to sort this thing out.

If that sounds good, please contact me at dancingjake <at> gmail.com

Thanks!

-Jake

ShiztasticShiztastic
It's currently showing its awesomeness in my development area right now.
NodakPaulNodakPaul
I ran into this same problem.  The solution that I have found, as have others, is to Enable Restrictions, and then explicitly allow access to any standard object that you want to interact with.

http://www.sundog.net/index.php/sunblog/entry/getting-dynamic-apex-to-work-in-managed-applications/

BTW, this works well as long as you are only trying to interact with the 13 standard objects that are listed.  Unfortunately there are a LOT of objects that are left out, such as the User object.  Out of the 125 default objects that are visible in an unpackaged application, only 39 are visible once you package it.


Message Edited by NodakPaul on 01-08-2009 09:40 AM
CliffACliffA

For closure, it looks like Spring 09 addressed this issue.  From the release notes:

 

API Access Change for Dynamic Apex Scripts
Prior to Spring '09, when the API Access for a package was set to Unrestricted, dynamic Apex scripts only had access to the custom objects contained in that package. Now, when API Access for a package is set to Unrestricted, dynamic pex scripts have access to the custom objects contained in the package as well as all standard and custom objects in the ubscriber's organization.

This was selected as the best answer
JakesterJakester

Yes, it did the trick-

 

Shizz and I have been able to reliably put out new releases ever since the little frog jumped on the scene.

xtgjxtgj

uncaught exception: {faultcode:'sf:INSUFFICIENT_ACCESS', faultstring:'

 

I am not 100% sure this is related to this thread, but it was the only one that came up when I search for the above, so thought I might as well post it for anyone else to know.

 

 

I got the above error, when our users in Germany was using a button that called a S-control webservice

 

    ... sforce.apex.execute('ApexClass' , 'serviceName',...

 

What I found out was:

That in the Setup->Develop->Apex

 

The security for that particular class had to allow the user role, which makes senses, but was not obvious when developing using an admin account :).

 

Message Edited by xtgj on 03-11-2009 08:36 AM