Generate 'META-INF/native-image/argfile' file for buildpack use

Update the Maven and Gradle plugin to generate an `argfile` file
file under `META-INF/native-image` that contains `--exclude-config`
arguments that should be passed when generating a native image.

The contents of the file is generated for each nested jar that has a
`reachability-metadata.properties` file containing 'override=true'.

The `reachability-metadata.properties` file is expected to be generated
by the Graal native build tools plugin.

Closes gh-32738
This commit is contained in:
Phillip Webb
2022-10-06 13:57:29 -07:00
parent 430c6b7e9f
commit 071649360b
10 changed files with 227 additions and 34 deletions

View File

@@ -20,6 +20,7 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
@@ -614,6 +615,42 @@ abstract class AbstractPackagerTests<P extends Packager> {
assertThat(packagedEntryNames).containsExactly("WEB-INF/lib/" + libraryTwo.getName());
}
@Test
void nativeImageArgFileWithExcludesIsWritten() throws Exception {
this.testJarFile.addClass("com/example/Application.class", ClassWithMainMethod.class);
File libraryOne = createLibraryJar();
File libraryTwo = createLibraryJar();
File libraryThree = createLibraryJar();
File libraryFour = createLibraryJar();
this.testJarFile.addFile("META-INF/native-image/com.example.one/lib-one/reachability-metadata.properties",
new ByteArrayInputStream("override=true\n".getBytes(StandardCharsets.ISO_8859_1)));
this.testJarFile.addFile("META-INF/native-image/com.example.two/lib-two/reachability-metadata.properties",
new ByteArrayInputStream("override=true\n".getBytes(StandardCharsets.ISO_8859_1)));
this.testJarFile.addFile("META-INF/native-image/com.example.three/lib-three/reachability-metadata.properties",
new ByteArrayInputStream("other=test\n".getBytes(StandardCharsets.ISO_8859_1)));
P packager = createPackager(this.testJarFile.getFile());
execute(packager, (callback) -> {
callback.library(new Library(null, libraryOne, LibraryScope.COMPILE,
LibraryCoordinates.of("com.example.one", "lib-one", "123"), false, false, true));
callback.library(new Library(null, libraryTwo, LibraryScope.COMPILE,
LibraryCoordinates.of("com.example.two", "lib-two", "123"), false, false, true));
callback.library(new Library(null, libraryThree, LibraryScope.COMPILE,
LibraryCoordinates.of("com.example.three", "lib-three", "123"), false, false, true));
callback.library(new Library(null, libraryFour, LibraryScope.COMPILE,
LibraryCoordinates.of("com.example.four", "lib-four", "123"), false, false, true));
});
List<String> expected = new ArrayList<>();
expected.add("--exclude-config");
expected.add("\"\\\\Q" + libraryOne.getName() + "\\\\E\"");
expected.add("\"^/META-INF/native-image/.*\"");
expected.add("--exclude-config");
expected.add("\"\\\\Q" + libraryTwo.getName() + "\\\\E\"");
expected.add("\"^/META-INF/native-image/.*\"");
assertThat(getPackagedEntryContent("META-INF/native-image/argfile"))
.isEqualTo(expected.stream().collect(Collectors.joining("\n")) + "\n");
}
private File createLibraryJar() throws IOException {
TestJarFile library = new TestJarFile(this.tempDir);
library.addClass("com/example/library/Library.class", ClassWithoutMainMethod.class);

View File

@@ -68,11 +68,15 @@ public class TestJarFile {
}
public void addFile(String filename, File fileToCopy) throws IOException {
try (InputStream inputStream = new FileInputStream(fileToCopy)) {
addFile(filename, inputStream);
}
}
public void addFile(String filename, InputStream inputStream) throws IOException {
File file = getFilePath(filename);
file.getParentFile().mkdirs();
try (InputStream inputStream = new FileInputStream(fileToCopy)) {
copyToFile(inputStream, file);
}
copyToFile(inputStream, file);
this.entries.add(new FileSource(filename, file));
}