为什么我需要指定'from files'?

时间:2017-01-10 09:16:38

标签: gradle groovy jar

我试图用我的第一个groovy脚本构建一个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

应用程序/的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

导致上述错误消息。

2 个答案:

答案 0 :(得分:0)

假设Test.groovy看起来像:

package app

class Test {
    static main(args) {
        println "Hi!"
    }
}

然后您只需要以下构建脚本:

apply plugin: 'groovy'

repositories {
    mavenCentral()
}

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

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

答案 1 :(得分:0)

你必须记住这个jar包含Groovy个编译类。答案就在您在开头展示的反编译源中。它导入Groovy运行时类。

如果你只是运行java -jar test.jar那些类不在类路径上。 要么在命令行的类路径中包含groovy,要么使用gradle应用程序插件来构建包含所有应用程序依赖项的fat JAR(可能更适合runnable个jar)。

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