Geertjan's Blog

  • May 6, 2005

NetBeans Modules for Dummies (Part 1)

Geertjan Wielenga
Product Manager
Let's pretend we haven't heard of Maven. Let's not use yesterday's blog entry to install Mevenide. Let's leave all that for another day. We'll appreciate Maven and Mevenide much more once we see how much more work we need to do without them. For now, let's just use our faithful friend NetBeans IDE together with Ant to create a simple NetBeans Module (NBM). You'll see it's actually pretty easy. At the end of the story, we'll use the Update Center to install the NBM in the NetBeans IDE. The NBM won't do much -- it will just add a menu, submenu, and menu item to the IDE's menubar. When you click the menu item you'll get a JOptionPane with a message. Still, despite its simplicity, we'll have a basic understanding of the process and have laid the basis for more advanced experiments.

  1. Let the IDE create the NBM structure. Click Ctrl-Shift-N. In the New Project wizard, select the "General" category and then the "Java Application" project. Name the project as follows:


    Before clicking Finish, specify that the following main class should be created:

  2. Code the NBM. Click Finish and use the Source Editor to change the class so that it looks as follows:

    public class TestAction extends CallableSystemAction {
    public HelpCtx getHelpCtx() {
    return HelpCtx.DEFAULT_HELP;
    public String getName() {
    return "Start Test";
    public void performAction() {
    String msg = "Test succeeded...";

    Click Alt-Shift-F in the Source Editor to generate import statements. You'll notice that some packages are still needed. Right-click the project's Libraries node and add the following JARs:

    • netbeans-installation-directory/platform5/core/openide.jar
    • netbeans-installation-directory/platform5/core/openide-loader.jar

    Now click Alt-Shift-F again. The following two import statements should be automatically added to your file:

    import org.openide.util.HelpCtx;
    import org.openide.util.actions.CallableSystemAction;

  3. Hook the code to a menu. Add a directory called resources containing a file called mf-layer.xml in src/org/netbeans/modules:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE filesystem
    PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN"
    <folder name="Menu">
    <folder name="Test">
    <folder name="Subtest">
    <file name="org-netbeans-modules-test-TestAction.instance"/>

    You can play around with the Menu section above. For example, do you want to add menus and submenus to invoke applications from the IDE? Simply create folder sections as shown above and hook them up to the Java classes that contain the code (also shown above). If you want to add a menu item to an existing menu, specify the name of the existing menu at the highest level and the menu items will arrange themselves below it. For example, if you put "View" instead of "Test" above, the "Subtest" menu item will be added below the "View" menu in the IDE. There's much more you can do with this file, but this is enough for now.

    The structure of your project in the Files window should now be as follows:

  4. Create the JAR. In the Projects window, right-click the project and choose Build Project. (Alternatively, use the File menu to set the project as the main project and then you can click F6 to build the project, even in the Files window.)
  5. Create the JAR's XML file. Add the following to the build.xml file:

    <target name="create-xml-file-for-module" 
    depends="compile,jar" description="Create JAR">
    <!-- Create directory for JAR. -->
    <mkdir dir="NetBeans/${ant.project.name}"/>
    <!-- Create directory for JAR's XML file. -->
    <mkdir dir="NetBeans/${ant.project.name}/config/Modules"/>
    <!-- Copy the JAR (therefore, you must build the JAR first!). -->
    <copy file="${dist.jar}"
    <!-- Create the XML for the JAR. -->
    <taskdef name="createmodulexml"
    classpath="${run.classpath}" />
    <createmodulexml xmldir="NetBeans/${ant.project.name}/config/Modules">
    <enabled dir="NetBeans/${ant.project.name}">
    <include name="modules/${ant.project.name}.jar"/>

    Now run the target. You'll get this error:

    build.xml:79: taskdef class org.netbeans.nbbuild.CreateModuleXML cannot be found

    Right-click the project's Libraries node and add the nbantext.jar. When you do so, the IDE adds it to the javac.classpath property in the project.properties file, so that you can use it transparently in the next step. (If you don't have it, you can get it from the Update Center.)

    Now run the target again. You'll get this error:

    build.xml:80: Missing manifest tag "OpenIDE-Module".

    Or you might get an error telling you that the project is not a module.

    Add this to the manifest.mf file:

    Manifest-Version: 1.0
    OpenIDE-Module: org.netbeans.modules.test/1
    OpenIDE-Module-IDE-Dependencies: IDE/1 > 4.0
    OpenIDE-Module-Layer: org/netbeans/modules/resources/mf-layer.xml
    OpenIDE-Module-Specification-Version: 1.0

    Now run the target again and everything should be well.

  6. Create the NBM. Add the following to the build.xml file:

    <target name="create-nbm" depends="create-xml-file-for-module" description="Create NBM.">
    <taskdef name="makenbm" classpath="${run.classpath}"
    <taskdef name="genlist" classpath="${run.classpath}"
    <genlist outputfiledir="NetBeans/${ant.project.name}" module="modules/${ant.project.name}.jar">
    <fileset dir="NetBeans/${ant.project.name}">

    <include name="modules/${ant.project.name}.jar"/>

    <include name="config/Modules/${ant.project.name}.xml"/>
    <makenbm file="${ant.project.name}.nbm"


    Now run the target. The genlist section above gives me a java.lang.NullPointerException, but does the required job anyway -- it creates update_tracking/org-netbeans-modules-test.xml. However, it prevents the NBM from being generated. So, remove the genlist section and run the target again. You'll get this error:

    build.xml:91: Can't read nb.system.dir property

    Add this to the project.properties file:


    (Update: In part 4 of this "NetBeans Modules for Dummies" pseudo-series the problems relating to nb.system.dir and the java.lang.NullPointerException are discussed and solved.)

    Now run the target again. Look in your Files window and you will see the NBM file that Ant has created for you:

  7. Install the NBM. In the IDE, choose Tools > Update Center. Select the radiobutton at the bottom of the dialog box so that you can browse to your NBM file. After you've installed it, there'll be a new menu in the IDE, next to the Help menu. It will be called Test. Its submenu is called Subtest and when you click on Start Test you'll get a message that says "Test succeeded..."

    If you want to play around with the above structure, go back to step 3, modify the layer XML file, build the project, run the two targets again, remove the module from the IDE (go to Tools > Options > IDE Configuration > System, expand the Modules node and delete the module), and install the new version. You can also use the Options window to re-order the menu in the menubar, and any menu items within the menu. To do this, go to IDE Configuration > Look and Feel, and then right-click the Menu Bar node or any of its subnodes.

With Mevenide, the creation part of step 3 and all of steps 5 - 6 are obsolete. Mevenide structures the NBM project, creates all necessary files, and uses Maven to carry out compilation and generation tasks. As a result, your only contribution to the process is the coding of the Java classes (step 2) and the adding of elements to the layer XML file (step 3).

Join the discussion

Comments ( 6 )
  • pprun Saturday, May 7, 2005
    Does it means that the abuliding 'Module Wizard' will base on Mevanide?

    If not. What is the difference between this and the home-grown one?

    A duplicate work?

    We are welcoming your detail informations, as this detail the process of NBMs.

    BTW. why didn't supply a preview function to assist me to comment.(maybe my shame!)

  • Geertjan Monday, May 9, 2005
    Hi pprun, I'm not 100% sure about the relationship between Mevenide and 4.2 development plans in the NBM area. However, my understanding is that if you want to use Maven in/from the IDE, you should use Mevenide. Thanks for your comments and sorry for there not being a Preview function -- I didn't make this blog, I only write in it... :-)
  • Timothy Sunday, June 5, 2005
    I guess I am to dumb I got no imports found on the following types :
    callablesystemaction and helpctx
    I am using netbeans 4.1
  • Timothy Sunday, June 5, 2005
    that was pressing Alt-Shift-F on #2
  • Geertjan Wednesday, June 8, 2005
    Hi Timothy,
    Are you sure you added openide.jar and open-ideloader.jar, as explained in step 2 above? To check, expand the Libraries node and see if you can see them there. That should resolve your problem. If not, please leave a note again!
  • abhisek Wednesday, February 20, 2008

    hi can u tell me how to garbage collect a topcomponent on close

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.