Files
hytale-f2p-mirror/docs/FASTUTIL_CLASSLOADER_ISSUE.md
sanasol 66493d35ca Fix community link order: TG Group > TG Channel > Chat
Consistent order across all files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 01:11:17 +01:00

4.6 KiB

Singleplayer Server Crash: fastutil ClassNotFoundException

Status: Open (user-specific, Feb 24 2026)

Symptom

Singleplayer server crashes immediately after DualAuth Agent installs successfully:

Exception in thread "main" java.lang.NoClassDefFoundError: it/unimi/dsi/fastutil/objects/ObjectArrayList
    at com.hypixel.hytale.plugin.early.EarlyPluginLoader.<clinit>(EarlyPluginLoader.java:34)
    at com.hypixel.hytale.Main.main(Main.java:36)
Caused by: java.lang.ClassNotFoundException: it.unimi.dsi.fastutil.objects.ObjectArrayList
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)

Server exits with code 1. Multiplayer works fine for the same user.

Affected User

  • Discord: ヅ𝚃 JAYED !
  • Platform: Windows (standard x86_64, NOT ARM)
  • Reproduces 100% on singleplayer, every attempt
  • Other users (including macOS/Linux) are NOT affected

What Works

  • Java wrapper correctly strips -XX:+UseCompactObjectHeaders
  • Java wrapper correctly injects --disable-sentry
  • DualAuth Agent v1.1.12 installs successfully (STATIC mode)
  • Multiplayer connections work fine
  • Repair and reinstall did NOT fix the issue

Root Cause Analysis

fastutil (it.unimi.dsi.fastutil) should be bundled inside HytaleServer.jar (fat JAR). The ClassNotFoundException means the JVM's app classloader cannot find it despite it being in the JAR.

Ruled Out

  • Wrapper issue: Wrapper is working correctly (confirmed in logs)
  • UseCompactObjectHeaders: Server also has -XX:+IgnoreUnrecognizedVMOptions, so unrecognized flags don't crash it
  • DualAuth Agent: Works for all other users; agent installs successfully before the crash
  • Corrupted game files: Repair/reinstall didn't help
  • ARM64/Parallels: User is on standard Windows, not ARM

Likely Causes (user-specific)

  1. Antivirus interference — Windows Defender or third-party AV blocking Java from reading classes out of JAR files, especially with -javaagent active
  2. Corrupted/incompatible JRE — bundled JRE might be broken on their system
  3. File locking — another process holding HytaleServer.jar open

Debugging Steps (ask user)

  1. Does official Hytale singleplayer work? (without F2P launcher)

    • Yes → something about our launch setup
    • No → their system/JRE issue
  2. Check antivirus — add game directory to Windows Defender exclusions:

    • Settings → Windows Security → Virus & threat protection → Exclusions
    • Add their HytaleF2P install folder
  3. Verify fastutil is in the JAR:

    jar tf "D:\path\to\Server\HytaleServer.jar" | findstr fastutil
    
    • If output shows fastutil classes → JAR is fine, classloader issue
    • If no output → JAR is incomplete/corrupt (different from other users)
  4. Try without DualAuth agent — rename dualauth-agent.jar in Server/ folder, retry singleplayer

    • If works → agent's classloader manipulation breaks fastutil on their setup
    • If still fails → unrelated to agent
  5. Check JRE version — have them run:

    "D:\path\to\jre\latest\bin\java.exe" -version
    

Update (Feb 24): -XX:+UseCompactObjectHeaders stripping removed from defaults

Stripping this flag did NOT fix the issue. The server already has -XX:+IgnoreUnrecognizedVMOptions so unrecognized flags are harmless. The flag was removed from default stripFlags in backend/core/config.js.

Using the Java Wrapper to Strip JVM Flags

If a user needs to strip a specific JVM flag (e.g., for debugging or compatibility), they can do it via the launcher UI:

  1. Open Settings → scroll to Java Wrapper Configuration
  2. Under JVM Flags to Remove, type the flag (e.g. -XX:+UseCompactObjectHeaders) and click Add
  3. The flag will be stripped from all JVM invocations at launch time
  4. To inject custom arguments, use the Arguments to Inject section (with optional "Server Only" condition)
  5. Restore Defaults resets to empty strip flags + --disable-sentry (server only)

The wrapper generates platform-specific scripts at launch time:

  • Windows: java-wrapper.bat in jre/latest/bin/
  • macOS/Linux: java-wrapper shell script in the same directory

Config is stored in config.json under javaWrapperConfig:

{
  "javaWrapperConfig": {
    "stripFlags": ["-XX:+SomeFlag"],
    "injectArgs": [
      { "arg": "--some-arg", "condition": "server" },
      { "arg": "--other-arg", "condition": "always" }
    ]
  }
}
  • Java wrapper config: backend/core/config.js (stripFlags / injectArgs)
  • DualAuth Agent: v1.1.12, package ws.sanasol.dualauth
  • Game version at time of report: 2026.02.19-1a311a592