How to include plugin dependencies in JavaExec task classpath?

boged :

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'
}
José Pereda :

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
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=105937&siteId=1