Jiri Rechtacek is a Senior Software Engineer in Sun Microsystems since 2001. Jiri is a member of NetBeans Platform Team as developer, he has been responsible for Auto Update feature in NetBeans IDE recently. Jiri was the speaker at JavaOne 2008 Conference. He holds a Masters Degree in Software and Database Engineering. Jiri has posted 1 posts at DZone. View Full User Profile

How to Quietly Disable NetBeans Modules at Runtime Programmatically

01.23.2009
| 8072 views |
  • submit to reddit

I received an inquiry from a user of the NetBeans Platform: he wants to know of a way to disable one or more modules in a running application built on the NetBeans Platform. In addition, this should happen silently, i.e. with no end-user intervention or any external assistance.

Well, the requirement is clear but its fulfillment has several difficulties: first, modules in the NetBeans Platform depend on each other and it's not easy to discover modules which don't involve any essential module of the NetBeans Platform. Secondly, modules could be depending on each other even though they don't declare such dependency in their meta-data. Such ad-hoc dependencies are mistakes and the NetBeans architecture aims at avoiding them, but a few of them might creep in somehow. This fact has led the NetBeans team to disable modules only in "offline" time, i.e., when the NetBeans Platform application is not running. Despite this, the Autoupdate Service still offers the possibility, even if it is never called in NetBeans IDE.

Okay. That was the bad news, the good news is that the Autoupdate Services API has the capability to perform the disabling of modules in the currently running application, with the awareness of the possible problems stated above.

Autoupdate Services has a specific "operation container" for disabling modules OperationContainer.createForDirectDisable. Now, below, I show a code snippet for how to use this container for disabling some modules:

public void doDisable (Collection codeNames) { // codeName contains code name of modules for disbale
    Collection toDisable = new HashSet ();
    List allUpdateUnits = UpdateManager.getDefault ().getUpdateUnits (UpdateManager.TYPE.MODULE);
    for (UpdateUnit unit : allUpdateUnits) {
        if (unit.getInstalled () != null) { // filter all installed modules
            UpdateElement el = unit.getInstalled ();
            if (el.isEnabled ()) { // filter all enabled modules
                if (codeNames.contains (el.getCodeName ())) { // filter given module in the parameter
                    toDisable.add (el);
                }
            }
        }
    }

    OperationContainer oc = OperationContainer.createForDirectDisable ();

    for (UpdateElement module : toDisable) {
        if (oc.canBeAdded (module.getUpdateUnit (), module)) { // check if module can be disabled
            OperationInfo operationInfo = oc.add (module);
            if (operationInfo == null) { // it means it's already planned to disable
                continue;
            }
            // get all module depending on this module
            Set requiredElements = operationInfo.getRequiredElements ();
            // add all of them between modules for disable
            oc.add (requiredElements);
        }
    }

    // check the container doesn't contain any invalid element
    assert oc.listInvalid ().isEmpty ();
    try {
        // get operation support for complete the disable operation
        Restarter restarter = oc.getSupport ().doOperation (null);
        // no restart needed in this case
        assert restarter == null;
    } catch (OperationException ex) {
        Exceptions.printStackTrace (ex);
    }
}

I hope it helps to achieve the user's need. If anyone has a problem with it, please let me know.

 

From http://blogs.sun.com/rechtacek/entry/quietly_disable_modules_at_runtime

 

Published at DZone with permission of its author, Jiri Rechtacek.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)