"no manifiest section for signature file entry"の対処法

mavenには配布用などのために依存するjarを全てひとまとめにアーカイブしてくれる assembly プラグインというものがあります。
これ非常に便利なんですが、依存jarに署名済みのjarが含まれていると以下のようなエラーが発生してしまい起動が出来なくなってしまうのが困りものです。

Exception in thread "main" java.lang.SecurityException: no manifiest section for signature file entry jp/example/foo/Bar.class

署名済みjarは何によって判断されるかというと、jarファイル内に META-INF/*.RSA や META-INF/*.DSA の存在を確認するとそのjarは署名済みとみなして、そのファイルで署名チェックを行うという流れになります。
assemblyプラグインでは全てのjarを一度展開して固めなおしている上に、署名済みjarが複数あった場合はjarが一つなのに*.RSAファイルが複数あったりなどという支離滅裂なjarファイルになってしまうので、そりゃ怒られるわけです。
原理的にはそのようになっている為、対処法としては *.RSA ファイルなど署名に関するファイルをjarに含めないようにすれば良いということになります。

それ、excludesオプションで出来ます

対処法ですが、よく使いそうなので設定をメモしておきます。
まず、pom.xml に以下の記述を追加します。

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <!--
          excludesオプションを使うた為に2.2以上が必要。最新バージョンは以下でチェック。
          http://mvnrepository.com/artifact/org.apache.maven.plugins/maven-assembly-plugin
        -->
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2-beta-5</version>
        <configuration>
          <archive>
            <manifest>
              <mainClass>jp.example.app.Main</mainClass>
            </manifest>
          </archive>
          <descriptors>
            <descriptor>src/assemble/descriptor.xml</descriptor>
          </descriptors>
        </configuration>
      </plugin>
      [...]
</project>

次にpom.xmlに書いた src/assemble/descriptor.xml を以下の内容で作成します。

<assembly>
  <id>jar-with-dependencies</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <unpack>true</unpack>
      <scope>runtime</scope>
      <unpackOptions>
        <excludes>
          <exclude>META-INF/*.RSA</exclude>
          <exclude>META-INF/*.DSA</exclude>
          <exclude>META-INF/*.SF</exclude>
          <exclude>META-INF/*.rsa</exclude>
          <exclude>META-INF/*.dsa</exclude>
          <exclude>META-INF/*.sf</exclude>
        </excludes>
      </unpackOptions>
    </dependencySet>
  </dependencySets>
  <fileSets>
    <fileSet>
      <directory>target/classes</directory>
    </fileSet>
  </fileSets>
</assembly>

ポイントはunpackOptionsで指定しているexcludesオプションです*1 *2。この設定により署名ファイルがjarに含まれなくなり、実行の際にEcurityExceptionが出ることを避けられるようになります。
最後に、以下を実行すれば署名のない合体jarが生成されることが確認できます。

mvn assembly:assembly

*1:但しexcludesオプションは、maven-assembly-pluginのバージョンが2.2位以上でないと使えません。現時点では2.2はまだbetaなのでpomでバージョン番号を指定してやる必要があります。

*2:ググってる最中に見た情報では /META-INF/*.RSA 等と書いてあるサイトもありましたが、頭の / があるとexcludeされてくれないので頭の/は付けないようにします。