【问题标题】:How do I call a static Java method from Gradle如何从 Gradle 调用静态 Java 方法
【发布时间】:2013-07-11 10:05:58
【问题描述】:

我有一个 gradle 构建脚本,目前只需通过它的 main 方法执行一个 Java 类即可。我想知道的是,我怎样才能在同一个类中调用静态方法而不必通过main方法。目前的gradle代码如下:

import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'java'

defaultTasks 'runSimple'

project.ext.set("artifactId", "test-java")

File rootDir = project.getProjectDir()
File targetDir = file("${rootDir}/target")
FileCollection javaClasspath = files("${targetDir}/tools.jar")

task(runSimple, dependsOn: 'classes', type: JavaExec) {
    main = 'com.test.model.JavaTest'
    classpath = javaClasspath
    args 'arg1'
    args 'arg2'
}

而我的Java类如下:

package com.test.model;

public class JavaTest {

    public static void main(String[] args) throws Exception {
        System.out.println("In main");
        anotherMethod(args[0], args[1]);
    }

    public static void anotherMethod(String arg1, String arg2) {
        System.out.println("In anotherMethod");
        System.out.println(arg1 + " " + arg2);
    }
}

这给了我输出:

:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:runSimple
In main
In anotherMethod
arg1 arg2

BUILD SUCCESSFUL

Total time: 2.344 secs

我的问题很简单,我怎样才能跳过主要方法,直接从 gradle 脚本调用方法“anotherMethod”?输出将是:

In anotherMethod
arg1 arg2

谢谢

【问题讨论】:

  • 您希望它在 Gradle 构建的上下文(即类加载器)中运行,还是作为单独的进程运行? JavaExec 任务的工作方式就像从 shell 调用 java 命令一样。它将始终执行main 方法。
  • 我希望它作为一个单独的进程运行。有什么方法可以在 Gradle 中实现这一点吗?此外,在执行 Gradle 脚本期间,将多次调用此 Java 方法。因此,我希望它不要在每次调用同一个 Java 方法时启动一个新的 JVM,并在同一个 JVM 中运行。这有意义吗?
  • 嗯...如果您希望它是一个单独的进程,您可以使用相同的进程重复调用它,它看起来更像是一个守护进程或服务。 Gradle 的JavaExec 仅支持等效于从shell 调用java 命令。也就是说,它将运行您指定的类的主方法一次。 Gradle 可以运行任何你想要的 Groovy 代码,所以我确信可以做到这一点,但我没有看到任何直接的方法。
  • 为什么不创建一个带有 main 方法的 Bootstrap 类,该类调用需要执行多次的静态方法?这样你就只有一个 JVM 运行你的代码。

标签: java gradle build.gradle


【解决方案1】:

您必须将 jar 或类添加到类路径中。这是一个包含该类的 jar 文件的示例。 在文件 build.gradle 中添加依赖项。 我的 jar 文件在 lib 文件夹中,路径是 lib/MQMonitor.jar

import mypackage.MyClass
buildscript {
   repositories {
      flatDir name: 'localRepository', dirs: 'lib'
   }
    dependencies {
        classpath name: 'MQMonitor'
    }
}

task myTaskCallJava << {
   MyClass.foo()
}

【讨论】:

  • &lt;&lt; 已弃用;应该使用doLast
【解决方案2】:

假设该类位于 buildscript 类路径中(应该是,因为您从同一个类调用 main

task runSimple {
  doLast {
    com.test.model.JavaTest.anotherMethod("foo", "bar")
  }
}

在 Gradle 4.6 上测试

【讨论】:

    【解决方案3】:

    我也一直在努力。你知道我喜欢使用 Junit 选项运行的 eclipse 和 intellij 的功能,我想使用命令行和 gradle 来做到这一点。

    如果您可以接受将您的测试方法放在 gradle 的 'test' 目录中。我其实有一个公平的解决方案。

    package com.udacity.gradle;
    import org.junit.Test;
    
        public class TestClass {
            @Test
            public void anotherMethod() {
                System.out.println("This is it, I want this!!!");
            }
            @Test
            public void notMyWantedMethod1() {
    
                System.out.println("not my wanted");
            }
    
            public void notMyWantedMethod2() {
                System.out.println("not my wanted");
            }
    
        }
    

    这是我的测试类,位于 src/test/java/com/udacity/gradle/TestClass.java

    那么下面就是我的build.gradle

    的文件
    apply plugin: "java"
    repositories {
        mavenCentral()
    }
    dependencies {
        testCompile group: 'junit', name: 'junit', version: '4.12'
    }
    
    
    test {
        testLogging.showStandardStreams = true
        filter {
            //include specific method in any of the tests
            includeTestsMatching "*.TestClass.anotherMethod"
        }
    }
    

    简单的想法,你知道这是一个测试类,所以我使用 gradle 的测试任务。为了指定要使用的方法,我添加了一个可以指定方法的测试过滤器。

    然后你就可以运行了

    gradle test
    

    然后你可以在控制台中找到你想要的东西。不过记得加

    testLogging.showStandardStreams = true
    

    如果你不这样做,gradle 会吞下你的控制台输出。但即使你不添加这一行。您可以在

    目录中读取测试日志

    ...../build/test-results/test/TEST-com.udacity.gradle.TestClass.xml

    里面有组织良好的测试报告输出。

    <?xml version="1.0" encoding="UTF-8"?>
    <testsuite name="com.udacity.gradle.TestClass" tests="1" skipped="0" failures="0" errors="0" timestamp="2018-03-31T19:26:44" hostname="hexin-PC" time="0.022">
      <properties/>
      <testcase name="anotherMethod" classname="com.udacity.gradle.TestClass" time="0.022"/>
      <system-out><![CDATA[This is it, I want this!!!
    ]]></system-out>
      <system-err><![CDATA[]]></system-err>
    </testsuite>
    

    【讨论】:

      【解决方案4】:

      如果要执行静态方法,则需要将类添加到 Gradle 构建脚本的类路径中。

      如果您的代码在存储库中,则将代码添加到构建脚本类路径:

      buildscript {
          repositories {
              maven { url "${yourRepositoryURL}" }
          }
          dependencies {
              classpath 'com.yourgroup:yourpackagename:version'
          }
      }
      

      如果您的代码是在本地构建的,则将代码添加到构建脚本类路径(我没有测试这个):

      buildscript {
          dependencies {
              classpath files("path/to/where/the/class/files/are")
          }
      }
      

      那么您应该可以像调用其他任何方法一样调用该方法:

      task runSimple(dependsOn: 'classes') {
          doFirst() {
              com.test.model.JavaTest.anotherMethod('arg1', 'arg2')
          }
      }
      

      【讨论】:

      • 是的..这根本行不通..我仍然想不出一个优雅的方法来做到这一点..我不想为一个人创建一个类Java行
      猜你喜欢
      • 2011-11-14
      • 1970-01-01
      • 2020-04-06
      • 1970-01-01
      • 2012-01-06
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多