How Do I Fix a JSON Error After Compiling My LibGDX Java Game

When working with LibGDX, everything might seem smooth during development until you export your game as a .jar file.

That’s exactly what happened to me. My small Java game ran flawlessly inside Eclipse, but when I compiled it and ran the .jar, it crashed with a runtime error:

The Error

Error reading file: ui/menuSkin.json

Stack trace:

com.badlogic.gdx.scenes.scene2d.ui.Skin.load(Skin.java:96)
com.badlogic.gdx.scenes.scene2d.ui.Skin.<init>(Skin.java:81)
com.castell.randomcastle.screens.BasicsScreen.show(BasicsScreen.java:105)

And the culprit

skin = new Skin(Gdx.files.internal("ui/menuSkin.json"), new TextureAtlas("ui/atlas.pack"))

What Caused the Error

After a few hours of debugging, I learned something important:

The issue wasn’t the content of the JSON file it was that the file couldn’t be found in the compiled .jar.

LibGDX uses Gdx.files.internal() to reference files located in the assets/ folder of the core project. In Eclipse, this works seamlessly because assets are linked properly at runtime.

But in a compiled .jar:

If the assets folder isn’t properly included, the game can’t find your files and crashes.

How to Fix It

Make sure:

  • Your assets/ directory is in the right place (core/assets/)
  • It is explicitly included in your .jar export

Using Gradle

If you’re using Gradle, this is the cleanest solution.

Add this line to your desktop/build.gradle:

sourceSets.main.resources.srcDirs += [rootProject.file("core/assets").path]

Rebuild with Gradle:

./gradlew desktop:dist

Your .jar file in desktop/build/libs should now include the assets/ folder and all necessary files.

Adding Robustness

To improve the code, let’s make it more resilient:

  • Catch asset-loading errors
  • Log missing files clearly
  • Use a fallback skin when possible
public class BasicsScreen extends ScreenAdapter {
private Skin skin;

@Override
public void show() {
try {
FileHandle skinFile = Gdx.files.internal("ui/menuSkin.json");
FileHandle atlasFile = Gdx.files.internal("ui/atlas.pack");

if (!skinFile.exists() || !atlasFile.exists()) {
throw new GdxRuntimeException("Required UI files not found.");
}

skin = new Skin(skinFile, new TextureAtlas(atlasFile));

} catch (Exception e) {
Gdx.app.error("SkinLoading", "Failed to load UI skin: " + e.getMessage(), e);

// Attempt fallback
try {
Gdx.app.log("SkinLoading", "Loading fallback skin.");
skin = new Skin(Gdx.files.internal("defaultSkin/uiskin.json")); // Ensure this file exists
} catch (Exception fallbackError) {
Gdx.app.error("SkinLoading", "Fallback skin also failed!", fallbackError);
}
}
}
}

Why This Practice Matter

Improves debugging clarity
Prevents game-breaking crashes
Prepares your game for real-world deployment
Builds habits around defensive programming

Final Thought

If your game runs perfectly in your IDE but crashes as a compiled .jar, the root cause is usually missing or misconfigured assets. Often, it’s either an incorrect file path or the asset wasn’t bundled during the export. To avoid these headaches, make sure your build process (especially with Gradle) is set up to include all required resources. Always test your compiled builds, and add fallback logic for missing files to make your game more robust.

Related blog posts