我有一个正在运行的Maven构建(如下所示),它准备了几个可执行文件作为两个独立的进程启动。
虽然这很好用,但如何使用Gradle完成?我看到Gradle提供了一个名为application
的插件,但我很难找到一个很好的例子来说明如何告诉它在键入:gradle stage
时,它应该创建2个可执行文件。
现在,当我调用stage
时,它只在我的gradle脚本中定义的“root”主类上提供了一个可执行文件:
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'SpringLauncher'
applicationName = 'foo'
compileJava.options.encoding = 'UTF-8'
targetCompatibility = '1.7'
sourceCompatibility = '1.7'
task stage(dependsOn: ['clean', 'installApp', 'hello'])
Maven构建:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>foo.bar.scheduler.SchedulerMain</mainClass>
<name>scheduler</name>
</program>
<program>
<mainClass>SpringLauncher</mainClass>
<name>web</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase><goals><goal>assemble</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
答案 0 :(得分:11)
不幸的是,gradle应用程序插件不提供对多个可执行脚本的一流支持。
幸运的是,因为gradle脚本是常规的,所以你可以很容易地改变应用程序插件的功能。
documentation for the Application plugin显示startScripts
任务的类型为CreateStartScripts,因此请尝试创建自己的同类型的第二个任务
task schedulerScripts(type: CreateStartScripts) {
mainClassName = "foo.bar.scheduler.SchedulerMain"
applicationName = "scheduler"
outputDir = new File(project.buildDir, 'scripts')
classpath = jar.outputs.files + project.configurations.runtime
}
然后在您的发行版中包含该任务的输出
applicationDistribution.into("bin") {
from(schedulerScripts)
fileMode = 0755
}
答案 1 :(得分:2)
使用JavaExec
task scheduler(type: JavaExec) {
main = "foo.bar.scheduler.SchedulerMain"
classpath = sourceSets.main.runtimeClasspath
}
task web(type: JavaExec) {
main = "SpringLauncher"
classpath = sourceSets.main.runtimeClasspath
}
然后您可以运行gradle scheduler web
答案 2 :(得分:1)
使用 Gradle Kotlin DSL 的 accepted answer 等价物,另外将创建多个脚本的通用逻辑抽象为一个可重用的函数:
fun createAdditionalScript(name: String, configureStartScripts: CreateStartScripts.() -> Unit) =
tasks.register<CreateStartScripts>("startScripts$name") {
configureStartScripts()
applicationName = name
outputDir = File(project.buildDir, "scripts")
classpath = tasks.getByName("jar").outputs.files + configurations.runtimeClasspath.get()
}.also {
application.applicationDistribution.into("bin") {
from(it)
fileMode = 0b000_111_101_101
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}
现在你可以像这样使用它:
createAdditionalScript("foo") {
mainClassName = "path.to.FooKt"
}
createAdditionalScript("bar") {
mainClassName = "path.to.BarKt"
}
buildSrc
函数 createAdditionalScript
最好放在 buildSrc
或插件中以保持主脚本干净,为此,它看起来像这样:
import org.gradle.api.Project
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.plugins.JavaApplication
import org.gradle.api.tasks.application.CreateStartScripts
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.register
import java.io.File
fun Project.additionalScript(name: String, configureStartScripts: CreateStartScripts.() -> Unit) =
tasks.register<CreateStartScripts>("startScripts$name") {
configureStartScripts()
applicationName = name
outputDir = File(buildDir, "scripts")
classpath = tasks.getByName("jar").outputs.files + configurations.getByName("runtimeClasspath")
}.also {
configure<JavaApplication> {
applicationDistribution.into("bin") {
from(it)
fileMode = 0b000_111_101_101
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}
}
请注意,fileMode
使用二进制权限表示来为用户、组和其他设置 r、w 和 x 位。 Kotlin DSL 不会像 Groovy 那样将 0755
之类的值解释为八进制。
答案 3 :(得分:0)
我发现的简单方法是添加一个新的CreateStartScripts
任务并使它成为schedulerScripts
的依赖项:
task schedulerScripts(type: CreateStartScripts) {
mainClassName = 'foo.bar.scheduler.SchedulerMain'
applicationName = 'scheduler'
classpath = startScripts.classpath
outputDir = startScripts.outputDir
}
startScripts.dependsOn schedulerScripts