Reference 如何在gradle中导出一个可执行jar,这个jar可以运行,因为它包含引用库

Reference 如何在gradle中导出一个可执行jar,这个jar可以运行,因为它包含引用库,reference,jar,executable,gradle,noclassdeffounderror,Reference,Jar,Executable,Gradle,Noclassdeffounderror,如何在gradle中导出一个可执行jar,这个jar可以运行,因为它包含引用库 格雷德尔先生 apply plugin: 'java' manifest.mainAttributes("Main-Class" : "com.botwave.analysis.LogAnalyzer") repositories { mavenCentral() } dependencies { compile ( 'commons-codec:commons-codec:1.

如何在gradle中导出一个可执行jar,这个jar可以运行,因为它包含引用库

格雷德尔先生

apply plugin: 'java'

manifest.mainAttributes("Main-Class" : "com.botwave.analysis.LogAnalyzer")

repositories {
    mavenCentral()
}

dependencies {
    compile (
        'commons-codec:commons-codec:1.6',
        'commons-logging:commons-logging:1.1.1',
        'org.apache.httpcomponents:httpclient:4.2.1',
        'org.apache.httpcomponents:httpclient:4.2.1',
        'org.apache.httpcomponents:httpcore:4.2.1',
        'org.apache.httpcomponents:httpmime:4.2.1',
        'ch.qos.logback:logback-classic:1.0.6',
        'ch.qos.logback:logback-core:1.0.6',
        'org.slf4j:slf4j-api:1.6.0',
        'junit:junit:4.+'
    )
}
我跑完后:gradle build

它创建build文件夹,我在build/libs/XXX.jar中运行jar:

java-jarbuild/libs/XXX.jar

下面是一个执行说明:

Exception in thread "main" java.lang.NoClassDefFoundError: ch/qos/logback/core/joran/spi/JoranException

如何使用参考库运行它?

您可以使用实现它,希望这对某些人有所帮助(不幸的是,我花了很多时间试图找到解决方案)。这是一个为我创建可执行JAR的解决方案。我在主要方法中嵌入了Jetty,具体来说是Jetty 9,并使用Gradle 2.1

在build.gradle文件中包含以下代码(如果子项目是构建jar所需的“主”项目,则将其添加到子项目中,该子项目应该像此项目一样开始(“:”){将代码插入依赖项之后的此处某处。}

此外,您还需要添加插件java来实现这一点:应用插件:“java”

我的jar任务如下所示:

apply plugin: 'java'

jar {

    archiveName = "yourjar.jar"

    from {

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

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

    manifest {
        attributes 'Main-Class': 'your.package.name.Mainclassname'
    }

    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}
dependencies {

    // add the subprojects / modules that this depends on
    compile project(':subproject-1')
    compile project(':subproject-2')

    compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.2.6.v20141205'
    compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.2.6.v20141205'
    compile group: 'org.eclipse.jetty', name: 'jetty-http', version: '9.2.6.v20141205'

}
然后可以通过命令行执行yourjar.jar:

java -jar yourjar.jar
必须排除META-INF/.RSA、META-INF/.SF和META-INF/*.DSA才能使其工作。否则会引发SecurityException

问题似乎出在嵌入式Jetty上,因为Jetty迁移到Eclipse,现在正在对其JAR进行签名,当其他未签名的JAR想要加载已签名的JAR时,我读到的JAR会出现问题。如果我在这方面有错,请随时告诉我,这正是我读到的

项目所依赖的JAR在依赖项中定义如下:

apply plugin: 'java'

jar {

    archiveName = "yourjar.jar"

    from {

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

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

    manifest {
        attributes 'Main-Class': 'your.package.name.Mainclassname'
    }

    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}
dependencies {

    // add the subprojects / modules that this depends on
    compile project(':subproject-1')
    compile project(':subproject-2')

    compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.2.6.v20141205'
    compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.2.6.v20141205'
    compile group: 'org.eclipse.jetty', name: 'jetty-http', version: '9.2.6.v20141205'

}
编辑:在之前,而不是仅仅

configurations.runtime.collect{...}
我有

configurations.runtime.asFileTree.files.collect{...}
这在clean build中的一个较大项目中导致了奇怪的行为。在第一次执行gradle clean build后(手动清理构建目录后)运行jar时,它会抛出NoClassDefFoundException(在我们有许多子项目的项目中),但在第二次执行gradle clean build后运行jar(无需手动清空生成目录),由于某些原因,它具有所有依赖项。如果忽略asFileTree.files,则不会发生这种情况

我还应该注意,所有的编译依赖项都包含在运行时中,但并非所有的运行时都包含在编译中

        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
然后请务必记住,如果抛出NoClassDefFoundException,则在运行时找不到某个类,这意味着您还应包括以下内容:

        configurations.runtime.collect {
            it.isDirectory() ? it : zipTree(it)
        }
快速回答
  • 将以下内容添加到您的
    build.gradle

    apply plugin: 'application'
    
    mainClassName = 'org.example.app.MainClass'
    
    jar {
        manifest {
            attributes 'Main-Class': mainClassName,
                       'Class-Path': configurations.runtime.files.collect {"$it.name"}.join(' ')
        }
    }
    
  • 从项目目录中,运行
    gradle installDist
  • 运行
    java-jarbuild/install/or

    我尝试了shadow,但不喜欢我的所有依赖项及其资源与我的应用程序代码一起被直接转储到构建的jar中。我还更喜欢尽量减少外部插件的使用

    另一种选择是使用上面回答的as@erdi。运行
    gradle build
    将为您构建一个jar,并将其与您的所有依赖项很好地捆绑在一个zip/tar文件中。您也可以只运行
    gradle installDist
    跳过压缩

    然而,正如@jeremyjjbrown在那里的评论中所写的那样,插件本身并不创建一个可执行jar。它创建一个jar和一个脚本,用于构造类路径并执行一个命令来运行应用程序的主类。您将无法运行
    java-jar appname.jar


    为了充分利用这两个世界,请按照上面的步骤创建jar,并将所有依赖项作为单独的jar一起创建,并将正确的值添加到MANIEST中。

    我查看了很多解决方案的链接,最后执行了下面提到的步骤以使其正常工作。我正在使用Gradle 2.9。

    在您的内部版本gradle文件中进行以下更改:

    1.提及插件:

    2.提供构建脚本:

    3.提供主要类别:

    4.创建fatjar:

    5.从/build/libs/运行fatjar:


    所有这些答案要么是错误的,要么是过时的

    OP要求的是所谓的“胖jar”,这是一个可执行的jar,它包含所有依赖项,因此运行时不需要外部依赖项(当然,JRE除外!)

    在撰写本文时,答案是Gradle Shadow Jar插件,在

    我有点挣扎,但这是有效的:

    将所有这些行放在build.gradle文件中的某个位置(我将它们放在顶部附近):

    PS不必担心构建文件中其他地方的任何“存储库”、“依赖项”或“插件”行,do将这些行保留在这个“buildscript”块中(我不知道为什么需要这样做)

    PPS的影子插件用户指南和例子写得很好,但没有告诉你 包括线路

    attributes 'Main-Class': 'core.MyClassContainingMainMethod'
    
    可能是因为作者认为你没有我那么笨,你也可能是。我不知道为什么我们被告知要把一个奇怪的“类路径”属性放进去,但如果它没有坏,就不要修复它

    你什么时候走

    > gradle shadowjar
    
    Gradle希望在/build/libs(默认名称“shadow.jar”)下构建一个fat可执行jar,您可以通过以下方式运行:

    > java -jar shadow.jar
    

    酷,我不知道他们加了这个。我总是用“肥罐子”recipe和手动为主类添加了一个清单条目。他们添加了1.0版本左右的某个地方,它可以写入build.gradle文件吗?我不想得到zip或tar文件,只需要folderGradle应用程序插件中的依赖项库jar不会创建可执行jar。我还应该注意,在我的代码中,依赖项库jar不会创建可执行jaries{…}部分位于jar{…}部分之前,以防相关。-1 OP是明确的:他/她想要创建
    java -jar MyFatJar.jar
    
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.4' 
        }
    }
    apply plugin: 'com.github.johnrengelman.shadow'
    shadowJar {
        baseName = 'shadow'
        classifier = null
        version = null
    }
    jar {
        manifest {
            attributes 'Class-Path': '/libs/a.jar'
            attributes 'Main-Class': 'core.MyClassContainingMainMethod'
        }
    }
    
    attributes 'Main-Class': 'core.MyClassContainingMainMethod'
    
    > gradle shadowjar
    
    > java -jar shadow.jar