How to make an Ant task to sign and pack200 all my JAR files?
Asked Answered
A

3

9

My JAR files must be signed for a webstart application. It would be nice to also have them packed to minimize the download time. I'm trying to configure an Ant task to automatically do it during the deploy of the application. Since the pack process reorganizes the jar internal structure invalidating the signature, the Pack200 documentation recommends a 3 steps process:

  1. Repack the JAR with pack200
  2. Sign the JAR with jarsigner
  3. Compress JAR jar with pack200 generating an .jar.pack.gz file

Ant has a default signjar task, and Sun published a Pack200 ant task.

The problem is that Sun pack200 task just operate on one file at a time and the repack operation must specify an output file.

I believe it should be a fairly common operation, but my ant file is becoming overly complex and there's too many temporary files. Time to beg for the wisdom of the community:

Is there an easy or, at least, standard way to pack and sign all my JAR files?

Abutting answered 22/7, 2010 at 19:2 Comment(0)
A
10

Here is my own solution. I've discarded the prebuild ant targets, and decided to run directly the pack200 executable.

This approach has some advantages:

  • it works (jarsigner was failing to verify some jars)
  • no dependencies besides the jdk
  • it doesn't spend a lot of time repacking already repacked jars
  • it can sign and repack the files inline, allowing me to put the signed version under version control. No need to sign twice.

Here is the code of the macro that repack and signs inline:

<macrodef name="repack-and-sign">
    <attribute name ="rootdir"/>
    <sequential>
            <echo message="Repacking libs in @{rootdir}"/>
        <apply executable="pack200" parallel="false">
            <arg value="--repack"/> 
            <arg value="--segment-limit=-1"/> 
            <fileset dir="@{rootdir}" includes="**/*.jar" />
        </apply>

        <echo message="Signing libs in @{rootdir}"/>
        <signjar 
            alias="${keystore.alias}" keystore="${keystore.file}" storepass="${keystore.password}"
            lazy="true">
            <path>
                <fileset dir="@{rootdir}" includes="**/*.jar" />
            </path>
        </signjar>
     </sequential>
</macrodef>

And here is how to pack:

    <apply executable="pack200" parallel="false" dest="${dir.tomcat.jar}">
        <arg value="--modification-time=latest"/>
        <arg value="--deflate-hint=true"/>
        <arg value="--segment-limit=-1"/>
        <targetfile/>
        <srcfile/>
        <fileset dir="${dir.tomcat.jar}" includes="**/*.jar" />
    <mapper type="glob" from="*" to="*.pack.gz" />
    </apply>

Edited to provide a little more info for people that don't know ant so well:

The task above goes before your tags. Inside your tag first put a call to the macro like this so that it first repacks and signs each file:

    <repack-and-sign rootdir="${dir.tomcat.jar}" />

Then follow that with the tag from above. This will do the final packing for each file.

Abutting answered 17/8, 2010 at 22:35 Comment(2)
pack200 will fail if the JAR was signed before the repack operation. In this case, you'll get an error message like "Exception in thread "main" java.lang.SecurityException: SHA1 digest error for ..." The underlying bug is that signing the packed jar returns success, but if you run jarsigner -verify, it will report a failure.Remonstrance
It's also a good idea to add the --segment-limit=-1 argument to the repack target to avoid bug bugs.sun.com/view_bug.do?bug_id=5078608 (see 1st workaround).Taw
W
1

You could use a fileset within the signjar task

<signjar alias="ws" keypass="wskey"
                 storepass="wspass" keystore="${artifact.root.dir}/deployJAWS.key">
            <fileset dir="${lib.temp.root.dir}">
                <include name="**/*.jar" />
            </fileset>
</signjar>

I use the above snippet to sign my WebStart application that consists of approx 70 jars

Wyatan answered 16/8, 2010 at 7:51 Comment(0)
M
1

The Pack200 tasks on Java.net have been updated to work with filesets. Give it another try:

http://java.net/projects/deployment

Monkeypot answered 4/8, 2011 at 12:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.