The Java Package Manager (JPM) is a set of class libraries and associated tools for managing bundles of distributable Java code. Inspired by the Red Hat Package Manager (RPM) distribution format, the Java Package Descriptor (JPD) format provides similar benefits to Java development.
At present, JPM provides a command-line tool that can automate the downloading, installation, and building of Java code. However, as successful use of JPM depends on having a suitable JPD for the package one wishes to use, success with the tool is limited to those few descriptors already created or descriptors created from scratch. Some of the descriptors that are available in limited form are:
Ant - The XML-based, cross-platform Java build tool from The Apache Group's Jakarta project
Hypersonic SQL - A small, 100% Java JDBC-compliant SQL database capable of running as an in-memory database or as a standalone server
JPM - The Java Package Manager itself
Kissme - The Kissme Java VM, a simple but functional Java VM
MindTerm - An open source implementation of SSH written in Java
WeirdX - An X server written in Java
Unfortunately, I do not have a tutorial on writing a JPD from scratch at this time. I suggest you look at the DTD for descriptors, then review the descriptors already available here. The best way to start a new descriptor is usually to copy one that already works for another package, then just change the names and values as appropriate. Also, comfort with Ant build files is highly suggested, since JPM just extends the features already provided by Ant.
As of October 4, 2000, the 0.6.0 release of JPM included the following features:
A command-line tool to download and process JPD files suitable as a replacement for Ant, if an appropriate JPD is available in place of an Ant buildfile
Supports all tasks provided by the Ant package, including: exec, javac, expand, etc.
Using the jCVS package, can checkout code from a remote CVS repository using 100% Java code. Using JCVS tasks instead of Ant CVS tasks means that a non-Java CVS client is no longer required on the developer's machine; the jCVS libraries are included with JPM. However, for repositories protected with SSH (e.g., Sourceforge), a functioning SSH client is still required.
Features planned for future releases, may include the following:
Integration of MindTerm's SSH libraries to replace the need for a non-Java SSH package
Automatic downloads and installation of dependencies; currently, the DTD for JPDs defines a way to identify dependencies, but the JPM classes do not attempt to automatically initiate a download if dependencies are not available when installing a package
Add code to manage local configuration files for JPM; for example, storing the root directory where all installed packages reside, viewing/modifying essential settings like the SSH client to use when performing secure CVS operations, etc.
Creating a servlet-based application for integrated browsing of the API docs from installed packages, viewing nicely-formatted presentations of each package's descriptor, etc.
Creating a classloader based on the JPM code; although this may not be necessary, some applications may be benefit from a more intelligent class search strategy
The current version of JPM is available for download from the JPM project page at Sourceforge.
To use, download the JPM archive from Sourceforge and extract to a directory of choice. It is suggested you create a tree looking something like this:
$HOME /java /packages /jpm
where $HOME is your home directory. If cd to the ~/java/packages/jpm directory listed here and extract the archive from there, then you will have the same setup as that used to develop JPM.
As execution of JPM depends on several libraries, all libraries found in the /lib subdirectory should be added to the classpath prior to executing the main class, which is blue.tools.jpm.PackageManager. On *nix platforms, the following command executed from /jpm directory will be sufficient to start JPM (note the use of the back-tick to execute the find command):
java -cp `find lib -name *.jar -printf ':%p'` blue.tools.jpm.PackageManager
Depending on how JPM is invoked, it will either either download a JPD specified on it's command-line (through the -p option), or look for a package.xml file in the current directory. When JPM downloads a JPD, it copies the descriptor to package.xml in the current directory, so repeated invocations of JPM in the same directory do not need to specify the -p option, as the local copy in package.xml will be used. JPM does not use any hidden files in the current directory, so be aware that deleting the package.xml in the current directory will require subsequent executions to download the descriptor again using the -p option.
Here's the output of running the -usage option:
Usage: jpm [options] target(s) ... where valid options are -p URL of the package descriptor; defaults to package.xml in current directory -b Path to base or working directory for installing the package; defaults to current directory -terse Print only errors from build -verbose Print most messages output from build -extra Print all messages output from build -usage Print this message -user User name for CVS access -password Password for CVS access -checkout Checkout the package from CVS -build Build the package; this is default, but if multiple 'actions' are specfied, use of this option will determine where in the sequence a build occurs
Note that using JPM is similar to using Ant (or make, if that is more familiar): after specifying options, all remaining arguments are treated as targets to the build process. If none is specified, then the default target will be executed. Reporting of messages is reasonably thorough, but it will not look the same as output from Ant: some bugs in the Ant toolset do not report messages with the appropriate priority level, so the JPM logger filters out some messages that Ant (incorrectly) does not.
Currently, all JPM development happens on the Linux platform, and as such has not been tested on any Windows operating systems, nor have any been scripts been produced to run on a Windows operating system. However, since the entire package is written in Java, JPM should work unchanged on other platforms.
Further, development of JPM currently uses JDK 1.3 from Sun. Although JPM has not been tested on early VM specifications or the VM of other vendors, JPM should run unchanged on most JDK 1.2 or greater VMs.
JPM depends on 3 other external libraries to operate, but presently those libraries are included in the distribution. No additional downloads are necessary. Those libraries are:
Ant
Sun's Java extensions for XML (JAXP
jCVS
I started creating the JPM libraries after growing frustated at the difficulty of downloading, installing, and evaluating all the open source Java products available on the Net. For each product, I needed to:
To download and extract an archive or checkout the code from CVS, then optionally run an install or make script
Attempt to find relevant documentation
Determine the main class for any applications, if any, provided by the product
Determine the CLASSPATH needed to run the application(s), including dependencies on other well-known products (e.g., IBM's Xerces XML parser)
Sift through the source code when the product failed to work on my machine
Finally, I decided to create a set of classes to manage Java Package Descriptors (JPDs): a package descriptor is a small XML file that describes all of the relevant bits of a specific Java product. With this descriptor (and nothing else), the libraries should have sufficient information to:
To download and extract any archives, or checkout code from CVS
To compile any resulting source code into a working product
To determine the classpath to use when compiling and when running the compiled code
To declare the location of essential resources such as source code, API documentation, user's guides, etc.
To declare and manage dependencies between multiple JPDs, so that packages could be automatically downloaded before using a dependent package
After some early efforts, I decided to extend the Ant toolset developed for the Apache Jakarta project. The Ant toolset provides a platform-independent make facility that instead of using traditional (and cumbersome) make files uses XML-based build files. For those familiar with Ant, all of done is create code around the Ant libraries to embed Ant build information inside JPDs. Together, the ant-compliant portion of the JPD provides complete instructions for downloading, installing, building, etc., a product, while the remaining meta-info stored in the JPD is available for other functions.
The JPD approach differs from that of other distribution formats, such as RPM or the various .JAR based Java deployment formats. RPM and most .jar formats embed the meta-info and the contents of the files in the distribution directly in the distribution file. However, I realized that I didn't want to waste time or diskspace downloading, installing, packaging, and then uploading dozens or hundreds of open source packages. Further, some packages may have licensing restrictions that prohibit direct redistribution. Using a descriptor is essentially the same as "linking" to a package in the same way that hyperlinks are links to packages, but do not contain the content themselves.
As for the .JAR formats proposed by Sun (.JARs for archives and bean distribution, .WAR for web applications, etc.), unfortunately most of these formats were unsatisfactory for 2 reasons:
They are targeted at production deployment instead of aiding the developer; the latter was my goal
Most of the meta-info embedded in the various .JAR files (except for EJB deployment descriptors) is not stored in XML, but in very crude text files containing name-value pairs.
One more format that was considered by not included: Sun's Java Network Launch Protocol (JNLP) or Web Start. I chose not to follow Sun's conventions for 2 reasons:
It was not apparent that JNLP or any libraries based on JNLP as delivered by Sun would be considered open source
JNLP, like most other deployment methods, targets deployment into production, while I wanted to solve the problem of deployment to development
I did recommend to the JNLP team some changes to their format, but they politely declined at the time of my request on the basis of their need to stabilize the specification. Granted, JNLP includes semantics that support lazy-downloading, caching of resources, specifying target VMs, and even automatic downloading of VMs, but I considered those beyond the scope of my present needs.