gradleintellij-ideajavafxmodule-path

IntellijIDEA + Gradle + JavaFX: java.lang.ClassNotFoundException for one "Run Configuration" but not the other


Intellij IDEA driving me nuts with bad behaviour:

I have one (Gradle-based) Project with two main classes written in Java, each in its own package.

Project View

Both use JavaFX so need some special "Run configuration".

HelloFX run configuration

ImageViewExample run configuration

The configuration is the same in both cases (It would be nice to not have to deal with a baroque complex set of textboxes and just have everything in an attribute-value text description, that one could copy-paste too, but I digress)

Everything works perfectly well for application "HelloFX" but for application "ImageViewExample", the message is that "Class 'pack2.ImageViewExample' not found in module 'JavaFXTrial.main'.

Something precludes Intellij IDEA (or rather, the Gradle runtime?) to discover the main class in one case, but not in the other case.

The compilation has definitely worked perfectly, after compilation:

JavaFxTrial/
├── build
│   ├── classes
│   │   └── java
│   │       └── main
│   │           ├── pack1
│   │           │   └── HelloFX.class
│   │           └── pack2
│   │               └── ImageViewExample.class
│   │
│   │

And I can launch the class from the command line, too.

So this works on the command line and in Intellij IDEA:

JAVA=/usr/local/java
IDEA_PROJECTS=$HOME/Development/idea_projects

$JAVA/jdk15_64_adopt/bin/java \
--module-path $JAVA/javafx/javafx-sdk-16/lib/ \
--add-modules javafx.controls \
-cp $IDEA_PROJECTS/JavaFxTrial/build/classes/java/main \
pack1.HelloFX

But this, which just calls the main of another class, does NOT work in Intellij IDEA:

JAVA=/usr/local/java
IDEA_PROJECTS=$HOME/Development/idea_projects

$JAVA/jdk15_64_adopt/bin/java \
--module-path $JAVA/javafx/javafx-sdk-16/lib/ \
--add-modules javafx.controls \
-cp $IDEA_PROJECTS/JavaFxTrial/build/classes/java/main \
pack2.ImageViewExample

Definitely missing something, but what?

Update:

When right-clicking "Run ImageViewExample.main()" (which means "Run via the Gradle plugin", I think) ("Run HelloFX.main()" results in success), one gets the message:

JavaFX runtime components are missing, and are required to run this application

which is not quite the same as "Class not Found".

Running "with info" then reveals that the command line that that the Gradle plugin runs to start "ImageViewExample" puts all the JavaFX jars cached by Gradle on the CLASSPATH instead of the module path, which evidently fails with

Error: JavaFX runtime components are missing, and are required to run this application

This may have something to do with it...

Update: but probably not.

Right-clicking Run just cobbles together a Run Configuration which is obviously wrong ... but which at least finds the main class.

Wrong Run Configuration

Update Update

Fixing the Run Configuration created by Intellij IDEA by adding the module path makes the "Run Configuration" work in spite of the fault "Run Configuration" and the new (now working) "Run Configuration" looking exactly alike on the surface.

That one works but it's the same

Update^3

Even when looking at .idea/workspace.xml of the Project the working and non-working run configurations are the same .. except that the non-working one is not marked as temporary

<component name="RunManager" selected="Application.ImageViewExampleB"> 

   <configuration name="HelloFX" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true"> 
     <option name="MAIN_CLASS_NAME" value="pack1.HelloFX" /> 
     <module name="JavaFxTrial.main" /> 
     <option name="VM_PARAMETERS" value="--module-path /usr/local/java/javafx/javafx-sdk-16/lib/ --add-modules javafx.controls " /> 
     <method v="2"> 
       <option name="Make" enabled="true" /> 
     </method> 
   </configuration> 
   
   <configuration name="ImageViewExample" type="Application" factoryName="Application"> 
     <option name="MAIN_CLASS_NAME" value="pack2.ImageViewExample " /> 
     <module name="JavaFxTrial.main" /> 
     <option name="VM_PARAMETERS" value="--module-path /usr/local/java/javafx/javafx-sdk-16/lib/ --add-modules javafx.controls" /> 
     <method v="2"> 
       <option name="Make" enabled="true" /> 
     </method> 
   </configuration> 
   
   <configuration name="ImageViewExampleB" type="Application" factoryName="Application" temporary="true"> 
     <option name="MAIN_CLASS_NAME" value="pack2.ImageViewExample" /> 
     <module name="JavaFxTrial.main" /> 
     <option name="VM_PARAMETERS" value="--module-path /usr/local/java/javafx/javafx-sdk-16/lib/ --add-modules javafx.controls" /> 
     <extension name="coverage"> 
       <pattern> 
         <option name="PATTERN" value="pack2.*" /> 
         <option name="ENABLED" value="true" /> 
       </pattern> 
     </extension> 
     <method v="2"> 
       <option name="Make" enabled="true" /> 
     </method> 
   </configuration> 
   
   <configuration name="JavaFxTrial" type="GradleRunConfiguration" factoryName="Gradle" temporary="true"> 
     <ExternalSystemSettings> 
       <option name="executionName" /> 
       <option name="externalProjectPath" value="$PROJECT_DIR$" /> 
       <option name="externalSystemIdString" value="GRADLE" /> 
       <option name="scriptParameters" value="--info" /> 
       <option name="taskDescriptions"> 
         <list /> 
       </option> 
       <option name="taskNames"> 
         <list /> 
       </option> 
       <option name="vmOptions" value="" /> 
     </ExternalSystemSettings> 
     <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess> 
     <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess> 
     <DebugAllEnabled>false</DebugAllEnabled> 
     <method v="2" /> 
   </configuration> 
   <list> 
     <item itemvalue="Application.ImageViewExample" /> 
     <item itemvalue="Application.HelloFX" /> 
     <item itemvalue="Application.ImageViewExampleB" /> 
     <item itemvalue="Gradle.JavaFxTrial" /> 
   </list> 
   <recent_temporary> 
     <list> 
       <item itemvalue="Application.ImageViewExampleB" /> 
       <item itemvalue="Gradle.JavaFxTrial" /> 
       <item itemvalue="Application.HelloFX" /> 
     </list> 
   </recent_temporary> 
</component>

Too many moving parts in this setup. Do not like.


Solution

  • All right.

    It turns out that the widget for Build and Run is whitespace sensitive...

    Which becomes obvious if one looks at the workspace.xml file

    <option name="MAIN_CLASS_NAME" value="pack2.ImageViewExample " /> 
    

    This is why XML should not be dismissed easily as config language.

    It's Whitespace Sensitive

    A telling sign, if you know what to look for:

    One can see the whitespace if one is primed for it

    Well, that was easy.

    Error report submitted to JetBrains.