Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nasaworldwind/worldwindjava/llms.txt

Use this file to discover all available pages before exploring further.

WorldWind Java uses JOGL (the Java Binding for the OpenGL API) to create and manage OpenGL rendering contexts that integrate with Java’s AWT and Swing windowing toolkits. JOGL ships as a combination of portable Java JARs and platform-native shared libraries (.dll, .so, .dylib). By default, JOGL automatically extracts these native binaries from their containing JARs into the user’s temp directory at runtime. While convenient for development, this automatic extraction is blocked in certain managed or sandboxed environments, adds startup latency, and can collide with security policies that prohibit executing files from temp directories. This page explains the JOGL library structure, the default extraction mechanism, and the recommended approach for production deployments.

JOGL Overview

WorldWind Java uses JOGL v2.4, released on 7 March 2020. The JOGL distribution is checked into the WorldWind Java project root and distributed with all builds to ensure version compatibility (JOGL changes are occasionally unstable between minor versions). The distribution consists of two groups of JARs: API and runtime JARs (platform-independent, always required):
JARPurpose
jogl-all.jarJava bindings to OpenGL, GLU, GLUT, and related APIs
gluegen-rt.jarGlueGen runtime — native method dispatch layer used by JOGL
Native binary JARs (platform-specific, contain shared libraries): These JARs are JAR archives that embed the native shared libraries for their target platform. JOGL extracts these at runtime unless the alternative library-path loading strategy described below is used.

Native Binary JARs

The following native binary JARs are included in WorldWind Java and cover all supported platforms. 64-bit (amd64) and universal (macOS) variants are the ones most commonly deployed; i586 variants target 32-bit JVMs.
JARPlatformArchitecture
gluegen-rt-natives-linux-amd64.jarLinux64-bit x86
gluegen-rt-natives-linux-i586.jarLinux32-bit x86
gluegen-rt-natives-macosx-universal.jarmacOSUniversal (x86_64 + ARM)
gluegen-rt-natives-windows-amd64.jarWindows64-bit x86
gluegen-rt-natives-windows-i586.jarWindows32-bit x86
jogl-all-natives-linux-amd64.jarLinux64-bit x86
jogl-all-natives-linux-i586.jarLinux32-bit x86
jogl-all-natives-macosx-universal.jarmacOSUniversal (x86_64 + ARM)
jogl-all-natives-windows-amd64.jarWindows64-bit x86
jogl-all-natives-windows-i586.jarWindows32-bit x86
For a typical production deployment targeting a single architecture you only need two JARs: one gluegen-rt-natives-PLATFORM.jar and one jogl-all-natives-PLATFORM.jar. The i586 variants can be omitted if you only support 64-bit JVMs.

Default Runtime Extraction

When the native binary JARs are present on the classpath, JOGL automatically extracts the embedded shared libraries to a subdirectory of the OS temp directory (e.g. java.io.tmpdir/jogamp_<hash>/). This extraction happens once per unique JOGL version and is then reused on subsequent runs. This approach works in most development environments but has the following drawbacks in production:
  • Requires write access to the temp directory.
  • May be blocked by OS security policies (e.g. noexec mount on /tmp in hardened Linux environments).
  • Adds a brief startup delay on first run or after OS temp cleanup.
  • Can cause issues in environments where multiple applications share the same JVM temp directory.

Library Path Loading (Production)

To bypass temp-directory extraction entirely, you can extract the native binaries once and place them on the native library path. JOGL will then load them directly from that location. Follow these steps:
1

Extract native binaries from the JARs

For each platform-native JAR (gluegen-rt-natives-PLATFORM.jar and jogl-all-natives-PLATFORM.jar), extract the contained shared library files. Native libraries sit at the root of the JAR archive.
Extracting native libraries (Linux amd64 example)
mkdir -p ./native-libs
cd ./native-libs

jar xf ../gluegen-rt-natives-linux-amd64.jar
jar xf ../jogl-all-natives-linux-amd64.jar
After extraction you will have files such as:
  • libgluegen_rt.so (Linux), gluegen_rt.dll (Windows), libgluegen_rt.dylib (macOS)
  • libjogl_desktop.so (Linux), jogl_desktop.dll (Windows), libjogl_desktop.dylib (macOS)
  • Several additional libjogl_*.so/jogl_*.dll/libjogl_*.dylib files
2

Place native libraries on the library path

Copy the extracted native library files to either the application’s working directory or to a directory that is included in the platform-specific native library path variable. The working directory is the simplest option for self-contained deployments.
Copying to the application working directory
cp native-libs/*.so   /opt/myapp/         # Linux
cp native-libs/*.dll  C:\MyApp\           # Windows
cp native-libs/*.dylib /Applications/MyApp.app/Contents/MacOS/  # macOS
3

Remove native JARs from the classpath

Remove gluegen-rt-natives-PLATFORM.jar and jogl-all-natives-PLATFORM.jar from your application’s classpath. JOGL checks for native JARs before checking the library path. If the native JARs remain on the classpath, JOGL will still attempt to extract them to the temp directory and ignore the pre-placed libraries.Keep jogl-all.jar and gluegen-rt.jar on the classpath — only the *-natives-* JARs should be removed.
4

Add the JVM argument to disable temp JAR cache

Pass the following JVM argument when launching your application:
Disabling JOGL temp JAR cache
-Djogamp.gluegen.UseTempJarCache=false
Without this flag, JOGL’s GlueGen runtime may still attempt to use a JAR-based cache path even when the native JARs are absent from the classpath.
A complete launch command line looks like this:
Full launch command with library path loading
java \
  -Djogamp.gluegen.UseTempJarCache=false \
  -Djava.library.path=/opt/myapp \
  -cp jogl-all.jar:gluegen-rt.jar:worldwind.jar:myapp.jar \
  com.example.myapp.Main

Platform Library Path Variables

JOGL respects the standard Java native library path mechanism as well as OS-level environment variables. The table below summarises what to set on each platform:
PlatformVariableExample value
All (JVM)-Djava.library.path/opt/myapp or C:\MyApp
LinuxLD_LIBRARY_PATHexport LD_LIBRARY_PATH=/opt/myapp:$LD_LIBRARY_PATH
macOSDYLD_LIBRARY_PATHexport DYLD_LIBRARY_PATH=/Applications/MyApp.app/Contents/MacOS:$DYLD_LIBRARY_PATH
WindowsPATHset PATH=C:\MyApp;%PATH%
Add the native library directory to the PATH environment variable before launching the JVM, or use -Djava.library.path:
Windows — library path setup
set PATH=C:\MyApp\natives;%PATH%
java -Djogamp.gluegen.UseTempJarCache=false ^
     -cp jogl-all.jar;gluegen-rt.jar;worldwind.jar;myapp.jar ^
     com.example.myapp.Main
Alternatively, in a .bat launcher:
Windows — launcher.bat
@echo off
set APP_HOME=%~dp0
set PATH=%APP_HOME%natives;%PATH%
java -Djogamp.gluegen.UseTempJarCache=false ^
     -cp "%APP_HOME%jogl-all.jar;%APP_HOME%gluegen-rt.jar;%APP_HOME%worldwind.jar;%APP_HOME%myapp.jar" ^
     com.example.myapp.Main

Verifying JOGL Setup

Once the application starts, you can confirm that JOGL loaded correctly and that WorldWind has selected an appropriate OpenGL profile:
Verifying JOGL profile selection
import gov.nasa.worldwind.Configuration;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLProfile;

// Should return a fixed-function compatible profile (e.g. GL2 or GL4bc)
GLProfile profile = Configuration.getMaxCompatibleGLProfile();
System.out.println("Max compatible GL profile: " + profile.getName());

// Inspect the capabilities WorldWind will request
GLCapabilities caps = Configuration.getRequiredGLCapabilities();
System.out.println("Double buffered:  " + caps.getDoubleBuffered());
System.out.println("Depth bits:       " + caps.getDepthBits());
System.out.println("RGBA bits:        "
    + caps.getRedBits() + "/" + caps.getGreenBits()
    + "/" + caps.getBlueBits() + "/" + caps.getAlphaBits());
You can also inspect VBO availability through the scene controller’s GLRuntimeCapabilities after the first frame has rendered:
Checking VBO availability at runtime
import gov.nasa.worldwind.SceneController;

SceneController sc = wwd.getSceneController();
boolean vboEnabled = sc.getGLRuntimeCapabilities().isUseVertexBufferObject();
System.out.println("VBO enabled: " + vboEnabled);
GLRuntimeCapabilities.isUseVertexBufferObject() returns true when VBO usage is both supported by the driver and enabled via AVKey.VBO_USAGE in the configuration.

Troubleshooting

Symptom: The WorldWindowGLCanvas renders a black or blank frame, or the JVM throws UnsatisfiedLinkError: no jogl_desktop in java.library.path.Cause: The native JOGL libraries are not found. Either the native JARs were removed from the classpath but the extracted .so/.dll/.dylib files are not on the library path, or the graphics driver does not expose a compatible OpenGL profile.Resolution:
  1. Verify the native library directory is listed in -Djava.library.path or the OS library path variable.
  2. Update your graphics card driver to the latest version from the manufacturer’s website (NVIDIA, AMD/ATI, or Intel). On Windows, use Device Manager → Display Adapters → Update Driver. On Linux, use the distribution’s package manager or the official .run installer.
  3. Confirm you are using the correct architecture variant (amd64 vs. i586) for your JVM bitness.
Symptom: A com.jogamp.opengl.GLException is thrown with a message about the OpenGL context or AWT event thread.Cause: On macOS, JOGL requires all OpenGL operations to run on the AWT Event Dispatch Thread (EDT). WorldWind respects this constraint internally, but if you construct WorldWindowGLCanvas or call any GL-bound method from a non-EDT thread (e.g. from main() directly), JOGL will throw.Resolution: Always construct and interact with WorldWind UI components from the EDT:
Constructing WorldWindow on the EDT
SwingUtilities.invokeLater(() -> {
    WorldWindowGLCanvas wwd = new WorldWindowGLCanvas();
    // ... configure and add to a JFrame
});
Symptom: You have extracted the native JARs and placed the files on the library path, but UnsatisfiedLinkError persists.Cause: Either the native binary JARs are still on the classpath (JOGL will try them first), or the -Djogamp.gluegen.UseTempJarCache=false JVM flag is missing.Resolution:
  1. Confirm that none of gluegen-rt-natives-*.jar or jogl-all-natives-*.jar appear in the JVM classpath.
  2. Confirm that -Djogamp.gluegen.UseTempJarCache=false is present in the JVM arguments.
  3. Print System.getProperty("java.library.path") at startup and verify the directory containing the extracted libraries is listed.
  4. On Linux, run ldd libjogl_desktop.so from the native library directory to check that all shared library dependencies are satisfied.
Symptom: Frame rates are extremely low (single digits), or Configuration.getMaxCompatibleGLProfile() returns GL2 but rendering appears to use software fallback.Cause: The JVM may have selected a software OpenGL renderer (e.g. Mesa’s llvmpipe on Linux, or Microsoft’s software OpenGL on Windows).Resolution:
  1. Verify that VBO usage is active at runtime using sc.getGLRuntimeCapabilities().isUseVertexBufferObject(). If it returns false even when AVKey.VBO_USAGE is true in configuration, the driver may not support VBOs — update drivers.
  2. On Linux, ensure the hardware GL driver is installed (libGL.so should point to the hardware driver, not libGL.so.1 → /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1).
  3. On Windows, check Device Manager for any “Microsoft Basic Display Adapter” entries — these indicate Windows is using the software fallback because the hardware driver is not installed.
  4. Confirm AVKey.VBO_USAGE is set to true (this is the default in worldwind.xml).

Build docs developers (and LLMs) love