简体   繁体   English

Gradle - FatJar - 无法找到或加载主 class

[英]Gradle - FatJar - Could not find or load main class

I know that question was asked a lot and has many answers, but i still get it and I don't understand why...我知道这个问题被问了很多并且有很多答案,但我仍然明白,但我不明白为什么......

I am trying to generate a .jar from a projet with dependencies with gradle.我正在尝试从具有.jar依赖项的项目生成 .jar。

I have a class src/main/java/Launcher.java , in which I have my main method.我有一个 class src/main/java/Launcher.java ,其中有我的main方法。

there is my build.gradle这是我的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) }
    }
}

I use $>gradle assemble to generate my jar then $>java -jar path/to/my/.jar And i get the error "could not find or load main class Launcher"...我使用$>gradle assemble生成我的 jar 然后$>java -jar path/to/my/.jar我收到错误“找不到或加载主 class 启动器”...

I dont understand why, when I look in the.jar, I have Launcher class and in META-INF I have my manifest我不明白为什么,当我查看 .jar 时,我有 Launcher class 并且在 META-INF 中有我的清单

截屏

Sorry for still asking this question in 2018 but i'm loosing my mind trying to figure out what's wrong.很抱歉在 2018 年仍然问这个问题,但我正在失去理智试图找出问题所在。 I hope somone will have the answer !我希望有人会得到答案!

I reproduced your issue locally.我在本地复制了您的问题。

Just add exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' to the jar task.只需将exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'到 jar 任务中。

This will exclude the signatures of interfering dependencies.这将排除干扰依赖的签名。

Example:例子:

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'
}

You are running into the the one major problem when building a FAT JAR:您在构建 FAT JAR 时遇到了一个主要问题:

One of your source JARs is signed and merging it into one fat jar destroys the signature.您的源 JAR 之一已签名并将其合并到一个胖 jar 中会破坏签名。

It looks like Java recognizes that there are unsigned classes and ignores everything but the signed classes.看起来 Java 识别出存在未签名的类并忽略除签名类之外的所有内容。 As all classes that do not belong to the signed library are unsigned (like your Launcher class) they are ignored and therefore can't be loaded.由于所有不属于签名库的类都是未签名的(如您的Launcher类),因此它们会被忽略,因此无法加载。

In your case it looks like that the dependency org.bouncycastle:bcprov-jdk15on:1.55 of com.auth0:java-jwt:3.1.0 is the signed jar file.在您的情况下, com.auth0:java-jwt:3.1.0的依赖项org.bouncycastle:bcprov-jdk15on:1.55 com.auth0:java-jwt:3.1.0是已签名的 jar 文件。 Because my sample project correctly executes Launcher when I uncomment this dependency.因为当我取消注释此依赖项时,我的示例项目会正确执行Launcher

Bouncy castle is a crypto provider that requires a valid signature otherwise it will not run from my experience. Bouncy Castle 是一个需要有效签名的加密货币提供商,否则根据我的经验它将无法运行。 Therefore it is impossible to create a fat jar for your project that just contains all classes.因此,不可能为您的项目创建一个只包含所有类的胖 jar。

You can try to create a fat jar with everything except Bouncycastle and ship Bouncycastle JAR seperatly.您可以尝试使用除 Bouncycastle 之外的所有内容创建一个胖 jar 并单独发送 Bouncycastle JAR。

Or a fat jar that contains all the required JAR files inside (JAR inside JAR) and that uses a special class loader that is able to load classes from within such a JAR inside a JAR.或者一个包含所有必需 JAR 文件的胖 jar(JAR 内的 JAR)并且使用特殊的类加载器,该类加载器能够从 JAR 内的此类 JAR 中加载类。 See for example: https://stackoverflow.com/a/33420518/150978参见例如: https : //stackoverflow.com/a/33420518/150978

Try to exclude .SF .DSA .RSA files, example below, Nipun尝试排除 .SF .DSA .RSA 文件,下面的示例,Nipun

Hope this works out for you希望这对你有用

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'
  }
}

Adding添加

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

Fixed my issue.解决了我的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM