问题描述
现有 Gradle 项目打包 Jar 的配置如下,Sample 类里有 main 方法。
csharp
plugins {
id 'java'
}
group 'sapmle'
version '1.0'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
implementation'com.azure:azure-identity:1.4.0'
}
jar {
archivesBaseName = 'sample'
manifest {
attributes(
"Manifest-Version": 1.0,
'Main-Class': 'Sample'
)
}
// 打包依赖包
from {
(configurations.runtimeClasspath).collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
打包完成后,使用命令 java -jar sample-1.0.jar 启动报错如下:
makefile
C:\Users\Yuhang\Desktop>java -jar sample-1.0.jar
错误: 找不到或无法加载主类 Sample
问题原因
再次检查了所有的配置和文件名,确认无误。
经搜索得知签名证书验证失败也会报出这个错误,使用以下命令验证,证实是证书错误。
makefile
C:\Users\Yuhang\Desktop>jarsigner -verify sample-1.0.jar
jarsigner: java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
至此找到方向,开始进行详细的确认:
-
使用压缩软件打开 jar 包,发现 META_INF 文件夹下有多个同名的 RSA 和 SF 类型文件,经查询得知是证书文件。
-
排查项目依赖,发现多个依赖下有同名证书文件:
解决办法
多个证书导致 jar 包运行时无法完成签名验证,我们只需要在打包时排除证书文件即可。
具体修改如下:
csharp
jar {
archivesBaseName = 'sample'
manifest {
attributes(
"Manifest-Version": 1.0,
'Main-Class': 'Sample'
)
}
// 打包依赖包
from {
(configurations.runtimeClasspath).collect {
it.isDirectory() ? it : zipTree(it)
}
}
// 排除各个依赖包的签名文件
exclude(['META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA'])
}