The mrJar Plugin v0.0.16 has been released — JPMS Modules Made Easy

Check out what’s new in this release of the mrJar plugin

☆ Easily exclude individual artifacts from the module path
☆ Easily specify packages to export & open
☆ Improved Eclipse/Buildship/vscode Moduleability
☆ JavaFX friendly
☆ Supports src/javaN/java and src/main/javaN source set structures 1
☆ Improved test framework support (JUnit4, JUnit5, Spock, TestNG)
☆ Gradle 6+ support
☆ JDK 13 support — Compile, Test & Run with Java SE 13
☆ Bug fixes

These other posts have more details and usage examples:

Try it out and let me know if it works for you? TIA :+1:






1Actually, this feature has been available since v0.0.1. Introduced now for the first time. It’s a little-known built-in Gradle thing I leverage.

Thanks for that explanation @Graou74,

I totally empathize with you on the pain points that are unfortunately inevitable with JPMS development.

I hesitate to ask you for just one favor. But if the memories of it are not too painful for you to recall, I would really, really like to get a deeper understanding of your «access non-exported packages of the JavaFX modules» problem that you referred to.

I will not try to persuade you to return to a JPMS architecture. I promise. I only want to understand your problem myself. Because if I understand you correctly so far, then I think my latest implementation of mrJar might provide an easy solution. (why I moved the discussion to this thread)

I would like to do some functional testing, using your problem as the basis to test my latest implementation. So if you could either:

  1. Elaborate in a little more detail on your «violate JavaFx which lacks openness in places» problem? Or

  2. Upload a sample project that demonstrates that one, single, particular problem?

Please? You would be helping me out big time! TIA :+1:

Hi Lingocoder,

You have been a great help to me, I am grateful to you and it is with pleasure that I can help you in return.

In terms of providing you with a project with the configuration of this moment I’m afraid it will be difficult but I remember enough of the outline to be able to describe them:
Elipse version 2019-09 (4.13) on Mac.
It seems to me that at this point the JVM was integrating JavaFX. Since I have a version without JavaFX:
openjdk version “11.0.1” 2018-10-16
But without JavaFX integrated into the JVM I had to go through the Gradle plugin “‘org.openjfx.javafxplugin’ version ‘0.0.8’” :
javafx {
version = “11”
modules = [ ‘javafx.controls’, ‘javafx.fxml’ ]
}

So much for the configuration. The first step is to launch a JavaFX window “Hello world”.

Then I needed to replace the system-provided javafx.stage.Stage instance in the “start ()” method of the javafx.application.Application (@Override public void start (final Stage PrimaryStage) {… .) by an instance javafx.stage.Stage to me.

For that I have to go through the static method (public static void setPrimary (Stage Stage, boolean primary)) of the com.sun.javafx.stage.StageHelper class. And this is where access rights issues manifest themselves. How does the compiler know how to see this StageHelper class?

public class MainApp extends Application {

@Override
public void start(final Stage primaryStage) {
//‘mainWin’ is my own instance of primaryStage.
mainWin = new MainWindow();
StageHelper.setPrimary(mainWin, true);

I have to leave this morning but if this description is not enough I can make you a mini-project but in my current configuration. At least you will have the sources.

best regards

----- Mail original -----

Hi again Lingocoder,

I may have forgotten to specify what corresponds to “JavaFx violate which lacks openness in places”.

Many JavaFx methods are declared as “final” which already limits the inheritance needed for customization.
But also a number of internal object constructions are not facing outward.
For example, instead of making a public method of construction available, the object is directly instantiated in a private method to an attribute that is also private. All often in a package hidden by the JPMS.

So, since I want total control of rendering and behavior of my graphics components, I have to “violate” the protections set up by JavaFX using java.lang.reflect.
But this is only possible if my IDE agrees to compile ;0).

Best Regards.

----- Mail original -----

I had to make a couple tweaks to get the attached test project into a presentable state. But mrJar v0.0.16 does pass this one simple functional test which kinda-sorta models your problem.

Getting access to com.sun.javafx.stage.StageHelper was relatively straightforward. I configured the jpmsOpts property of the mrjar{} block with an add-exports to allow the test application to import and access com.sun.javafx.stage.StageHelper



You’ll see in the recording that to verify that the test application’s module does have access to that JavaFX module’s package, I simply import that class and call StageHelper.getStageAccessor( ) instead of calling the setPrimary(Stage) method you mentioned.

I don’t do the setPrimary(Stage) method call in the test project; only because I didn’t have a specialized implementation of Stage to pass it. Implementing one would have been more time-consuming, besides, since I’m pretty green with JavaFX.

Getting access to the package and class of the javafx.graphics module was the main focus of this particular test anyway. Of course, any public method on that StageHelper class could be called, in actual real usage.

Once again, Graou74, your feedback was super valuable in helping me flesh out this functional test. So I sincerely appreciate it :+1:

If I understand correctly what you’re aiming for, then you can enable reflection into the members of a module using one of the java JPMS options.

For example: jpmsOpts = [ '--add-opens', 'javax-graphics/some.javafx.pkg=your.module', ... ]

Just follow the option and value formats detailed in both that java JPMS options reference link and this javac one.

Typically the JPMS-related error messages that java and javac throw at you, will more or less tell you exactly which of the options you will need to set.

For example an error might say: ...such and such module cannot be accessed because module foo does not export it.... So, that’s pretty much telling you that you need to set an --add-exports option, for instance.

Please don’t hesitate to get in touch if you have any questions.

Hi Lingocoder,

It is a great satisfaction for me to know that I was able to contribute modestly to your beautiful project.

I understand your explanation, but I can not open the ZIP file that goes back an error.

Best Regards

----- Mail original -----

Honestly, I consider it our project: yours and mine :slight_smile: I couldn’t have done it without your input.

Sorry about that. Hopefully this direct upload works|attachment (59.0 KB)

So did the test project — as it appears in the recording — model your problem close enough?

Hi again Lingocoder,

Yes you have perfectly understood the context.

In the first roll of my application (not JPMS) with which I used Maven instead of Gradle, I had to declare for the runtime lines ‘–add-opens’ and ‘–add-exports’ (JavaFx was in " User Library ").
Now in the new version of the project (still not JPMS) with the plugin Gradle ‘org.openjfx.javafxplugin’, I just declare the modules I use (it’s very comfortable):
javafx {
version = “11”
modules = [‘javafx.controls’, ‘javafx.fxml’]
}

Another reason I put aside the JPMS is that I use AspectJ. For example, for now I still can not launch a Gradle build on the command line because of AspectJ (I pushed back the study of Gradle and the compilation with AspectJ). However, with the AspectJ plugin Eclipse I can develop with AspectJ and test without problems.

Best regards

----- Mail original -----

Lol, our project if you want but something like 99.99% vs. 0.01% ;0).

Yes I think this project models my problem enough (no compilation error in Eclipse, all classes declared are recognized) however I could not try because I have errors.

I launched the project and the test walked a first time it seems to me, I wanted to make changes and even removing my change he told me he can not find the class:
Caused by: java.lang.ClassNotFoundException: mr.jar.graou74.LibraryTest
at java.base / jdk.internal.loader.BuiltinClassLoader.loadClass (BuiltinClassLoader.java:583)
at java.base / jdk.internal.loader.ClassLoaders $ AppClassLoader.loadClass (ClassLoaders.java:178)
at java.base / java.lang.ClassLoader.loadClass (ClassLoader.java:521)
at java.base / java.lang.Class.forName0 (Native Method)
at java.base / java.lang.Class.forName (Class.java:398)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.loadClass (JUnitPlatformTestClassProcessor.java:110)
… 30 more
Yet the class exists, I do not understand what is happening.

I also tried to launch directly from Eclipse and I have an error like this :
Error occurred during initialization of boot layer
java.lang.module.FindException: Module javafx.xxx not found

Well looking I should find what happens but you will understand that I can not investigate much anymore. My project has already fallen behind and requires all my energy.
I hope to one day my application on the market and to be able to live it but for the moment it is far from being finished.

Best regards

----- Mail original -----

Ooops! Well, back to the drawing board :slight_smile: Thanks. I will investigate.

I think I have reproduced what you described, @Graou74. The solution is that, when you import a JPMS-ified Gradle project for the very first time into Eclipse/Buildship, you must do one of these three things before you run a regular Eclipse JUnit test:

  1. Do Run as a Gradle Test first
  2. Execute the :test or :check task from the Gradle Task view first
  3. Execute the :eclipse task from the Gradle Task view first

Like I’m doing in this recording…

The reason that is necessary is centered on what @st_oehme says here

„…Buildship doesn’t use the module path, it uses the classpath. You’ll find all your dependencies in the “Project and External dependencies” container…“

You might be able to see at brief instances in the recording, Eclipse’s Java Build Path. First you see it before Eclipse Modulefication. Only the JDK’s built-in modules are on the module path.

Then you see the Java Build Path after Eclipse Modulefication. All the declared dependencies (except for test dependencies) are then on the module path. After that, Eclipse’s Run As JUnit Test worked as expected for me.

The job of the mrJar feature that I have dubbed Eclipse Modulefication is to add your declared dependencies to the module path. Because Buildship is brain dead in that department.

Without mrJar’s intervention, Buildship does not even know what a module path is. So, you gotta explicitly set it in one of the three ways listed above.

At some point, I will look into refactoring mrJar’s Eclipse Modulefication so that it is more or less automatic. Actually, I would have sworn that I had already solved that before believe it or not. But some very recent change has knocked it out of whack it looks like.

But as long as you don’t do a Gradle Refresh, manual Eclipse Modulefication should be a set-and-forget type deal.

By the way, @Graou74. This explanation is not intended to persuade you to return to the JPMS fold :slight_smile: I just thought it might be informative as general usage guidance for other prospective users.

Thank you for the explanations, I’ll look at this later.

----- Mail original -----

@GradleCommunity, here is a project that tests mrJar’s JDK 13 JPMS module support.

The JUnit 5 test simply exercises a couple of the new String methods introduced in Java SE 13. But it does so on a JPMS module implemented with JDK 13.

The new java.lang.String.stripIndent() method operates on a new JDK 13 preview feature: Text Blocks. So you’ll notice in the recording, the Eclipse compiler forces you to explicitly opt-in to the preview feature with an error in the Problems view. That’s easily applied — as shown in this recording

Of course, the Eclipse compiler is different than the compiler that Gradle uses when building this project with raw Gradle from the command line. In that usage scenario, mrJar seamlessly takes care of the --enable-preview setting for you under the hood.


Incidentally, @Graou74. While doing this JDK 13 test, Run as JUnit Test was successful immediately after initial import — without the need to Run as Gradle Test beforehand. So this test confirms what I suspected in a previous comment: «…I would have sworn that I had already solved that before…But some very recent change has knocked it out of whack…».

Something with the processing of the jpmsOpts property seems to undo the apply-automatically-on-import behavior of the Eclipse Modulefication feature that I knew I’d already implemented before. I will fix that (again) at some point.

Hi Lingocoder,

I take advantage of an end of stage in my project to return on your example.

I deleted the “build” directory, made a “Refresh Gradle project” in Eclipse and then launched “1 Gradle test” from the LibraryTest.java class and everything works fine.

But after if I want to raise again “1 Gradle test” or the task “test:” or “check:”, I have again the error message which says that the class mr.jar.graou74.LibraryTest does not exist (while it is present).

It’s completely crazy, I do not understand what’s going on, I will not investigate more but I add a video to prove that I saw a UFO.

Best Regards

----- Mail original -----

(Attachment Graou74.mp4 is missing)

Hi again Lingocoder,

Oops, the video has not passed.
It can be downloaded here: http://dl.free.fr/naRQM5Y4f

----- Mail original -----

Thanks @Graou74. It would not be nice of me to play the Neil DeGrasse Tyson to your Giorgio Tsoukalos :wink: So I will gladly investigate this.

Super thanks for the video. Can you also spare a copy of the actual project in which the alien bug occurred? :wink:

Warning: comes from area 51

Graou74.zip (460.8 KB)

Ah Yes! That Xtra-File I requested. Thanks, man :wink:

I want to believe that I did everything that you did in your vid, @Graou74. But I got a different result…

However, I did do something that you might not have done, which you could also try:

  1. Go to your $GRADLE_USER_HOME/caches/modules-2/files-2.1/
  2. Delete all com.lingocoder... folders you find there
  3. Then try Run as Gradle Test again

Also, please upload your Eclipse error logs? While I check whatever I can find in those, you could in the meantime additionally try upgrading your version of Buildship — which should turn up in a search of the Eclipse Marketplace.

The only other thing that I can think of off the top of my head at the moment, is to:

  1. Navigate to Run - Run Configurations
  2. Check whether there is a Gradle Test - LibraryTest configuration
    • if there is one there, delete it and readd one manually
    • if there is NOT one there, add one manually
  3. Then try Run as Gradle Test again

Also, please let me know what happens when you do Run as JUnit Test?

I deleted all com.lingocoder files, updated Eclipse Buildship to Buildship 3.1.3.v20191117-2045, then I tried the test again and I have exactly the same behavior.
It does not change anything if I try to do a Gradle Test manually in Run Configurations.

Here is the Eclipse log:

!ENTRY org.eclipse.buildship.core 2 3 2019-12-03 14:20:52.962
!MESSAGE Launch Gradle tests failed due to an error connecting to the Gradle build.
!STACK 0
org.gradle.tooling.TestExecutionException: Could not execute tests using Gradle distribution ‘https://services.gradle.org/distributions/gradle-6.0.1-all.zip’.
at org.gradle.tooling.internal.consumer.ExceptionTransformer.transform(ExceptionTransformer.java:49)
at org.gradle.tooling.internal.consumer.ExceptionTransformer.transform(ExceptionTransformer.java:29)
at org.gradle.tooling.internal.consumer.ResultHandlerAdapter.onFailure(ResultHandlerAdapter.java:43)
at org.gradle.tooling.internal.consumer.async.DefaultAsyncConsumerActionExecutor$1$1.run(DefaultAsyncConsumerActionExecutor.java:62)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.base/java.lang.Thread.run(Thread.java:834)
at org.gradle.tooling.internal.consumer.BlockingResultHandler.getResult(BlockingResultHandler.java:46)
at org.gradle.tooling.internal.consumer.DefaultTestLauncher.run(DefaultTestLauncher.java:115)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.eclipse.buildship.core.internal.workspace.ConnectionAwareLauncherProxy.invokeRun(ConnectionAwareLauncherProxy.java:102)
at org.eclipse.buildship.core.internal.workspace.ConnectionAwareLauncherProxy.invoke(ConnectionAwareLauncherProxy.java:92)
at com.sun.proxy.$Proxy71.run(Unknown Source)
at org.eclipse.buildship.core.internal.launch.RunGradleJvmTestLaunchRequestJob$RunLaunchRequestJob.executeLaunch(RunGradleJvmTestLaunchRequestJob.java:128)
at org.eclipse.buildship.core.internal.launch.RunGradleJvmTestLaunchRequestJob$RunLaunchRequestJob.executeLaunch(RunGradleJvmTestLaunchRequestJob.java:89)
at org.eclipse.buildship.core.internal.launch.BaseLaunchRequestJob.executeLaunch(BaseLaunchRequestJob.java:66)
at org.eclipse.buildship.core.internal.launch.BaseLaunchRequestJob.runInToolingApi(BaseLaunchRequestJob.java:42)
at org.eclipse.buildship.core.internal.launch.BaseLaunchRequestJob.runInToolingApi(BaseLaunchRequestJob.java:34)
at org.eclipse.buildship.core.internal.operation.ToolingApiJob$1.runInToolingApi(ToolingApiJob.java:54)
at org.eclipse.buildship.core.internal.operation.DefaultToolingApiOperationManager$WorkspaceRunnableAdapter.run(DefaultToolingApiOperationManager.java:58)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2295)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2322)
at org.eclipse.buildship.core.internal.operation.DefaultToolingApiOperationManager.run(DefaultToolingApiOperationManager.java:39)
at org.eclipse.buildship.core.internal.operation.ToolingApiJob.run(ToolingApiJob.java:65)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.gradle.api.tasks.testing.TestExecutionException: No matching tests found in any candidate test task.
Requested tests:
Test class mr.jar.graou74.LibraryTest
at org.gradle.tooling.internal.provider.runner.TestExecutionResultEvaluator.evaluate(TestExecutionResultEvaluator.java:68)
at org.gradle.tooling.internal.provider.runner.TestExecutionRequestActionRunner.run(TestExecutionRequestActionRunner.java:52)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:63)
at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:39)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:51)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:45)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:50)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:78)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:47)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:31)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:42)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:28)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:78)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:52)
at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:59)
at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:36)
at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:68)
at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:38)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:37)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:26)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:60)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:48)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:32)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:68)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:27)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.base/java.lang.Thread.run(Thread.java:834)

The trace of what happens when I do a Run with JUnit Test:

Error occurred during initialization of boot layer
java.lang.module.FindException: Module javafx.graphics not found, required by myApplication