Skip to content

Commit

Permalink
Don't rely on external jar command to amend jar files' manifests
Browse files Browse the repository at this point in the history
  • Loading branch information
zakkak committed Mar 13, 2023
1 parent 03cc9ab commit 809898c
Showing 1 changed file with 40 additions and 19 deletions.
59 changes: 40 additions & 19 deletions build.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
Expand Down Expand Up @@ -562,16 +561,8 @@ void build(Options options) throws IOException
LOG.debugf("Build Mandrel's wrapper jar...");
Mx.BuildArgs buildArgs = Mx.BuildArgs.of("--only", "MANDREL_PACKAGING_WRAPPER");
exec.exec.accept(Mx.mxbuild(options, fs.mxHome(), fs.mandrelRepo(), os.javaHome()).apply(buildArgs));
// Add Specification-Version and Implementation-Version to jars' manifests.
// These attributes are access by Red Hat Build of Quarkus to verify that the correct artifacts are being used.
// The value of Specification-Version is not that important, but the Implementation-Version should match the version of the native-image.
LOG.debugf("Patch jars' manifests with Specification-Version and Implementation-Version...");
File manifest = createTempManifest(options);
mx.artifacts.forEach((artifact, paths) ->
{
final String jarPath = PathFinder.getFirstExisting(fs.mandrelRepo().resolve(paths[0]).toString(), artifact).toString();
exec.exec.accept(Tasks.Exec.of(List.of("jar", "uvfm", jarPath, manifest.getPath()), fs.mandrelRepo()));
});
mx.artifacts.forEach(amendOrCreateManifest(options, replace));
LOG.debugf("Deploy maven artifacts...");
Mx.mavenDeploy(options, exec, fs.mxHome(), fs.mandrelRepo(), os.javaHome());
}
Expand All @@ -587,18 +578,48 @@ void build(Options options) throws IOException
}
}

private File createTempManifest(Options options) throws IOException
private BiConsumer<String, Path[]> amendOrCreateManifest(Options options, Tasks.FileReplace.Effects replace)
{
File manifest = File.createTempFile("manifest", "mf");
manifest.deleteOnExit();
try (FileWriter manifestWriter = new FileWriter(manifest))
return (artifact, paths) ->
{
manifestWriter.write("Specification-Version: 0.0\n");
manifestWriter.write("Implementation-Version: " + options.mavenVersion + "\n");
manifestWriter.flush();
}
return manifest;
final Path jarPath = PathFinder.getFirstExisting(fs.mandrelRepo().resolve(paths[0]).toString(), artifact);
try (java.nio.file.FileSystem jarfs = FileSystems.newFileSystem(jarPath, this.getClass().getClassLoader()))
{
Path metaInfPath = jarfs.getPath("/META-INF");
Path manifestPath = metaInfPath.resolve("MANIFEST.MF");
if (!Files.exists(manifestPath))
{
if (!Files.exists(metaInfPath))
{
Files.createDirectory(metaInfPath);
}
Files.createFile(manifestPath);
}
Tasks.FileReplace.replace(new Tasks.FileReplace(manifestPath, amendManifest(options)), replace);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
};
}

/*
* Add Specification-Version and Implementation-Version to jars' manifests.
* These attributes are accessed by Red Hat Build of Quarkus to verify that the correct artifacts are being used.
* The value of Specification-Version is not that important, but the Implementation-Version should match the version of the native-image.
*/
private static Function<Stream<String>, List<String>> amendManifest(Options options)
{
return lines ->
{
List<String> result = lines.collect(Collectors.toList());
result.add("Specification-Version: 0.0");
result.add("Implementation-Version: " + options.mavenVersion);
return result;
};
}

}

class EnvVar
Expand Down

0 comments on commit 809898c

Please sign in to comment.