私のJavaプログラムはjarファイルにパッケージされていて、外部のjarライブラリを利用しています、 弾む城 。私のコードはうまくコンパイルされますが、jarを実行すると以下のエラーが発生します。
スレッド "main"での例外Java.lang.SecurityException:マニフェストの主な属性に対する無効な署名ファイルダイジェスト
私は1時間以上かけて説明を探していましたが、ほとんど価値がありませんでした。誰かが以前にこのエラーを見たことがあり、何らかの助けを提供できるのであれば、私は義務付けられているでしょう。
ここにリストされた解決策はポインタを提供するかもしれません。
一番下の行
公式のjarファイルをそのままにして、アプリケーションのjarファイルのマニフェストファイルに依存関係として追加することをお勧めします。
maven-shade-plugin
を使用して uber-jar を作成しようとしたときにこのエラーが発生した場合は、次の行をに追加してマニフェスト署名ファイルを除外します。プラグイン設定:
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<!-- Additional configuration. -->
</configuration>
Gradleを使用して太いjarファイルを作成して使用しようとしている場合は、次の構文が役に立ちます。
jar {
doFirst {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}
あなたの依存関係のいくつかはおそらく署名されたjarファイルです。それらすべてを1つの大きなjarファイルに結合すると、対応するシグネチャファイルはまだ存在し、 "big combined" jarファイルとは一致しなくなります。話す)。
あなたはあなたのjarfileの依存関係から署名ファイルを排除することによって問題を解決することができます。残念ながら、 ant ではこれを1ステップで行うことはできません。
ただし、次のようにして、各jarファイルの依存関係に特に名前を付けることなく、Antでこれを2段階で機能させることができました。
<target name="jar" depends="compile" description="Create one big jarfile.">
<jar jarfile="${output.dir}/deps.jar">
<zipgroupfileset dir="jars">
<include name="**/*.jar" />
</zipgroupfileset>
</jar>
<sleep seconds="1" />
<jar jarfile="${output.dir}/myjar.jar" basedir="${classes.dir}">
<zipfileset src="${output.dir}/deps.jar" excludes="META-INF/*.SF" />
<manifest>
<attribute name="Main-Class" value="com.mycompany.MyMain" />
</manifest>
</jar>
</target>
Sleep要素は、将来の変更日を持つファイルに関するエラー を防ぐためのものです 。
リンクされたスレッドで見つけた他のバリエーションは私にとってはうまくいきませんでした。
次のコマンドを使ってください
Zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
IntelliJ IDEA 14.01を使用しているときにこの問題が発生しました。
私はそれを修正することができました:
「モジュールからのJarの作成」ウィンドウで、「ファイル」 - >「プロジェクト構造」 - >「新規追加(成果物)」 - >「jar」 - >「モジュールから」を選択します。
メインクラスを選択してください
ライブラリからのJARファイル出力ディレクトリへのコピーを選択し、マニフェストを介してリンクする
セキュリティはすでに難しいトピックですが、最も人気のあるソリューションがセキュリティ署名を削除することであることに私はがっかりしています。 JCEにはこれらの署名が必要です 。 Mavenシェードは、署名をMETA-INFに入れるBouncyCastle jarファイルを爆発させますが、BouncyCastle署名は新しいuber-jar(BC jarのみ)に対して有効ではなく、それが無効な署名の原因ですこのスレッドのエラー。
はい、@ ruhsuzbaykusが示唆するように署名を除外または削除すると、元のエラーは実際になくなりますが、新たな不可解なエラーにつながる可能性もあります。
Java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available
このようにアルゴリズムを見つける場所を明示的に指定することにより:
SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC");
私は別のエラーを受け取ることができました:
Java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
暗号化署名を削除したため、JCEはプロバイダーを認証できませんこの同じスレッドの他の場所の提案に従って 。
私が見つけた解決策は、単一の実行可能なjarでBouncyCastle署名を保持するにjar-in-jarアプローチを使用する executable packer プラグインでした。
これを行う別の方法(正しい方法?)は、 Maven Jar signer を使用することです。これにより、セキュリティエラーを発生させずにMavenシェードを使用し続けることができます。ただし、コード署名証明書が必要です(「Javaコード署名証明書」を検索することをお勧めします)。 POM設定は次のようになります。
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>org.bouncycastle:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.Apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>your.class.here</mainClass>
</transformer>
</transformers>
<shadedArtifactAttached>true</shadedArtifactAttached>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>sign</id>
<goals>
<goal>sign</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<keystore>/path/to/myKeystore</keystore>
<alias>myfirstkey</alias>
<storepass>111111</storepass>
<keypass>111111</keypass>
</configuration>
</plugin>
いいえ、JCEに自己署名証明書を認識させる方法がないため、BouncyCastle証明書を保持する必要がある場合は、jar-in-jarプラグインを使用するか、JCE証明書を取得する必要があります。
あなたがあなたのjarファイルをantで構築すると仮定すると、META-INFディレクトリを除外するようにantに指示することができます。これは私のantターゲットの簡易版です。
<jar destfile="app.jar" basedir="${classes.dir}">
<zipfileset excludes="META-INF/**/*" src="${lib.dir}/bcprov-jdk16-145.jar"></zipfileset>
<manifest>
<attribute name="Main-Class" value="app.Main"/>
</manifest>
</jar>
私は同じ問題に直面しました、どこかで参照した後に、それは以下の変更として働きました:
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
Gradleを使用している場合は、farJarの完全なタスクがあります。
version = '1.0'
//create a single Jar with all dependencies
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Gradle Jar File Example',
'Implementation-Version': version,
'Main-Class': 'com.example.main'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
with jar
}
私は最近自分のプロジェクトでIntelliJを使い始めました。しかし、私の同僚の中にはまだ同じプロジェクトでEclipseを使っている人がいます。今日、私は私のIntelliJによって作成されたjarファイルを実行した後に私は全く同じエラーを得ました。ここでのすべての解決策がほぼ同じことについて話している間、それらのどれも私のために容易に働きませんでした(おそらく私はANTを使わないので、maven buildは私に httpを参照してくれた//cwiki.Apache.org/confluence/display/MAVEN/MojoExecutionException 、そして私は自分自身で署名されたjarファイルが何であるかわからなかった!)
最後に、 これ が私を助けてくれました
Zip -d demoSampler.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
私のjarファイルから何が削除されたと思いますか?
deleting: META-INF/Eclipse_.SF
deleting: META-INF/Eclipse_.RSA
この問題はいくつかのEclipse関連ファイルに関連しているようです。
(新しいライブラリを追加する前に)新しいjar内のフォルダMETA-INFを古いjarと比較します。新しいファイルがある可能性があります。もしそうなら、それらを削除することができます。それは役立つはずです。よろしく、999michal
エラー:JNIエラーが発生しました。インストールを確認して、もう一度試してください。スレッド "main"での例外。Java.lang.SecurityException:Sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.Java:)でのマニフェストの主属性に対する署名ファイルダイジェストが無効です。 314)Sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.Java:268)at Java.util.jar.JarVerifier.processEntry(JarVerifier.Java:316)at Java.util.jar.JarVerifier.update(JarVerifier.Java) :228)Java.util.jar.JarFile.initializeVerifier(JarFile.Java:383)at Java.util.jar.JarFile.getInputStream(JarFile.Java:450)at Sun.misc.URLClassPath $ JarLoader $ 2.getInputStream(URLClassPath) .Java:977)at Sun.misc.Resource.cachedInputStream(Resource.Java:77)at Sun.misc.Resource.getByteBuffer(Resource.Java:160)at Java.net.URLClassLoader.defineClass(URLClassLoader.Java:454) Java.net.URLClassLoader.access $ 100(URLClassLoader.Java:73)でJava.net.URLClassLoader $ 1.run(URLClassLoader.Java:368)でJava.net.URLClassLoadeで$ 1.run(URLClassLoader.Java:362)at Java.security.AccessController.doPrivileged(ネイティブメソッド)at Java.net.URLClassLoader.findClass(URLClassLoader.Java:361)at Java.lang.ClassLoader.loadClass(ClassLoader.Java) :424)Sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.Java:331)at Java.lang.ClassLoader.loadClass(ClassLoader.Java:357)at Sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.Java:495)
助けになったのは(IntelliJ IDEA 2016.3):[ファイル] - > [プロジェクト構造] - > [アーティファクト] - > [JARの追加] - > [メインクラスの選択] - > [出力ディレクトリにコピーしてマニフェストでリンクする]を選択 - > OK - >適用 - >ビルド - >アーティファクトのビルド... - >ビルド
戦略は、ANTを使用して各Jarファイルから署名を簡単に削除することです。それは以下のステップで進むでしょう。
これが ANTマクロ定義 の作業です。
<macrodef name="unsignjar" description="To unsign a specific Jar file">
<attribute name="jarfile"
description="The jar file to unsign" />
<sequential>
<!-- Copying to the temporary manifest file -->
<copy toFile="@{jarFile}_MANIFEST.tmp">
<resources>
<zipentry zipfile="@{jarFile}" name="META-INF/MANIFEST.MF"/>
</resources>
</copy>
<!-- Removing the Name and SHA entries from the temporary file -->
<replaceregexp file="@{jarFile}_MANIFEST.tmp" match="\nName:(.+?)\nSH" replace="SH" flags="gis" byline="false"/>
<replaceregexp file="@{jarFile}_MANIFEST.tmp" match="SHA(.*)" replace="" flags="gis" byline="false"/>
<!-- Creating a temporary Jar file with the temporary manifest -->
<jar jarfile="@{jarFile}.tmp"
manifest="@{jarFile}_MANIFEST.tmp">
<zipfileset src="@{jarFile}">
<include name="**"/>
<exclude name="META-INF/*.SF"/>
<exclude name="META-INF/*.DSA"/>
<exclude name="META-INF/*.RSA"/>
</zipfileset>
</jar>
<!-- Removing the temporary manifest -->
<delete file="@{jarFile}_MANIFEST.tmp" />
<!-- Swapping the original Jar file with the temporary one -->
<move file="@{jarFile}.tmp"
tofile="@{jarFile}"
overwrite="true" />
</sequential>
`
この定義はANTタスクでこのようにして呼び出すことができます。
<target name="unsignJar">
<unsignjar jarFile="org.test.myjartounsign.jar" />
</target>
2人の異なる署名者がJavaの心を台無しにする可能性があります。
META-INFフォルダをjarから削除し、マニフェストを追加し、JARに再度署名してください。 http://jehy.ru/articles/2013/12/13/invalid-signature-fileマニフェストの主要属性の-digest /
オリジナルのライブラリを開梱したり改ざんしたりせずに、特別なJARクラスローダを使ってFat JARソリューションを探しているなら、 私のプロジェクトを見てください 。
免責事項:私はコードを書かず、単にそれをパッケージ化してMaven Centralに公開し、そして私のread-meでそれを使用する方法を説明します。
私は個人的にBouncyCastleの依存関係を含む実行可能なuber JARを作成するためにそれを使用しています。たぶんそれはあなたにとっても役に立つでしょう。
太いJarを作成するときにgradle
に同じ問題があり、exclude行でbuild.gradle
ファイルを更新して問題を修正しました。
jar {
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
manifest {
attributes 'Main-Class': 'com.test.Main'
}
}