Author: mjj29 Date: 2010-08-06 19:06:52 +0000 (Fri, 06 Aug 2010) New Revision: 12887
Added: trunk/website/docs/tutorial.html Log: add tutorial from javahelper Added: trunk/website/docs/tutorial.html =================================================================== --- trunk/website/docs/tutorial.html (rev 0) +++ trunk/website/docs/tutorial.html 2010-08-06 19:06:52 UTC (rev 12887) @@ -0,0 +1,626 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> + <head> + <meta name="Author" content="Matthew Johnson (mj...@debian.org)"/> + <title>Packaging Java with Javatools</title> + </head> + <body> + <div id="page"> + <div id="container"> + <div id="main"> + <div class="shadow"> + <div id="sticky"> + <h2 style="display:none;">Page Body</h2> + <hr style="display:none;"/> + <h3>Packaging Java with Javatools</h3> + <p> + Javatools replaces the existing <tt>jarwrapper</tt> package and also contains programs + to help packagers in creating packages for Java programs and libraries. + </p> + <h3>Packaging tools</h3> + <p> + The <tt>javahelper</tt> package consists of several small programs which make + packaging Java programs and libraries easier. They are generally designed to work + in the same fashion as the debhelper programs, but start with the <tt>jh_</tt> prefix. + </p> + <p> + All of the programs have their command line arguments documented in manpages. + </p> + <h4>jh_build</h4> + <p> + Many Java programs and libraries are distributed without sane build systems. + <tt>jh_build</tt> provides a simple interface for building Java source code + into Jars, including setting the appropriate entries in the manifest. + </p> + <p> + In almost all cases all that needs to be done to call <tt>jh_build</tt> is to set + <tt>JAVA_HOME</tt> and <tt>CLASSPATH</tt> and then call <tt>jh_build</tt> with the + name of the jar and the directory containing the source. + </p> + <pre class="code"> +JAVA_HOME=/usr/lib/jvm/default-java +CLASSPATH=/usr/share/java/esd.jar:/usr/share/java/jsch.jar +jh_build weirdx.jar src + </pre> + <p> + This command will compile all the Java files under <tt>src</tt>, set the + classpath in the manifest and build it all into weirdx.jar. + </p> + <p> + A couple of other options are worth mentioning. If this jar contains an application + rather than a library then the <tt>-m</tt> or <tt>--main</tt> option can be used + to set the <tt>Main-Class</tt> attribute in the manifest which will allow the resulting jar + file to be be executed + </p> + + <p> + Alternatively, you may provide a <tt>debian/javabuild</tt> file containing one jar per + line, each jar name followed by a list of source files or directories. In this + case you can call <tt>jh_build</tt> with no jar or source and it will build + those jars. The jars will then be removed by <tt>jh_build --clean</tt>. + </p> + <p><tt>jh_build</tt> also provides a <tt>--clean</tt> parameter which should be called in the + <tt>clean</tt> target of <tt>debian/rules</tt>. It will be called for you by <tt>jh_clean</tt> + </p> + <p> + jh_build will also create javadoc, but only for the last jar built in each + package. It can be installed automatically using jh_installjavadoc (see + below). + </p> + + <h4>jh_installlibs</h4> + <p> + For library packages Debian Java policy currently requires that the libraries be installed + to <tt>/usr/share/java</tt> in a versioned format and with an unversioned symlink. + <tt>jh_installlibs</tt> will take a jar and correctly install it. + </p> + <p> + As with debhelper programs, this can either take a jar as a parameter, or read a list of + jars from a file in the Debian directory. It also follows the <tt>-p</tt>, <tt>-i</tt> and + <tt>-a</tt> semantics of debhelper for selecting which packages to install the jar to. + When operating on a package, <tt>jh_installlibs</tt> will read the list of library jars from + <tt>debian/package.jlibs</tt> or <tt>debian/jlibs</tt>. + </p> + <p> + The jlibs file is a list of jars to install, one per line, and works exactly the same as listing + them on the command line. Each jar is installed to <tt>debian/package/usr/share/java/</tt> in + the appropriate versioned and unversioned forms. + </p> + <p> + If the jars built by upstream already contain the version number, this + will be stripped before installing. <tt>jh_installlibs</tt> will also try to strip the upstream version number + of any dfsg suffix. Other version-mangling options or explicit version numbers can also be provided. + </p> + <h4>jh_depends</h4> + <p><tt>jh_depends</tt> works like <tt>dpkg-shlibdeps</tt>, but for jar files. For each jar in the package it + takes the jars on which it depends and finds the packages to which they belong. These are included + in the debhelper substvars as <tt>${java:Depends}</tt>. The control file can then just list that + variable which is filled in automatically. + </p> + <p> + This is done by reading the <tt>Class-Path</tt> attribute from the manifest of each jar. Jar files + should include this attribute to prevent applications which use them from needing a full recursive + classpath in their startup scripts and to prevent unneccessary transitions when the library changes + its dependencies. If the package is not built with <tt>jh_build</tt> and the upstream build system + doesn't set it correctly then <tt>jh_manifest</tt> or <tt>jh_classpath</tt> can be used to fix this. + </p> + <p> + If the application uses executable jars (see <i>Runtime support</i> below) then jh_depends will + also add the appropriate depends on <tt>jarwrapper</tt> and the correct Java runtime. + </p> + <p> + As of version 0.32, <tt>jh_depends</tt> also checks installed javadocs for links + to system installed javadocs. It will use this to populate the + <tt>${java:Recommends}</tt> variable, which can be used for the doc package. + </p> + <p> + Note that both substvars are always created even if they are empty, + like <tt>debhelper</tt> does with <tt>${misc:Depends}</tt>. + </p> + + <h4>jh_manifest</h4> + <p> + Many upstream build systems do not set the <tt>Class-Path</tt> attribute in the jars they create. + This leads to several unwanted problems, such as expanding the classpath which applications have + to use and introducing unneccessary transitions. They also may not set the <tt>Main-Class</tt> + attribute. Both of these are required for running jars with the <tt>-jar</tt> parameter. + </p> + <p><tt>jh_manifest</tt> can fix the manifest files of jars. It can either read from a manifest + file in the Debian directory or run in a mode which updates all the jars with the CLASSPATH + environment variable. + </p> + <p> + The manifest files can either be <tt>debian/package.manifest</tt> or <tt>debian/manifest</tt>. + The format of this file is a list of jars and indented below each one a list of manifest elements + to set: + </p> + <pre class="code"> +usr/share/weirdx/weirdx.jar: + Main-Class: com.jcraft.weirdx.WeirdX + Debian-Java-Home: /usr/lib/jvm/default-java + </pre> + <h4>jh_classpath</h4> + <p> + If you are just setting the classpath then this command is simpler than + jh_manifest. jh_classpath can either take jars on the command line with the + classpath specified on the command line or in the CLASSPATH environment + variable. + </p><p> + Alternatively, it can read classpaths from a debian/classpath or + debian/package.classpath file. This should be one jar per line specifying the + jar followed by it's space-separated classpath: + </p> +<pre class="code"> +src/bar.jar /usr/share/java/quux.jar +src/foo.jar /usr/share/java/bar.jar /usr/share/java/baz.jar +</pre> + + <h4>jh_exec</h4> + <p> + The <i>Runtime support</i> section below describes running executable jars directly. + <tt>jh_exec</tt> will scan package directories for jars in the paths, or symlinks to + jar from the paths, and ensure that they have been set executable if necessary. + </p> +<h4>jh_installjavadoc</h4> +<p> + If you have javadoc which has been built by your build system, then + <tt>jh_installjavadoc</tt> will install it in the correct location and register it + with doc-base for you. Either run <tt>jh_installjavadoc</tt> with the directory + containing the javadoc as a parameter, or it will read <tt>debian/javadoc</tt> or + <tt>debian/package.javadoc</tt> which should contain a single path to the javadoc + for that package. +</p> +<p> + If you have used <tt>jh_build</tt> that will automatically have created javadoc. To + install that put the string <tt>internal</tt> in the javadoc file and it will be + installed. +</p> +<p> + The second parameter, or the second string on the line in the javadoc file, + can be used to override the install location, for example, so that a -doc + package can install to <tt>/usr/share/doc/$library/api</tt>. +</p> + <h4>jh_makepkg</h4> + <p><tt>jh_makepkg</tt> will create template Debian packages for Java programs and libraries + similar to <tt>dh-make</tt>. It should be run in the source directory and it will + create the orig.tar.gz and most of the files in the Debian directory, which need only + small changes neccessary to build the package. + </p> +<h4>jh_linkjars</h4> +<p> + If upstream ship convenience copies of third-party jar files which have been + removed (see <tt>jh_repack</tt> below), but the build system refers to that + directory, <tt>jh_linkjars</tt> can be used to populate the directory with symlinks + to the packaged jars in <tt>/usr/share/java</tt>. +</p> +<p> + It is called either with a directory on the command line or by specifying + one target directory per line in the file <tt>debian/linkjars</tt>. +</p> +<p> + <tt>jh_linkjars</tt> will scan all of the (installed) build-dependencies and create a + symlink to every jar which is installed by those packages in the target + directory. +</p> +<p> + <tt>jh_linkjars</tt> can be called with <tt>-u</tt> to remove all the symlinks in the clean + target. This is done automatically by <tt>jh_clean</tt>. +</p> + +<h4>jh_clean</h4> +<p> + <tt>jh_clean</tt> should be called in the clean target to remove files which have beenn + created by other jh_ commands, such and jh_build and jh_linkjars. +</p> + +<h4>jh_repack</h4> +<p> + <tt>jh_makepkg</tt> provides functionality to help clean your upstream tarball of + prebuilt jars, classfiles and javadoc. If you want to do this whenever + you download a new version you can use <tt>jh_repack</tt> as a uscan helper. Just + put <tt>jh_repack</tt> as the command at the end of the uscan line. E.g. +</p> +<pre> +version=3 +http://www.matthew.ath.cx/projects/salliere/ (?:.*/)?salliere-?_?([\d+\.]+|\d+)\.(tar.*|tgz|zip|gz|bz2|) debian jh_repack +</pre> +<p>Alternatively you can run it by hand:</p> +<pre> +jh_repack --upstream-version <version> <tarball> +</pre> +<p> + jh_repack will remove any .class files, any .jar files, the whole directory + tree containing javadoc and any empty directories as a result of the above. +</p> + <h4>java-propose-classpath</h4> + <p> + Some upstreams have complicated classpaths which may not be obvious to the packager + when using <tt>jh_manifest</tt> to set the <tt>Class-Path</tt> attribute. + <tt>java-propose-classpath</tt> will unpack a jar and look at the symbols imported to + the class files, then scan all the jars in <tt>/usr/share/java</tt>. This shouldn't be + run in the build since it is slow, and there may be ambiguities that the packager must + resolve. It is still very useful for the packager as most of the time it will get it right + automatically. + </p> + <p> + To avoid bloating the recursive build-deps of packages, + java-propose-classpath is in a separate package to javahelper. It should not + be on any package's build-depends. + </p> + + <h4>jh_installeclipse</h4> + <p> + <tt>jh_installeclipse</tt> will install eclipse features built + by eclipse's <tt>pde-build</tt> script. It supports most of + debhelpers normal options. Features can either be put in the + <tt>>package<.eh-install</tt> or be given per command-line. + By default <tt>jh_installeclipse</tt> expects <tt>pde-build</tt> + to have been run from <tt>debian/.eclipse-build</tt>; if you + decide to run it from another directory, you should + use <tt>--pde-build-dir</tt> to tell <tt>jh_installeclipse</tt> + where pde-build was run from. + </p> + + <p> + <tt>jh_installeclipse</tt> knows where <tt>pde-build</tt> + dumps its output, so only the name of the feature should be + given. It supports file globbing both in the files and per + command-line (though in the latter case your shell may + attempt to expand the globs if they are not properly escaped + or quoted). + </p> + + <p> + Due two the way the underlying build system works; orbit dependencies will + be embedded directly into the installation. <tt>jh_installeclipse</tt> will replace + any orbit dependencies imported by <tt>jh_generateorbitdir</tt>. If you add/import + orbit dependencies yourself through other means, you <i>must</i> replace them + yourselves after running <tt>jh_installeclipse</tt>. + </p> + + <p> + Finally, <tt>jh_installeclipse</tt> will output a <tt>${orbit:Depends}</tt> variable if it + replaces any orbit dependency for that package. + </p> + + <h4>jh_generateorbitdir</h4> + <p> + <tt>jh_generateorbitdir</tt> is an javahelper program that handles creation + of an orbit dependency dir. This directory has to be populated with + non-eclipse jar files. However, eclipse refers to these jars by + their <i>symbolic name</i>. <tt>jh_generateorbitdir</tt> can extract this name + from the jar's manifest (provided it has the OSGi metadata) and + create a symlink to it. + </p> + <p> + <tt>jh_generateorbitdir</tt> will replace regular files with symlinks + if they are present in the orbit dir and clash with the name + of one of the orbit jars. If an orbit jar name clashes with a + symlink in the orbit dir, then <tt>jh_generateorbitdir</tt> will assume + that the given jar has already been symlinked and skip it. + </p> + <p> + <tt>jh_generateorbitdir</tt> will also check the default installation for + jar files on Debian systems (at the time of writing <tt>/usr/share/java</tt>), + if it cannot find the jar in the current dir. + </p> + <p> + If present, <tt>jh_generateorbitdir</tt> will read <tt>debian/eclipse.orbitdeps</tt> and + add the jar files listed in it to the list of orbit dependencies. + </p> + + <h4>jh_setupenvironment</h4> + <p> + <tt>jh_setupenvironment</tt> is a javahelper program that handles creating + an environment for building an eclipse feature. It does not setup + an orbit dir (use <tt>jh_generateorbitdir</tt> for that). It will copy files + specified in <tt>debian/eclipse.environment</tt> as well as those given on + command line into the environment dir. If no files are given per + command line and the environment file is not present (or is empty), + it will default to <tt>org.eclipse.*</tt> + </p> + + <h4>jh_compilefeatures</h4> + <p> + <tt>jh_compilefeatures</tt> handles compilation of eclipse features. It will read + debian/eclipse.features as a list of features to compile and their + dependencies. The first item on a line is the id of the feature and the + remaining are either ids of previously compiled features or features + installed on the system (identified by the folder they are installed in). + </p> + <p> + By default <tt>jh_compilefeatures</tt> will set the source and the target version + of the class files to 1.5. This can be overriden by explicitly changing + the build options (see man jh_compilefeatures for more information). + </p> + + <h4>java-vars.mk</h4> + <p> + + You can include <tt>/usr/share/javahelper/java-vars.mk</tt> in your <tt>debian/rules</tt> to + get the following variables defined: + </p> + <ul> + + <li><b>JAVA_HOME</b>—If you haven't already set it, will default to the default JDK for the architecture + (you must depend on default-jdk or -headless if you are not overriding this). + To override this set <b>JAVA_HOME</b> <i>before</i> including <tt>java-vars.mk</tt></li> + + <li><b>JAVA_ARCH</b>—The JVM version of the build architecture (eg ppc not powerpc)</li> + + <li><b>JRE_HOME</b>—If <b>JAVA_HOME</b>/jre exists then that, otherwise <b>JAVA_HOME</b></li> + + <li><b>JVM_CLIENT_DIR</b>/<b> + JVM_SERVER_DIR</b>—set if the respective types of JVM are installed.</li> + </ul> + <p> + If you need the Java architecture in a non-make context then you can use + <tt>/usr/share/javahelper/java-arch.sh</tt> instead. + </p> + + + <h3>Runtime support</h3> + <p> + Javatools also provides some runtime support. Unlike compiled programs, or purely interpreted + programs with hash-bang lines, Java programs cannot be directly executed. Many upstreams + expect them to be run using <tt>java -jar jarname</tt> or <tt>java classname</tt>. This is not + generally acceptible in systems which expect to just be able to run the command or launch it from + a menu. As a result, many packagers are writing wrapper scripts which just call java with the correct + classpath, jar and main class. + </p> + <h4>jarwrapper</h4> + <p> + There is an alternative to wrapper scripts, however. The <tt>binfmt_misc</tt> kernel module allows + the kernel to call out to a program in userspace to execute specific types of file. <tt>jarwrapper</tt> + registers itself as a handler for executable jars. This is done by reading values from the manifest + file. + </p> + <p> + In order for executable jars to work the following attributes must or may be defined in the manifest. + These attributes can be set using <tt>jh_build</tt> and <tt>jh_manifest</tt>. + </p> + <ul> + <li>Main-Class: The name of the class to be run when the application starts. (REQUIRED)</li> + <li>Class-Path: The path to all the jar files on which this jar depends. (REQUIRED unless empty)</li> + <li>Debian-Java-Home: A Debian-specific property if this application depends on a specific runtime. + Specify the path to the runtime which should be used. Multiple space-separated paths may + be given if any of the runtimes will work. (OPTIONAL)</li> + <li>Debian-Java-Parameters: A Debian-specific property if this application needs extra options + to the JVM. (OPTIONAL)</li> + </ul> + <h4>Java Architecture</h4> + <p> + + If you need to know the JVM architecture name at runtime (for example + to put <tt>libjvm.so</tt> on the <b>LD_LIBRARY_PATH</b>) then jarwrapper also provides + <tt>/usr/share/jarwrapper/java-arch.sh</tt> which will either print the current + one or convert a debian arch name to a JVM arch name. + </p> + <h3>Putting it together</h3> + <p> + This section shows the debian packaging generated by <tt>jh_makepkg</tt> for an application and a library + using <tt>jh_build</tt>. + </p> + <h4>Sample Library Packaging</h4> + <h5>debian/control</h5> + <pre class="code"> +Source: jsch +Section: libs +Priority: optional +Maintainer: Matthew Johnson <mj...@debian.org> +Build-Depends: debhelper (>= 5), javahelper, default-jdk, libzlib-java +Standards-Version: 3.7.3 +Homepage: http://www.jcraft.com/jsch/ + +Package: libjsch-java +Architecture: all +Depends: ${java:Depends}, ${misc:Depends} +Description: Java secure channel + JSch is a pure Java implementation of SSH2. JSch allows you to + connect to an sshd server and use port forwarding, X11 forwarding, + file transfer, etc., and you can integrate its functionality + into your own Java programs. JSch is licensed under a BSD style + license. + </pre> + <h5>debian/rules</h5> + <pre class="code"> +#!/usr/bin/make -f + +export JAVA_HOME=/usr/lib/jvm/default-java +export CLASSPATH=/usr/share/java/zlib.jar + +build: build-stamp +build-stamp: + dh_testdir + jh_build jsch.jar src + touch $@ + +clean: + dh_testdir + dh_testroot + jh_build --clean + dh_clean + rm -f build-stamp jsch.jar + +install: build + dh_testdir + dh_testroot + dh_prep + dh_installdirs + +binary-arch: build install + # Java packages are arch: all, nothing to do here + +binary-indep: build install + # Create the package here + dh_testdir + dh_testroot + dh_prep + dh_install -i + jh_installjavadoc -i + dh_installdocs -i + dh_installchangelogs -i + jh_installlibs -i + jh_depends -i + dh_compress -i + dh_fixperms -i + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install + </pre> + <h5>debian/libjsch-java.jlibs</h5> + <pre class="code"> +jsch.jar + </pre> + <h5>debian/libjsch-java.javadoc</h5> + <pre class="code"> +internal + </pre> + <h4>Sample Application Packaging</h4> + <h5>debian/control</h5> + <pre class="code"> +Source: salliere +Section: misc +Priority: optional +Maintainer: Matthew Johnson <mj...@debian.org> +Build-Depends: debhelper (>= 5), default-jdk, + libmatthew-debug-java, libcsv-java, + libitext-java, javahelper +Standards-Version: 3.7.3 + +Package: salliere +Architecture: all +Depends: ${java:Depends}, ${misc:Depends} +Description: Short Description + Long Description + </pre> + <h5>debian/rules</h5> + <pre class="code"> +#!/usr/bin/make -f +export JAVA_HOME=/usr/lib/jvm/default-java +export CLASSPATH=/usr/share/java/csv.jar:/usr/share/java/debug-disable.jar:/usr/share/java/itext.jar + +build: build-stamp +build-stamp: + dh_testdir + # Build the package + jh_build salliere.jar src + touch $@ + +clean: + dh_testdir + dh_testroot + jh_build --clean + dh_clean + rm -f build-stamp salliere.jar + +install: build + dh_testdir + dh_testroot + dh_prep + dh_installdirs + +binary-arch: build install + # Java packages are arch: all, nothing to do here + +binary-indep: build install + # Create the package here + dh_testdir + dh_testroot + dh_prep + dh_install -i + dh_installdocs -i + dh_installchangelogs -i + jh_manifest -i + dh_link -i + jh_exec -i + jh_depends -i + dh_compress -i + dh_fixperms -i + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install + </pre> + <h5>debian/salliere.install</h5> + <pre class="code"> +salliere.jar usr/share/salliere + </pre> + <h5>debian/salliere.links</h5> + <pre class="code"> +usr/share/salliere/salliere.jar usr/bin + </pre> +<h4>Using javahelper with CDBS</h4> +<p> +Javahelper 0.18 introduces a CDBS class for javahelper. It runs all the jh_ +commands after dh_install* and dh_link and has options for running jh_build +under the build target. +</p> +<p> +The jh_ commands are invoked once per package. You can pass options to all the +invocations using the JH_EXEC_ARGS, JH_INSTALLLIBS_ARGS, JH_MANIFEST_ARGS and +JH_DEPENDS_ARGS variables. +</p> +<p> +To invoke jh_build you must set JH_BUILD_JAR and JH_BUILD_SOURCE and JAVA_HOME. +Optionally you can also set CLASSPATH and JH_BUILD_ARGS. +</p> +<p> +Please note: you <b>must</b> include javahelper.mk before ant.mk. +</p> +<p> +The above debian/rules can be rewritten with CDBS as follows: +</p> +<pre class="code"> +#!/usr/bin/make -f +export JAVA_HOME=/usr/lib/jvm/default-java +export CLASSPATH=/usr/share/java/csv.jar:/usr/share/java/debug-disable.jar:/usr/share/java/itext.jar +JH_BUILD_JAR=salliere.jar +JH_BUILD_SRC=src + +include /usr/share/cdbs/1/class/javahelper.mk +</pre> + + +<h4>Using javahelper with dh</h4> +<p> +Javahelper 0.20 introduces a dh extension for javahelper. It runs all the jh_ +commands after dh_install* and dh_link and also runs jh_build if you have a +debian/javabuild file. +</p> +<p> +The above debian/rules can be rewritten with dh 7 as follows: +</p> +<h5>debian/javabuild</h5> + +<pre class="code"> +salliere.jar src +</pre> + +<h5>debian/rules</h5> + +<pre class="code"> +#!/usr/bin/make -f + +export JAVA_HOME=/usr/lib/jvm/default-java +export CLASSPATH=/usr/share/java/csv.jar:/usr/share/java/debug-disable.jar:/usr/share/java/itext.jar + +%: + dh $@ --with javahelper +</pre> + + </div> + </div> + </div> + </div> + </div> + </body> +</html> _______________________________________________ pkg-java-commits mailing list pkg-java-comm...@lists.alioth.debian.org http://lists.alioth.debian.org/mailman/listinfo/pkg-java-commits