10

I want to find a quick way to be able to run ad-hoc pieces of Apex code asynchronously in developer console so I have higher limits. I want to be able to write and update this code quickly (no sandbox deployments or anything like that). Here's my problem:

The code below runs when I take out @future but when I add it, it will throw a "no enclosing class for method updateCD" error. When I put it in a class, the error changes to "Only top-level methods can be static". How can I resolve this?

@future
public static void updateCD(){
myObject cf = [SELECT id,name FROM myObject WHERE Name =:'ABC' LIMIT 1];
cf.name = 'DEF';
update cf;
}

updateCD();

2 Answers 2

11

I suspect you won't be able to get true asynchronous anonymous code working.

The problem is that your anonymous Apex only exists for the transaction it was created in. By the time the asynchronous Apex runs there is no definition of your anonymous Apex to be found on the application server that would ultimately run it.

Without true Eval support in Apex there isn't a way to run anonymous Apex on the fly. You can fake it a bit with callouts, but that won't give you the higher limits you are after.

See also:

6

You might be able to accomplish this by implementing a future class in the org that takes a string and runs it through the Tooling API. This answer has more details.

I've included some things I tried that didn't work below:

My first thought was to use Queueable, which initially seemed to work just fine inside Execute Anonymous:

public class testQueue implements Queueable
{
    public void execute(QueueableContext context)
    {
        System.debug('test');
    }
}

System.enqueueJob(new testQueue());

However, although this compiles and runs without errors, and even returns a job ID from `system.enqueueJob, the job is not actually enqueued and if you check the database no job with that ID will exist. I also verified by attempting to update a record that the job does not run.

So, I figured that another option might be to implement a class that runs a constructor inside a future method, and dynamically construct the type:

Class saved to Org:

public virtual class futureHandler 
{
    @future
    public static void runFuture(string toRun)
    {
        Type runnableType = Type.forName(toRun);
    futureRunnable toRunInstance = (futureRunnable)runnableType.NewInstance();
    toRunInstance.run();
    }
}

public interface futureRunnable
{
    void run(){};
}

Execute Anonymous Code:

public class futureDo implements futureRunnable
{
    public void run()
    {
        System.debug('test');
    }
}

futureHandler.runFuture('futureDo');

However, the issue with this is that the execute anonymous class doesn't exist by the time the future method is called, so Type.forName returns null. I'm guessing this issue is what's causing the issue with the Queueable attempt as well. This leads me to believe that there is no way to accomplish this outside using Execute Anonymous via the Tooling API.

You must log in to answer this question.

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