Hi LWJGL,
glad to see that this account still exists. Long time no see. :)
[LWJGL] Failed to load a library. Possible solutions:
a) Add the directory that contains the shared library to -Djava.library.path or -Dorg.lwjgl.librarypath.
b) Add the JAR that contains the shared library to the classpath.
Would it be possible to either scan the module-path in addition to the class-path or even better look for the resolved org.lwjgl module and examine the location of the JAR via the Module API.
Happy to provide a PR.
Cheers!
After adding a --class-path option manually, everything works like a charm:
java --class-path lwjgl-natives-windows.jar:lwjgl-glfw-natives-windows.jar:lwjgl-opengl-natives-windows.jar --module-path bin\compiled\main;modules --module demo/demo.HelloWorld
Hello LWJGL 3.2.1 build 12!
<red squared window opens>
By default, modules in the module-path that are not explicitly required are not loaded. The correct fix, that avoids using --class-path, is to add requires statements for the LWJGL natives in the application's module-info.java, for example:
requires org.lwjgl.natives;
requires org.lwjgl.glfw.natives;
requires org.lwjgl.opengl.natives;
Note that org.lwjgl.natives transitively requires org.lwjgl, so you don't need to specify requires statements for both.
Alternatively, you could use --add-modules ALL-MODULE-PATH to force loading of all modules present in the module path, even if they are not explicitly required by your application.
I missed the compiled module descriptor in `lwjgl-natives-${OS}.jar` files yesterday, because I didn't look deeper into the JAR after seeing the native libraries in the root directory in each one.
Having
module org.lwjgl.natives {
requires transitive org.lwjgl;
}
declared as a MRJAR is 8)
Thanks for the pointers.
The various lwjgl-xyz-natives-${OS}.jar files aren't uploaded to Maven Central, are they? My "Java module name scanner observing Maven Central" didn't catch any: https://github.com/jodastephen/jpms-module-names/blob/ee1e2f5c58ed9e8040e3bfab641aa34b4a513271/generated/module-version.properties#L2752-L2788
They are available on Maven Central. We use classifiers to differentiate the native artifacts, maybe that's why jpms-module-names isn't detecting them. For example, the core module would be declared in Gradle as:
dependencies {
implementation "org.lwjgl:lwjgl:3.2.2-SNAPSHOT"
runtimeOnly "org.lwjgl:lwjgl:3.2.2-SNAPSHOT:natives-windows"
}
LWJGL provides a lot of modules and the above can become tedious, so we've created the build customizer (https://www.lwjgl.org/customize) tool on the website. It generates the appropriate Maven/Gradle/Ivy scripts for you.
> They are available on Maven Central. We use classifiers to differentiate the native artifacts, maybe that's why jpms-module-names isn't detecting them.
Either this, or the https://github.com/sandermak/modulescanner doesn't generate entries for classified artifacts. Have to check both ends. Thanks for the explanation!
One more related question: what would such a configuration look like, if I want my modular application to be platform-agnostic?
requires org.lwjgl.natives; // pointing to a "merged" MJAR containing all native binaries for Linux, MacOS and Windows?
Quote from: Sormuras on February 22, 2019, 07:58:53if I want my modular application to be platform-agnostic?
The module descriptor in the natives jar is the same for all platforms. You simply add e.g. requires org.lwjgl.natives in your module-info, without specifying a platform.
Note that this means you can't have the same natives jar for multiple platforms in your module path, you'd get a conflict. So, when you select multiple platforms in the build customizer, it will generate a script that uses a variable for the natives classifier. The same script will work across platforms and only a single natives jar (per module) will be downloaded when you build.