Friday, August 28, 2015

Dreamforce 2015 Session picks

Here are some of my current picks for Dreamforce 2015 sessions. They are mostly development focused. There could probably be more Lightning Experience sessions in the mix.

Likely I've made the same mistake as last year and overbooked myself with sessions, of which the list below is only a sampling. There will no doubt be lots of last minute chopping and changing. I'll probably triage based on if I can later catch the sessions recorded content. As Peter Knolle suggests, favoring sessions that occur in Moscone West will keep you mostly around the Developer Zone for technical sessions and save on trying to run from location to location.

Tuesday, September 15

Wednesday, September 16

Thursday, September 17

Friday, September 18

  • 12:30 PM Meet the Developers
    Because: Questions!
    As I've mentioned before, this is a great session to ask any burning questions of Salesforce developers.
  • 2:00 - 3:00 Marc Benioff & Parker Harris Q&A
    Because: That's a wrap
    Depending on the timing for getting to the airport for my flight home, it could be a fun way to end the conference.

Thursday, August 13, 2015

Salesforce Apex gotchas for a C# developer

There are a number of areas in Salesforce Apex that can routinely catch a developer coming from a .NET language out. Worse still, when constantly switching between Apex and C# the similarities in syntax can lead to confusion about what is applicable in the current language.

This post will be a continual work in progress. I'll come back to it as things come up.


Feature .NET C# Salesforce Apex
String Delimiter " - double quote ' - single quote
String Comparrison Case sensitive by default. String.Equals can take a StringComparison.OrdinalIgnoreCase InvariantCultureIgnoreCase or to ignore case Using == will be case insensitive. Use the String.equals or String.equalsIgnoreCase methods.
For each loop syntax foreach(X x in y) { } for(X x : y) { }
Case sensitivity Case sensitive Case insensitive. The variable map can easily conflict with the system type Map.
Collections List<string> or string[] are interchangeable in Apex.
Appending to the end of a list The List<T>.add(index, T) method doesn't work if the list is empty. See Should List<Object>.add(index, listElement) work if the index is at the upper bound?
params Apex doesn't have the concept of params like C# does. So if you try and pass a single string to something like String.format() you get the error
Variable does not exist: String
. Instead you need to explicitly put the formattingArguments into a List<string> or string[]

Source: Stuck on a “Variable does not exist: String” error

Properties Either automatic properties or explicit members required. Apex properties have an implicit member with the same name as the property.
Properties provide storage for values directly. You do not need to create supporting members for storing values.
Read-only and write-only automatic properties
Integers int or System.Int32 integer
Booleans bool or Boolean Boolean
Nullable Types Need to explicitly use Nullable<T> or ? notation to make primitive types nullable. All variables are implicitly nullable. In addition to the usual suspects like Integer, Boolean, Decimal, Double, Long, String, Time, Date, DateTime, it also includes Boolean. So you may be passed a Boolean parameter that is neither true or false.
Collections Dictionary Map
Exceptions Classes extending Exception must have a name ending in 'Exception'
Use this.setMessage(message); to set message rather that constructor.
switch statement switch Not available, use multiple if/else if/else statements. Add "Switch" or "Case" Statement to Apex
Generics Yes Internal Types only
Winter 13 Release Notes
Parameterized Interfaces No Longer Supported
Parameterized interfaces are not supported in Apex saved using Salesforce.com API version 26.0 and later.
Access Modifiers public "Public access is the most permissive access level. There are no restrictions on accessing public members" global "This means the method or variable can be used by any Apex code that has access to the class, not just the Apex code in the same application."
public - "This means the method or variable can be used by any Apex in this application or namespace."
In Apex, the public access modifier is not the same as it is in Java. This was done to discourage joining applications, to keep the code for each application separate. In Apex, if you want to make something public like it is in Java, you need to use the global access modifier.

See also:

Friday, August 7, 2015

Salesforce UNKNOWN_EXCEPTION, portal account owner must have a role: []

After being dropped into an existing Salesforce Org to make changes the first thing I like to do is run the existing test cases. It gives me a rough lay of the land and a feel for the health of Org.

Is it just scrapping by the 75% threshold? Or, worse still, are current test cases already failing in production?
These are things that are going to make change set deployments from a sandbox difficult. More so when combined with any further changes I want to make.

One such recent Org started with a large number of test cases failing with the message:

UNKNOWN_EXCEPTION, portal account owner must have a role: []

This was occurring when the test methods were attempting to insert a User with the "Customer Community Login User" profile. Oddly this wasn't occurring in the sandbox.

The test cases in question were inserting an Account, Contact, and User record that were all related to each other. From the error message, the Salesforce User that inserts that Account needs to have a role assigned. For some reason the Sandbox user I was provided had the Role set, and the production user didn't.

Setting my current users Role in production fixed that particular issue.

For good measure, I updated the test cases with the following to make the resolution more apparent.

// UNKNOWN_EXCEPTION, portal account owner must have a role: []
System.assertNotEquals(null, UserInfo.getUserRoleId(), 'The current user with Id: ' + UserInfo.getUserId() + 
             ' Name: ' + UserInfo.getUserName() + ' needs a Role assigned to test Portal/Community users');

Onward to fix the the remaining existing failures...

Thursday, August 6, 2015

Incremental learning with Salesforce Trailhead - Event Monitoring

For a long time my go to place for doing small incremental learning exercises for Salesforce has been the Salesforce Stackexchange site. It was my Trailhead before Trailhead existed.

If I had a spare 5 minutes due to a long compile, or similar, I'd typically look for questions that I knew a bit about and then research the gaps in my knowledge to hopefully provide the answer. This was great for a number of reasons:

  • I was helping a fellow Salesforce developer/admin.
  • It was someones real world Salesforce problem. Chances are that I'd run into the same or similar problem at some point.
  • I had a focused reason for going into the documentation. Reading the docs front to back is a bit like reading the dictionary. Yes, you could probably learn lots, but I was more likely to learn something if I had a specific goal.
  • Typically it didn't require a great deal of time to answer a question if I already knew part of the problem. I could do some quick research through the documentation and/or put together a basic prototype.
  • Maybe I got the answer wrong. That's OK too, as I can either revisit it or learn more from another users answer.
  • Sometimes I'd stray into areas of Salesforce where I had very little experience. It was a great excuse to at least get familiar with a new area or feature.

From the last point, it was often the case that the more I learnt about Salesforce the more I knew I didn't know. This is still very much the case.

Trailhead

Now there is Trailhead, which provides a focused guide through specific areas of Salesforce in manageable chunks. So if you have 15 minutes to spare you can work through a small exercise to explore new areas. They are usually evaluated with either some applicable questions or, better yet, Salesforce will use the various APIs to either inspect the state of the org and execute functionality to see if you have completed the given tasks.

One area I'd been meaning to investigate but hadn't got round to yet has been the Event Monitoring, which was introduced in the Winter '15 release. I've been skimming through Adam Torman's blog posts on it for some time and meaning to crack open the APIs and have a poke around at the available data.

When the Trailhead Event Monitoring Module appeared it was the perfect excuse to delve into the workings. As a module I knew all the parts I needed to get started with the API would be contained in one place, so I could work through each of the challenges as I got a few minutes to spare.

This module differs a bit from others, as it requires interacting with the APIs directly. The first part of the module does a good job of easing admins into accessing the REST API if it was previously a foreign concept. In many ways it provides a good reason to poke around in the SOAP and REST APIs. Doing so using Workbench to interact with the REST API saves you from having to handle session authorization headers and formatting the responses.

After completing the module it turns out accessing the Event Monitoring data is really easy with the existing tools at hand. For example, I can use a SOQL query to pull the available logs. Once you have the required Id then pull the LogFile field with the CSV data.


One of my earlier experiences with Trailhead was handling problems when using an older Org that was full of testing data. The anonymous apex that Salesforce was using to test the code was trying to insert a new record, and was encountering a storage limit exceeded error. See details in Troubleshooting Salesforces Trialheads execution of Developer Edition org code

Dreamforce

With Dreamforce 2015 just around the corner it would also be timely to do the #DF15 module. It helps with pressing questions such as:

  • Should I attend the keynotes?
  • Where do I get more information to stay updated?
  • What should you pack in your bag?

I put some notes together on my #DF14 experience for things like on site food.

Friday, July 3, 2015

FuseIT SFDC Explorer 2.9 Features

The new v2.9 release of the FuseIT SFDC Explorer has some new features.

Run anonymous apex in a testing context

For some time I've been promoting the idea of being able to run anonymous apex in a testing context. This offered a few benefits.

  • The anonymous apex could then call existing apex test methods. They could then be run in isolation.
  • Helper methods defined in a test class could be accessed.
  • You would be 100% safe from accidentally updating real data in the org. No callouts could occur.

The first point has largely been addressed in The Holy Grail of Apex Testing in Salesforce

To address the other points I've applied the same technique to run anonymous apex in a testing context. This can be access with the "Use Testing Context" check button. With it active, you can do things like access Test.getStandardPricebookId().

Improved support for running selected test methods

Individual test methods can now be checked in the asynchronous test results viewer. Pressing the "Run Selected Tests" button will run those tests in isolation.

Miscellaneous

Fixed the "Open Log" button on the Apex Tests Queued tab. It will now correctly open the log or prompt to create the TraceFlag to capture it for the next run.

Several users reported problems with the 2.7 and 2.8 release with the login process. It would fail with the message:

java.lang.NullPointerException Error Id: 1655897833-5655 (293693299)

This was a Salesforce GACK response from a call to the Metadata API describeMetadata() web method. I'm not sure what causes it for some orgs and not others, but I believe I've isolated it from the login process in our code.

Friday, June 26, 2015

A short history of Salesforce bugs and issues

Below is a history of the Salesforce bugs/issues that I've either directly raised with Salesforce or been involved in. While not comprehensive at the moment, it is mostly useful for me to have a single place the references them all.

  1. Bulk API gets error "MISSING_ARGUMENT:fiedXXX__c not specified:--" when using "N/A#"
    A customer using the Scribe data loading tool encountered a MISSING_ARGUMENT error when trying to create OpportunityLineItem records where there is a custom field from our managed package. The custom field is an external id, but not required.
    It turned out to be a limitation in Scribe - Topic: "Upsert issue - issue with multiple External Ids?". It can't handle multiple External Id fields and just uses the first one encountered for the upsert, even if you aren't populating it with data.
  2. Events continue to get delivered to Streaming API client which uses a session id , the session which has been explicitly terminated The Streaming API continues to send messages for expired/deleted Sessions - Case 11745520
  3. Spring '15 - Compile error occurs when deploying a test class using an @isTest(SeeAllData=true) method with a separate class using @TestSetup method
  4. "Generate WSDL" generates a WSDL that does not contain the definition of the compound types address and location if API version is 30.0 or above
  5. WSDL-Based Asynchronous Callouts using Continuations can't be unit tested.
    Known Issue: Running Test for WSDL-based asynchronous callouts fails with Internal Salesforce.com Error
  6. The Tooling API isn't enforcing the package version dependency in the class/trigger metadata
  7. Tooling API SymbolTable contains “private” visibility modifiers instead of “protected”
  8. The SOAP Tooling API is missing the SessionHeader in WSDL operation
  9. Querying ApexExecutionOverlayResult via the Tooling API gives an UNKNOWN_EXCEPTION

Friday, June 12, 2015

Using the Salesforce Metadata API to run a single test method in isolation

In my previous post The Holy Grail of Testing in Salesforce I covered my journey towards being able to execute a single Apex test method in isolation of the others defined in an Apex class. Here I'll cover how it actually works.

The Metadata API

In working with the Metadata API deploy() method as part of a continuous integration projection it dawned on me that I already had everything I needed to run a single test method in isolation.

As long as the test class and test method in question were public I could create a temporary wrapper test class that calls just the target test method.

For example, say the target was the Foo ApexClass and method bar(). Something like this, but with more actual testing and assertions going on:

@IsTest
public class Foo {
    public static testMethod void bar() {
        System.Debug(LoggingLevel.Debug,'Example Foo.bar() method');
        // Assertions and stuff
    }
}

Then to invoke this via a Metadata API deploy call all I need to do is create a wrapper class, the associated .cls-meta.xml, and package.xml to send in the zip payload. The wrapper class can be as simple as:

@IsTest
public class FooWrapper {
    public static testMethod void barWrapper() {
        Foo.bar();
    }
}

The most important part in deploy call is the DeployOptions.

  • Setting checkOnly to true will prevent any changes being actually deployed to the org. The FooWrapper class only exists to execute the test.
  • runTests(string[]) allows the deployment to run a specific test case. This should be set to the name of the wrapper test class that is being deployed. E.g. "FooWrapper"
    Once v34.0 is widely available the testLevel should also be set to RunSpecifiedTests.

The DebuggingHeader can be used to control the debug log contents that comes back in the response.

After starting the deploy process it is just a matter of monitoring the AsyncResult and DeployResult until it completes and then extracting the RunTestsResult.

The end result

Given an Apex testing class and the name of a test method it contains I can run a checkOnly deployment that will run just that test. As I mentioned before, the test in question needs to be public so that the wrapper class can access it. There are also likely to be issues if the @testSetup annotation is being used in the target class.

The future

It occured to me that this would also be a great mechanism for running anonymous apex in a testing context as well. The anonymous apex could easily be wrapped in a temporary class annotated with @IsTest and a test method. It could optionally specify @IsTest(SeeAllData=true) as well.

Additional test methods could be created in the wrapper class to target other test methods.


Update: Tooling API runTestsAsynchronous

Nate Lipke kindly pointed out to me that the Summer '15 release includes a runTestsAsynchronous method that accepts the target class Id's and a testMethods parameter "containing the name of a test method in the test class."

The REST version takes this as a POST request. The SOAP API also has this method, but it isn't apparent how to specify the target test methods yet.

If you are using the Force.com IDE v34.0.0.20150511 Beta Version you can use the new API to run a specific test method.

From the Summer '15 - Tooling API Updates

POST JSON arrays of test methods to runTestsAsynchronous
You can now POST a JSON array of test methods to the runTestsAsynchronous endpoint. Formerly, in POST methods, therunTestsAsynchronous endpoint accepted only comma-separated lists of class IDs.

Format:
POST
/runTestsAsynchronous/
   Body:
   {"tests":<tests array>}

Example <tests array>:

[{
  "classId" : "<classId 1>",
  "testMethods" : ["testMethod1","testMethod2","testMethod3"]
 },{
  "classId" : "<classId 2>",
  "testMethods" : ["testMethod1","testMethod2"]
}];