From 454dbbf30528e75f6d08324954ca576c321bf110 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 11 Jan 2024 08:34:58 +0200 Subject: [PATCH 1/2] Bump fs-util to 0.0.10 --- independent-projects/bootstrap/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/independent-projects/bootstrap/pom.xml b/independent-projects/bootstrap/pom.xml index 44220f01bd483..4e8f7add2e257 100644 --- a/independent-projects/bootstrap/pom.xml +++ b/independent-projects/bootstrap/pom.xml @@ -76,7 +76,7 @@ 2.1.2 1.3.2 8.5 - 0.0.9 + 0.0.10 0.1.3 2.23.0 1.9.0 From 95a069b23c1f62d6df88d2d68b59dd8adeb90bd3 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Wed, 10 Jan 2024 19:32:59 +0200 Subject: [PATCH 2/2] Introduce option to create uncompressed jars This is done by setting `quarkus.package.compress-jar` to `false`. This is a niche setting, but it can lead to slightly reduced boot time when using uber-jar packaging Closes: #38128 --- .../quarkus/deployment/pkg/PackageConfig.java | 7 ++++ .../pkg/steps/JarResultBuildStep.java | 33 ++++++++++++------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java index 4e616696cbedb..a38ed23b1ecd7 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java @@ -103,6 +103,13 @@ public static BuiltInType fromString(String value) { @ConfigItem(defaultValue = "jar") public String type; + /** + * Whether the created jar will be compressed. This setting is not used when building a native image + */ + @ConfigItem + @ConfigDocDefault("false") + public Optional compressJar; + /** * Manifest configuration of the runner jar. */ diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java index 166562b4c1d2d..fdcbe78e85e25 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java @@ -329,7 +329,7 @@ private void buildUberJar0(CurateOutcomeBuildItem curateOutcomeBuildItem, MainClassBuildItem mainClassBuildItem, ClassLoadingConfig classLoadingConfig, Path runnerJar) throws Exception { - try (FileSystem runnerZipFs = ZipUtils.newZip(runnerJar)) { + try (FileSystem runnerZipFs = createNewZip(runnerJar, packageConfig)) { log.info("Building uber jar: " + runnerJar); @@ -530,7 +530,7 @@ private JarBuildItem buildLegacyThinJar(CurateOutcomeBuildItem curateOutcomeBuil Files.deleteIfExists(runnerJar); IoUtils.createOrEmptyDir(libDir); - try (FileSystem runnerZipFs = ZipUtils.newZip(runnerJar)) { + try (FileSystem runnerZipFs = createNewZip(runnerJar, packageConfig)) { log.info("Building thin jar: " + runnerJar); @@ -629,7 +629,7 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, if (!transformedClasses.getTransformedClassesByJar().isEmpty()) { Path transformedZip = quarkus.resolve(TRANSFORMED_BYTECODE_JAR); fastJarJarsBuilder.setTransformed(transformedZip); - try (FileSystem out = ZipUtils.newZip(transformedZip)) { + try (FileSystem out = createNewZip(transformedZip, packageConfig)) { for (Set transformedSet : transformedClasses .getTransformedClassesByJar().values()) { for (TransformedClassesBuildItem.TransformedClass transformed : transformedSet) { @@ -650,7 +650,7 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, //now generated classes and resources Path generatedZip = quarkus.resolve(GENERATED_BYTECODE_JAR); fastJarJarsBuilder.setGenerated(generatedZip); - try (FileSystem out = ZipUtils.newZip(generatedZip)) { + try (FileSystem out = createNewZip(generatedZip, packageConfig)) { for (GeneratedClassBuildItem i : generatedClasses) { String fileName = i.getName().replace('.', '/') + ".class"; Path target = out.getPath(fileName); @@ -683,7 +683,7 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, if (!rebuild) { Predicate ignoredEntriesPredicate = getThinJarIgnoredEntriesPredicate(packageConfig); - try (FileSystem runnerZipFs = ZipUtils.newZip(runnerJar)) { + try (FileSystem runnerZipFs = createNewZip(runnerJar, packageConfig)) { copyFiles(applicationArchivesBuildItem.getRootArchive(), runnerZipFs, null, ignoredEntriesPredicate); } } @@ -695,7 +695,7 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, if (!rebuild) { copyDependency(parentFirstKeys, outputTargetBuildItem, copiedArtifacts, mainLib, baseLib, fastJarJarsBuilder::addDep, true, - classPath, appDep, transformedClasses, removed); + classPath, appDep, transformedClasses, removed, packageConfig); } else if (includeAppDep(appDep, outputTargetBuildItem.getIncludedOptionalDependencies(), removed)) { appDep.getResolvedPaths().forEach(fastJarJarsBuilder::addDep); } @@ -768,7 +768,7 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, } } if (!rebuild) { - try (FileSystem runnerZipFs = ZipUtils.newZip(initJar)) { + try (FileSystem runnerZipFs = createNewZip(initJar, packageConfig)) { ResolvedDependency appArtifact = curateOutcomeBuildItem.getApplicationModel().getAppArtifact(); generateManifest(runnerZipFs, classPath.toString(), packageConfig, appArtifact, QuarkusEntryPoint.class.getName(), @@ -783,7 +783,7 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, copyDependency(parentFirstKeys, outputTargetBuildItem, copiedArtifacts, deploymentLib, baseLib, (p) -> { }, false, classPath, - appDep, new TransformedClassesBuildItem(Map.of()), removed); //we don't care about transformation here, so just pass in an empty item + appDep, new TransformedClassesBuildItem(Map.of()), removed, packageConfig); //we don't care about transformation here, so just pass in an empty item } Map> relativePaths = new HashMap<>(); for (Map.Entry> e : copiedArtifacts.entrySet()) { @@ -884,7 +884,8 @@ private Set getRemovedKeys(ClassLoadingConfig classLoadingConfig) { private void copyDependency(Set parentFirstArtifacts, OutputTargetBuildItem outputTargetBuildItem, Map> runtimeArtifacts, Path libDir, Path baseLib, Consumer targetPathConsumer, boolean allowParentFirst, StringBuilder classPath, ResolvedDependency appDep, - TransformedClassesBuildItem transformedClasses, Set removedDeps) + TransformedClassesBuildItem transformedClasses, Set removedDeps, + PackageConfig packageConfig) throws IOException { // Exclude files that are not jars (typically, we can have XML files here, see https://github.com/quarkusio/quarkus/issues/2852) @@ -912,7 +913,7 @@ private void copyDependency(Set parentFirstArtifacts, OutputTargetB // This case can happen when we are building a jar from inside the Quarkus repository // and Quarkus Bootstrap's localProjectDiscovery has been set to true. In such a case // the non-jar dependencies are the Quarkus dependencies picked up on the file system - packageClasses(resolvedDep, targetPath); + packageClasses(resolvedDep, targetPath, packageConfig); } else { Set transformedFromThisArchive = transformedClasses .getTransformedClassesByJar().get(resolvedDep); @@ -934,8 +935,8 @@ private void copyDependency(Set parentFirstArtifacts, OutputTargetB } } - private void packageClasses(Path resolvedDep, final Path targetPath) throws IOException { - try (FileSystem runnerZipFs = ZipUtils.newZip(targetPath)) { + private void packageClasses(Path resolvedDep, final Path targetPath, PackageConfig packageConfig) throws IOException { + try (FileSystem runnerZipFs = createNewZip(targetPath, packageConfig)) { Files.walkFileTree(resolvedDep, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor() { @Override @@ -1649,4 +1650,12 @@ public boolean decompile(Path jarToDecompile) { } } + private static FileSystem createNewZip(Path runnerJar, PackageConfig config) throws IOException { + boolean useUncompressedJar = config.compressJar.map(o -> !o).orElse(false); + if (useUncompressedJar) { + return ZipUtils.newZip(runnerJar, Map.of("compressionMethod", "STORED")); + } + return ZipUtils.newZip(runnerJar); + } + }