gradle - 为什么需要指定 'from files'?

标签 gradle groovy jar

我试图用我的第一个常规脚本构建一个jar。我的项目结构如下:

- build.gradle
- src\main\groovy\app\Test.groovy

我最初的gradle脚本:
apply plugin: 'groovy'
apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.3.11'
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

sourceSets.main.groovy.srcDirs = ["src/main/groovy"]

jar {
    manifest {
        attributes('Main-Class': 'app.Test')
    }
}

根据我阅读的指南,这应该创建一个可运行的jar。当我尝试运行它时,尽管总是出现错误
Error: Could not find or load main class app.Test

我现在发现我需要将这两行添加到jar任务中:
from files(sourceSets.main.output.classesDir)
from configurations.runtime.asFileTree.files.collect { zipTree(it) }

奇怪的是,如果我用Test.java类(内容相同)替换groovy脚本,则不需要这两行来运行jar。
我找不到我为什么需要它们,或者它们究竟做什么。谁能解释一下,还是提供文档链接?

我是SO的新手,请帮助我解决我的错误。

编辑

tim_yates建议的代码将转换为具有以下内容的test.jar:
META-INF / MANIFEST.MF
Manifest-Version: 1.0
Main-Class: app.Test

app / Test.class
package app;

import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.callsite.CallSite;

public class Test implements GroovyObject {
    public Test() {
        CallSite[] var1 = $getCallSiteArray();
        MetaClass var2 = this.$getStaticMetaClass();
        this.metaClass = var2;
    }

    public static void main(String... args) {
        CallSite[] var1 = $getCallSiteArray();
        var1[0].callStatic(Test.class, "Hi!");
    }
}

我执行以下语句:
java -jar test.jar

这将导致上述错误消息。

最佳答案

您必须记住,此jar包含Groovy编译的类。答案是在一开始显示的反编译源中。它导入Groovy运行时类。

如果仅运行java -jar test.jar,则这些类不在类路径中。
可以在命令行的类路径上包含groovy,也可以使用gradle应用程序插件构建包含所有应用程序依赖项的fat JAR(对于runnable jars可能更好)。

apply plugin: 'groovy'
apply plugin: 'application'

mainClassName='app.Test'

repositories {
    mavenCentral()
}

dependencies {
    compile     'org.codehaus.groovy:groovy-all:2.4.7'
    testCompile 'junit:junit:4.12'
}

task uberjar(type: Jar,dependsOn:[':compileJava',':compileGroovy']) {
    from files(sourceSets.main.output.classesDir)
    from configurations.runtime.asFileTree.files.collect { zipTree(it) }

    manifest {
        attributes 'Main-Class': mainClassName
    }
}

然后用gradle uberjar构建你的jar

关于gradle - 为什么需要指定 'from files'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41565149/

相关文章:

grails - 如何在Grails中使用 'render'方法从导入的Java类呈现简单的txt

java - 尝试执行我的 jar 文件中的文件

java - 从 Jarfile 加载图像

Gradle:Spring Boot 的带有 jvm 参数的自定义任务

android - 第三方库证书未添加到 apk

java - 构建 java 项目时 build.gradle 中的 Groovy 语法

grails - 导致GORM字段的类型转换导致验证失败

java - 无法访问可执行 Jar 中的资源

android - 'build' 中的 'main' 不能应用于 '(groovy.lang.closure'

javafx - 使用 gradle 在 JavaFX 中需要位置