feat(CodeSourceLocationResolver): implement utility for resolving code source paths and update resource handling

This commit is contained in:
extio-de
2026-07-06 23:15:19 +02:00
parent 35892b4898
commit fe53e90f0f
4 changed files with 56 additions and 34 deletions

View File

@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>de.extio</groupId> <groupId>de.extio</groupId>
<artifactId>game-engine</artifactId> <artifactId>game-engine</artifactId>
<version>1.0.25</version> <version>1.0.26</version>
<properties> <properties>
<java.version>25</java.version> <java.version>25</java.version>

View File

@@ -2,7 +2,6 @@ package de.extio.game_engine.resource;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@@ -14,7 +13,7 @@ import java.util.stream.Stream;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import de.extio.game_engine.storage.StorageServiceImpl; import de.extio.game_engine.util.CodeSourceLocationResolver;
import de.extio.game_engine.util.ObjectSerialization; import de.extio.game_engine.util.ObjectSerialization;
public class StaticResourceServiceImpl implements StaticResourceService { public class StaticResourceServiceImpl implements StaticResourceService {
@@ -27,23 +26,13 @@ public class StaticResourceServiceImpl implements StaticResourceService {
String location = System.getProperty("datalocation"); String location = System.getProperty("datalocation");
if (location == null) { if (location == null) {
try { try {
final URL url = StorageServiceImpl.class.getProtectionDomain().getCodeSource().getLocation(); final var url = StaticResourceServiceImpl.class.getProtectionDomain().getCodeSource().getLocation();
LOGGER.info("Code source location: {}", url); LOGGER.info("Code source location: {}", url);
Path parent; final var codeSourcePath = CodeSourceLocationResolver.resolvePath(StaticResourceServiceImpl.class);
if (url.toString().startsWith("jar:nested:")) { final var parent = codeSourcePath.getParent();
if (Objects.requireNonNullElse(System.getProperty("os.name"), "").toLowerCase().contains("windows")) { final Path jarPath = parent != null ? parent.toAbsolutePath().normalize() : codeSourcePath;
parent = Paths.get(url.toString().substring("jar:nested:/".length(), url.toString().indexOf("/!"))).getParent();
}
else {
parent = Paths.get(url.toString().substring("jar:nested:".length(), url.toString().indexOf("/!"))).getParent();
}
}
else {
parent = Paths.get(url.toURI()).getParent();
}
final Path jarPath = parent != null ? parent.toAbsolutePath().normalize() : Paths.get(url.toURI()).toAbsolutePath().normalize();
final String currentSubDir = jarPath.getFileName().toString(); final String currentSubDir = jarPath.getFileName() != null ? jarPath.getFileName().toString() : "";
if ("bin".equals(currentSubDir) || "target".equals(currentSubDir)) { if ("bin".equals(currentSubDir) || "target".equals(currentSubDir)) {
location = jarPath.getParent().resolve("data").toString(); location = jarPath.getParent().resolve("data").toString();
} }

View File

@@ -3,7 +3,6 @@ package de.extio.game_engine.storage;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@@ -16,6 +15,7 @@ import java.util.UUID;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import de.extio.game_engine.util.CodeSourceLocationResolver;
import de.extio.game_engine.util.ObjectSerialization; import de.extio.game_engine.util.ObjectSerialization;
import de.extio.game_engine.util.rng.FastRandomUUID; import de.extio.game_engine.util.rng.FastRandomUUID;
@@ -37,22 +37,11 @@ public class StorageServiceImpl implements StorageService {
String location = System.getProperty("storagelocation"); String location = System.getProperty("storagelocation");
if (location == null) { if (location == null) {
try { try {
final URL url = StorageServiceImpl.class.getProtectionDomain().getCodeSource().getLocation(); final var codeSourcePath = CodeSourceLocationResolver.resolvePath(StorageServiceImpl.class);
Path parent; final var parent = codeSourcePath.getParent();
if (url.toString().startsWith("jar:nested:")) { final Path jarPath = parent != null ? parent.toAbsolutePath().normalize() : codeSourcePath;
if (Objects.requireNonNullElse(System.getProperty("os.name"), "").toLowerCase().contains("windows")) {
parent = Paths.get(url.toString().substring("jar:nested:/".length(), url.toString().indexOf("/!"))).getParent();
}
else {
parent = Paths.get(url.toString().substring("jar:nested:".length(), url.toString().indexOf("/!"))).getParent();
}
}
else {
parent = Paths.get(url.toURI()).getParent();
}
final Path jarPath = parent != null ? parent.toAbsolutePath().normalize() : Paths.get(url.toURI()).toAbsolutePath().normalize();
final String currentSubDir = jarPath.getFileName().toString(); final String currentSubDir = jarPath.getFileName() != null ? jarPath.getFileName().toString() : "";
if ("bin".equals(currentSubDir) || "target".equals(currentSubDir)) { if ("bin".equals(currentSubDir) || "target".equals(currentSubDir)) {
location = jarPath.getParent().resolve("storage").toString(); location = jarPath.getParent().resolve("storage").toString();
} }

View File

@@ -0,0 +1,44 @@
package de.extio.game_engine.util;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
public final class CodeSourceLocationResolver {
private CodeSourceLocationResolver() {
}
public static Path resolvePath(final Class<?> clazz) throws Exception {
final var codeSource = clazz.getProtectionDomain().getCodeSource();
if (codeSource == null) {
throw new IllegalStateException("Could not determine code source for " + clazz.getName());
}
return resolvePath(codeSource.getLocation());
}
public static Path resolvePath(final URL url) throws Exception {
var location = url.toExternalForm();
if (location.startsWith("jar:nested:")) {
location = location.substring("jar:nested:".length());
final var nestedSeparator = location.indexOf("/!");
if (nestedSeparator >= 0) {
location = location.substring(0, nestedSeparator);
}
return decodePath(location).toAbsolutePath().normalize();
}
return Paths.get(url.toURI()).toAbsolutePath().normalize();
}
private static Path decodePath(final String location) {
if (location.startsWith("file:")) {
return Paths.get(URI.create(location));
}
if (location.matches("^[A-Za-z]:/.*")) {
return Paths.get(URI.create("file:/" + location));
}
return Paths.get(URI.create("file:" + location));
}
}