Testing Jar Packing for minimization

This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-24 06:46:27 -04:00
1 parent 38cf4ac7c7
commit 68aa6adec7
13 files changed
+2604 -14

No files matched your search

@@ -26,6 +26,7 @@ import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
@@ -60,6 +61,11 @@ public final class NativeRuntimeLibraries {
}
static NativeRuntimeLibraries from(Properties manifest, String minecraftVersion) throws IOException {
String storage = manifest.getProperty("storage", "repository");
if (!storage.equals("repository") && !storage.equals("embedded")) {
throw new IllegalStateException("Invalid native runtime storage: " + storage);
}
boolean embedded = storage.equals("embedded");
NativeVersion version = NativeVersion.resolve(minecraftVersion).orElseThrow(
() -> new UnsupportedOperationException("No native provider for Minecraft " + minecraftVersion));
List<String> modules = List.of(manifest.getProperty("modules", "").split(","));
@@ -71,13 +77,14 @@ public final class NativeRuntimeLibraries {
String[] coordinate = manifest.getProperty(module + ".coordinate", "").split(":");
String digest = manifest.getProperty(module + ".sha256", "");
if (coordinate.length != 3 || !coordinate[0].equals("com.github.VolmitSoftware.VolmLib")
|| !coordinate[1].equals(module) || coordinate[2].isBlank() || !digest.matches("[0-9a-f]{64}")) {
|| !coordinate[1].equals(module) || coordinate[2].isBlank() || !digest.matches("[0-9a-f]{64}")
|| embedded && !coordinate[2].equals("embedded-" + digest)) {
throw new IllegalStateException("Invalid native dependency manifest entry: " + module);
}
selected.put(new Dependency(coordinate[0], coordinate[1], coordinate[2], null, List.of()), digest);
}
return new NativeRuntimeLibraries(Map.copyOf(selected),
new Repository(URI.create(manifest.getProperty("repository")).toURL()));
Repository repository = embedded ? null : new Repository(URI.create(manifest.getProperty("repository")).toURL());
return new NativeRuntimeLibraries(Map.copyOf(selected), repository);
}
public <T extends ApplicationBuilder<?>> T configure(T builder, Path downloads) {
@@ -111,15 +118,7 @@ public final class NativeRuntimeLibraries {
public URLClassLoader openProviderLoader(Path downloads) {
try {
List<URL> urls = new ArrayList<>(dependencies.size());
for (Map.Entry<Dependency, String> entry : dependencies.entrySet()) {
Dependency dependency = entry.getKey();
Path artifact = downloads.resolve(dependency.groupId().replace('.', '/'))
.resolve(dependency.artifactId()).resolve(dependency.version())
.resolve(dependency.artifactId() + "-" + dependency.version() + ".jar");
verify(artifact.toFile(), entry.getValue());
urls.add(artifact.toUri().toURL());
}
List<URL> urls = providerUrls(downloads, NativeRuntimeLibraries.class.getClassLoader());
URLClassLoader loader = new URLClassLoader("Iris native providers", urls.toArray(URL[]::new),
NativeAdapters.class.getClassLoader());
NativeAdapters.registerProviderLoader(loader);
@@ -130,6 +129,9 @@ public final class NativeRuntimeLibraries {
}
DependencyData merge(DependencyData original) {
if (repository == null) {
return original;
}
List<Dependency> combined = new ArrayList<>(original.dependencies());
combined.addAll(dependencies.keySet());
List<Repository> repositories = new ArrayList<>(original.repositories());
@@ -139,14 +141,61 @@ public final class NativeRuntimeLibraries {
return new DependencyData(original.mirrors(), repositories, combined, original.relocations());
}
List<URL> providerUrls(Path downloads, ClassLoader resources) throws IOException {
List<URL> urls = new ArrayList<>(dependencies.size());
for (Map.Entry<Dependency, String> entry : dependencies.entrySet()) {
Dependency dependency = entry.getKey();
Path artifact = downloads.resolve(dependency.groupId().replace('.', '/'))
.resolve(dependency.artifactId()).resolve(dependency.version())
.resolve(dependency.artifactId() + "-" + dependency.version() + ".jar");
if (repository == null) {
extractEmbedded(resources, dependency.artifactId(), artifact, entry.getValue());
} else {
verify(artifact.toFile(), entry.getValue());
}
urls.add(artifact.toUri().toURL());
}
return urls;
}
private static void extractEmbedded(ClassLoader resources, String module, Path artifact, String expected) throws IOException {
if (Files.isRegularFile(artifact) && digest(artifact).equals(expected)) {
return;
}
String resource = "META-INF/iris/native/" + module + ".jar";
try (InputStream input = resources.getResourceAsStream(resource)) {
if (input == null) {
throw new IOException("Missing embedded native provider: " + resource);
}
Files.createDirectories(artifact.getParent());
Path temporary = Files.createTempFile(artifact.getParent(), module + "-", ".tmp");
try {
Files.copy(input, temporary, StandardCopyOption.REPLACE_EXISTING);
verify(temporary.toFile(), expected);
Files.move(temporary, artifact, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
} finally {
Files.deleteIfExists(temporary);
}
}
}
private static String digest(Path file) throws IOException {
try {
return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(Files.readAllBytes(file)));
} catch (NoSuchAlgorithmException exception) {
throw new IllegalStateException(exception);
}
}
static void verify(File file, String expected) {
try {
String actual = HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(Files.readAllBytes(file.toPath())));
String actual = digest(file.toPath());
if (!actual.equals(expected)) {
throw new DownloaderException("Native dependency does not match this Iris build: " + file.getName());
}
} catch (IOException | NoSuchAlgorithmException exception) {
} catch (IOException exception) {
throw new DownloaderException("Cannot verify native dependency: " + file, exception);
}
}
}