Tuesday 30 September 2008

Excluding the pom.xml from a maven jar

To prevent Maven 2 adding the pom.xml file to your generated jar (you may not want to distribute build information, SCM information, storepass details etc) you can do the following:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  ...
  <configuration>
     ...
     <archive>
       <addMavenDescriptor>false</addMavenDescriptor>
     <archive>
     ...
  </configuration>
</plugin>


Monday 29 September 2008

Maven2 assembly plugin and jar signing

We use a java applet to talk to the local print service, which means to distribute it we need to sign the jar file. Normally, in Maven2 you'd set the following in your pom.xml:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>sign
      </goals>
    </execution>
  </executions>
  <configuration>
    <keystore>src/main/resources/code-cert.pfx</keystore>
    <type>pkcs12</type>
    <alias>SomeAlias</alias>
    <storepass>SomePassword</storepass>
    <signedjar>${project.build.directory}/signed/${project.build.finalName}.jar</signedjar>
    <verify>true</verify>
  </configuration>
</plugin>
]]>

and when you run

$ mvn clean package

all is well and good.  However, when you come to want to include resources in your jar, by using the following plugin:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
    <excludes>
      <exclude>**/com/spektrix/**</exclude>
    </excludes>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id>
      <phase>package</phase>
      <goals>
        <goal>attached</goal>
      </goals>
    </execution>
  </executions>
</plugin>      

You'll need to add some configuration to the original element.

Firstly, you'll need a jarPath element:

<configuration>
  ...
  <jarPath>${project.build.directory}/${project.build.FinalName}-${project.packaging}-with-dependencies.${project.packaging}</jarPath>
  ...
</configuration>


To tell it to sign the full jar, rather than the basic one.  However, this is still not quite right, and you'll get the following error:

[INFO] jarsigner: unable to sign jar: java.util.zip.ZipException: duplicate entry: some/path/to/a/Class.class

If we look at the contents of the full jar, you'll see the contents of your project added twice!  To get around this you'll need the following in your configuration section:

<configuration>
  <excludes>
    <exclude>**/com/company/**<exclude>
  </excludes>
  ...
</configuration>

With one line for each such error you get from the jarsigner.  Eventually, all your project contents will only be added once and you'll see:

[INFO] [jar:sign {execution: default}]
[debug] jarsigner executable=[C:\Program Files\Java\jdk1.6.0_10\jre\..\bin\jarsi
gner.exe]
[debug] Executing: cmd.exe /X /C '""C:\Program Files\Java\jdk1.6.0_10\jre\..\bin
\jarsigner.exe" -verify <Some Jar File>"'
[info] jar verified.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------

Friday 19 September 2008

Hello, world

This will be a technology blog, detailing life in a startup company and the daily tribulations of using C# and ASP.NET