[Solved] Using gradle to use local jme3 does not extract dlls

I have set up a gradle multi project. All subprojects are able to successfully pick the requested jme3 jars from where I pulled/forked jme3 (and built the jars using gradle). However, the application exits and gives the following error :

Exception in thread "main" java.lang.NoClassDefFoundError: org/lwjgl/opengl/GLDebugMessageARBCallback
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:292)
at com.jme3.system.JmeDesktopSystem.newContextLwjgl(JmeDesktopSystem.java:199)
at com.jme3.system.JmeDesktopSystem.newContext(JmeDesktopSystem.java:279)
at com.jme3.system.JmeSystem.newContext(JmeSystem.java:162)
at com.jme3.app.LegacyApplication.start(LegacyApplication.java:461)
at com.jme3.app.LegacyApplication.start(LegacyApplication.java:424)
at com.jme3.app.SimpleApplication.start(SimpleApplication.java:125)
at com.chevreuilgames.retroflashyrpg.noiseviewer.main.NoiseViewer_Main.main(NoiseViewer_Main.java:18)
Caused by: java.lang.ClassNotFoundException: org.lwjgl.opengl.GLDebugMessageARBCallback
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
... 9 more

And I know why : lwjgl3 is used as a dependency correctly, however it fails to use/extract its dlls. To test this out, I tried to use the local bullet-native jar. It didnā€™t extract its dll but the jar from the jcenter repository did extract a dll.

Now, some of you might say : ā€œWhat tells you that your local jme3 jars are actually used as dependenciesā€. My response to this is that, while I was programming my gradle set up, I made a mistake in my groovy code, which made the local jme3 jars not properly linked. What happens then is that all my code breaks. In other words, if my local jme3 jars werenā€™t actually used, the application couldnā€™t launch.

My application build.gradle (some parts of it). Sorry for the formatting, I canā€™t get it right on this forum. :

configure(subprojects.findAll { it.name != 'assets' }) {
dependencies {
    compile files(getJmeJar('core'))
    compile files(getJmeJar('lwjgl3'))
    compile group: 'com.sudoplay.joise', name: 'joise', version: '1.+'
}
}

configure(subprojects.findAll { it.name.contains('library') }) {
apply plugin: 'java-library'
}

configure(subprojects.findAll { it.name.contains('prototype') && !it.name.contains('library') }) {
dependencies {
    compile project(':prototype-library')
}
}

configure([project(':game'), project(':noiseviewer'), project(':prototype-flatshading'), project(':prototype-marchingcubes')]) {
apply plugin: 'application'

dependencies {
    compile files(getJmeJar('desktop'))
}
}

The getJmeJar method is what I told that is working. I also have an assert in this method just in case. Do you have an idea what I am doing wrong?

Thank you :slight_smile:

Rather than recreating your whole project environment locallyā€¦ perhaps you can provide the output of gradle dependencies?

Maybe something shows up there.

Whatā€™s this ā€œgetJmeJar()ā€ stuff about?

Why not use the standard mechanisms for resolving dependencies?

1 Like

Do you mean writing the whole path down? I just hate hard coding, especially when in the version.gradle file from jmonkeyengine project there are variables to defines the output name for the jar.

ext.getJmeJar = { String subprojectName ->
	File file = new File(jme.folder, "${jme.alias}-${subprojectName}/${jme.jarFolder}${jme.alias}-${subprojectName}-${jme.pomVersion}.jar")
	assert file.exists()
	return file
}

Iā€™m still setting up my project, so maybe I overdid it and Iā€™ll just remove that. Anyway, for now, thatā€™s not an urgent problem.

Hmmm Iā€™ll try to get an image from Intellij? Seriously, I just started using / learning gradle and Intellij. I was using Eclipse with maven before.

No. I mean specifying the dependency like normal instead of reading it from the disk with cludgy self-written code.

Why would you have to write the whole path down? Why get paths involved at all?

Because of this :cry: https://stackoverflow.com/questions/47819232/include-other-root-project-within-a-gradle-multi-project

I want to be able to modify the source code of jme3 and manage myself the version.

Open a command line.
Change into the directory of your project.
Type:
gradle dependencies
Post the output here.

I recommend spending a few minutes with the gradle documentation. Itā€™s tremendously useful.

But why are you trying to use JME as a subproject at all. Just depend on it like any of the other 100 jars your project will need.

Is the issue that you want to use some self-built version? Then just gradle install it so that it will be in your local maven repo.

These things have simple solutions. In fact, 95% of gradle learning is ā€œWow, this seems hard, there must be an easier wayā€¦ā€ and there is.

2 Likes

Hereā€™s the output for my executable subproject :

$ ./gradlew.bat :prototype-marchingcubes:dependencies
Full Version: 3.1-stable-custom
POM Version: 3.1.0-stable-custom
NBM Revision: 0
NBM UC Suffix: stable/3.1/plugins
:prototype-marchingcubes:dependencies

------------------------------------------------------------
Project :prototype-marchingcubes
------------------------------------------------------------

apiElements - API elements for main. (n)
No dependencies

archives - Configuration for archive artifacts.
No dependencies

compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
+--- com.sudoplay.joise:joise:1.+ -> 1.1.0
\--- project :prototype-library
	\--- com.sudoplay.joise:joise:1.+ -> 1.1.0

compileClasspath - Compile classpath for source set 'main'.
+--- com.sudoplay.joise:joise:1.+ -> 1.1.0
\--- project :prototype-library
	\--- com.sudoplay.joise:joise:1.+ -> 1.1.0

compileOnly - Compile only dependencies for source set 'main'.
No dependencies

default - Configuration for default artifacts.
+--- com.sudoplay.joise:joise:1.+ -> 1.1.0
\--- project :prototype-library
	\--- com.sudoplay.joise:joise:1.+ -> 1.1.0

implementation - Implementation only dependencies for source set 'main'. (n)
No dependencies

runtime - Runtime dependencies for source set 'main' (deprecated, use 'runtimeOnly ' instead).
+--- com.sudoplay.joise:joise:1.+ -> 1.1.0
\--- project :prototype-library
	\--- com.sudoplay.joise:joise:1.+ -> 1.1.0

runtimeClasspath - Runtime classpath of source set 'main'.
+--- com.sudoplay.joise:joise:1.+ -> 1.1.0
\--- project :prototype-library
	\--- com.sudoplay.joise:joise:1.+ -> 1.1.0

runtimeElements - Elements of runtime for main. (n)
No dependencies

runtimeOnly - Runtime only dependencies for source set 'main'. (n)
No dependencies

testCompile - Dependencies for source set 'test' (deprecated, use 'testImplementation ' instead).
+--- com.sudoplay.joise:joise:1.+ -> 1.1.0
+--- project :prototype-library
|    \--- com.sudoplay.joise:joise:1.+ -> 1.1.0
\--- junit:junit:4.+ -> 4.12
	\--- org.hamcrest:hamcrest-core:1.3

testCompileClasspath - Compile classpath for source set 'test'.
+--- com.sudoplay.joise:joise:1.+ -> 1.1.0
+--- project :prototype-library
|    \--- com.sudoplay.joise:joise:1.+ -> 1.1.0
\--- junit:junit:4.+ -> 4.12
	\--- org.hamcrest:hamcrest-core:1.3

testCompileOnly - Compile only dependencies for source set 'test'.
No dependencies

testImplementation - Implementation only dependencies for source set 'test'. (n)
No dependencies

testRuntime - Runtime dependencies for source set 'test' (deprecated, use 'testRuntimeOnly ' instead).
+--- com.sudoplay.joise:joise:1.+ -> 1.1.0
+--- project :prototype-library
|    \--- com.sudoplay.joise:joise:1.+ -> 1.1.0
\--- junit:junit:4.+ -> 4.12
	\--- org.hamcrest:hamcrest-core:1.3

testRuntimeClasspath - Runtime classpath of source set 'test'.
+--- com.sudoplay.joise:joise:1.+ -> 1.1.0
+--- project :prototype-library
|    \--- com.sudoplay.joise:joise:1.+ -> 1.1.0
\--- junit:junit:4.+ -> 4.12
	\--- org.hamcrest:hamcrest-core:1.3

testRuntimeOnly - Runtime only dependencies for source set 'test'. (n)
No dependencies

(*) - dependencies omitted (listed previously)

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

Wow Iā€™ll definitely use this command again :smile:

It seems that Lwgl3 is not actually ā€œcompiledā€ (more like linked), even jme3-core. However, if I remove the line

compile files(getJmeJar('core'))

Puts everything in red in Intellij because he cannot imports jme3 core.

Thatā€™s the best way to say it actually.

Wow I just didnā€™t know this was possible. Iā€™ll look into it thank you very much! I confirm that it works. For those who want more information : gradle docs

1 Like