Intro to Chatter article now available

by Quinton Wall on March 3, 2010 at 08:56 AM

I wanted to let you know that my Introduction to Chatter article is now available. I tried to make sure I covered everything you need to start extending Chatter, and making it your own. (I have some ideas, and would love to hear yours) There is a lot of discussion around the Chatter Model (by far the biggest question we have been getting from the developer community,) some handy tips for working with Chatter in your Developer Edition, and of course, LOTs of code/SOQL samples.

 So, read up, jot down your thoughts and questions, register for the upcoming Chatter Developer Preview Tech Talk, (we have some cool demos and code to share, so make sure you attend), share, and as always, feedback is appreciated!

Using the System Log and Filters to speed debug time.

by Quinton Wall on March 1, 2010 at 11:10 AM

Sometimes the simplest tips are the best. It always surprises me how many people forget about the System Log Console. This innocuous little link at the top of your Salesforce screen is a gem for debugging code snippets or tracking code execution. With the Spring '10 introduction of customizable filters, things just got a whole lot better! Here are a few quick tips to help you speed the time you spend debugging code in the app.

Let's start by executing a code snippet using the System Log to check the size of the number of Accounts I have in my org. After typing my code and clicking execute, I can click on the latest log line item to drill into the debug to see the result of my little test. (and better still, I can go back to previous logs without jumping back to a previous screen)

System Log1

Cool huh? By itself, the System log is extremely helpful: I tested my code snippet, and quickly found the line of debug I wanted.

But what happens when I have a LOT of other activities in my system? My log messages might get lost amid the other output statements being written to the log. This is where Filter Settings really help.

Let's use our same Apex Statement, but this time click "Show Filter Settings" at the top of the System Log. You will be presented with a Filter Details section where you can control what log messages are displayed when. A good tip I like to do when debugging some complex Apex code, for example, is to set all of the Category levels to "NONE", except for Apex. Now execute our snippet again, click the log, and see the difference:

System Log3

 Much neater isn't it? We can see just the information we want quickly, and easily. The nice thing is that, after playing with Filter levels, clicking the Reset button will return the Filters to their default values Keep in mind too that setting the Filters through the System Console effect the logs accessible via Setup | Administration Setup | Monitoring, not just the System Console.

With the ability to filter log levels across categories, a best practice for development I typically follow is to add business related log messages using the LoggingLevel.INFO static variable throughout my application (I use LoggingLevel.DEBUG--the default log level if you do not specify anything in your System.Debug statement--for development time checking only, and remove these statements before pushing my code to production). Then when I have a piece of code that appears to be functioning incorrectly, I can quickly filter my logs, narrow in on the offending section of code, and determine if, indeed, I have an error.

Using Scheduled Apex jobs to retrieve stock quotes.

by Quinton Wall on February 17, 2010 at 07:46 PM

Spring '10 saw the general availability of one of my favorite new features of the platform: the Apex Scheduler. 

With the Apex Scheduler, developers can now schedule cron style jobs to run any Apex classes which implement the Schedulable interface.  The Schedule Apex page, available from Setup | Develop | Apex Classes, lets you define the how often your particular job will run.

Apex-schedule
 One of things which you may notice is that you are can only schedule jobs to run up to once a day using the Schedule Apex page. Never fear, however, for with a little bit of code you can schedule your jobs to run every hour.  Let's look at a real world example:

Suppose that every hour I wanted to retrieve the current stock quote for an account using the very handy, but often overlooked Yahoo stock API. 

global class getStockPrice implements Schedulable
{ 
 global void execute(SchedulableContext ctx)
 {
 //call a future method so we can do callouts within a schedule
    CallYahooQuotes.getQuotes();
}
}

You will notice that I have implemented the Schedulable interface and overriden the execute method in my Apex class. That is all I need to do to take advantage of Apex Scheduling. Pretty cool, huh. In this example I also used the @future annotation to allow me to do a callout from within a Scheduled Job. Here is the code which does the actual retrieval of stock price information from Yahoo's service:

global class CallYahooQuotes
{
    @future(callout=true)
    public static void getQuotes()
    {   //for our simple example we are going to just update the quotes on one Account
       Account acct = [select id, TickerSymbol, stock_price__c from account where name = 'Salesforce.com'];
   
       //where f stands for the fields to be displayed (in this case: s - symbol; l1 - last price; c1 - change; d1 = last date)
       // String url = 'http://quote.yahoo.com/d/quotes.csv?s='+acct.TickerSymbol+'&f=sl1c1d1&e=.csv';
     
     String url = 'http://download.finance.yahoo.com/d/quotes.csv?s='+acct.TickerSymbol+'&f=l1&e=.csv';
    
    Http h = new Http();
    
    HttpRequest req = new HttpRequest();
    req.setEndpoint(url);
    req.setMethod('GET');
    
    HttpResponse res = h.send(req);
    
    //omitting error handling for example
    acct.stock_price__c = decimal.valueOf(res.getBody().trim());  
    update acct;  
   }

}

 Next, I want to schedule my job to run every hour.

A best practice I like to follow is to create a wrapper Schedule class with a static start method. This way I can either call my class from, say a custom Visualforce page after a user clicks a button, or via  the execute function in the System Log.

global class StockPriceJobScheduler
{
 global void StockPriceJobScheduler() {}
 
 public static void start()
 {
 //Seconds Minutes Hours Day_of_month Month Day_of_week optional_year
 System.schedule('Stock Price Update', '0 0 1-23 * * ?', new getStockPrice());
 }
}

The System.schedule method takes three parameters: a job name, a cron expression, and the name of the schedulable class. The only tricky parameter is the cron expression. Take some time to read the docs to fully understand the syntax of cron expressions as they are a handy tool to have in your developer toolbox.

One thing that you will discover as you try out scheduling is that, although it is possible to schedule a job to run more frequently than every hour, the platform will assign a minimum frequency of 1 hour. 

Let's go ahead and use the System Log (click on the System Log link at the top of your screen) to start our new Scheduled Job:

System Log
Finally, navigate to Setup |   Monitoring | Scheduled Jobs and you should see our new job with the name we gave it during the scheduling process.

Scheduledjob
That's it. With less than 30 lines of code (a some of those are comments!) we just created a scheduled job to receive stocks quotes from the web and updated our Account. 

Spring is certainly here!

Developing in the Cloud grows in importance

by Quinton Wall on February 4, 2010 at 02:35 PM

I came across an interesting article by Paul Krill of Infoworld the other day which the author made a important point in regards to developers moving into the cloud. Krill refers to a recent survey that indicates "61 percent of developers report that at least some of their IT resources will move to a public cloud within the next year". This is further re-enforced by analysts like Forrester, who are also referenced in the article.

That percentage alone, is a good indicator that cloud development, and in particular ,feature-rich platforms must make it easy for the millions of existing application developers to start developing in the cloud. 

Jeff Cogswell, from Ziff Davis recently tried out developing in the cloud. His experience mirrored many of my initial impressions which I first began developing on the Force.com platform. Yes, there is a mind-shift to get used to with everything no longer happening on your local machine, but you quickly become comfortable with a familiar Java or C-like syntax of Apex making you feel, as Jeff stated, "quite at home using it."

The ability to easily shift between platforms and languages is increasingly important in a modern developers bag-of-tricks. Krill, in his article refers to another survey which suggests the hybrid cloud---a combination of existing on-premise and cloud application---will continue to play a bit part in IT departments, and therefore the developers, lives. 

Tonight is the first of a series of Developer Meetups with direct intention of getting people to experience developing on the platform. I am sure there will be a strong mix of existing application developers and veteran Force.com developers. It should be a great night. I hope to see you there soon.


Apex Code Enhancements and Collections best practices

by Quinton Wall on January 29, 2010 at 03:45 PM

Spring '10 is just around the corner, with many great new features. One of the Apex Code enhancements which caught my attention was the limits on the number of items a collection can hold has been removed. The previous limit was set at 1000. Add this to the new ability to use generic sObjects to create a collection and Collections within the platform just got a whole lot more powerful.

As Ben Parker, the o-so-wise uncle of Peter Parker (aka Spiderman) once said: "with great power comes great responsibility." Changes to Collections is no different, and require some new thinking in regards to best practices.

The release notes, for example, mention that there is still a limit on heap size so care must be taken to not load up a collection and hit this limit. Good news is that a few other other Spring '10 changes can certainly be used to ensure you design your applications as efficiently as possible. 

Here are just a few new SOQL clauses and functions which can be used with collections to help make the most fo the changes.

This is certainly not a complete list, but should certainly be something every developer is familiar with.

Default Task Type to Email when sending an email

by Rasmus Mencke on October 30, 2009 at 03:01 PM

One question I hear over and over again, is why is the task type when I am sending an email in Salesforce not defaulted to Email? This is becomes an issue when you want to do reporting on all your tasks and they are logged as your default task type which generally is "Call".

I have written an Apex Trigger you can use to overwrite the Task Type and set it to "Email" when you are sending out an email from Salesforce. The trigger will look for "Email:" in the subject and also look for "Additional to:" as the first part of the description.

trigger SetTaskType on Task (before insert) {
For (Task nc:Trigger.new) {
String subject = nc.Subject;
String description = nc.Description;

if ( subject != null && subject.startsWith('Email:') && description.startsWith('Additional To:')) {
nc.Type = 'Email';
}
}
}

Quiz - how can you have 100% test coverage in Sandbox and 0% in production?

by Nick Simha on October 1, 2009 at 05:36 PM

Answer - if your test suite is not self contained i.e. it depends on specific data in Sandbox.

I got a call from one of our customers today about not being able to deploy into their production org due to inadequate test coverage even though they were getting 100% coverage in their development sandbox.  Our support tracked it down to hard coded test methods.  If your test methods depend on specific data in an org and you move such a test method to a different org, it will fail.

Here is an example where the record Id is hardcoded.....

static testMethod void myTestHardcodedIds(){

// INCORRECT - By hardcoding this Account Id in the test method, the test method
// will fail in every other org where this code is deployed because the hardcoded
// Account Id won't exist there.
Account testAccount = [select id,name from Account where Id='001300000040lMM'];
testAccount.billingState='CA';

update testAccount;

// Verify that the billingState field was updated in the database.
Account updatedAccount = [SELECT billingState FROM Account WHERE Id = :testAccount.Id];
System.assertEquals('CA', updatedAccount.billingState);

The right way to write test methods is to make them self contained i.e. not depend on data in a particular org.  I have taken the above example from this great article on testing.  I encourage you to go through that to find out how to write the above test method correctly as well as other best practices.

A hog in armour is still but a hog

by Nick Simha on September 23, 2009 at 01:35 PM

There are two distinct approaches that the industry has taken towards platform as a service (PaaS).  The first approach is offering an integrated and vastly simplified programming model in the cloud.  This provides all the infrastructural benefits of Cloud Computing like multi-tenancy, automatic upgrades & elastic infrastructure PLUS it speeds up application development considerably.  Force.com is representative of this approach. I would also encourage you to checkout Mike Kreaden and Peter Coffee's blogs.  Mike relates Force.com to 4GL environment and Peter refers to three independent studies which quantify the productivity improvements of developing on Force.com - one study found a five fold improvement in developer productivity.

The other approach is to wrap existing products and APIs into a PaaS.  Essentially, the approach involves packaging existing products (database, middleware, tools) into a deploy-able unit and them provisioning it for each tenant into an infrastructure cloud - either something like Amazon or a custom built one.  This may be somewhat of an over simplification but the fact remains that these existing products were not built for a multi-tenant environment so some form of retro-fitting or working around is required.  Even if we assume that the provisioning and management infrastructure works smoothly to provide the infrastructural benefits of cloud computing, you still have to deal with the same old, complex application development model.  The JEE for example, has over a dozen APIs that you need to learn and then each of the each component - the database, the middleware etc. has its own tools and tricks.  So this approach does nothing to make it easier and faster to build applications.  Most incumbent middleware vendors (and you know who they are :) ) follow this approach.  There are a variety of marketing spins given to this approach - choice, legacy portability and ironically developer productivity.  However, the main reason is to protect their existing franchises - however, as the saying goes a hog in armour or in this case development complexity remains complex.

Partitioning your data with Divisions for usability & performance

by Nick Simha on August 28, 2009 at 10:10 AM

Data partitioning is a database technique commonly used to improve performance and manageability.  Salesforce provides a feature called Divisions that lets you partition your records into logical sections. As an example, you can divide your customer records based on their geographical location by creating divisions called US, EMEA and APAC.  The users in these regions can then be enabled to use these division. One of the benefits of doing so would be that division specific searches and division specific list views will provide them with data that is most relevant to them.  The other potential benefit is performance.  I was recently working with a customer with very large data volumes and partitioning the records into divisions significantly improved reporting performance.

Divisions have to be explicitly enabled for your organization by Salesforce. Divisions can be used with both standard and custom objects.  Effective usage of divisions require that you understand the usage pattern, criteria used to create the division, optimal number of divisions to create, data distribution between the divisions and data growth pattern. To get started look at online help or this cheat sheet.  

Your project on CruiseControl

by Nick Simha on August 20, 2009 at 10:41 AM

Over time the software development community has developed several best practices to make the development process more predictable. Many of these best practices are relevant for Force.com development as well. The tools provided with Force.com make it fairly easy to integrate these best practices into your development methodology. One such best practice is the idea of continuous integration - integrating the code developed by various developers on a regular basis vs. trying to cram it in before the release.  In this article I describe how you can use CruiseControl, an open source tool to automate continuous integration for your Force.com project. 

Let me know what you think and Happy Cruising!