Following the JavaFX IntelliJ modular with Gradle tutorial here, I downloaded the project from github and followed the instructions. When I do gradlew run, I get the error:
> Task :run FAILED
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: C:\Users\ANDREW-SL3\github\hellofx\build\classes\java\main
Caused by: java.lang.module.InvalidModuleDescriptorException: Package hellofx.org.openjfx not found in module
Since I made no modification to the project I assume I've done something else wrong but can't figure out what it is.
I have suffered the same problem. I think that it is related to a change in how latest Gradle versions (>= 6.4) treat modules. In my case this post helped me to solve it.
Basically, add this to your build.gradle file:
java {
modularity.inferModulePath.set(true)
}
application {
mainModule = 'hellofx' // name defined in module-info.java
mainClass = 'org.openjfx.MainApp'
}
run {
main = "$moduleName/org.openjfx.MainApp"
}
Related
Before we get started, here's some important Infos:
Main objective: create a jar executable of my project (with gradle modular project it is a pain)
I'm using gradle as dependency management
I have a modular project (using a single modular-info.java file)
The error message listed in the title is only retrieved after inserting the piece of code provided as the first code sample in this post. The reason for implementing this code is to fulfill a step to create a jar executable of my project.
Every time I run any gradle task (e.g. build, run, jpackage, etc), I get this error:
Error occurred during initialization of boot layer java.lang.module.FindException: Module projects not found
As you can see, I've set "projects" as my main module.
Judging by the error and based on some research, the most probable cause of the issue is that the compiler for some reason is not recognizing "projects" as my main module (but don't get fixed to that, it's just my guess). Here are a few pieces of code in which could be helpful:
mainClassName='projects.Main.Main'
jar {
manifest {
attributes "Main-Class": "$mainClassName"
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
application{
mainClassName("projects.Main.Main")
mainModule.set("projects")
applicationDefaultJvmArgs = [
// more than 20 JVM arguments listed here
]
}
Yes, my mainModule.set() has the same name as my module-info.java module name (which is "projects")
So, based on all of that, any thoughts on why I'm getting this error?
Thanks in advance!
P.S: this stackoverflow post might help, since it has a pic of my current modules and directories configuration
I am trying to allow my test classes to access the main classes (in a standard gradle setup). It was working fine until I put my main classes in a module (for JavaFX), at which point all tests stopped working. The main code runs fine.
If I understand correctly, according to this gradle documentation, doing nothing should run the tests normally, but I get an error:
org.gradle.api.internal.tasks.testing.TestSuiteExecutionException: Could not complete execution for Gradle Test Executor 1.
...
Caused by: java.lang.IllegalAccessError: class org.junit.platform.launcher.core.LauncherFactory (in unnamed module #0x50650eec) cannot access class org.junit.platform.commons.util.Preconditions (in module org.junit.platform.commons) because module org.junit.platform.commons does not export org.junit.platform.commons.util to unnamed module #0x50650eec
This happens if I use the intellij configuration, or run ./gradlew test.
So I attempted to fix the issue by patching the module-info, but then I get hundreds of errors like this one:
error: cannot find symbol
import snake.Snake
^
symbol: class Snake
location: package snake
Which IntelliJ explains with Package 'snake' is declared in module 'snakegame', which does not export it to module 'snakegame'. I'm guessing that it's referring to the original module-info.java which is defined in src/main/java, and the secondary module-info.java in src/test/java.
In the Gradle documentation it had a code snippet for adding the patch argument yourself in the build.gradle, however this just results in this error:
> java.lang.IllegalArgumentException: error: --patch-module specified more than once for module snakegame
The command which was actually executed looks like this:
compiler args for task compileTestJava: [--patch-module, snakegame=/project/path/snake/build/classes/java/main, --module-path, ... , --add-modules, org.junit.jupiter.api, --add-reads, snakegame=org.junit.jupiter.api, --patch-module, snakegame=/project/path/snake/src/test/java]
So it's patching two different modules, which I don't understand. It doesn't really matter to me how, I just need the classes to be runnable and have access to the main classes.
UPDATE:
So I recreated the project to try to create a minimal reproducible example and added in elements one at a time, and the problem didn't show up until I added in the gradle JavaFX plugin, at which point it stopped working.
So I started with the default structure, simply created a package called example with an Example.class, and created the same package in test, with a test class Example_Test.class with one test that creates an Example object. I then added an empty module-info in main. Original build.gradle:
plugins {
id 'java'
}
// default stuff
So at this point, everything is working fine. Then I change this to:
plugins {
id 'java'
id 'org.openjfx.javafxplugin' version '0.0.9'
}
And everything stops working
My preferred solution would be to use a test module-info.java or module-info.test, but I was not able to get this to work. I ended up simply ignoring modules for tests, which is a terrible workaround, but works for the moment. To ignore modules during testing, add this to the build.gradle:
plugins {
id 'java'
id 'org.openjfx.javafxplugin' version '0.0.9'
// other plugins
}
// other stuff
test {
useJUnitPlatform()
moduleOptions {
runOnClasspath = true
}
}
Set moduleOptions { runOnClasspath = true } in test
Useful links:
https://stackoverflow.com/a/58854685/12393574
https://github.com/junit-team/junit5/issues/2111#issuecomment-557925312
https://sormuras.github.io/blog/2018-09-11-testing-in-the-modular-world.html
https://stackoverflow.com/a/58990250/12393574
The JavaFX plugin adds the gradle-modules-plugin
I had an existing project without Gradle and needed to add com.google.code.gson:gson:+ library to work with JSON objects. To begin with I ran either gradle init or gradle build, I'm not sure. This caused my java classes with a main() not to run as the source path was wrong/changed. I have changed the structure following advice to at least get the classes to compile and run, but I still have this warning in run configurations "Warning: Class 'Main' not found in module 'src'" ;
If I set Use classpath of module to src.main, the warning goes away but when I run Main.main() Gradle seems to execute Gradle tasks, like this - this will run indefinitely;
Here is my project structure;
This is my build.gradle file;
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java project to get you started.
* For more details take a look at the Java Quickstart chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.3/userguide/tutorial_java_projects.html
*/
plugins {
// Apply the java plugin to add support for Java
id 'java'
// Apply the application plugin to add support for building a CLI application.
id 'application'
// idea plugin? // I added this to original build.gradle file
id 'idea'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
google()
}
dependencies {
// This dependency is used by the application.
implementation 'com.google.guava:guava:28.2-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// For use with JSONUtil class // I added this to original build.gradle file
compile 'com.google.code.gson:gson:+'
}
application {
// Define the main class for the application.
mainClassName = 'java.Main' // changed to 'Main' and I can `gradle run` seems to actually run Main.java
}
I have imported com.google.gson.JsonObject and com.google.gson.JsonParser from com.google.gson:gson:2.8.6 library, with no code inspection warnings, i.e available at compile time. If I run my code with a JsonObject jsonObject = new JsonObject I get the error;
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/JsonParser
at HttpUtils.getAccessToken(HttpUtils.java:80)
at Main.auth(Main.java:75)
at Main.play(Main.java:36)
at Main.main(Main.java:17)
Caused by: java.lang.ClassNotFoundException: com.google.gson.JsonParser
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 4 more
Line 80 of HttpUtils.java;
JsonObject jsonResponse = JsonParser.parseString(response.body()).getAsJsonObject(); // todo: status 200 "success" else failed
accessToken = jsonResponse.get("access_token").getAsString();
System.out.println(accessToken);
I understand this means that JVM can't compile a .class for JsonParser? I suppose this means the compiler has no knowledge of the library existing, which makes me suspect that Gradle isn't configured properly with the project, as it has downloaded the library, but not added a path to it?
I have tried gradle cleanIdea and then gradle idea. I have rebuilt the the project. I have "Mark directory as source root" on various directories for testing being careful to revert when it failed to change behaviour.
Edit;
I have added a package com.example in the src.main.Java directory and added the java files.
I edited run configuration for Main.java to
Main class: com.example.Main
Use classpath of module: src.main
I also changed the build.gradle file to;
application {
// Define the main class for the application.
mainClassName = 'com.example.Main'
}
Main runs but I am stuck at this point, which seems to run indefinitely;
Also, I am sure I right clicked on build.gradle and selected import, although I can't recreate this as the option isn't available now.
Edit 2;
I have been able to get the classes Main and Test with main() to run by putting them in the test/java/src package, and using unusual run configuration with warnings. Although on closer inspection, it seems to be running code that is previously compiled somewhere, as any changes I make aren't reflected in output.
Here is my project structure at the moment;
This is my run configuration that actually runs main in the standard output console, rather than a Gradle Task. It's clearly wrong, as Main is not in the com.example package or src.main module. If I set it correctly using module src.test and main class src.Main Gradle runs as screenshot 5.
Edit 3;
I see now that Gradle has took over responsibility to build and run the java files. I didn't know running in the output could be done with another CLI app and I admit it confused me, so please forgive anything above that seems stupid, I'm learning and figuring this out as I go.
I found in InteliJ settings Build, Execution, Deployment > Build Tools > Gradle I can change the Build and run using option between InteliJ IDEA and Gradle. The only issue I'm having with Gradle now I understand what is happening is Gradle doesn't seem to update my .class files when I run my main() with Gradle. Maybe this is for another question though.
mainClassName = 'java.Main' // changed to 'Main' and I can "gradle run" seems to actually run Main.java
This is not correct. Based on screenshot - you have not package named java (also I doubld that this is a valid name for a Java package). Create proper package inside src/main/java directory and specify it in the Main source file and in build.gradle file.
Also make sure you have imported build.gradle file in IDE, see Link a Gradle project to an IntelliJ IDEA project
I'm trying to develop a Gradle project which involves JavaFX.
Specs: Linux Mint 18.3, Java 11, Eclipse 2019-06, JavaFX: either 13 or 11...
A couple of useful answers to questions have helped me over the past hours: this one tells me (with useful clonable example) how to configure things, at least using a Java file to hold my project's main class (in fact I ultimately want to write all my code in Groovy ideally), in order to overcome the error "JavaFX runtime components are missing, and are required to run this application".
But Eclipse doesn't like it when you add the final step: the file module-info.java. At this point I have to confess I know nothing whatsoever about Eclipse "modules": only that this unknown aspect of the IDE has occasionally caused me frustrating headaches in the past. Probably time to read up on it now.
I should also clarify that at this point the Gradle tasks build and installdist (or assemble) work fine at the CLI. I am only concerned about getting rid of these horrid Eclipse white-cross-in-red-box error marks:
in module-info.java: "javafx.controls cannot be resolved to a module"
in Main.java: all the JavaFX classes have this next to them "Application [etc.] cannot be resolved to a type", and all the imports have "The type javafx.scene.Scene [etc.] is not accessible"
This answer says to download the JavaFX-JDK and then add various .jars from it to your project's module path. I did that: the horrid errors all disappeared!
Next time I did a Gradle - Refresh they all came back. I checked module path: all these .jar files had been removed. How can I stop the Gradle-Eclipse functionality messing with my configured module path?
edit
re the comment by Slaw: yes, already using
id 'org.openjfx.javafxplugin' version '0.0.8'
... my build.gradle javafx block looks like this:
javafx {
version = "13"
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
(NB I have now tried experimenting by adding 'javafx.graphics' and 'javafx.base' to the above.)
The issue is that Gradle - Refresh nevertheless causes the above "disappearing .jars" phenomenon.
I tried adding this to my plugins block:
id 'org.javamodularity.moduleplugin' version '1.6.0' apply true/false // NB tried both
... no go: Gradle - Refresh leads to an incomprehensible (to me) error:
An exception occurred applying plugin request [id: 'org.openjfx.javafxplugin', version: '0.0.8']
> Failed to apply plugin [id 'org.openjfx.javafxplugin']
> Could not create task ':configJavafxRun'.
> Could not create task of type 'ExecTask'.
> Could not generate a decorated class for class org.openjfx.gradle.tasks.ExecTask.
> org/javamodularity/moduleplugin/tasks/ModuleOptions
I'm building a NativeScript plugin and wrapping some functionality from a JAVA library. In most cases, I've seen users define a dependency with compile 'org.namespace:library:x.y.z' in src/platforms/android/include.gradle but in my case the library is not available in any JAVA repos and is a standalone .jar file.
I've tried some suggestions users have done with actual Android apps, but of course NativeScript is a little different and so far these methods aren't working.
Steps I've tried:
1) platforms/android/include.gradle
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
compile name: 'SimpleNetworking'
}
2) platforms/android/include.gradle
dependencies {
compile files('libs/SimpleNetworking.jar')
}
Both attempts have ended up failing when testing this on a NativeScript app requiring this plugin as a dependency:
FAILURE: Build failed with an exception.
* What went wrong:
Could not resolve all files for configuration
':app:debugCompileClasspath'.
> Could not find :SimpleNetworking:.
Required by:
project :app
The specific plugin I'm working to resolve can be found here.
Update
After reading this Android Studio Doc about build dependencies and changing the include.gradle file to look like:
dependencies {
implementation files('libs/SimpleNetworking.jar')
}
It seems to have found the file! What appears to be broken now is something else:
FAILURE: Build failed with an exception.
* What went wrong:
Could not resolve all files for configuration ':app:debugCompileClasspath'.
> Failed to transform file 'SimpleNetworking.jar' to match attributes {artifactType=processed-jar} using transform IdentityTransform
> Transform output file /Users/USERNAME/git/ons-testapp/platforms/android/app/libs/SimpleNetworking.jar does not exist.
I'm not sure if this is a related error or something new.
You will just have to place your JAR / AAR files inside platforms/android, your plugin will automatically pick it up during compilation.