Generate native image config data in recommended location
Closes gh-30827
This commit is contained in:
		
							parent
							
								
									6c607ac622
								
							
						
					
					
						commit
						096420cc4c
					
				| 
						 | 
				
			
			@ -57,18 +57,29 @@ public class AotProcessor {
 | 
			
		|||
 | 
			
		||||
	private final Path resourceOutput;
 | 
			
		||||
 | 
			
		||||
	private final String groupId;
 | 
			
		||||
 | 
			
		||||
	private final String artifactId;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new processor for the specified application and settings.
 | 
			
		||||
	 * @param application the application main class
 | 
			
		||||
	 * @param applicationArgs the arguments to provide to the main method
 | 
			
		||||
	 * @param sourceOutput the location of generated sources
 | 
			
		||||
	 * @param resourceOutput the location of generated resources
 | 
			
		||||
	 * @param groupId the group ID of the application, used to locate
 | 
			
		||||
	 * native-image.properties
 | 
			
		||||
	 * @param artifactId the artifact ID of the application, used to locate
 | 
			
		||||
	 * native-image.properties
 | 
			
		||||
	 */
 | 
			
		||||
	public AotProcessor(Class<?> application, String[] applicationArgs, Path sourceOutput, Path resourceOutput) {
 | 
			
		||||
	public AotProcessor(Class<?> application, String[] applicationArgs, Path sourceOutput, Path resourceOutput,
 | 
			
		||||
			String groupId, String artifactId) {
 | 
			
		||||
		this.application = application;
 | 
			
		||||
		this.applicationArgs = applicationArgs;
 | 
			
		||||
		this.sourceOutput = sourceOutput;
 | 
			
		||||
		this.resourceOutput = resourceOutput;
 | 
			
		||||
		this.groupId = groupId;
 | 
			
		||||
		this.artifactId = artifactId;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +134,8 @@ public class AotProcessor {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	private void writeGeneratedResources(RuntimeHints hints) {
 | 
			
		||||
		FileNativeConfigurationWriter writer = new FileNativeConfigurationWriter(this.resourceOutput);
 | 
			
		||||
		FileNativeConfigurationWriter writer = new FileNativeConfigurationWriter(this.resourceOutput, this.groupId,
 | 
			
		||||
				this.artifactId);
 | 
			
		||||
		writer.write(hints);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -137,7 +149,8 @@ public class AotProcessor {
 | 
			
		|||
		StringBuilder sb = new StringBuilder();
 | 
			
		||||
		sb.append("Args = ");
 | 
			
		||||
		sb.append(String.join(String.format(" \\%n"), args));
 | 
			
		||||
		Path file = this.resourceOutput.resolve("META-INF/native-image/native-image.properties");
 | 
			
		||||
		Path file = this.resourceOutput
 | 
			
		||||
				.resolve("META-INF/native-image/" + this.groupId + "/" + this.artifactId + "/native-image.properties");
 | 
			
		||||
		try {
 | 
			
		||||
			if (!Files.exists(file)) {
 | 
			
		||||
				Files.createDirectories(file.getParent());
 | 
			
		||||
| 
						 | 
				
			
			@ -151,17 +164,21 @@ public class AotProcessor {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	public static void main(String[] args) throws Exception {
 | 
			
		||||
		if (args.length < 3) {
 | 
			
		||||
		int requiredArgs = 5;
 | 
			
		||||
		if (args.length < requiredArgs) {
 | 
			
		||||
			throw new IllegalArgumentException("Usage: " + AotProcessor.class.getName()
 | 
			
		||||
					+ " <applicationName> <sourceOutput> <resourceOutput> <originalArgs...>");
 | 
			
		||||
					+ " <applicationName> <sourceOutput> <resourceOutput> <groupId> <artifactId> <originalArgs...>");
 | 
			
		||||
		}
 | 
			
		||||
		String applicationName = args[0];
 | 
			
		||||
		Path sourceOutput = Paths.get(args[1]);
 | 
			
		||||
		Path resourceOutput = Paths.get(args[2]);
 | 
			
		||||
		String[] applicationArgs = (args.length > 3) ? Arrays.copyOfRange(args, 3, args.length) : new String[0];
 | 
			
		||||
 | 
			
		||||
		String groupId = args[3];
 | 
			
		||||
		String artifactId = args[4];
 | 
			
		||||
		String[] applicationArgs = (args.length > requiredArgs) ? Arrays.copyOfRange(args, requiredArgs, args.length)
 | 
			
		||||
				: new String[0];
 | 
			
		||||
		Class<?> application = Class.forName(applicationName);
 | 
			
		||||
		AotProcessor aotProcess = new AotProcessor(application, applicationArgs, sourceOutput, resourceOutput);
 | 
			
		||||
		AotProcessor aotProcess = new AotProcessor(application, applicationArgs, sourceOutput, resourceOutput, groupId,
 | 
			
		||||
				artifactId);
 | 
			
		||||
		aotProcess.process();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
 | 
			
		|||
 * Tests for {@link AotProcessor}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Stephane Nicoll
 | 
			
		||||
 * @author Andy Wilkinson
 | 
			
		||||
 */
 | 
			
		||||
class AotProcessorTests {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +45,7 @@ class AotProcessorTests {
 | 
			
		|||
	void processApplicationInvokesRunMethod(@TempDir Path directory) {
 | 
			
		||||
		String[] arguments = new String[] { "1", "2" };
 | 
			
		||||
		AotProcessor processor = new AotProcessor(SampleApplication.class, arguments, directory.resolve("source"),
 | 
			
		||||
				directory.resolve("resource"));
 | 
			
		||||
				directory.resolve("resource"), "com.example", "example");
 | 
			
		||||
		processor.process();
 | 
			
		||||
		assertThat(SampleApplication.argsHolder).isEqualTo(arguments);
 | 
			
		||||
		assertThat(directory).satisfies(hasGeneratedAssetsForSampleApplication());
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +54,7 @@ class AotProcessorTests {
 | 
			
		|||
	@Test
 | 
			
		||||
	void processApplicationWithMainMethodThatDoesNotRun(@TempDir Path directory) {
 | 
			
		||||
		AotProcessor processor = new AotProcessor(BrokenApplication.class, new String[0], directory.resolve("source"),
 | 
			
		||||
				directory.resolve("resource"));
 | 
			
		||||
				directory.resolve("resource"), "com.example", "example");
 | 
			
		||||
		assertThatIllegalArgumentException().isThrownBy(processor::process)
 | 
			
		||||
				.withMessageContaining("Does it run a SpringApplication?");
 | 
			
		||||
		assertThat(directory).isEmptyDirectory();
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +63,8 @@ class AotProcessorTests {
 | 
			
		|||
	@Test
 | 
			
		||||
	void invokeMainParseArgumentsAndInvokesRunMethod(@TempDir Path directory) throws Exception {
 | 
			
		||||
		String[] mainArguments = new String[] { SampleApplication.class.getName(),
 | 
			
		||||
				directory.resolve("source").toString(), directory.resolve("resource").toString(), "1", "2" };
 | 
			
		||||
				directory.resolve("source").toString(), directory.resolve("resource").toString(), "com.example",
 | 
			
		||||
				"example", "1", "2" };
 | 
			
		||||
		AotProcessor.main(mainArguments);
 | 
			
		||||
		assertThat(SampleApplication.argsHolder).containsExactly("1", "2");
 | 
			
		||||
		assertThat(directory).satisfies(hasGeneratedAssetsForSampleApplication());
 | 
			
		||||
| 
						 | 
				
			
			@ -79,10 +81,10 @@ class AotProcessorTests {
 | 
			
		|||
			assertThat(directory
 | 
			
		||||
					.resolve("source/org/springframework/boot/SampleApplication__ApplicationContextInitializer.java"))
 | 
			
		||||
							.exists().isRegularFile();
 | 
			
		||||
			assertThat(directory.resolve("resource/META-INF/native-image/reflect-config.json")).exists()
 | 
			
		||||
					.isRegularFile();
 | 
			
		||||
			assertThat(directory.resolve("resource/META-INF/native-image/com.example/example/reflect-config.json"))
 | 
			
		||||
					.exists().isRegularFile();
 | 
			
		||||
			Path nativeImagePropertiesFile = directory
 | 
			
		||||
					.resolve("resource/META-INF/native-image/native-image.properties");
 | 
			
		||||
					.resolve("resource/META-INF/native-image/com.example/example/native-image.properties");
 | 
			
		||||
			assertThat(nativeImagePropertiesFile).exists().isRegularFile().hasContent("""
 | 
			
		||||
					Args = -H:Class=org.springframework.boot.AotProcessorTests$SampleApplication \\
 | 
			
		||||
					--allow-incomplete-classpath \\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue