You need to sign in to do that
Don't have an account?

Null Object Error for Managed Package Class
1% of installers surface this error to me every time the Lead trigger in the app fires:
Apex script unhandled exception by user/organization: 00560000000nYMJ/00D30000000039c
Failed to invoke future method 'public static void evaluateLeads(SET:Id)'
caused by: System.NullPointerException: Attempt to de-reference a null object
(leadScoring)
External entry point
Debug Log:
Any ideas why the class LeadScoring would be null and the method call fails?
This Lead trigger calls the class, which should exist upon install unless something went wrong:
trigger evaluateLeadScoringRulesLeadInsertOrUpdate on Lead (After insert, After update) {
Set<Id> leadIds=new Set<Id>();
//Needed as asynch apex does not allow passage of Sobjects, only Set's
for (Lead l:trigger.new){
leadIds.add(l.Id);
}//for
//Send that list of created or updated campaign members to the apex class for processing
system.debug('Future lead scoring method evaluateLeads already called? '+LeadScoring.leadScoringClassAlreadyCalled());
if (LeadScoring.leadScoringClassAlreadyCalled()==False){
system.debug('# Future Calls until limit hit: '+Limits.getLimitFutureCalls());
if (Limits.getLimitFutureCalls()>0){//don't call the method if the limit is reached
LeadScoring.evaluateLeads(leadIds);
}
}
}//trigger
Class called from the trigger that seems to be the source of the NPE:
public global class LeadScoring {
public static Boolean leadScoringClassAlreadyCalled=FALSE;
public static boolean leadScoringClassAlreadyCalled(){
return leadScoringClassAlreadyCalled;
}
@future //this method is called from the trigger. It's an asynch method so the trigger call has high governor limits
public static void evaluateLeads(Set<Id> leadIds){
evaluateLeads2(leadIds);
}//evaluateLeads
//this method is called from batch apex. It cannot be an asynch method as batch apex can't call @future methods
public static void evaluateLeads2(Set<Id> leadIds){
Integer i,j;
Double scoreChange;//safer to define as a double in case anyone tries to change the field's # decimals
Schema.DescribeFieldResult cmFieldDescribe;
leadScoringClassAlreadyCalled=TRUE;
...
...
Thanks for the help!
I have a managed package that works for 99% of installers, but 2 are returning these email errors to me:
Apex script unhandled exception by user/organization: 00560000000nYMJ/00D30000000039c
Failed to invoke future method 'public static void evaluateLeads(SET:Id)'
caused by: System.NullPointerException: Attempt to de-reference a null object
(leadScoring)
External entry point
Debug Log:
This trigger calls a bigger class, which should exist upon install unless something went wrong:
trigger evaluateLeadScoringRulesLeadInsertOrUpdate on Lead (After insert, After update) {
Set<Id> leadIds=new Set<Id>();
//Needed as asynch apex does not allow passage of Sobjects, only Set's
for (Lead l:trigger.new){
leadIds.add(l.Id);
}//for
//Send that list of created or updated campaign members to the apex class for processing
system.debug('Future lead scoring method evaluateLeads already called? '+LeadScoring.leadScoringClassAlreadyCalled());
if (LeadScoring.leadScoringClassAlreadyCalled()==False){
system.debug('# Future Calls until limit hit: '+Limits.getLimitFutureCalls());
if (Limits.getLimitFutureCalls()>0){//don't call the method if the limit is reached
LeadScoring.evaluateLeads(leadIds);
}
}
}//trigger
Class called from the trigger that seems to be the source of the NPE:
public global class LeadScoring {
public static Boolean leadScoringClassAlreadyCalled=FALSE;
public static boolean leadScoringClassAlreadyCalled(){
return leadScoringClassAlreadyCalled;
}
@future //this method is called from the trigger. It's an asynch method so the trigger call has high governor limits
public static void evaluateLeads(Set<Id> leadIds){
evaluateLeads2(leadIds);
}//evaluateLeads
//this method is called from batch apex. It cannot be an asynch method as batch apex can't call @future methods
public static void evaluateLeads2(Set<Id> leadIds){
Integer i,j;
Double scoreChange;//safer to define as a double in case anyone tries to change the field's # decimals
Schema.DescribeFieldResult cmFieldDescribe;
leadScoringClassAlreadyCalled=TRUE;
...
...
Could these be caused by:
- No apex perms for the running user?
- Bad package install?
- No @future perms for the running user?
As this is a managed package, the customer can't do much to debug either.
Hey
Can't see anything obviously wrong here. There is one bit that might confuse the call method though:
I'm sure this sounds like I'm grasping at straws - and I am - but try declaring the variable as private. I've had more than one issue related to various code/object artifacts with the same name and similar levels of access. In each of these cases I've gotten red herring error messages.
Good luck,
Wes
Thanks Wez! I tried this but it fails creation of leads as the method is not visible from the trigger then.
I appreciate you responding though as this is a really tricky issue to debug.
Ah sorry, I meant that the variable should be private:
haha-thanks. I'm a little slow on both reading carefully & replying timely.
I've made the var private and we'll see how it goes! Tricky part is that I'll only know in a month or two if the next 200 installs have zero issues like this.
Thanks again for the help!
John,
We are running into "too many future calls:11" error.
Looking at this code, it appears that there is a bug. The getLimitsFutureCalls will always return 10 - this is the maximum number of calls that can be executed in the context. The code should be as follows. Let me know what you think.
Good call GoForceGo - I don't receive those as errors via email, so I wasn't aware of the mistake. I've updated both of the triggers that use the limit check.
I'll have an updated package live probably tomorrow as the security review can take a day or two.
You don't get apex exception messages? I assume you have sent the exception user for your package?
I am surprised no one else has reported this - I guess no one is calling future more than 10 times!
Looks like you're the one :) I think most folks don't have many apps that make @future calls and there probably aren't a lot of people that are writing their own code to make that many either.
I think this will get fixed with this fix,. but it might be worth validating.
If someone else has a @future calls where they update leads, your trigger will get called. I suspect the getLimitsFutureCalls will return 0 and your @future won't get called. Otherwise,. people will get the "future cannot call future" error.
Hey GoForceGo, just wondering why you think the Limit.getLimitFutureCalls() > 0 is a bug
When it executes in a Batch Context, it should have a value of 0.
Also when in a Future Context, it should have a value of 0?
Limit.getLimitFutureCalls() - Limit.getFutureCalls() should in theory yield the same value?
I'm hitting a similar error in my code.
If this code is evoked when you are not in a future/batch call, Limit.getLimitFutureCalls() will always return 10. So if you are calling a future method based on this condition, you will eventually hit the limit - that's why it is a clear bug. If you call it from a future method, I am not too sure.