Libgdx 1.12.0 LWJGL3 Migration: Dual‑Backend Support for Desktop Targets?
0 reputation · 25 Dec 2022, 18:12 UTC
0 reputation · 25 Dec 2022, 18:12 UTC
Upgrade a legacy Libgdx 1.11.x project to 1.12.0 while retaining the ability to run on the old LWJGL2 backend for legacy desktop users and the new LWJGL3 backend for modern builds.
lwjgl3Natives configuration and platform‑specific classifiers (natives‑windows, natives‑linux, natives‑macos).gdx-backend-lwjgl3 artifact cannot coexist with gdx-backend-lwjgl in the same Gradle source set due to overlapping package names and classpath conflicts.UnsatisfiedLinkError.Is there a supported configuration or plugin that allows a single project to compile and run both LWJGL2 and LWJGL3 desktop backends, selecting the appropriate native libraries at runtime without manual reconfiguration?
LwjglApplicationConfiguration and Lwjgl3ApplicationConfiguration within the same binary?33275 reputation · 25 Dec 2022, 19:46 UTC
There is no officially supported Gradle configuration or Libgdx plugin that lets a single JAR contain both gdx-backend-lwjgl (LWJGL2) and gdx-backend-lwjgl3 (LWJGL3) without class‑path clashes. The two backends share package names (e.g. com.badlogic.gdx.backends.lwjgl) and their native libraries are incompatible, so the JVM will load the wrong classes or fail with UnsatisfiedLinkError if both are present.
core – contains all shared Libgdx core code.desktop-lwjgl – depends on gdx-backend-lwjgl and the legacy lwjgl natives.desktop-lwjgl3 – depends on gdx-backend-lwjgl3 and the lwjgl3Natives configuration.// desktop-lwjgl/build.gradle
plugins { id 'java' }
repositories { mavenCentral() }
dependencies {
implementation project(':core')
implementation 'com.badlogicgames.gdx:gdx-backend-lwjgl:1.12.0'
runtimeOnly 'com.badlogicgames.gdx:gdx-backend-lwjgl:natives-windows' // adjust for OS
}
application {
mainClass = 'com.example.MyGame'
}
// desktop-lwjgl3/build.gradle
plugins { id 'java' }
repositories { mavenCentral() }
dependencies {
implementation project(':core')
implementation 'com.badlogicgames.gdx:gdx-backend-lwjgl3:1.12.0'
runtimeOnly 'com.badlogicgames.gdx:gdx-backend-lwjgl3:natives-windows' // adjust for OS
}
application {
mainClass = 'com.example.MyGame'
}
./gradlew desktop-lwjgl:run./gradlew desktop-lwjgl3:runLauncher that reads a system property (e.g., -Dbackend=lwjgl3) and uses reflection to instantiate either LwjglApplication or Lwjgl3Application.
-Djava.library.path at runtime; you can do this by launching with a classpath that contains only the chosen desktop module.
UnsatisfiedLinkError.
lwjgl3Natives classifier for LWJGL3 builds and the legacy lwjgl natives for LWJGL2 builds.
With the multi‑module layout you keep the core code in one place, avoid class‑path conflicts, and can still publish two separate desktop binaries: one for legacy Windows users and one for modern systems. If you truly require a single binary that decides at runtime, you must implement a custom launcher and classloader, which is complex and not recommended for most projects.
Do you need to deliver a single executable that supports both backends, or are separate legacy and modern desktop builds acceptable for your release process?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.