【问题标题】:How to call custom Java method from Gradle如何从 Gradle 调用自定义 Java 方法
【发布时间】:2017-11-01 13:55:33
【问题描述】:

请问,如何在 Gradle 构建脚本中调用 Java 方法最方便的方法是什么?此方法包含我想在构建期间使用的功能;一个功能过于复杂,无法作为脚本中的 Groovy 方法,但不足以命令完整的自定义 Gradle 插件。

我的问题不是关于从 Gradle 运行 Java 应用程序。这将涉及分叉 JVM,并且没有简单的方法可以将输出发布回 Gradle,我需要该输出。

最初我的代码位于 src/main/java 中,但必须尽早编译才能从 Gradle 构建脚本中调用。

然后我尝试将构建助手类移动到一个子模块项目,一个类子模块,希望在调用主构建脚本之前构建子模块;我放在那里:

 buildscript {
    dependencies {
       classpath 'this.project:build-helper:1.0-SNAPSHOT'
    }
 }

但是 build-helper 子项目显然不是首先构建的,尽管在 settings.gradle 中作为第一个并且构建失败,因为依赖项未被识别。似乎 buildscript 在构建子模块之前被评估,在其他任何事情之前。哦!

【问题讨论】:

    标签: java gradle


    【解决方案1】:

    有两个主要用例

    源在当前项目中的src/main/java - 因此,当定义 buildscript 类路径时,该类不存在

    选项:

    1. 使用JavaExec 任务在另一个JVM 中运行该类

    2. sourceSets.main.runtimeClasspath 构造一个URLClassLoader 并通过类加载器加载/运行类

    例如:

    task doStuff {
        doLast {
            URL[] urls = sourceSets.main.runtimeClasspath.files as URL[]
            def classloader = new URLClassLoader(urls, null)
            Class myClass = classloader.load("foo.bar.MyClass")
            def myInstance = myClass.newInstance()
            Method method = myClass.getMethod("doStuff")
            method.invoke(myInstance)
        }
    }
    

    源在另一个项目中。 - 因此该类将在定义 buildscript 类路径之前存在

    在这种情况下,您可以将项目添加到 buildscript 类路径并调用它

    buildscript {
        dependencies {
            classpath project(':other-project')
        }
    }
    task doStuff {
        doLast {
            def myClass = new MyClass()
            myClass.doStuff()
        }
    }
    

    【讨论】:

    • 我尝试了第二个建议,但它对我不起作用,项目属性不允许在那里,并且辅助项目没有构建。我必须使用稍微过时的 Gradle 3.5 版,所以也许这就是为什么..
    • 啊,你是对的......你可以使用composite build。见herehere
    【解决方案2】:

    所以最简单的方法就是把我的构建助手Java源码放到buildSrc目录:<project root dir>/buildSrc/src/main/java/foo/bar/Extractor.java就这样了,你可以在Gradle构建脚本的任何地方直接调用new Extractor(..).extratMetadata(...),不需要导入包,不需要使用 Java 插件,Gradle 默认理解类似 Maven 的 buildScr 目录结构。

    致谢:https://zeroturnaround.com/rebellabs/using-buildsrc-for-custom-logic-in-gradle-builds/

    【讨论】:

      【解决方案3】:

      时髦

      1. 构建您的项目文件。
      2. 运行这个 groovy 文件并调用对象方法
              // This code is similar to lance-java's
              def files = sourceSets.main.runtimeClasspath.files
              // files[0] is C:\...\YourProject\build\classes\java\main
              def classLoader = new URLClassLoader((new URL[]{files[0].toURI().toURL()}))
              def myClass = Class.forName("aa.bb.c.MyClass", true, classLoader);
              def myInstance = myClass.newInstance()
              Method method = myClass.getMethod("sayHello")
              method.invoke(myInstance)
      

      科特林

      1. 构建您的项目文件。
      2. 运行这个 groovy 文件并调用类静态方法。
      import java.net.URLClassLoader
      ...
      task("helloworld") {
          doLast {
              val file: File = project.projectDir.toPath().resolve(tasks.jar.get().archiveFile.get().toString()).toFile()
              val classloader: ClassLoader = URLClassLoader(arrayOf(file.toURI().toURL()))
              Class.forName("mypackage.MyClass", true, classloader)
                  .getMethod("sayHello").invoke(null)
          }
      }
      ...
      

      【讨论】:

        【解决方案4】:

        要从 Gradle 构建脚本(没有 JVM fork)运行您的自定义 Java 类,您可以将其包含在 buildscript 类路径中,然后显式导入它。示例:

        buildscript {
            ext {
                ownRepo = "${System.properties['user.home']}/.gradle/local"
            }
            // Repositories for the build script.
            repositories {
                ivy {
                    url ownRepo
                }
            }
            // Dependencies for the build script.
            dependencies {
                classpath "org:mytool:1.0"
            }
        }
        
        import org.mytool.Checksums
        task calculateChecksums() {
            doLast {
                new Checksums().calculate(myAppDir)
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2012-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多