Launching HelloWorld sample on the --module-path

Started by Sormuras, February 21, 2019, 20:30:54

Previous topic - Next topic



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.



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, 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.

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:


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 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 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.