How to include plugin dependencies in JavaExec task classpath? - java

I am using JavaExec tasks to run different classes, but whenever I try to run one of the tasks using gradle <task>, I get an error saying Error: JavaFX runtime components are missing, and are required to run this application.
If I just set mainClassName='exercise1.Cards' or whatever other className, running gradle run works completely fine. I'm guessing that the JavaFX classes are not found when running classes with JavaExec and I'm wondering how I can include them.
build.gradle:
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.7'
}
version '1.0-SNAPSHOT'
sourceCompatibility = 11
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
javafx {
modules = [ 'javafx.controls' ]
}
task runExercise1(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'exercise1.Cards'
}
task runExercise2(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'exercise2.InvestmentCalculator'
}
task runExercise3(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'exercise3.PointCircle'
}
task runExercise4(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'exercise4.OccurrenceHistogram'
}

The org.openjfx.javafxplugin plugin manages for you a few things.
When you add to your build file:
javafx {
modules = [ 'javafx.controls' ]
}
the plugin translates that into something like:
run {
doFirst {
jvmArgs = ['--module-path', classpath.asPath,
'--add-modules', 'javafx.controls']
}
}
However, if you create a new JavaExec task, it seems the plugin doesn't process it.
Given the error you have posted:
Error: JavaFX runtime components are missing
it is clear that a possible fix is to do exactly what the plugin does and add the expected jvm args when using modular dependencies.
So this should work:
task runExercise1(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
jvmArgs = ['--module-path', classpath.asPath,
'--add-modules', 'javafx.controls' ]
main = 'exercise1.Cards'
}
Alternatively you could create a launcher class that doesn't extend from Application, as that will bypass the modular check (as explained here).
public class Launcher {
public static void main(String[] args) {
// optionally process args to select class to run
Cards.main(args);
}
}
Then you could add your task, and even uses runtime arguments to select the main class to run from the launcher.
task runExercise1(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'exercise1.Launcher'
args 'exercise1' // <-- optionally select class to run
}

Related

How to generate cucumber html report with attached failed screenshot and cucumber.json file using gradle based project

Using gradle, I am trying generate cucumber html report with failed screenshot attached to it for security reason I cannot have online plugins in build.gradle file so I have to download required jar and plugins and implement and configure library manually in build.gradle file.
Please suggest how can configure TestRunner file in build.gradle and generate cucumber html report with cucumber.json file
build.gradle file
plugins {
id 'java'
id 'idea'
}
group 'org.example'
version '1.0-SNAPSHOT'
configurations {
cucumberRuntime.extendsFrom testRuntime
}
task cucumber() {
dependsOn assemble, compileTestJava
doLast {
javaexec {
main = "io.cucumber.api.cli.Main"
classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
args = ['--plugin', 'pretty', '--glue', 'stepDef', 'src/test/java']
}
}
}
repositories {
mavenCentral()
}
dependencies {
implementation fileTree(dir:System.getProperty("user.dir")+'/Plugin',include:['*.jar'])
implementation files('junit-4.12')
implementation files('testng-6.7.jar')
implementation files('junit-jupiter-api-5.6.2')
implementation files('hamcrest-all-1.3')
.....................
TestRunner file
package TestRunner;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(
features = "src/test/resources",
glue = "StepDefs",
plugin = {
"pretty", "html:target/cucumber-html-report", "json:target/cucumber.json", "pretty:target/cucumber-pretty.txt"
}
)
public class TestRunner {
}
Whatever StepDefs may be ...
Running with gradle cucumber --info might be useful for debugging... because the error message finished with non-zero exit value 1 just indicates "error" or "no success".
You'd probably need these Java dependencies, to begin with:
testImplementation 'io.cucumber:cucumber-java:6.5.0'
testImplementation 'io.cucumber:cucumber-junit:6.5.0'
And one might have to add gradle.cucumber as the --glue into the arguments args, as the documentation suggests. Task dependency compileTestJava should rather be testClasses.
html generally is a plugin, which expects an output directory, therefore this should look alike this:
task cucumber() {
dependsOn assemble, testClasses
doFirst {
}
doLast {
javaexec {
main = 'io.cucumber.core.cli.Main'
classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
args = [
'--plugin', 'pretty', 'html:target/reports',
'--glue', 'gradle.cucumber',
'src/test/resources'
]
}
}
}
These args can also be annotated in Java; not sure which of them takes precedence.It probably makes no sense and only creates a mess, when defining the arguments twice.
Make sure to follow instruction #4:
Add feature .feature files and associated step mapping classes .java in src/test/resources and src/test/java respectively in a gradle.cucumber package.
-g, --glue PATH Where glue code (step definitions, hooks and plugins) are loaded from.
When running with jUnit, one can also pass options with a junit-platform.properties file.
The most easy might be to start with the cucumber-java-skeleton (it is known to be working).
It didn't work for me, If I run this cucumber task it gives me error
Task :cucumber FAILED
Error: Could not find or load main class io.cucumber.api.cli.Main
Caused by: java.lang.ClassNotFoundException: io.cucumber.api.cli.Main
Error: Could not find or load main class io.cucumber.api.cli.Main
I have created one task cucumberRunner which executes the TestRunner.java file, it is creating cucumber.json file and html report but htlm
report but HTML report is not expected is weird no graphics and colorless colorless
build.gradle I'm using:
```
configurations {
cucumberRuntime {
extendsFrom testRuntime
}
}
task cucumber() {
dependsOn assemble, testClasses
doFirst {
}
doLast {
javaexec {
main = 'io.cucumber.api.cli.Main' // tried with io.cucumber.core.cli.Main
classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
args = [
'--plugin', 'pretty', 'html:target/reports',
'--glue', 'gradle.cucumber',
'src/test/resources'
]
}
}
}
task cucumberRunner(type: Test) {
include '**/**TestRunner.class'
}
Also I have added jars
implementation files('junit-4.12')
implementation files('testng-6.0.jar')
implementation files('cucumber-core-6.0.0')
implementation files('cucumber-java-6.0.0')
implementation files('cucumber-plugin-6.0.0')
implementation files('cucumber-junit-6.0.0')
implementation files('cucumber-testng-6.0.0')
implementation files('cucumber-jvm-deps-1.0.5')
implementation files('cucumber-gherkin-6.0.0')
implementation files('cucumber-java8-6.0.0')
implementation files('cucumber-html-0.2.3')
```

Task in gradle to include java class before compile

I need to create Gradle task which can replace .java files before Gradle build.
Gradle build package app in .war file. And I need to have replaced bytecode there after build.
I tried sourceSets Gradle task but it can only exclude files.
sourceSets {
main {
java {
exclude 'com/myapp/example/resource/impl/ResourceBundleImpl.java'
}
}
}
But I need to also include file in the same place. How I can do it with Gradle?
The directory to file that I need to exclude: com/myapp/example/resource/impl/ResourceBundleImpl.java
The directory to file that I need to include: src/main/webapp/WEB-INF/my/ResourceBundleImpl.java
To copy file content it is also posible solution.But How can I do it before compile time?
The below task didn't helped, becouse in build file have .java files instead of .classe file.
task prepareSources(type: Copy) {
from('src/main/webapp/WEB-INF/my')
into('build/classes/java/main/com/myapp/example/resource/impl')com/myapp/example
}
// Prepare sources, before compile
compileJava {
dependsOn prepareSources
}
The below task throws :
Task :cdx-war:compileJava FAILED
error: package com.myapp.example.util does not exist
sourceSets {
main {
java {
srcDir "$projectDir"
exclude 'com/medtronic/diabetes/carelink/rbps/resource/impl/ResourceBundleImpl.java'
include 'src/main/webapp/WEB-INF/my/ResourceBundleImpl.java'
}
}
I put classes that I need to replace together and add suffix to one of them and replace this suffix during compile time :
sourceSets {
main {
java {
srcDirs = ["$buildDir\\generated-src"]
}
}
}
task copySourceSet(type: Copy) {
println 'Change java class in patient-svc-war'
from "$rootDir\\patient-svc-war\\src\\main\\java"
into "$buildDir\\generated-src"
from file("$rootDir\\patient-svc-war\\**_suffix.java")
into "$buildDir\\generated-src"
rename { String fileName ->
fileName.replace("_suffix", "")
}
filter { line -> line.replaceAll('_suffix', '')}
}
compileJava.source "$buildDir\\generated-src"
compileJava {
dependsOn copySourceSet
}
compileJava.doLast {
delete "$buildDir\\generated-src"
}

Protobuf plugin for gradle does not generate service class

I try to build a gRPC and protobuf application in java with Gradle
I followed the instruction from: https://github.com/grpc/grpc-java/blob/master/README.md
The issue is that one file is not generated: *ServiceGrpc.java
But the corresponding *ServiceGrpc.class file is in the build directory generated by the gradle build.
I tried with running the compiler manually with the command protoc but I have the exact same issue (I'm on Ubuntu 18.04)
Here is my proto file
syntax = "proto3";
option java_multiple_files=true;
option java_generic_services= true;
//...//
message Track {
int64 id = 1; //... }
service TrackService {
rpc Create(Track) returns (Response); }
//...
The file Track.java, TrackOrBuilder.java, TrackOuterClass.java are all there. As well as their corresponding .class files in the build directory.
With the flag "option java_generic_services= true", TrackService.java is generated, and again .class file.
But not matter what, the file TrackServiceGrpc.java is not created, contrary its correspond .class file, which is quite confusing.
here is my build.gradle :
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.8'
}
}
plugins {
id 'java'
}
repositories {
mavenCentral()
}
apply plugin: 'com.google.protobuf'
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.9.0"
generateProtoTasks.generatedFilesBaseDir = 'src'
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.23.0'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
//https://github.com/grpc/grpc-java/blob/master/README.md
implementation 'io.grpc:grpc-netty-shaded:1.23.0'
implementation 'io.grpc:grpc-protobuf:1.23.0'
implementation 'io.grpc:grpc-stub:1.23.0'
compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
}
What am I doing wrong ?
If the .class file for the gRPC service exists, the corresponding .java file must have been at some place. By default, it should appear in $generatedFilesBaseDir/{main, test}/grpc. By default, $generatedFilesBaseDir is $buildDir/generated/source/proto. But seems you have changed (or intended to change) generatedFilesBaseDir, that configuration should be done inside the protobuf closure instead of the protoc closure.
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.9.0"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.23.0'
}
}
generatedFilesBaseDir = 'src'
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
Also, need to mention that configuring generatedFileBaseDir is discouraged as it might have potential problems. See discussion at https://github.com/google/protobuf-gradle-plugin/issues/332

How to pass parameters to main method using Gradle?

I have to pass two arguments to my main method. My build script is
// Apply the java plugin to add support for Java
apply plugin: 'java'
// In this section you declare where to find the dependencies of your project
repositories {
// Use 'maven central' for resolving your dependencies.
mavenCentral()
}
// In this section you declare the dependencies for your production and test code
dependencies {
compile 'com.example:example-core:1.7.6'
}
task main(type: JavaExec, dependsOn: classes) {
description = 'This task will start the main class of the example project'
group = 'Example'
main = 'com.example.core.Example'
classpath = sourceSets.main.runtimeClasspath
}
If I try:
gradlew main doc.json text.txt
Then an error occured.
org.gradle.execution.TaskSelectionException: Task 'doc.json' not found in root project
How can I pass arguments to my main method command line easily?
task run(type: JavaExec) {
main = "pkg.MainClass"
classpath = sourceSets.main.runtimeClasspath
args = ["arg1", "arg2"]
}
You should use use -P as listed in the Gradle command line documentation.
For example, the following will work:
gradlew main -Parg1=doc.json --project-prop arg2=text.txt
And you access them in your Gradle script like this:
println "$arg1 $arg2"
task run1(type: JavaExec) {
main = "pkg.mainclass"
classpath = sourceSets.main.runtimeClasspath
args = ["$arg1","$arg2",...]
}
//I have named as run1 it can be any task name
While invoking the gradle script:
c:\> gradle run1 -Parg1="test123" -Parg2="sss"

How can I use Gradle's CreateStartScripts Task

I want to use gradle's CreateStartScripts Task to generate the script to start the application.
I use it in the following way:
apply plugin: 'java'
mainClass = 'UIMain';
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}
task copyResources(type: Copy) {
from 'config.ini'
into 'build/dist'
}
task copyLibs(type: Copy) {
from configurations.default
from configurations.default.allArtifacts.files
into 'build/dist/libs'
}
task generateScript(type: CreateStartScripts) {
applicationName = "Dagang"
mainClassName = mainClass
outputDir = "build/dist/"
classpath = ""
}
task distribute(dependsOn: [
build,
copyLibs,
copyResources,
generateScript
]) <<{
description = 'Copies all the project libs to the distribution place.'
}
However when I run the build, it runs into error like:
A problem occurred evaluating root project 'dagang'.
[org.gradle.BuildExceptionReporter] Cause: Could not find property 'CreateStartScripts' on root project 'dagang'.
Can anyone shed me some light? Thanks.
Either import the class (org.gradle.api.tasks.application.CreateStartScripts), or use the application plugin. The latter is generally preferable.
CreateStartScripts appears to be a package-private class, hence it's invisible.
Try using the application plugin instead. You can then additionally override some other properties of the built-in startScripts task.

Categories

Resources