【问题标题】:How do I generate the class path for a Gradle project?如何为 Gradle 项目生成类路径?
【发布时间】:2013-11-20 20:41:12
【问题描述】:

我有一个包含多个包的 gradle 项目。构建后,每个包都会在 build/libs 中生成其 jar 文件。外部 jar 依赖项被拉入 ~/.gradle。我现在想从命令行使用适当的类路径在本地运行该服务。为此,我正在编写一个构建类路径的脚本。问题是脚本不理解所有外部依赖项,因此无法构造类路径。有没有办法让 gradle 帮助解决这个问题?理想情况下,我想在构建结束时将所有依赖项转储到一个文件夹中。

【问题讨论】:

    标签: java gradle


    【解决方案1】:

    首先,如果可以的话,我建议使用application plugin,因为它已经解决了这个问题。

    如果您想自己将类路径转储到文件中,最简单的方法是:

    task writeClasspath << {
        buildDir.mkdirs()
        new File(buildDir, "classpath.txt").text = configurations.runtime.asPath + "\n"
    }
    

    如果你想真正将类路径上的所有库复制到一个目录中,你可以这样做:

    task copyDependencies(type: Copy) {
        from configurations.runtime
        into new File(buildDir, "dependencies")
    }
    

    【讨论】:

    • 感谢您的回答。如果我使用应用程序插件,如何控制 JVM 设置?我想使用命令行中传递的特定设置启动 JVM。如果应用程序插件可以帮助我配置它,那将很有用。
    • 我找到了这个 -gradle.org/docs/current/dsl/org.gradle.api.Project.html#N13953。让我玩弄这个,看看我能不能让它做我想做的事。
    • 我没有成功让它工作。我添加了应用程序插件并指定了主类名称。在运行 gradle run 时,我得到 class not found 错误。也没有创建类和资源文件夹,因此我假设错误。命令 gradle 运行问题是 - /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/java -Dfile.encoding=UTF-8 -cp /Users/name/gradleproject/build/classes/main :/Users/name/gradleproject/build/resources/main MainClass
    • 我发现了问题所在。我有一个包含多个包的项目。每个包都有一个 build/classes 和 build/resources 文件夹,但主项目没有。我不确定从哪里运行这个命令
    • 当您说“具有多个包的项目”时,您的意思是多个子项目,对吗?这种情况是子项目的配置(运行时、编译等)独立于父项目的配置;两者都不包括另一个。因此,确实,简单地在根目录构建应用程序是行不通的。但是,您应该能够将子项目的依赖项添加到根项目,这应该可以正常工作。
    【解决方案2】:

    你可以在你的构建脚本中尝试这样的事情:

    // add an action to the build task that creates a startup shell script
    build << {
        File script = file('start.sh')
    
        script.withPrintWriter {
            it.println '#!/bin/sh'
            it.println "java -cp ${getRuntimeClasspath()} com.example.Main \"\$@\""
        }
    
        // make it executable
        ant.chmod(file: script.absolutePath, perm: 'u+x')
    }
    
    String getRuntimeClasspath() {
        sourceSets.main.runtimeClasspath.collect { it.absolutePath }.join(':')
    }
    

    【讨论】:

    • 谢谢。这看起来很有希望。我可以在 build.gradle 文件中的任何位置添加它吗?另外,我想理想地将类路径转储到某个地方,并让脚本引用文件中的内容。这使我能够拥有一个可以做很多事情的脚本,而不必成为 gradle 脚本的一部分。
    • 我更新了问题以显示我尝试了什么以及我看到了什么错误。
    • sourceSets.main.runtimeClasspath 基本上是一个FileCollection,其中包含引用 1) 构建输出文件夹(build/classes/mainbuild/references/main 等)和 2) 任何存储库中的外部 jar 依赖项的文件对象在。您可以轻松地遍历此集合并将 jar 复制到 aribtrary 文件夹中。
    • 这正是application plugin 所做的,只不过它做得更加奢华——它生成一个非常便携的 unix shell 脚本,加上一个 Windows 批处理脚本,并将所有依赖项复制到一个目录,以便脚本和库可以一起分发。
    • @TomAnderson,感谢您指出这一点。当我最近有这个需求时,应用程序插件引起了我的注意,因此我手动编写了上述脚本。我今天也学到了一些新东西,所以我 +1 了你的答案。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    相关资源
    最近更新 更多