VMforce first impressions

I suggest that these are two common thoughts for an experienced developer working in Apex and Visualforce on Force.com:

  • if my next job doesn’t use Force.com, learning this stuff is taking me nowhere
  • in Java you can do it like this, but I’ve just wasted an hour discovering you can’t do it at all in Apex/Visualforce

And the proprietary lock-in of Force.com is uncomfortable for an organization to take on too.

So the VMforce story, well articulated in VMforce and VMware’s “Open PaaS” Strategy offers some promise albeit perhaps further in the future than we might like given the “VMforce will be open for Developer Preview in the second half of 2010” quote from VMforce Provides Spring Cloud Platform.

However, at first sight the winner here looks like the Java/Spring/JPA developer/organization not the Apex/Visualforce developer/organization. The productivity benefits of the current Force.com proprietary platform are largely in the early stages of projects where you have a ready-made technology stack (including the database) and hosting environment and want to create CRUD pages. As soon as you have to start defining behavior – business logic – and task-oriented UI – custom pages and navigation – the weaknesses kick in and cost a lot of time and effort.

If the VMforce Java/Spring/JPA environment provides similar early stage benefits, then ultimately the ability to create a differentiated product (with multiple hosting options) in a mature and complete environment with good tools support will win compared to the ability to create a more limited product (that is locked in to Force.com hosting) in a distinctly limited environment.

Extracting an ERD from Force.com using SchemaSpy

PS Winter ’12 has a built in ERD viewer – see e.g. An ERD is Worth a Thousand Words: Schema Builder in Winter ’12 – that may meet some or all of your ERD needs so take a look at that first before considering the approach described below.

I looked around for a data modelling tool for Force.com that can output a complete data model but didn’t find one. (SoqlXplorer for OSX can produce diagrams but is an interactive tool. Other suggestions very welcome.) In the past when working with conventional JDBC databases I have used SchemaSpy. The cool thing about this is that the diagrams are automatically laid out in a rational way, and the accompanying HTML provides extra information and hyper-linking.

The opportunity to use SchemaSpy for Force.com comes from the fact that SchemaSpy primarily uses the java.sql.DatabaseMetaData interface part of the JDBC API which is relatively small and easy to implement. So with the benefit of SchemaSpy being open source to allow inspection and debugging, I went ahead and created a JDBC driver that uses the Force.com enterprise web service (DescribeSObjectResult, Field etc) to implement the parts of the JDBC API that SchemaSpy uses. That allows SchemaSpy to produce its output for a Force.com org.

Here is a small example of the output:

The driver and supporting libraries are available in the Google code project force-metadata-jdbc-driver along with the source code. This project is also linked from the Force.com Code Share project Force Metadata JDBC Driver for SchemaSpy.

Allow Apex code customization of a managed package

I work in a business where customers often want small variations in logic. The open/closed principle provides a good guide as to how to go about this and at first sight managed packages look promising. But those small variations in logic are best expressed in code and at present there is no way to extend a managed package using Apex code.

So take a look at (and vote for if you agree) Allow Apex code customization of a managed package.

Collection initialization

Apex collections support better initialization syntax than Java collections:

List<String> l = new List<String>{'a', 'b', 'c'};
Set<String> s = new Set<String>{'a', 'b', 'b'};
Map<String, String> m = new Map<String, String>{'a' => 'x', 'b' => 'y', 'c' => 'z'};

This means clearer code and the possibility of skipping the assignment to a variable if the collection is being created just as an argument to a method. The normal array initialization is also available and can be used interchangeably with the list initialization.

Plus there is this magical map initialization which automatically populates the key of the map with the Id of the object and the value with the object:

Map<Id, Contact> m = new Map<Id, Contact>([select Id, LastName from Contact]);

Free Force.com Security Source Code Scanner

While this isn’t a Checkstyle or FindBugs, it does give you feedback on some aspects of your work; I think it is worth running at various stages of development rather than just at the end to avoid bad patterns being replicated:

Force.com Security Source Code Scanner

Its free, all on-line and I got my results emailed after just a few minutes.