Как вызвать статический метод Java из Gradle

У меня есть скрипт сборки gradle, который в настоящее время работает, просто выполняя класс Java через его основной метод. Я хочу знать, как я могу вызвать статический метод в том же классе, но не должен проходить через основной метод. Текущий код градации выглядит следующим образом:

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

Мой вопрос просто в том, как я могу пропустить основной метод и вызвать метод «anotherMethod» непосредственно из сценария gradle? Тогда вывод будет просто:

In anotherMethod
arg1 arg2

Спасибо


person danielbeddoe    schedule 11.07.2013    source источник
comment
Вы хотите, чтобы он запускался в контексте (то есть в загрузчике классов) сборки Gradle или как отдельный процесс? Задача JavaExec работает так же, как вызов команды java из оболочки. Он всегда будет выполнять метод main.   -  person ajoberstar    schedule 12.07.2013
comment
В идеале я хотел бы, чтобы он работал как отдельный процесс. Есть ли способ добиться этого в Gradle? Кроме того, этот метод Java будет вызываться много раз во время выполнения скрипта Gradle. Поэтому я хотел бы, чтобы он не запускал новую JVM каждый раз, когда он вызывает один и тот же метод Java, и запускался в одной и той же JVM. Имеет ли это смысл?   -  person danielbeddoe    schedule 15.07.2013
comment
Хм... Если вы хотите, чтобы это был отдельный процесс, который вы можете многократно вызывать, используя один и тот же процесс, он больше похож на демона или службу. JavaExec Gradle просто поддерживает эквивалент вызова команды java из оболочки. То есть он будет запускать основной метод указанного вами класса один раз. Gradle может запускать любой код Groovy, который вы хотите, поэтому я уверен, что это возможно сделать, но я не вижу прямого пути.   -  person ajoberstar    schedule 16.07.2013
comment
Почему бы вам не создать класс Bootstrap с основным методом, который вызывает ваш статический метод, который необходимо выполнить несколько раз? Таким образом, у вас будет только одна JVM, выполняющая ваш код.   -  person mtrovo    schedule 19.07.2013


Ответы (4)


вам нужно добавить банку или класс в путь к классам. вот пример с файлом 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()
}
person user3271098    schedule 12.08.2016
comment
<< устарел; следует использовать doLast - person Abhijit Sarkar; 31.03.2018

Предполагая, что класс находится в пути к классам buildscript (так и должно быть, поскольку вы вызываете main из того же класса)

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

Протестировано на Gradle 4.6

person Abhijit Sarkar    schedule 31.03.2018

Я тоже работал над этим. Вы знаете, мне нравится функция eclipse и intellij с запуском с параметрами Junit, и я хочу сделать это с помощью командной строки и gradle.

Если бы вы могли принять размещение своего тестового метода в каталоге «тестового» каталога gradle. На самом деле у меня есть справедливое решение.

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>
person X.HE    schedule 31.03.2018

Если вы хотите выполнить статический метод, вам нужно будет добавить класс в путь к классам сценария сборки 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')
    }
}
person Adam R.    schedule 27.12.2013
comment
да .. это вообще не работает .. и я до сих пор не могу найти элегантный способ сделать это .. Я не хочу создавать класс для одной строки Java - person Thomas Beauvais; 29.07.2015