Monday Dec 04, 2006

NetBeans Free-Form Projects as Library Wrappers

When the developer defines a library in NetBeans 5.x, the library definition is stored locally, in the user directory. This makes it difficult to share library definitions among more than one workspace. While library definitions are stored locally, references to them, in the form of entries in a project's properties file, are typically stored along with all other project files, in a remote code repository. When a user first fetches the project from the repository and opens it in NetBeans, a missing references error will occur. All missing local library definitions must be created anew in each local workspace.

One solution to this problem is to store shared libraries in the remote workspace, and to make projects depend directly on the libraries' constituent JAR files. Such dependencies are stored in the project's properties file as relative paths to the JAR files, so assuming that the directory structure that includes both project and library remains the same in all users' workspaces, no local definitions are needed.

There are however drawbacks to this solution. Under the Libraries node of the project logical view, only the JAR file name is displayed. If your project depends on a large number of libraries, it can be difficult to distinguish among them by file name alone. The names may by cryptic, or worse, there may be files in different directories that share the same name. There is also no way of determining from the project logical view that a group of JAR files form a logical unit, unless they share a common infix.

As an example, consider the following project, in which one library provided JAR files aaa and bbb, and another library provided another JAR file, also named aaa:

There is a hack that I have used to improve the quality of the information available about JAR files in the project logical view, which does not require use of the local storage. Instead of grouping them into library definitions, I add them to free-form projects. Projects may then be declared to depend on the library wrapper projects.

Here is the same example, with the JAR files from the two libraries exported from two free-form library projects:

How to create a free-form library wrapper project

To create a free-form library wrapper project, start by putting all JAR files that belong together into a directory, which will serve as the project root directory. For this example, I will define two libraries, 01 and 02, the first containing two JAR files, aaa.jar and bbb.jar, and the second containing just one, aaa.jar:

Each directory will server as one logical library, represented by one free-form project. To create the project skeleton, in each directory create an empty source directory, e.g. ./src. You will also need a stub ant build script. Add the following contents to the file build.xml in the project directory:
  <project name="01_Library_Wrapper" default="build" basedir=".">
    <target name="build"/>
    <target name="clean"/>

To create the project, from within NetBeans, choose File->New Project, and choose a "Java Project with Existing Ant Script" within the General category. In the next wizard panel, select as location the project's directory, e.g. ./lib01. NetBeans will fill in the build file information. You'll want to choose a short, but descriptive, project name, as this will be the name that appears under the Libraries node once you have declared a dependency on this library wrapper project. I chose the names "01 Library Wrapper Project" and "02 Library Wrapper Project". In the next, penultimate wizard panel, NetBeans will fill in the ant targets found, and in the final panel it will prompt you for a source directory. Choose the source directory that you created earlier.

[It may seem superfluous to create an empty source directory and empty build targets, but I discovered that without these, some actions in the IDE can have the side effect of removing the exported JAR definintions.]

After the project is created, bring up the project's properties window, and choose Output. Here you will declare the JARs that this free-form project exports. Select all the JARs that you put into the library wrapper project directory. When later you declare a dependency on this project, these are the JARs that will be added to the class path. Here is what this step looks like for my first library, 01:

And that's it! Now you are ready to declare project dependencies on your new library wrapper projects. Right-click on the Libraries node in the project logical view, and choose "Add Project...". Select the project directory. All JARs in the project will be added as dependencies.




Top Tags
« August 2016