# 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.(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**: ```cmd 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: ```cmd "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`: ```json { "javaWrapperConfig": { "stripFlags": ["-XX:+SomeFlag"], "injectArgs": [ { "arg": "--some-arg", "condition": "server" }, { "arg": "--other-arg", "condition": "always" } ] } } ``` ## Related - 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`