EMC OnDemand: Best Practices for Custom Methods

The concept of custom methods which run directly on the Java Method Server has proven an extremely useful extension point for Documentum developers and solutions architects.  Whether used in a workflow activity to integrate with an enterprise message queue or as an action for Webtop users who need temporarily escalated privileges to apply legal retention, custom Java methods have become a key customization in most customer environments. Features include:

  • Lightweight invocation of methods as compared to dmbasic and external Java methods that require execution
  • DFC operations execute on the same host as the Content Server which minimizes the effects of network latency and throughput
  • Can be configured to run as the repository owner which allows them elevated privileges to content when necessary
  • Provide the logic for workflow auto-activities, able to utilize any Java library including the DFC
  • Provide the logic for custom job/methods, again able to utilize the full power of Java and its libraries

The Legacy Deployment Process

In older versions of Documentum, methods needed to be archived in a jar file and copied into the Java Method Server’s dba/java_methods directory.  In 6.6, the Documentum Administrator User Guide  stated this directory is deprecated, and the DmMethods.war/WEB-INF/lib directory should be used instead.

Regardless of the exact location of your custom jar and then any supporting 3rd party libraries, they still needed to be physically copied to the Content Server.  And if you were updating the code, a full restart ofthe Java Method Server was necessary because the classes would be cached in a classloader.

The New Deployment Process

From 6.7 onward, the recommended deployment model for custom methods allows them to be hot-deployed via Composer – in other words, there is no need to physically copy the jar or its dependent libraries into any special directories on the Content Server. They are added as objects into the repository and automatically retrieved from there.

When deployed as a BOF module, these methods can be deployed and updated at will without needing to incur any downtime because restarts of the Java Method Server are not necessary.  Each module has its own classloader which allows the ability to hot-update.

Best Practice for OnDemand

For OnDemand it becomes even more important to follow this newer model of BOF deployment for custom methods. In an OnDemand environment, developers have limited control of the systems and this includes changes made to the Content Server and service restarts (which rules out coping files to dba/java_methods and restarting the JMS at will).  These limits are in place so that availability is not compromised and strict change control is maintained across the DEV/TEST/PROD environments.

If a developer needed a jar placed into dba/java_methods, that would have to be approved and then executed by an OnDemand Support resource at a scheduled time.  This process is not ideal for a developer who is used to a quick code/test/debug cycle.  Adhering to the platform best practice of using BOF modules gives control of the development cycle back to the developer.

In addition to the development cycle benefits, there are also clear advantages for the release cycle.  A system that needs 3 jars manually copied to certain directories on the Content Server, and then a JMS or Content Server restart is going to need a maintenance window, and will take a hit on availability of the system.  A BOF module can be deployed into a production environment without any downtime or loss of availability to end users.

Implementing Custom Methods as BOF Modules

To jumpstart your conversion efforts, I have built a Composer 6.7 project ‘MethodsAsBOFModules’, with a simple method and workflow method that follows the newer deployment model. Here are the general steps we will follow:

  1. Load the ‘MethodsAsBOFModules’ project into Composer 6.7
  2. Create .jar archives for each method
  3. Define Composer artifacts for each method: Jar Definition, Module object, Method object
  4. Install the project into a repository
  5. Invoke the method using DQL
  6. Validate by examing the logs

Here is a description of the key source files in the project:

  • TestModule.java – custom method that establishes a session to the repository, outputs the  dm_server_config.object_name
  • TestWorkflowModule.java – custom method invoked from a workflow, outputs dm_server_config.object_name and then completes workitem
  • MethodHelper.java – contains helper methods for session creation and logging, used by both methods

LOAD PROJECT INTO COMPOSER

  1. Unzip the MethodsAsBOFModules.zip into a local directory
  2. Open Composer
  3. File > Import > Documentum > Existing Projects into Workspace
  4. Enter the full path of the unzipped directory (e.g. c:\temp\MethodsAsBOFObjects), press “Browse”
  5. “Finish”

JARS CREATED FOR EACH METHOD

Each of the classes needs its own jar so that Composer can upload it into the repository.  Composer’s AntBuilder automatically generates the following jars from the source files:

  • TestModule.java -> dist/TestModule.jar
  • TestWorkflowModule.java -> dist/TestWorkflowModule.jar
  • MethodHelper.java -> dist/MethodHelper.jar

DEFINE COMPOSER ARTIFACTS FOR EACH METHOD

The basic sequence of steps from inside Composer are:

  1. Create the Jar Definition Artifacts
  2. Create the Module Artifacts
  3. Create the Method Artifacts

The reader can refer to this project as a template – but essentially each jar gets its own Jar Definition, then a standard module is created that uses the jar definition as an implementation jar. Finally, the method artifact is created that refers to the module name.

Jar Definition artifact

Module artifact

Method artifact


INSTALL INTO REPOSITORY

  1. Right-click on project name in left hand tree view, ‘Install Documentum Project’
  2. Select repository name
  3. username/password
  4. Press “Login”
  5. Use project and Artifact Settings
  6. Press ‘Finish’

INVOKE METHOD
Execute the following DQL using Documentum Administrator, substituting your own local docbase name and install owner:

dql> EXECUTE do_method WITH method = 'TestModuleMethod', arguments ='-user_name <installowner> - docbase_name <docbase> -myparam thisisatest'

VALIDATE
To see the invocation of each method, see the following files:

  • docbase log on the Content Server to see the method launch trace
  • JMS ServerApps.log for DfLogger.WARN output
  • JMS server.log for stdout

TESTING THE WORKFLOW METHOD

To validate the ‘TestWorkflowModuleMethod’, create a very simple workflow with an autoactivity and assign this method as the action.  Again, you will see the launch trace in the docbase log and the output of DfLogger.WARN go the ServerApps.log.  If Process Engine installed, then look instead at that log for the DfLogger output.

UPDATING THE JARS AFTER SOURCE CHANGES

Modify the source file, which will trigger the jars being rebuilt.  Then press ‘Remove’ on the Jar Definition and then re-add the jar.  Finally, install to repository again with overwrite on.

NOTES ON DEPENDENT JARS AND CLASSLOADING

There are two different ways that we could have provided the modules access to the shared MethodHelper.jar clases:

  1. We chose to add MethodHelper.jar directly to each module, in essence creating a sandboxed version for each module.  This keeps the module and the exact version of the dependency isolated to this module’s classloader
  2. The other way would have been to add MethodHelper.jar as a ‘Java Library’ artifact in Composer, which would make it a shared global BOF library.  Then under the ‘Deployment’ tab in each module definition, it could have been added as a Java Library.  This would mean that the JMS would load the classes into a shared classloader only a single time.

Also note that these module will not have visibility into classes in the dba/java_methods directory, so be sure to include any dependencies in either the ‘Core jars’ or as a ‘Java Library’.

And if a BOF module calls a TBO/SBO, add this TBO/SBO to the ‘Required Modules’ section of the module definition.

 

REFERENCES

https://community.emc.com/docs/DOC-4360 – BOF classloaders, antBuilder, ClassDefNotFoundException, ClassNotFoundException, example SBO

http://donr7n.wordpress.com/2008/10/20/methods-as-bof-modules/ – summary of IDfMethod use and hot deployment

http://donr7n.wordpress.com/category/bof/ – describes why shared Java Libraries cannot be reloaded

http://donr7n.wordpress.com/2009/01/20/jar-defs-and-java-libraries/ – discussion of shared libaries and jar definitions

https://github.com/fabianlee/blogcode/blob/master/MethodsAsBOFModules.zip