mirror of
https://git.sanhost.net/sanasol/hytale-f2p
synced 2026-02-27 14:31:47 -03:00
Fix JRE flatten failing silently on Windows EPERM
When extracting the bundled JRE, flattenJREDir renames files from the nested jdk subdirectory up one level. On Windows this fails with EPERM when antivirus or file indexing holds handles open, leaving the JRE nested and unfindable — causing "Server failed to boot". - Fall back to copy+delete when rename gets EPERM/EACCES/EBUSY - getBundledJavaPath checks nested JRE subdirs as last resort
This commit is contained in:
@@ -106,6 +106,23 @@ function getBundledJavaPath(jreDir = JRE_DIR) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback: check for nested JRE directory (e.g. jdk-25.0.2+10-jre/bin/java)
|
||||||
|
// This happens when flattenJREDir fails due to EPERM/EACCES on Windows
|
||||||
|
try {
|
||||||
|
if (fs.existsSync(jreDir)) {
|
||||||
|
const entries = fs.readdirSync(jreDir, { withFileTypes: true });
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.isDirectory() && entry.name !== 'bin' && entry.name !== 'lib') {
|
||||||
|
const nestedCandidate = path.join(jreDir, entry.name, 'bin', JAVA_EXECUTABLE);
|
||||||
|
if (fs.existsSync(nestedCandidate)) {
|
||||||
|
console.log(`[JRE] Using nested Java path: ${nestedCandidate}`);
|
||||||
|
return nestedCandidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) { /* ignore */ }
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,12 +437,48 @@ function flattenJREDir(jreLatest) {
|
|||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const oldPath = path.join(nested, file.name);
|
const oldPath = path.join(nested, file.name);
|
||||||
const newPath = path.join(jreLatest, file.name);
|
const newPath = path.join(jreLatest, file.name);
|
||||||
|
try {
|
||||||
fs.renameSync(oldPath, newPath);
|
fs.renameSync(oldPath, newPath);
|
||||||
|
} catch (renameErr) {
|
||||||
|
if (renameErr.code === 'EPERM' || renameErr.code === 'EACCES' || renameErr.code === 'EBUSY') {
|
||||||
|
console.log(`[JRE] Rename failed for ${file.name} (${renameErr.code}), using copy fallback`);
|
||||||
|
copyRecursiveSync(oldPath, newPath);
|
||||||
|
} else {
|
||||||
|
throw renameErr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
fs.rmSync(nested, { recursive: true, force: true });
|
fs.rmSync(nested, { recursive: true, force: true });
|
||||||
|
} catch (rmErr) {
|
||||||
|
console.log('[JRE] Could not remove nested JRE dir (non-critical):', rmErr.message);
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Notice: could not restructure Java directory:', err.message);
|
console.error('[JRE] Failed to restructure Java directory:', err.message);
|
||||||
|
// Last resort: check if java exists in a nested subdir and skip flatten
|
||||||
|
try {
|
||||||
|
const entries = fs.readdirSync(jreLatest, { withFileTypes: true });
|
||||||
|
const nestedDir = entries.find(e => e.isDirectory() && e.name !== 'bin' && e.name !== 'lib');
|
||||||
|
if (nestedDir) {
|
||||||
|
const nestedBin = path.join(jreLatest, nestedDir.name, 'bin', process.platform === 'win32' ? 'java.exe' : 'java');
|
||||||
|
if (fs.existsSync(nestedBin)) {
|
||||||
|
console.log(`[JRE] Java found in nested dir: ${nestedDir.name}, leaving structure as-is`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) { /* ignore */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyRecursiveSync(src, dest) {
|
||||||
|
const stat = fs.statSync(src);
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
fs.mkdirSync(dest, { recursive: true });
|
||||||
|
for (const child of fs.readdirSync(src)) {
|
||||||
|
copyRecursiveSync(path.join(src, child), path.join(dest, child));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fs.copyFileSync(src, dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user