Sharing code and components across managed packages

If you are creating multiple managed packages and want to re-use some code and components in several of them there is no simple solution. (The approach you might take in the Java world of creating a JAR file that contains many related classes that you use in multiple applications is not available.)

You can put the components in a separate managed package, but that is a course-grained approach and has its own set of problems. This post outlines how to use svn:externals (yes this is SVN; I’m unsure about Git) to add shared components into the source tree, so the shared components just become part of each managed package. They pickup the namespace as part of the normal packaging process.

So in the version control system you have an extra project that contains the components you want to share:

  • SharedComponents
  • ManagedPackage1
  • ManagedPackage2

“SharedComponents” can only have dependencies on the core platform; it cannot have dependencies on anything in your managed packages.

Then in the managed package projects, add external file definitions to the svn:externals property of the src folder:

classes/SharedSms.cls              https://.../src/classes/SharedSms.cls
classes/SharedSms.cls-meta.xml     https://.../src/classes/SharedSms.cls-meta.xml
classes/SharedSmsTest.cls          https://.../src/classes/SharedSmsTest.cls
classes/SharedSmsTest.cls-meta.xml https://.../src/classes/SharedSmsTest.cls-meta.xml

where represents the SVN path to the “SharedComponents” project. In this example there are just two classes but each managed package can opt into as few or as many of the components as it needs. The purpose of the “Shared” prefix is to make it clearer in the managed package source where the components come from. (IDEs like Eclipse also decorate the icon of svn:externals to distinguish them.)

Once the svn:externals definition is in place, an SVN update automatically pulls content from both locations. You need to be using at least version 1.6 of SVN; our Jenkins (Continuous Integration server) was set to use version 1.4 by default so that had to be changed to get the builds to work.

Discipline is needed when modifying components in “SharedComponents” to not break any managed package code that depends on them. Running Continuous Integration builds on all the projects will help give early warning of such problems.