написание задачи gradle, расширяющейся из теста

#groovy #gradle

#groovy #gradle

Вопрос:

Я хочу написать пользовательский плагин, который должен определять его собственную тестовую задачу. Эта задача должна обладать свойствами обычной тестовой задачи, но выполнять некоторые дополнительные действия.

Мой класс задач выглядит следующим образом:

 import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.testing.Test

class MyTestTask extends Test {

    @TaskAction
    def intTest() {
        dosomething()
    }
}
  

Мой класс плагина, который должен создать эту задачу, выглядит следующим образом:

 import org.gradle.api.Plugin
import org.gradle.api.Project;

class JavaProjectPlugin implements Plugin<Project> {

    @Override
    public void apply(Project project) {
        project.plugins.apply('java')
        project.task('myTest', type: MyTestTask)

        doMoreStuff()
    }
}
  

Но когда я пытаюсь выполнить проект, применяющий этот плагин, я получаю эту ошибку:

 Caused by: java.lang.ClassNotFoundException: org.gradle.api.tasks.testing.TestFilter
    at java.net.URLClassLoader.findClass(URLClassLoader.java:588)
    at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:756)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:733)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:703)
    ... 232 more
  

Я что-то упускаю или мне нужно сделать это совершенно по-другому?

После сборки плагина с gradle 1.9 я получил этот stacktrace:

 Caused by: java.lang.NoSuchMethodError: org/gradle/api/tasks/testing/Test.<init>()V
    at com.ibm.gradle.MyTestTask.<init>(MyTestTask.groovy)
    at com.ibm.gradle.MyTestTask_Decorated.<init>(Unknown Source)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:68)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:529)
    at org.gradle.api.internal.DependencyInjectingInstantiator.newInstance(DependencyInjectingInstantiator.java:62)
    at org.gradle.api.internal.ClassGeneratorBackedInstantiator.newInstance(ClassGeneratorBackedInstantiator.java:36)
    at org.gradle.api.internal.project.taskfactory.TaskFactory$1.call(TaskFactory.java:124)
    ... 218 more
  

Ответ №1:

Не могли бы вы, пожалуйста, проверить, используете ли вы gradle 1.2 во время выполнения? Вы можете сгенерировать свой плагин в gradle 1.12, но использовать его с более низкой версией во время выполнения

Комментарии:

1. на самом деле я понятия не имею, как выполнить на 1.2. Я запускаю этот плагин с оболочкой (версия 1.9), и я не могу просто перейти на другую версию. Плагин построен с помощью плагина gradle для eclipse. Я предполагаю, что это версия 1.12

2. Похоже, вам нужно создать свой плагин в версии 1.9, иначе он не будет работать.

3. Я построил ее с 1.9, но теперь я получаю java.lang.NoSuchMethodError: org/gradle/api/tasks/testing/Test.<init>()V

4. Не могли бы вы предоставить полную трассировку стека? Кажется, что-то все еще не так с версией…

5. Я добавил это в вопрос.

Ответ №2:

Эта ошибка NoSuchMethodError была вызвана не таким конструктором для org / gradle / api/tasks/testing/Test. Этот пустой конструктор (без параметров) был добавлен в gradle 0.8. Похоже, что ваша версия gradle для среды выполнения — gradle 0.7 или более ранняя. смотрите http://www.gradle.org/docs/0.7/javadoc/org/gradle/api/tasks/testing/Test.html

Это означает, что вы должны предоставить пустой конструктор для вашей MyTestTask, который вызывает Test constructor:

 Test(Project project, java.lang.String name) 
  

Я настоятельно рекомендую вам использовать более новую версию gradle во время выполнения.

Комментарии:

1. Я действительно не понимаю. Я создаю как плагин, так и проект с оболочкой, используя один и тот же дистрибутив gradle 1.9. Как один из них мог бы использовать gralde 0.7 или что-либо еще?

2. Похоже, что версия gradle для среды выполнения равна 0.7 или более ранней. Не могли бы вы, пожалуйста, проверить, использовалась ли оболочка?

3. Хорошо, действительно кажется, что есть проблема с версиями. Но я все еще понятия не имею, почему gradle должен использовать такую старую версию. Я предполагаю, что я решил эту проблему с помощью плагина gradle для eclipse из STS. И я понятия не имею, где изменить / установить версию gradle для разработки и сборки.

4. Хорошо, я проверил новейший документ API и обнаружил, что у тестового класса снова есть конструктор с параметрами. смотрите gradle.org/docs/1.4/javadoc/org/gradle/api/tasks/testing/… Этот API не менялся до gradle 2.0. Поскольку я пока не хочу использовать gradle 2.0, знаете ли вы, как использовать тестовый класс с этим параметром?

Ответ №3:

В общем, ответ Билла Лина правильно решает эту проблему. Как я уже сказал в комментарии, это не gradle 0.7, а gradle 1.12. Поскольку они изменили конструктор тестового класса, вы должны предоставить конструктор, по крайней мере, такой:

 @Inject
public MyTestTask(ListenerManager listenerManager, StyledTextOutputFactory textOutputFactory, FileResolver fileResolver,
                Factory<WorkerProcessBuilder> processBuilderFactory, ActorFactory actorFactory, Instantiator instantiator,
                ProgressLoggerFactory progressLoggerFactory) {
    super(listenerManager, textOutputFactory, fileResolver, processBuilderFactory, actorFactory, instantiator, progressLoggerFactory )
}