来自buildSrc中定义的Task的Gradle传递依赖项

时间:2014-08-06 12:12:40

标签: gradle

我想让我的构建中的所有子项目都可以访问任务。任务ant执行依赖于jaxb-xjc JAR,提供给ant的类路径必须包含jaxb-xjc。

我的意见: 使用jaxb-xjc依赖项的自定义配置创建/buildSrc/build.gradle:

configurations {
    jaxb
}
repositories {
    mavenCentral()
}
dependencies {
    jaxb 'com.sun.xml.bind:jaxb-xjc:2.2.4-1'
}

然后在/ buildSrc下创建使用jaxb配置中的类路径的任务:

class JaxbTask extends DefaultTask {
...
    @TaskAction
    def main() {
        ...
        ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: project.configurations.jaxb.asPath)
        ...
        }
}

但是, project.configurations 最终会引用项目使用任务类,而不是/buildSrc/build.gradle的配置。因此,使此任务有效的唯一方法是将 jaxb 配置+依赖包含到使用该任务的所有项目中。

  • 是否可以让任务引用/buildSrc/build.gradle配置类路径?
  • 是否可以避免使用任务从项目中依赖jaxb-xjc?

1 个答案:

答案 0 :(得分:2)

新解决方案

实际上在考虑这个问题时,我发现了一个比我之前更好的解决方案,我认为这个解决方案非常高兴,并且不应该以任何方式干扰实际的项目构建。

build.gradle项目的buildSrc

configurations {
   wsimport
   xjc
}

dependencies {
   wsimport 'com.sun.xml.ws:jaxws-tools:2.1.4'
   xjc 'com.sun.xml.bind:jaxb-xjc:2.2.4-1'
}

def generatedResourcesDirectory = "$buildDir/resources/generated"

task generateClasspathsPropertiesFile {
   inputs.file configurations.wsimport
   inputs.file configurations.xjc
   def outputFile = file("$generatedResourcesDirectory/classpaths.properties")
   outputs.file outputFile
   doLast {
      def classpaths = new Properties()
      classpaths.wsimport = configurations.wsimport.asPath
      classpaths.xjc = configurations.xjc.asPath
      outputFile.parentFile.mkdirs()
      outputFile.withOutputStream { classpaths.store it, null }
   }
}

sourceSets.main.output.dir generatedResourcesDirectory, builtBy: generateClasspathsPropertiesFile

然后在各自的任务中:

class Xjc extends DefaultTask {
   ...

   @TaskAction
   def xjc() {
      ...

      def classpaths = new Properties()
      getClass().getResource('/classpaths.properties').withInputStream { classpaths.load it }
      ant.taskdef name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: classpaths.xjc
      ant.xjc ...

      ...
   }
}
class Wsimport extends DefaultTask {
   ...

   @TaskAction
   def wsimport() {
      ...

      def classpaths = new Properties()
      getClass().getResource('/classpaths.properties').withInputStream { classpaths.load it }
      ant.taskdef name: 'wsimport', classname: 'com.sun.tools.ws.ant.WsImport', classpath: classpaths.wsimport
      ant.wsimport ...

      ...
   }
}

旧解决方案

我目前如何解决这种情况 - 虽然我对它不太满意 - 除了需要应用的任务外还有一个插件:

class XjcPlugin implements Plugin<Project> {
   static final CONFIGURATION_NAME = "xjc_${System.currentTimeMillis()}"

   @Override
   void apply(Project project) {
      project.configurations.create(CONFIGURATION_NAME) { visible: false }

      project.dependencies {
         "$CONFIGURATION_NAME" group: 'com.sun.xml.bind', name: 'jaxb-xjc', version: '2.2.4-1'
      }
   }
}
class Xjc extends DefaultTask {
   ...

   @TaskAction
   def xjc() {
      if (!project.configurations.hasProperty(XjcPlugin.CONFIGURATION_NAME)) {
         throw new ConfigurationException("xjc configuration is missing on project ${project.name}, did you forget to apply XjcPlugin?")
      }
      ...
      def runClassPath = project.configurations."$XjcPlugin.CONFIGURATION_NAME".asPath
      ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: runClassPath)
      ant.xjc(...)
   }
}

但请注意,configurations.all { ... }nebula-dependency-recommender-plugin等内容也会影响这些配置,并可能产生意外结果。