Using Documentum Composer to streamline the BOF2 Development Process

In a previous post I introduced one alternative for performing integrated BOF development within Composer. 

For the uninitiated, in BOF2 class loading is performed by DFC using a special class loader.   This allows module (type, aspect, service, …) implementations to be stored in the Repository and served up to clients upon-demand.  This allows you to leverage the power of the Content Server (version control, etc) on your Java modules.  Overall this is a nice feature and it ensures you get the right behaviour for the aspects, types and services that your application uses. 

However, it does complicate the development lifecycle as you have to package and deploy your modules to a development repository before you can test them.  For IDE debugging this can be a nuisance.

To assist during development there is a feature built in to DFC that allows you to skip the Repository class loading step for specific modules.   Let’s take a closer look.

Create the Module

As per my previous article create a project and within it your module. 

A quick overview follows;

  1. the module’s interface should extend the marker interface com.documentum.fc.client.IDfModule,
  2. the module’s implementation should extend com.documentum.fc.client.DfSingleDocbaseModule (or equivalent) and implement your interface,
  3. the project should include an additional ant builder that executes a simple ant script that builds your module jar(s) into your jardef artifact’s content directory
  4. finally your jardef artifact XMI should be modified to link to the jar(s) (as opposed to the dummy one(s) you had to import)

image

Create the Module Test

Now create another Documentum project to host your module’s test code.  The reason we create a Documentum project as opposed to, let’s say, a regular Java project is that a Documentum project will be set up with a DFS library already on its classpath.  This library contains DFC and as result is a very convenient leg-up as we are just about to create some DFC-based test code.

But first create a plain text file and call it something like bof.registry_file.properties.  In the file add the following line:-

mymodule=module,my.module.MyModule

where “mymodule” is the name of your module as specified in the Module Artifact:

image

“module” specifies the module’s type.  Other values could be “aspect”,”type” or “service”.

And “my.module.MyModule” is the fully qualified class name to your module’s implementation class.  The same class name is specified in the class name field of your Module Artifact. 

This file is a local module registry.  You can add additional lines to suit for each module that you wish to debug in your IDE.

Next create a JUnit test case (File->New->Other->Java->JUnit-> JUnit Test Case) and add some simple test code:-

image

And as you will no doubt be aware for DFC to really work we need a dfc.properties file.  Create a folder in the root of the project and call it something like “rsc” or “resources”.  Import (or create) a dfc.properties file into this folder and make sure that it is configured with the docbroker that is hosting your test Repository.  Add this folder to the project’s Java Build Path.  Right-click on the project, choose Properties->Java Build Path.  Select the Libraries tab and then hit the Add Class Folder… button and select the folder you just create and click OK, as follows:

image

Next we need to define a launch configuration.  To do this, from the Menu choose Run->Debug Configurations…  Select the JUnit category and then hit the New button.  Give the new JUnit launch configuration a name, “BOF Test – local invocation” for example.  Select the Arguments tab.  In the VM Arguments field enter “-Ddfc.development.bof.registry_file=${project_loc}/bof.registry_file.properties” which sets a system property upon launch.  This particular property, dfc.development.bof.registry_file, will be checked by DFC and, if set, instructs it to fulfil any request for a module that is also specified in the local registry file using a local class loader instead of its special Repository class loader.  The net result is that it will load the class from your project:-

image

Now select the Common tab.  In the Save As panel select the Shared file radio button and browse to a suitable location within this project.  This will save the launch configuration in the project which means you can place it under source control in order to share it with others in your team:-

image

Click Apply to save the launch configuration.

I would also recommend that you create a second launch configuration, call it something like “BOF Test – Remote Invocation” and on this configuration remove the system property.  Make sure you save it to the same location as the local invocation configuration.  This will allow you to test in local mode or remote mode.  There is good reason for doing this as I will explain shortly.

Finally, as a one-time only operation we need to install the module so that it is registered properly with the Repository.  Right-click on your module project and select Install Documentum Project.

That’s it.  You are now all set.  To test your module.  Right-click your test project and choose Debug As… (or Run As…)->Debug Configurations…  Make sure the local invocation launch configuration that you created earlier is selected and hit Debug.  Or simply use the toolbar short cuts buttons.  Once its run.  Make a change to your module’s implementation.  Be sure not to install the project again and re-invoke the launch configuration.  By setting breakpoints in your module implementation you will be able to see you modified implementation being executed.

In Conclusion

This article demonstrates how to streamline the BOF development process.  It also demonstrates how to create launch configurations and how to share them with your team by saving their definitions in the workspace and using source control.

One very important note.  Be aware that this local invocation is really a bit of a cheat and that its usage can mask packaging problems.  The fact that the class is visible in your project does not necessarily mean it will be visible with proper BOF class loading.  To a large extent DFC and Composer try to negate this through the insistence of the one-time only install and through the build process respectively which catches errors.  And also why I recommended creating a remote invocation launch configuration as well as a local one.  But this might not stop packaging problems creeping if, let’s say, you subsequently modify your module’s packaging structure.  The long and short of it is that whilst the workflow outlined here can be a real productivity boon for your developers your Documentum applications should also always go through a proper QA cycle.

As always happy Composing…

Advertisement

18 thoughts on “Using Documentum Composer to streamline the BOF2 Development Process

  1. Hi Paul,

    awesome writeup. Wish they would make posts like these a part of the EDN…

    While on the subject of best practices: how do you get the interface jar into the BOFtest project? Link it by defining it as a “Required Project” in the Java Build Path? I don’t assume copying manually. Or do you include the in the JUnit referenced the interface in another way? Just to clarify…

    Cheers ‘n Thanks,
    Ingo.

  2. Hi Ingo,

    Thanks for the comment and apologies for the delayed reply. I have been busy recently.

    A link to my blog has been added to EDN now so hopefully people will be able to find it through there as well as through google, etc.

    Yes the way I import the module’s interface classes into the test project is by configuring the Java Build Path. But I prefer using the Libraries tab to add the API jar there rather than simply adding the project. Both will work of course but the jar alternative is really the analog of how the runtime system would work and therefore I think it is a better option.

    HTH
    _Paul

  3. I was trying to follow your blog entry to locally debug and test Modules. Unfortunately with no success. If not running with the -D switch in the VM argument tab of the Testcase configuration, everything is running fine but the module is loaded from the repository. If i now just add the line -Ddfc.development.bof.registry_file=${project_loc}/bof.registry_file.properties to the VM arguments tabs of the testcase run configuration (and the bog.registry_file.properties is empty at this state of testing) i immediately get the following error:

    java.lang.NoClassDefFoundError: and

    Strange. According to the stace trace this happens even before the testcase class is run.

    • Hi Jorg,

      Sounds like DFC is doing what it should do. No -D switch – downlaods from the repo. -D switch checks the local registry file.

      >>> (and the bog.registry_file.properties is empty at this state of testing)
      If you dont have an entry in this file then DFC won’t know what class to load. Can you add an entry to this file (as per my post) and then retry please?

      Also make sure the jar that you build is on the classpath of your test project.

      HTH
      _Paul

  4. Ok, i tried it with the following entry:

    com.bhn.test.IHelloTest=service,com.bhn.test.HelloTest

    I hope service is the correct module type for a SBO.

    But it gives the same error.

    My structure is as follows: I´ve created a new source Folder srcBOF with Output folder binBOF. The JarBuilder is creating two Jar´s (for Interface and Implementation class) in the root of the Project. I would assume that the output folders are automatically on the class path.

    • Jorg and I resolved this issue in the end. Turns out that eclipse was failing to resolve launch config variable. Eliminating this variable resolved the problem.

    • Hi Sergey,

      Yes I know. Something weird happened when I published the post. I did try and fix this, but failed. I will give it another go as soon as I can.

      • Any chance to fix the three missing screenshots?

        What I am missing in most of the Dctm documentation is some kind of guide including naming conventions (e.g. jardef) and file locations (where would one put the jars created from e.g. Aspects besides the root of the project folder).

        I know you can write what you want but I am always wondering how does a workspace/tool layout of the EMC internal developers look like?
        Say, one of the built-in aspects, how did the responsible EMC developer do it? Also things if one creates several aspects would it make sense to build them within one project or on a project per aspect basis? (Since modules can’t be deployed individually this might be one reason against it)

        (Even more interested in this information for DFS service development in terms of continuous testing without constant packaging and deploying – trying to bring across the idea)

        Your write ups are the best in terms of best practice usage of the tools and functionalities so please keep them coming! 🙂

      • Aaargh, just saw your latest post including the link to the EDN article where it (almost) describes pretty much what I was looking for (need to improve my search skills ;-))

        Thks,
        Ingo.

      • No problem Ingo. Thanks for your continued readership. Much appreciated.

        I deleted your Dardocs comments as per your request but please keep trying to add the comment. I am sure others readers will find your insights useful. Or feel free to send them to me directly and will publish them on your behalf.

        Many thanks
        _Paul

    • Hi Jose,

      We have no specific naming conventions other than the constraint imposed by Composer on the type name prefix of dm which is reserved for Documentum types only.

      Other than that you can name your artifacts as you see fit.

      HTH
      _Paul

  5. I tried to run your module and everything went well but when i run this. i get this error

    xception in thread “main” java.lang.ClassCastException: my.module.MyModule cannot be cast to com.documentum.fc.client.IDfModule
    at com.documentum.fc.client.impl.bof.classmgmt.ModuleManager.newModule(ModuleManager.java:136)
    at com.documentum.fc.client.impl.bof.classmgmt.ModuleManager.newModule(ModuleManager.java:78)
    at com.documentum.fc.client.impl.bof.classmgmt.ModuleManager.newModule(ModuleManager.java:52)
    at com.documentum.fc.client.DfClient$ClientImpl.newModule(DfClient.java:432)
    at Test.main(Test.java:38)

    Can anybody faced such error? i tried to cast it IDfModule than i dont get that function with it.

    Thanks

      • Thanks Paul, I was missing the argument to the JVM which you specified and Can you please fix these images or put the whole article with images in zip and attach to your article, I know you are busy but that would be a great help to newbies like me.

        Thanks Again

        Ksingh

  6. Hi Paul ,
    There is a TBO in our repository , for some reason we do not want to use that . So we have made use of dfc.development.bof.registry_file as mentioned in your article to load the local TBO(present in Java source) . This works fine in local . But when we try to deploy the same to development environment , it seems to download the TBO from the repository and there by causing class cast exception . We are using WAS 6.1 server and I have set the dfc.development.bof.registry_file property during server startup .

    Please find my entry in bof.registry_file.properties file
    sample_request=type,com.test.services.SampleRequest

    Could you please tell me whether anything else is required .

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s