22

我知道这个问题被问了很多并且有很多答案,但我仍然明白,我不明白为什么......

我正在尝试.jar从具有 gradle 依赖关系的项目中生成一个。

我有一个班级src/main/java/Launcher.java,其中有我的main方法。

有我的build.gradle

plugins {
    id 'java'
    id 'application'
}

version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
mainClassName = 'Launcher'

repositories {
    mavenCentral()
}

dependencies {
    compile 'commons-io:commons-io:2.1'
    compile 'io.vertx:vertx-core:3.4.0'
    compile 'io.vertx:vertx-web:3.4.0'
    compile 'com.google.code.gson:gson:1.7.2'
    compile "com.auth0:java-jwt:3.1.0"
    compile 'org.mongodb:mongo-java-driver:3.4.1'
    compile 'com.google.guava:guava:24.1-jre'
    compile 'commons-io:commons-io:2.6'
}

jar {
    manifest {
        attributes "Main-Class": mainClassName
    }

    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

$>gradle assemble用来生成我的 jar 然后$>java -jar path/to/my/.jar 我得到错误“找不到或加载主类启动器”......

我不明白为什么,当我查看 .jar 时,我有 Launcher 类,而在 META-INF 中我有我的清单

截屏

很抱歉在 2018 年仍然问这个问题,但我正在失去理智试图找出问题所在。我希望有人能给出答案!

4

3 回答 3

46

我在本地复制了您的问题。

只需添加exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'到 jar 任务中。

这将排除干扰依赖项的签名。

例子:

jar {
    manifest {
        attributes "Main-Class": mainClassName
    }

    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
    exclude 'META-INF/*.RSA'
    exclude 'META-INF/*.SF'
    exclude 'META-INF/*.DSA'
}
于 2018-07-21T12:29:45.713 回答
10

您在构建 FAT JAR 时遇到了一个主要问题:

您的一个源 JAR 已签名并将其合并到一个胖 jar 中会破坏签名。

看起来 Java 认识到存在未签名的类并忽略除签名类之外的所有内容。由于所有不属于已签名库的类都是未签名的(如您的Launcher类),因此它们将被忽略,因此无法加载。

org.bouncycastle:bcprov-jdk15on:1.55在您的情况下,它的依赖项似乎com.auth0:java-jwt:3.1.0是签名的 jar 文件。Launcher因为当我取消注释此依赖项时,我的示例项目会正确执行。

Bouncy castle 是一个需要有效签名的加密货币提供商,否则它不会根据我的经验运行。因此,不可能为您的项目创建一个只包含所有类的胖 jar。

您可以尝试使用除 Bouncycastle 之外的所有内容创建一个胖 jar,然后单独发送 Bouncycastle JAR。

或者一个包含所有必需 JAR 文件的胖 jar(JAR inside JAR)并且使用一个特殊的类加载器,该类加载器能够从 JAR 内的此类 JAR 中加载类。参见例如:https ://stackoverflow.com/a/33420518/150978

于 2018-07-21T12:04:23.540 回答
1

尝试排除 .SF .DSA .RSA 文件,下面的示例,Nipun

希望这对你有用

task customFatJar(type: Jar) {
  baseName = 'XXXXX'
  from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } 
  }
  with jar

  exclude "META-INF/*.SF"
  exclude "META-INF/*.DSA"
  exclude "META-INF/*.RSA"

  manifest {
    attributes 'Main-Class': 'com.nipun.MyMainClass'
  }
}
于 2018-08-19T18:41:24.977 回答