【问题标题】:How can I call code from one subproject in a gradle tasks of another subproject?如何在另一个子项目的 gradle 任务中调用一个子项目的代码?
【发布时间】:2019-10-23 12:41:16
【问题描述】:

我有一个包含两个子项目的项目。

其中一个子项目“A”包含发布到工件的代码。

另一个子项目“B”有一项任务,需要完全按照 A 代码中的一个方法执行的操作。我可以在 groovy 中复制逻辑,但是有什么方法可以让我在子项目 B 中的任务调用作为子项目 A 的一部分编译的代码?

我尝试在 B 中添加一个构建脚本块,将 A 中的工件添加到类路径:

buildscript {
    dependencies {
        classpath project(':subproject-a')
    }
}

...但这给了我一个错误:

不能在脚本类路径定义中使用项目依赖项。

我不相信我可以将 subproject-a 移动到 buildSrc,因为我还将其工件发布到 maven 存储库以供其他项目使用。

【问题讨论】:

    标签: gradle gradle-multi-project-build


    【解决方案1】:

    您有一个先有鸡还是先有蛋的问题,即所有 Gradle 项目类加载器在编译任何类之前都已解决。这可以使用自定义配置和类加载器来解决

    例如:

    configurations {
       custom 
    } 
    dependencies {
       custom project(':subproject-a')
    } 
    task customTask {
       doLast {
          def urls = configurations.custom.files.collect { it.toURI().toURL() } 
          ClassLoader cl = new java.net.URLClassLoader(urls as URL[]) 
          Class myClass = cl.loadClass('com.foo.MyClass')
    
          // assuming zero args constructor 
          Object myObject = myClass.newInstance()
    
          // assuming method which accepts single String argument 
          java.lang.reflect.Method myMethod = myClass.getMethod('myMethodName', String.class)  
          myMethod.invoke(myObject, 'methodArg')
       } 
    } 
    

    【讨论】:

    • 谢谢!我需要进行一些调整才能使其正常工作: 1. 在构造 ClassLoader 时,我需要将 this.class.classLoader 作为父级传递,否则 ServiceLoader 会因“不是子类型”错误而失败。 2. 我需要添加一个 `customTask.dependsOn(':subproject-a:assemble') 以确保 subproject-a 的 jar 能够及时构建。 3.我需要将subproject-a的一些依赖添加到buildscript依赖中。
    • 我仍然不太了解#3,而且这种解决方法感觉就像一个巨大的杂物。我尝试将这些依赖项添加为子项目中的“自定义”依赖项(这仍然看起来像一个杂物,但不那么糟糕),但它没有帮助。执行“myMethod”时出现错误,提示它无法加载资源或无法找到其依赖项中的类。
    • 我已经更新了我的答案,以使用 java 反射而不是常规的动态行为来调用该方法。以前的解决方案可能导致通过项目类加载器调用该方法,从而导致您看到的问题。请删除您的 hack 并尝试新的解决方案
    • 感谢您的更新!看起来异常实际上来自构造函数内部。我尝试将其更改为使用反射的 Constructor 对象,但这没有任何效果。异常来自内部测试容器,所以我做了一些探索,看看可能是什么原因。事实证明他们使用线程的“上下文类加载器”。在任务中设置它(并在之后重置它)似乎解决了这个问题。我现在遇到了一些其他异常,其中堆栈跟踪太长以至于 gradle 截断它,所以我还没有找出原因。
    • 看起来最后一个问题是由于缺少一些“自定义”依赖项。现在可以了!
    猜你喜欢
    • 1970-01-01
    • 2021-11-12
    • 2014-02-08
    • 2015-06-23
    • 2020-05-15
    • 1970-01-01
    • 2021-08-27
    • 2017-12-27
    • 1970-01-01
    相关资源
    最近更新 更多