JJAR is an acronym for Jakarta JAR Archive Repository, an attempt at making a CPAN-like service/infrastructure for the Java development community.
Note :Until JJAR is officially in production, no guarantees will be made as to the correctness of the delivered jars. Best efforts will be made, but at any time, what you get might not be what you want.
Currently, JJAR is an experimental work in progress. It does work as advertised, and every effort is being made to ensure that it works at any point in time. However, as we are learning about what works and what doesn't, change will happen. Further this is currently not an official Apache Commons project, but a well-organized sandbox project. Therefore, production dependencies are discouraged.
Repeat : JJAR is neither an official Jakarta project, nor an official Apache Commons project. This document may have been found via a http://jakarta.apache.org/jjar/ link - it is there for information purposes for the repository.
Ok. Now that that's over, simply put, JJAR consists of two parts :
Together, these two parts [hopefully] make up a complete system for package management and delivery for building Java applications.
As currently defined, a repository physically consists of a directory containing a repository descriptor, an XML file containing repository information, and a set of jars described by that descriptor.
There is no strict requirement as to how a repository is implemented. The expected common implementation will be via http through a regular web server (no server-side programmatic support will be required.) However, in the case of local or enterprise use, it is expected that local file access will be enough. The technical limitation will be that there is a protocol handler for the access method of choice.
The central repository will be located on http://jakarta.apache.org/jjar/. The central repository will contain information on any project that does not want to host it's own repository. For any project that does host it's own repository (a remote repository), the central repository will simply contain information about the remote repository. The JJAR toolkit will use this information to tie the central and remote repositories together in a seamless manner.
The repository is distributed for several reasons :
The toolset is designed for general command-line use, integration with Java applications, and direct integration with Ant the fab Java-based build tool (rapidly becoming the Perl of Java...).
Commandline ToolFor command line use, a small Java program has been included. It is included in the jjar.jar distribution jar. To use it, it is invoked as :
$ java -jar jjar.jar command [parameters]
list [-p packagename] : List one or all packages in repository | |
Example : java -jar jjar.jar list | |
verify [-j jarname] : Verify jars in the classpath, or individually | |
Example : java -jar jjar.jar verify -j foo.jar | |
fetch -p package [-nd | -od] [-vi] [-d directory] [-v version] [-j outputjarname] : Fetch jars from the repository | |
Notes: -nd = no depeondences. -od = only dependencies. -vi = 'verify ignore' - will check to find each package/dependency and not fetch if found. Without -j, will go to 'default name'. Without -v, will get 'default' version. -d specifies local directory to hold the jars (the local repository). | |
Example : java -jar jjar.jar verify -j foo.jar | |
Please note that this documentation may be incomplete.
Jakarta Ant SupportJJAR also offers direct support for the fabulous Java-based build tool Ant. Please see the Ant site for more information. The following assumes that you understand the basics of Ant, and that you have it installed on your computer.
Ant support in JJAR is intended to simplify building projects by providing a facility to fetch the packages that a project depends on, as well as the dependencies for that package. The driving idea here is that a project will use JJAR to get any packages it depends on, and therefore removes the requirment of providing those jars to the users or developers of the package.
To do this, JJAR includes the JJARTask
class that
is an Ant task, and can be used directly in Ant. It is use like
this. The following bit of a build.xml ant 'script' comes from
the /examples/ant-task/ example in the JJAR distribution :
<!-- declare our 'jjar' ant task. Assumes jjar.jar in --> <!-- local directory --> <taskdef name="jjar" classname="org.apache.commons.jjar.JJARTask"> <classpath> <pathelement location="jjar.jar"/> </classpath> </taskdef> <!-- task to get jars for the jakarta-velocity package --> <!-- version 1.2-dev, and places them in the --> <!-- ${rep.local} repository --> <target name="fetchjars"> <jjar package="jakarta-velocity" version="1.2-dev" localrepository="${rep.local}"> </jjar> </target>
A more interesting example is how to then let jjar get some dependencies and also add them to the classpath. Again, from the /examples/ant-task/build.xml example :
<!-- assume jjar task defined... --> <target name="test-classpath"> <!-- use JJAR to fetch the Velocity package and --> <!-- dependencies, placing in the repository --> <jjar package="jakarta-velocity" version="1.2-dev" pathrefid="jjarclasspath" localrepository="${rep.local}"> </jjar> <!-- lets see if that worked --> <property name="jjarpath" refid="jjarclasspath"/> <echo message="jjarclasspath: ${jjarpath}"/> <!-- now compile the test file, using the jjar classpath --> <javac srcdir="${src.dir}" destdir="." > <classpath refid="jjarclasspath"/> </javac> </target>
The important thing about that last example is that as a user of Velocity, you no longer care what the Velocity developers add as dependencies to their project - as they add dependencies, they will update the repository, and the jars will automatically be downloaded, and automatically added to the classpath for building.
There are quite a few use-cases that have been identified, and by listing them here, it is hoped that you get a flavor of what this is about, if the flowery prose above didn't get the idea across.
In many of the examples below, the command line JJAR tool will be demonstrated. To use it, you must build the jjar.jar file. Please see the section on 'Building JJAR'.
Listing All Packages In The RepositoryThis is the simplest use of the toolset - you simply want to see whats there. Currently, you can do this with the command line tool :
java -jar jjar.jar list
JJAR : Jakarta Jar Archive Respository v0.1 =================================== Repository contains 9 packages : veltag desc : Velocity JSP taglibrary default : 0.01-dev versions : 0.01-dev deps : jakarta-servletapi:4.0, jakarta-commons-collections:0.0-1, jakarta-velocity:1.2-dev, -- jakarta-velocity desc : Jakarta Velocity template engine default : 1.0-1 versions : 1.0-1 deps : 1.1 deps : jakarta-commons-collections:0.0-1, 1.2-dev deps : jakarta-commons-collections:0.0-1, -- jaxp-parser desc : Java API for XML Processing default : 1.0 versions : 1.0 deps : --
In the (usual) case where you weren't interested in the entire repository, you can simply see the information and dependencies about a specific package :
java -jar jjar.jar list -p package
[gmj@192 jjar]$ java -jar jjar.jar list -p jakarta-velocity JJAR : Jakarta Jar Archive Respository v0.1 =================================== jakarta-velocity desc : Jakarta Velocity template engine default : 1.0-1 versions : 1.0-1 deps : 1.1 deps : jakarta-commons-collections:0.0-1, 1.2-dev deps : jakarta-commons-collections:0.0-1, --
Suppose you have a jar, and wish to figure out what JJAR package name and version it is. JJAR's toolset can do that :
java -jar jjar.jar verify -j jarname
Use JJAR to fetch a package and it's dependencies :
java -jar jjar.jar fetch -p jakarta-velocity -v 1.1
An interesting use-case is demonstrated by the Veltag JSP taglib
contribution in the Jakarta Velocity project. (Look in the
/contrib/temporary/veltag
directory.)
<!-- target to bootstrap by fetching jjar from central repository --> <target name="getjjar" depends="jjarcheck" unless="jjar.present"> <get src="http://207.138.188.222/jjar/jjar.jar" dest="${bin}/${jjar.jar}"/> </target> <!-- normal compile target uses JJAR to fetch dependencies --> <target name="compile" depends="static" description="Compile"> <taskdef name="jjar" classname="org.apache.commons.jjar.JJARTask"> <classpath> <pathelement location="${bin}/${jjar.jar}"/> </classpath> </taskdef> <jjar package="veltag" onlydependencies="true" verifyignore="true" localrepository="${local.repository}" pathrefid="jjarclasspath" > </jjar> <javac srcdir="${source.home}/java" destdir="${build.home}/classes" debug="${compile.debug}" deprecation="${compile.deprecation}" optimize="${compile.optimize}"> <classpath refid="jjarclasspath"/> </javac> </target>
The end result is that the Veltag developers, who dictate their project dependencies anyway, use the JJAR repository mechanism as the single point of maintenance, which then provides inclusion of the Veltag project in the JJAR repository system, as well as a maintenance free build.xml file. As they add external dependencies to the project, they automatically get included in the build.
To the user, after they get a snapshot of CVS or a distribution copy, all they have to do is :
$ ant getjjar $ ant jar
Then, as the project evolves and the developers add new dependencies (or the developers of the existing dependencies change things) then anyone building this project is immune to those changes, as a simple
$cvs update $ant jar
Note, there are still quite a few details to be worked out with Ant support...