September 22, 2010

Deep Dive - Static Context in Visualforce Apex Controllers !

Apex static is always confusing for me, I am from Java background, so it took a while for me to really understand differences between Apex vs Java static. This post discusses apex controller static behavior, i.e. in relation to Visualforce only. Here by Apex Controller static, I mean static variables/blocks declared in controller associated with a Visualforce page.

The Apex STATIC context – Variables & Code initialization blocks !

(Intermediate/Advanced Apex developers can skip this section)

Apex gives static context in form of static variables and static blocks. Most of developers from Java background understand the static block, but those who are ramping up from PHP etc, please go thru this topic on static in Salesforce Docs :

Apex VF Controller Static – Common MYTHs !

Developers, specially from Java background assume, that static variables once initialized on first class load, can be shared/updated across multiple HTTP requests. This typically goes with Java classes. But this is not true at all with Apex, never expect to set some value in Apex static variable and expect it back in next request, even next Ajax request. On every new request, you will find static variables re-initialized to the value declared or updated in static blocks.

Then, what is STATIC in Apex Controller ? – Real Story !

In general as per Salesforce docs, this is definition of static.

Static variables are only static within the scope of the request. They are not static across the server, or across the entire organization.

This definition is a one liner, but it applies well on every Apex static context. The thumb rule to understand static in Apex controller is

Static Variables and Blocks are re-executed on each User HTTP Request or Visualforce Ajax Request

Please NOTE that, the static variables/block are re-executed for Ajax requests generated via Visualforce i.e. by actionFunction, actionPoller, commandLink or commandButton tags etc. You must be wondering Whyyy ? This is because HTTP is stateless protocol, Visualforce only maintains view state(as hidden input field) to re-store all non-transient instance level variables in Apex Controller. Static variables are never stored in view state, as said in Salesforce docs clearly :

Static variables aren't transmitted as part of the view state for a Visualforce page.

So to re-store all static stuff back, force.com platform recreates all static variables and executes all static block on each normal or ajax http request. So thats why one can’t share data across the requests via static variables, they are always recreated first on each request(VF Ajax request too)

Apex Static, and the mind set change

For programmers from other backgrounds like J2EE, PHP etc, its a mindset change because:

  • JVM(Java Virtual Machine) usually don’t reload classes. A Java class is loaded once in memory usually stays till container is UP. Same stands true with static variables in Java too, all information kept in static context is available through out the application across different user sessions etc.
  • J2EE & Frameworks like Struts, create a Session per user login like Salesforce. But that session is available to multiple requests via Cookies etc and acts as good mini container to store logged in user specific information.

But these both Java approaches are memory hogs and not scalable to multiple users, that’s why J2EE containers have complex session and other clustering mechanisms to scale for huge enterprise apps.

So, having static in this manner is important for success of multitenant nature of force.com platform. As force.com is multitenant, multiple customer orgs, with multiple users share the same hardware resources like CPU, RAM(Memory). If Apex static was like Java, then I can’t imagine how much memory would be required by force.com servers to match the current load. I am sure, they can’t scale !

So, are Static variables good for anything in Apex Controllers ?

As, static variables are not part of view state. One can consider static as “C” language CONST, use them to declare constants in Apex.

Next …

In my next post, I will discuss Apex static context in Triggers.  Would love to discuss your ideas/views on Apex Controller static context, please comment !!