当前位置: 首页 > 知识库问答 >
问题:

在同一个构建文件中执行gradle Shayjar任务两次

胡云瀚
2023-03-14

我正在尝试使用ShadowJar插件作为同一构建文件的一部分创建两个“FatJars”。我试图通过声明两个ShadowJar类型的任务在构建中运行影子Jar任务两次

到目前为止,我已经定义了两个这样的任务:

task shadowjar_one (type: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar)
task shadowjar_two (type: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar)

现在我试着这样制作我的罐子:

shadowjar_one {
    mergeServiceFiles()
    exclude 'somefile.txt'

    archiveName = 'jar1.jar'

    appendManifest {
         attributes 'Main-Class': 'some.package.someClass'
    }
}

shadowjar_two {
    mergeServiceFiles()
    exclude 'someOtherfile.txt'

    archiveName = 'jar2.jar'

    appendManifest {
         attributes 'Main-Class': 'some.package.someOtherClass'
    }
}

我面临的问题是JAR是创建的,但它们不包含来自“其他”JAR的任何其他依赖项(包、文件等)。JAR只包含META-INF和当前项目的包目录。

知道有什么问题吗?

注意:我希望生成两个稍有不同的jar文件。两者必须具有相同的项目代码库,在清单的主类属性中存在差异(以及其他一些小差异)

非常感谢!

共有3个答案

贺靖
2023-03-14

我使用的一种解决方法是使用单个shadowJar任务,但传递参数。在您的情况下,类似于:

shadowJar {
  mergeServiceFiles()
  exclude System.properties.getProperty('exclude')
  archiveName = System.properties.getProperty('archiveName')
  appendManifest {
    attributes 'Main-Class': System.properties.getProperty('mainClass')
  }
}

然后,启动应用程序时:

gradlew shadowJar -Dexclude=... -DarchiveName=... -DmainClass=...
龙玄天
2023-03-14

阴影插件作者-我刚刚意识到这个问题。您所遇到的是,Shadow插件使用一组为该任务定义的约定创建和配置shadowJar任务。

当您使用该类型创建自己的任务时,您需要手动定义一些配置选项,因为插件无法知道您对这些任务的意图。

您可以在此处引用应用于内置任务的配置:https://github.com/johnrengelman/shadow/blob/master/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy#L38-L63

吕奇
2023-03-14

作者在这里给出了一个很好的解决方案(因为它既短又有效):

https://github.com/johnrengelman/shadow/issues/108

实际上,我正在对该解决方案进行调整,出现在该页面的底部(我添加了注释来解释它):

task bootstrapNodeJar(type: ShadowJar) {
 group = "shadow" // Not a must have, but it's always good to have a group, you can chose whichever - this is the one shadowJar belongs to
 description = "Builds a Bitsquare bootstrap node executable jar" // Same as the above
 manifest.attributes 'Main-Class': 'io.bitsquare.app.cli.BootstrapNodeMain' // The main attraction! Be sure to update this line
 classifier = 'bootstrapNode' // General jar task property - see more about it in the Gradle manual
 from(project.convention.getPlugin(JavaPluginConvention).sourceSets.main.output) // Leave as is
 configurations = [project.configurations.runtime] // Same as the above
 exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA') // This one is actually really important!

 // Here you can add other Jar properties like destinationDir, for example
}
 类似资料:
  • 在我的maven构建中,我必须按照下面提到的特定顺序执行以下步骤: exec-maven-plugin maven-antrun-plugin exec-maven-plugin maven-antrun-plugin maven-remote-resources-plugin,jaxb2-maven-plugin maven-javadoc-plugin exec-maven-plugin 在p

  • 我正在从事一个spring boot项目,以自动化与gradle的集成测试。我最近开始在一家新企业工作,我的同事们按如下方式运行集成测试:在构建中。gradle文件有一个集成测试任务 启动任务后,应用程序开始在指定端口运行,然后打开postman,导入集合并运行测试。 我的工作是找到一种方法来跳过额外的点击,即自动运行邮递员集合。第一个想法是使用postman-run gradle插件,但由于企业

  • Gulp任务定义 问题方案 当我发出时,发生的情况附在下面的日志中。 问题 为什么会这样?(请给我一个深入的解释,因为我正在搜索内部) 为什么gulp stream不能轮询文件是否已创建。 有没有更好的方法来处理这类情况?

  • 我试图在springboot上同时运行多个计划任务,但实际上它们运行队列(一个接一个,不是并行的) 这是我简单的服务: 输出: 但是,它应该是这样的: 我做错了什么? 这是我的配置:

  • yield 指令可以很简单的将异步控制流以同步的写法表现出来,但与此同时我们将也会需要同时执行多个任务,我们不能直接这样写: // 错误写法,effects 将按照顺序执行 const users = yield call(fetch, '/users'), repos = yield call(fetch, '/repos') 由于第二个 effect 将会在第一个 call 执行完

  • 我希望在编译任何子项目之前先执行protobuf任务,因为我的子项目依赖于从protobuf任务生成的java文件。那么我怎样才能做到这一点呢?我不想在每个子项目中都有protobuf任务,相反,我只想在根项目中同时完成它,但在编译子项目之前。