Compare commits

...

1 Commits

Author SHA1 Message Date
sanasol
ee53911a06 Revert debug builds, update fastutil issue docs
Agent and -Xshare:off both ruled out as causes.
Restored normal agent injection. Updated docs with
complete findings — issue remains unsolved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:15:01 +01:00
2 changed files with 44 additions and 84 deletions

View File

@@ -482,11 +482,15 @@ async function launchGame(playerNameOverride = null, progressCallback, javaPathO
}
}
// DualAuth Agent: DISABLED for debug - testing fastutil classloader issue
// TODO: re-enable after testing
// DualAuth Agent: Set JAVA_TOOL_OPTIONS so java picks up -javaagent: flag
// This enables runtime auth patching without modifying the server JAR
const agentJar = path.join(gameLatest, 'Server', 'dualauth-agent.jar');
if (fs.existsSync(agentJar)) {
console.log('DualAuth Agent: SKIPPED (debug build - fastutil classloader test)');
const agentFlag = `-javaagent:"${agentJar}"`;
env.JAVA_TOOL_OPTIONS = env.JAVA_TOOL_OPTIONS
? `${env.JAVA_TOOL_OPTIONS} ${agentFlag}`
: agentFlag;
console.log('DualAuth Agent: enabled via JAVA_TOOL_OPTIONS');
}
try {

View File

@@ -1,10 +1,10 @@
# Singleplayer Server Crash: fastutil ClassNotFoundException
## Status: Open (multiple users, Feb 24-27 2026)
## Status: Open — NO SOLUTION (Feb 24-27 2026)
## Symptom
Singleplayer server crashes immediately after DualAuth Agent installs successfully:
Singleplayer server crashes immediately on boot:
```
Exception in thread "main" java.lang.NoClassDefFoundError: it/unimi/dsi/fastutil/objects/ObjectArrayList
@@ -25,99 +25,55 @@ Server exits with code 1. Multiplayer works fine for the same user.
- Multiplayer works fine for both users
- macOS/Linux users are NOT affected
## What Works
## Ruled Out (confirmed via debug builds)
- 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
| Suspect | Tested | Result |
|---------|--------|--------|
| **DualAuth Agent** | Debug build with agent completely disabled (`debug-no-agent` tag) | **Same crash.** Agent is innocent. |
| **`-Xshare:off` (CDS)** | Added to `JAVA_TOOL_OPTIONS` in launcher code (`debug-xshare-off` tag) | **Did not help.** CDS is not the cause. |
| **`-XX:+UseCompactObjectHeaders`** | Stripped via wrapper | **Did not help.** Server has `-XX:+IgnoreUnrecognizedVMOptions` anyway. |
| **Corrupted game files** | User did repair + full reinstall | **Same crash.** |
| **Java wrapper** | Logs confirm wrapper works correctly | Not the cause. |
| **ARM64/Parallels** | User is on standard Windows x86_64 | Not applicable. |
| **AOT cache** | Asentrix has no AOT errors (JAYED did), both crash the same way | Not the root cause. |
## Root Cause Analysis
## What We Know
`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.
- `fastutil` is bundled inside `HytaleServer.jar` (fat/shaded JAR) — same JAR for all users
- JVM's `BuiltinClassLoader` cannot find `it.unimi.dsi.fastutil.objects.ObjectArrayList` despite it being in the JAR
- Crash happens at `EarlyPluginLoader` static initializer (line 34) which imports `ObjectArrayList`
- The bundled JRE is identical for all users (downloaded by launcher)
- The issue is **not** caused by anything the F2P launcher adds — it's the vanilla server JVM failing to load its own classes
### Ruled Out
## Remaining Theories
- **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
1. **Antivirus/security software** — Windows Defender or third-party AV intercepting JAR file reads. Real-time scanning + fat JAR = known conflict. **Untested** — user should try disabling AV temporarily.
2. **Windows Insider build** — Asentrix is on NT 10.0.26200.0 (Windows 11 Dev/Insider). Bleeding-edge Windows may have JVM compatibility issues.
3. **File locking** — Stalled `java.exe` processes holding `HytaleServer.jar` open (Asentrix had stalled processes killed at every launch).
4. **Corrupted JRE on disk** — Despite being the same download, filesystem or AV may have corrupted specific JRE files on their system.
### Likely Cause
## Next Steps to Try
**CDS (Class Data Sharing) broken by bootstrap classloader modification.** DualAuth agent calls `appendToBootstrapClassLoaderSearch()` which triggers JVM warning: `"Sharing is only supported for boot loader classes because bootstrap classpath has been appended"`. This disables AppCDS for application classes. On some Windows systems, this breaks the classloader's ability to find classes (including fastutil) from the fat JAR.
This warning appears for ALL users, but only breaks classloading on some Windows systems — reason unknown.
### Other Possible Causes
1. **Antivirus interference** — AV blocking Java from reading classes out of JAR files
2. **File locking** — another process holding HytaleServer.jar open (Asentrix had stalled java.exe killed at launch)
## Potential Fix: `-Xshare:off` (testing Feb 27)
Disables CDS entirely, forcing standard classloading. User can add via launcher:
1. **Settings****Java Wrapper Configuration****Arguments to Inject**
2. Add `-Xshare:off` with **Server Only** condition
3. Retry singleplayer
Sent to affected users for testing — **awaiting results**.
If confirmed, should be added as default inject arg (server-only) in launcher config.
## Debugging Steps (for reference)
Most steps are impractical for F2P users:
- ~~Official Hytale singleplayer~~ — F2P users don't have official access
- ~~Try without DualAuth agent~~ — not possible, agent required for F2P token validation
- ~~Verify fastutil in JAR~~ — same JAR for all users, not a user-actionable step
- ~~Check JRE version~~ — bundled with launcher, same for all users
**Practical steps:**
1. **Add `-Xshare:off`** via wrapper inject args (server-only) — testing now
2. **Check antivirus** — add game directory to Windows Defender exclusions
3. **Check for stalled processes** — kill any leftover java.exe/HytaleServer before launch
1. **Disable Windows Defender** temporarily — the only quick test left
2. **Delete bundled JRE** and let launcher re-download — rules out local JRE corruption
3. **Ask if official Hytale singleplayer works** — if it also crashes, it's their system (but F2P users may not have access)
## Update History
### 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`.
### Feb 24: First report (JAYED)
User reported singleplayer crash. Initial investigation found AOT cache errors + fastutil ClassNotFoundException. Stripping `-XX:+UseCompactObjectHeaders` did not help.
### Feb 27: Second user (Asentrix) reported, `-Xshare:off` sent for testing
Asentrix hit the same crash on Launcher v2.4.4. Unlike JAYED, no AOT cache errors — just the CDS sharing warning followed by fastutil ClassNotFoundException. This confirms the issue is not AOT-specific but related to CDS/classloader interaction with the DualAuth agent's bootstrap CL modification. Sent `-Xshare:off` workaround to affected users — awaiting results.
## 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" }
]
}
}
```
### Feb 27: Second report (Asentrix), extensive debugging
- Asentrix hit same crash, no AOT errors — ruled out AOT as root cause
- Built `debug-xshare-off`: added `-Xshare:off` to `JAVA_TOOL_OPTIONS`**did not help**
- Built `debug-no-agent`: completely disabled DualAuth agent — **same crash**
- **Conclusion**: Neither the agent nor CDS is the cause. The JVM itself cannot load classes from the fat JAR on these specific Windows systems.
- Note: wrapper `injectArgs` append AFTER `-jar`, so they cannot inject JVM flags — only `JAVA_TOOL_OPTIONS` works for JVM flags
## Related
- Java wrapper config: `backend/core/config.js` (stripFlags / injectArgs)
- DualAuth Agent: v1.1.12, package `ws.sanasol.dualauth`
- Game version at time of reports: `2026.02.19-1a311a592`
- Log submission ID (Asentrix): `c88e7b71`
- Debug tags: `debug-xshare-off`, `debug-no-agent`
- Log submission IDs: `c88e7b71` (Asentrix initial), `0445e4dc` (xshare test), `748dceeb` (no-agent test)