commit
						4015d70f00
					
				|  | @ -36,12 +36,16 @@ public class ImagePackager extends Packager { | |||
| 	/** | ||||
| 	 * Create a new {@link ImagePackager} instance. | ||||
| 	 * @param source the source file to package | ||||
| 	 * @param backupFile the backup of the source file to package | ||||
| 	 */ | ||||
| 	public ImagePackager(File source) { | ||||
| 		super(source, null); | ||||
| 	public ImagePackager(File source, File backupFile) { | ||||
| 		super(source); | ||||
| 		setBackupFile(backupFile); | ||||
| 		if (isAlreadyPackaged()) { | ||||
| 			Assert.isTrue(getBackupFile().exists() && getBackupFile().isFile(), | ||||
| 					"Original source '" + getBackupFile() + "' is required for building an image"); | ||||
| 			Assert.state(!isAlreadyPackaged(getBackupFile()), | ||||
| 					() -> "Repackaged archive file " + source + " cannot be used to build an image"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -57,8 +61,6 @@ public class ImagePackager extends Packager { | |||
| 
 | ||||
| 	private void packageImage(Libraries libraries, AbstractJarWriter writer) throws IOException { | ||||
| 		File source = isAlreadyPackaged() ? getBackupFile() : getSource(); | ||||
| 		Assert.state(!isAlreadyPackaged(source), | ||||
| 				() -> "Repackaged archive file " + source + " cannot be used to build an image"); | ||||
| 		try (JarFile sourceJar = new JarFile(source)) { | ||||
| 			write(sourceJar, libraries, writer); | ||||
| 		} | ||||
|  |  | |||
|  | @ -76,6 +76,8 @@ public abstract class Packager { | |||
| 
 | ||||
| 	private final File source; | ||||
| 
 | ||||
| 	private File backupFile; | ||||
| 
 | ||||
| 	private Layout layout; | ||||
| 
 | ||||
| 	private LayoutFactory layoutFactory; | ||||
|  | @ -88,9 +90,20 @@ public abstract class Packager { | |||
| 
 | ||||
| 	/** | ||||
| 	 * Create a new {@link Packager} instance. | ||||
| 	 * @param source the source JAR file to package | ||||
| 	 * @param layoutFactory the layout factory to use or {@code null} | ||||
| 	 * @param source the source archive file to package | ||||
| 	 */ | ||||
| 	protected Packager(File source) { | ||||
| 		this(source, null); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Create a new {@link Packager} instance. | ||||
| 	 * @param source the source archive file to package | ||||
| 	 * @param layoutFactory the layout factory to use or {@code null} | ||||
| 	 * @deprecated since 2.5.0 in favor of {@link #Packager(File)} and | ||||
| 	 * {@link #setLayoutFactory(LayoutFactory)} | ||||
| 	 */ | ||||
| 	@Deprecated | ||||
| 	protected Packager(File source, LayoutFactory layoutFactory) { | ||||
| 		Assert.notNull(source, "Source file must not be null"); | ||||
| 		Assert.isTrue(source.exists() && source.isFile(), | ||||
|  | @ -146,6 +159,14 @@ public abstract class Packager { | |||
| 		this.layersIndex = new LayersIndex(layers); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Sets the {@link File} to use to backup the original source. | ||||
| 	 * @param backupFile the file to use to backup the original source | ||||
| 	 */ | ||||
| 	protected void setBackupFile(File backupFile) { | ||||
| 		this.backupFile = backupFile; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Sets if jarmode jars relevant for the packaging should be automatically included. | ||||
| 	 * @param includeRelevantJarModeJars if relevant jars are included | ||||
|  | @ -291,6 +312,9 @@ public abstract class Packager { | |||
| 	 * @return the file to use to backup the original source | ||||
| 	 */ | ||||
| 	public final File getBackupFile() { | ||||
| 		if (this.backupFile != null) { | ||||
| 			return this.backupFile; | ||||
| 		} | ||||
| 		return new File(this.source.getParentFile(), this.source.getName() + ".original"); | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,16 +32,29 @@ import org.springframework.util.Assert; | |||
|  * @author Andy Wilkinson | ||||
|  * @author Stephane Nicoll | ||||
|  * @author Madhura Bhave | ||||
|  * @author Scott Frederick | ||||
|  * @since 1.0.0 | ||||
|  */ | ||||
| public class Repackager extends Packager { | ||||
| 
 | ||||
| 	private boolean backupSource = true; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Create a new {@link Repackager} instance. | ||||
| 	 * @param source the source archive file to package | ||||
| 	 */ | ||||
| 	public Repackager(File source) { | ||||
| 		this(source, null); | ||||
| 		super(source); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Create a new {@link Repackager} instance. | ||||
| 	 * @param source the source archive file to package | ||||
| 	 * @param layoutFactory the layout factory to use or {@code null} | ||||
| 	 * @deprecated since 2.5.0 in favor of {@link #Repackager(File)} and | ||||
| 	 * {@link #setLayoutFactory(LayoutFactory)} | ||||
| 	 */ | ||||
| 	@Deprecated | ||||
| 	public Repackager(File source, LayoutFactory layoutFactory) { | ||||
| 		super(source, layoutFactory); | ||||
| 	} | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| /* | ||||
|  * Copyright 2012-2020 the original author or authors. | ||||
|  * Copyright 2012-2021 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  | @ -40,7 +40,7 @@ class ImagePackagerTests extends AbstractPackagerTests<ImagePackager> { | |||
| 
 | ||||
| 	@Override | ||||
| 	protected ImagePackager createPackager(File source) { | ||||
| 		return new ImagePackager(source); | ||||
| 		return new ImagePackager(source, null); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
|  |  | |||
|  | @ -68,6 +68,54 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests { | |||
| 				}); | ||||
| 	} | ||||
| 
 | ||||
| 	@TestTemplate | ||||
| 	void whenBuildImageIsInvokedWithClassifierWithoutRepackageTheArchiveIsRepackagedOnTheFly(MavenBuild mavenBuild) { | ||||
| 		mavenBuild.project("build-image-classifier").goals("package") | ||||
| 				.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT") | ||||
| 				.prepare(this::writeLongNameResource).execute((project) -> { | ||||
| 					File jar = new File(project, "target/build-image-classifier-0.0.1.BUILD-SNAPSHOT.jar"); | ||||
| 					assertThat(jar).isFile(); | ||||
| 					File classifier = new File(project, "target/build-image-classifier-0.0.1.BUILD-SNAPSHOT-test.jar"); | ||||
| 					assertThat(classifier).doesNotExist(); | ||||
| 					assertThat(buildLog(project)).contains("Building image") | ||||
| 							.contains("docker.io/library/build-image-classifier:0.0.1.BUILD-SNAPSHOT") | ||||
| 							.contains("Successfully built image"); | ||||
| 					ImageReference imageReference = ImageReference.of(ImageName.of("build-image-classifier"), | ||||
| 							"0.0.1.BUILD-SNAPSHOT"); | ||||
| 					try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) { | ||||
| 						container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); | ||||
| 					} | ||||
| 					finally { | ||||
| 						removeImage(imageReference); | ||||
| 					} | ||||
| 				}); | ||||
| 	} | ||||
| 
 | ||||
| 	@TestTemplate | ||||
| 	void whenBuildImageIsInvokedWithClassifierSourceWithoutRepackageTheArchiveIsRepackagedOnTheFly( | ||||
| 			MavenBuild mavenBuild) { | ||||
| 		mavenBuild.project("build-image-classifier-source").goals("package") | ||||
| 				.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT") | ||||
| 				.prepare(this::writeLongNameResource).execute((project) -> { | ||||
| 					File jar = new File(project, "target/build-image-classifier-source-0.0.1.BUILD-SNAPSHOT-test.jar"); | ||||
| 					assertThat(jar).isFile(); | ||||
| 					File original = new File(project, | ||||
| 							"target/build-image-classifier-source-0.0.1.BUILD-SNAPSHOT-test.jar.original"); | ||||
| 					assertThat(original).doesNotExist(); | ||||
| 					assertThat(buildLog(project)).contains("Building image") | ||||
| 							.contains("docker.io/library/build-image-classifier-source:0.0.1.BUILD-SNAPSHOT") | ||||
| 							.contains("Successfully built image"); | ||||
| 					ImageReference imageReference = ImageReference.of(ImageName.of("build-image-classifier-source"), | ||||
| 							"0.0.1.BUILD-SNAPSHOT"); | ||||
| 					try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) { | ||||
| 						container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); | ||||
| 					} | ||||
| 					finally { | ||||
| 						removeImage(imageReference); | ||||
| 					} | ||||
| 				}); | ||||
| 	} | ||||
| 
 | ||||
| 	@TestTemplate | ||||
| 	void whenBuildImageIsInvokedWithRepackageTheExistingArchiveIsUsed(MavenBuild mavenBuild) { | ||||
| 		mavenBuild.project("build-image-with-repackage").goals("package") | ||||
|  | @ -92,6 +140,56 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests { | |||
| 				}); | ||||
| 	} | ||||
| 
 | ||||
| 	@TestTemplate | ||||
| 	void whenBuildImageIsInvokedWithClassifierAndRepackageTheExistingArchiveIsUsed(MavenBuild mavenBuild) { | ||||
| 		mavenBuild.project("build-image-classifier-with-repackage").goals("package") | ||||
| 				.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT") | ||||
| 				.prepare(this::writeLongNameResource).execute((project) -> { | ||||
| 					File jar = new File(project, | ||||
| 							"target/build-image-classifier-with-repackage-0.0.1.BUILD-SNAPSHOT.jar"); | ||||
| 					assertThat(jar).isFile(); | ||||
| 					File original = new File(project, | ||||
| 							"target/build-image-classifier-with-repackage-0.0.1.BUILD-SNAPSHOT-test.jar"); | ||||
| 					assertThat(original).isFile(); | ||||
| 					assertThat(buildLog(project)).contains("Building image") | ||||
| 							.contains("docker.io/library/build-image-classifier-with-repackage:0.0.1.BUILD-SNAPSHOT") | ||||
| 							.contains("Successfully built image"); | ||||
| 					ImageReference imageReference = ImageReference | ||||
| 							.of(ImageName.of("build-image-classifier-with-repackage"), "0.0.1.BUILD-SNAPSHOT"); | ||||
| 					try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) { | ||||
| 						container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); | ||||
| 					} | ||||
| 					finally { | ||||
| 						removeImage(imageReference); | ||||
| 					} | ||||
| 				}); | ||||
| 	} | ||||
| 
 | ||||
| 	@TestTemplate | ||||
| 	void whenBuildImageIsInvokedWithClassifierSourceAndRepackageTheExistingArchiveIsUsed(MavenBuild mavenBuild) { | ||||
| 		mavenBuild.project("build-image-classifier-source-with-repackage").goals("package") | ||||
| 				.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT") | ||||
| 				.prepare(this::writeLongNameResource).execute((project) -> { | ||||
| 					File jar = new File(project, | ||||
| 							"target/build-image-classifier-source-with-repackage-0.0.1.BUILD-SNAPSHOT-test.jar"); | ||||
| 					assertThat(jar).isFile(); | ||||
| 					File original = new File(project, | ||||
| 							"target/build-image-classifier-source-with-repackage-0.0.1.BUILD-SNAPSHOT-test.jar.original"); | ||||
| 					assertThat(original).isFile(); | ||||
| 					assertThat(buildLog(project)).contains("Building image").contains( | ||||
| 							"docker.io/library/build-image-classifier-source-with-repackage:0.0.1.BUILD-SNAPSHOT") | ||||
| 							.contains("Successfully built image"); | ||||
| 					ImageReference imageReference = ImageReference | ||||
| 							.of(ImageName.of("build-image-classifier-source-with-repackage"), "0.0.1.BUILD-SNAPSHOT"); | ||||
| 					try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) { | ||||
| 						container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); | ||||
| 					} | ||||
| 					finally { | ||||
| 						removeImage(imageReference); | ||||
| 					} | ||||
| 				}); | ||||
| 	} | ||||
| 
 | ||||
| 	@TestTemplate | ||||
| 	void whenBuildImageIsInvokedWithCustomImageName(MavenBuild mavenBuild) { | ||||
| 		mavenBuild.project("build-image-custom-name").goals("package") | ||||
|  |  | |||
|  | @ -0,0 +1,54 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
| 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
| 	<modelVersion>4.0.0</modelVersion> | ||||
| 	<groupId>org.springframework.boot.maven.it</groupId> | ||||
| 	<artifactId>build-image-classifier-source-with-repackage</artifactId> | ||||
| 	<version>0.0.1.BUILD-SNAPSHOT</version> | ||||
| 	<properties> | ||||
| 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
| 		<maven.compiler.source>@java.version@</maven.compiler.source> | ||||
| 		<maven.compiler.target>@java.version@</maven.compiler.target> | ||||
| 	</properties> | ||||
| 	<build> | ||||
| 		<plugins> | ||||
| 			<plugin> | ||||
| 				<groupId>org.apache.maven.plugins</groupId> | ||||
| 				<artifactId>maven-jar-plugin</artifactId> | ||||
| 				<version>3.2.0</version> | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<phase>package</phase> | ||||
| 						<goals> | ||||
| 							<goal>jar</goal> | ||||
| 						</goals> | ||||
| 						<configuration> | ||||
| 							<classifier>test</classifier> | ||||
| 						</configuration> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 			</plugin> | ||||
| 			<plugin> | ||||
| 				<groupId>@project.groupId@</groupId> | ||||
| 				<artifactId>@project.artifactId@</artifactId> | ||||
| 				<version>@project.version@</version> | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<id>repackage</id> | ||||
| 						<goals> | ||||
| 							<goal>repackage</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 					<execution> | ||||
| 						<goals> | ||||
| 							<goal>build-image</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 				<configuration> | ||||
| 					<classifier>test</classifier> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| </project> | ||||
|  | @ -0,0 +1,28 @@ | |||
| /* | ||||
|  * Copyright 2012-2021 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package org.test; | ||||
| 
 | ||||
| public class SampleApplication { | ||||
| 
 | ||||
| 	public static void main(String[] args) throws Exception { | ||||
| 		System.out.println("Launched"); | ||||
| 		synchronized(args) { | ||||
| 			args.wait(); // Prevent exit" | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,48 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
| 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
| 	<modelVersion>4.0.0</modelVersion> | ||||
| 	<groupId>org.springframework.boot.maven.it</groupId> | ||||
| 	<artifactId>build-image-classifier-source</artifactId> | ||||
| 	<version>0.0.1.BUILD-SNAPSHOT</version> | ||||
| 	<properties> | ||||
| 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
| 		<maven.compiler.source>@java.version@</maven.compiler.source> | ||||
| 		<maven.compiler.target>@java.version@</maven.compiler.target> | ||||
| 	</properties> | ||||
| 	<build> | ||||
| 		<plugins> | ||||
| 			<plugin> | ||||
| 				<groupId>org.apache.maven.plugins</groupId> | ||||
| 				<artifactId>maven-jar-plugin</artifactId> | ||||
| 				<version>3.2.0</version> | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<phase>package</phase> | ||||
| 						<goals> | ||||
| 							<goal>jar</goal> | ||||
| 						</goals> | ||||
| 						<configuration> | ||||
| 							<classifier>test</classifier> | ||||
| 						</configuration> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 			</plugin> | ||||
| 			<plugin> | ||||
| 				<groupId>@project.groupId@</groupId> | ||||
| 				<artifactId>@project.artifactId@</artifactId> | ||||
| 				<version>@project.version@</version> | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<goals> | ||||
| 							<goal>build-image</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 				<configuration> | ||||
| 					<classifier>test</classifier> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| </project> | ||||
|  | @ -0,0 +1,28 @@ | |||
| /* | ||||
|  * Copyright 2012-2021 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package org.test; | ||||
| 
 | ||||
| public class SampleApplication { | ||||
| 
 | ||||
| 	public static void main(String[] args) throws Exception { | ||||
| 		System.out.println("Launched"); | ||||
| 		synchronized(args) { | ||||
| 			args.wait(); // Prevent exit" | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,38 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
| 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
| 	<modelVersion>4.0.0</modelVersion> | ||||
| 	<groupId>org.springframework.boot.maven.it</groupId> | ||||
| 	<artifactId>build-image-classifier-with-repackage</artifactId> | ||||
| 	<version>0.0.1.BUILD-SNAPSHOT</version> | ||||
| 	<properties> | ||||
| 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
| 		<maven.compiler.source>@java.version@</maven.compiler.source> | ||||
| 		<maven.compiler.target>@java.version@</maven.compiler.target> | ||||
| 	</properties> | ||||
| 	<build> | ||||
| 		<plugins> | ||||
| 			<plugin> | ||||
| 				<groupId>@project.groupId@</groupId> | ||||
| 				<artifactId>@project.artifactId@</artifactId> | ||||
| 				<version>@project.version@</version> | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<id>repackage</id> | ||||
| 						<goals> | ||||
| 							<goal>repackage</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 					<execution> | ||||
| 						<goals> | ||||
| 							<goal>build-image</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 				<configuration> | ||||
| 					<classifier>test</classifier> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| </project> | ||||
|  | @ -0,0 +1,28 @@ | |||
| /* | ||||
|  * Copyright 2012-2021 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package org.test; | ||||
| 
 | ||||
| public class SampleApplication { | ||||
| 
 | ||||
| 	public static void main(String[] args) throws Exception { | ||||
| 		System.out.println("Launched"); | ||||
| 		synchronized(args) { | ||||
| 			args.wait(); // Prevent exit" | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,32 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
| 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
| 	<modelVersion>4.0.0</modelVersion> | ||||
| 	<groupId>org.springframework.boot.maven.it</groupId> | ||||
| 	<artifactId>build-image-classifier</artifactId> | ||||
| 	<version>0.0.1.BUILD-SNAPSHOT</version> | ||||
| 	<properties> | ||||
| 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
| 		<maven.compiler.source>@java.version@</maven.compiler.source> | ||||
| 		<maven.compiler.target>@java.version@</maven.compiler.target> | ||||
| 	</properties> | ||||
| 	<build> | ||||
| 		<plugins> | ||||
| 			<plugin> | ||||
| 				<groupId>@project.groupId@</groupId> | ||||
| 				<artifactId>@project.artifactId@</artifactId> | ||||
| 				<version>@project.version@</version> | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<goals> | ||||
| 							<goal>build-image</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 				<configuration> | ||||
| 					<classifier>test</classifier> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| </project> | ||||
|  | @ -0,0 +1,28 @@ | |||
| /* | ||||
|  * Copyright 2012-2021 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package org.test; | ||||
| 
 | ||||
| public class SampleApplication { | ||||
| 
 | ||||
| 	public static void main(String[] args) throws Exception { | ||||
| 		System.out.println("Launched"); | ||||
| 		synchronized(args) { | ||||
| 			args.wait(); // Prevent exit" | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -201,6 +201,42 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo | |||
| 		return filters.toArray(new ArtifactsFilter[0]); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Return the source {@link Artifact} to repackage. If a classifier is specified and | ||||
| 	 * an artifact with that classifier exists, it is used. Otherwise, the main artifact | ||||
| 	 * is used. | ||||
| 	 * @param classifier the artifact classifier | ||||
| 	 * @return the source artifact to repackage | ||||
| 	 */ | ||||
| 	protected Artifact getSourceArtifact(String classifier) { | ||||
| 		Artifact sourceArtifact = getArtifact(classifier); | ||||
| 		return (sourceArtifact != null) ? sourceArtifact : this.project.getArtifact(); | ||||
| 	} | ||||
| 
 | ||||
| 	private Artifact getArtifact(String classifier) { | ||||
| 		if (classifier != null) { | ||||
| 			for (Artifact attachedArtifact : this.project.getAttachedArtifacts()) { | ||||
| 				if (classifier.equals(attachedArtifact.getClassifier()) && attachedArtifact.getFile() != null | ||||
| 						&& attachedArtifact.getFile().isFile()) { | ||||
| 					return attachedArtifact; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	protected File getTargetFile(String finalName, String classifier, File targetDirectory) { | ||||
| 		String classifierSuffix = (classifier != null) ? classifier.trim() : ""; | ||||
| 		if (!classifierSuffix.isEmpty() && !classifierSuffix.startsWith("-")) { | ||||
| 			classifierSuffix = "-" + classifierSuffix; | ||||
| 		} | ||||
| 		if (!targetDirectory.exists()) { | ||||
| 			targetDirectory.mkdirs(); | ||||
| 		} | ||||
| 		return new File(targetDirectory, | ||||
| 				finalName + classifierSuffix + "." + this.project.getArtifact().getArtifactHandler().getExtension()); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Archive layout types. | ||||
| 	 */ | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ import java.util.zip.ZipEntry; | |||
| import org.apache.commons.compress.archivers.tar.TarArchiveEntry; | ||||
| import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; | ||||
| import org.apache.commons.compress.archivers.tar.TarConstants; | ||||
| import org.apache.maven.artifact.Artifact; | ||||
| import org.apache.maven.plugin.MojoExecutionException; | ||||
| import org.apache.maven.plugin.logging.Log; | ||||
| import org.apache.maven.plugins.annotations.Execute; | ||||
|  | @ -72,14 +73,14 @@ public class BuildImageMojo extends AbstractPackagerMojo { | |||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Directory containing the JAR. | ||||
| 	 * Directory containing the source archive. | ||||
| 	 * @since 2.3.0 | ||||
| 	 */ | ||||
| 	@Parameter(defaultValue = "${project.build.directory}", required = true) | ||||
| 	private File sourceDirectory; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Name of the JAR. | ||||
| 	 * Name of the source archive. | ||||
| 	 * @since 2.3.0 | ||||
| 	 */ | ||||
| 	@Parameter(defaultValue = "${project.build.finalName}", readonly = true) | ||||
|  | @ -93,7 +94,7 @@ public class BuildImageMojo extends AbstractPackagerMojo { | |||
| 	private boolean skip; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Classifier used when finding the source jar. | ||||
| 	 * Classifier used when finding the source archive. | ||||
| 	 * @since 2.3.0 | ||||
| 	 */ | ||||
| 	@Parameter | ||||
|  | @ -186,7 +187,7 @@ public class BuildImageMojo extends AbstractPackagerMojo { | |||
| 	} | ||||
| 
 | ||||
| 	private BuildRequest getBuildRequest(Libraries libraries) throws MojoExecutionException { | ||||
| 		ImagePackager imagePackager = new ImagePackager(getJarFile()); | ||||
| 		ImagePackager imagePackager = new ImagePackager(getArchiveFile(), getBackupFile()); | ||||
| 		Function<Owner, TarArchive> content = (owner) -> getApplicationContent(owner, libraries, imagePackager); | ||||
| 		Image image = (this.image != null) ? this.image : new Image(); | ||||
| 		if (image.name == null && this.imageName != null) { | ||||
|  | @ -223,19 +224,32 @@ public class BuildImageMojo extends AbstractPackagerMojo { | |||
| 		return new PackagedTarArchive(owner, libraries, packager); | ||||
| 	} | ||||
| 
 | ||||
| 	private File getJarFile() { | ||||
| 	private File getArchiveFile() { | ||||
| 		// We can use 'project.getArtifact().getFile()' because that was done in a | ||||
| 		// forked lifecycle and is now null | ||||
| 		StringBuilder name = new StringBuilder(this.finalName); | ||||
| 		if (StringUtils.hasText(this.classifier)) { | ||||
| 			name.append("-").append(this.classifier); | ||||
| 		File archiveFile = getTargetFile(this.finalName, this.classifier, this.sourceDirectory); | ||||
| 		if (!archiveFile.exists()) { | ||||
| 			archiveFile = getSourceArtifact(this.classifier).getFile(); | ||||
| 		} | ||||
| 		name.append(".jar"); | ||||
| 		File jarFile = new File(this.sourceDirectory, name.toString()); | ||||
| 		if (!jarFile.exists()) { | ||||
| 		if (!archiveFile.exists()) { | ||||
| 			throw new IllegalStateException("Executable jar file required for building image"); | ||||
| 		} | ||||
| 		return jarFile; | ||||
| 		if (archiveFile.getName().endsWith(".war")) { | ||||
| 			throw new IllegalStateException("Executable jar file required for building image"); | ||||
| 		} | ||||
| 		return archiveFile; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Return the {@link File} to use to backup the original source. | ||||
| 	 * @return the file to use to backup the original source | ||||
| 	 */ | ||||
| 	private File getBackupFile() { | ||||
| 		Artifact source = getSourceArtifact(null); | ||||
| 		if (this.classifier != null && !this.classifier.equals(source.getClassifier())) { | ||||
| 			return source.getFile(); | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	private BuildRequest customize(BuildRequest request) { | ||||
|  |  | |||
|  | @ -207,8 +207,8 @@ public class RepackageMojo extends AbstractPackagerMojo { | |||
| 	} | ||||
| 
 | ||||
| 	private void repackage() throws MojoExecutionException { | ||||
| 		Artifact source = getSourceArtifact(); | ||||
| 		File target = getTargetFile(); | ||||
| 		Artifact source = getSourceArtifact(this.classifier); | ||||
| 		File target = getTargetFile(this.finalName, this.classifier, this.outputDirectory); | ||||
| 		Repackager repackager = getRepackager(source.getFile()); | ||||
| 		Libraries libraries = getLibraries(this.requiresUnpack); | ||||
| 		try { | ||||
|  | @ -239,41 +239,6 @@ public class RepackageMojo extends AbstractPackagerMojo { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Return the source {@link Artifact} to repackage. If a classifier is specified and | ||||
| 	 * an artifact with that classifier exists, it is used. Otherwise, the main artifact | ||||
| 	 * is used. | ||||
| 	 * @return the source artifact to repackage | ||||
| 	 */ | ||||
| 	private Artifact getSourceArtifact() { | ||||
| 		Artifact sourceArtifact = getArtifact(this.classifier); | ||||
| 		return (sourceArtifact != null) ? sourceArtifact : this.project.getArtifact(); | ||||
| 	} | ||||
| 
 | ||||
| 	private Artifact getArtifact(String classifier) { | ||||
| 		if (classifier != null) { | ||||
| 			for (Artifact attachedArtifact : this.project.getAttachedArtifacts()) { | ||||
| 				if (classifier.equals(attachedArtifact.getClassifier()) && attachedArtifact.getFile() != null | ||||
| 						&& attachedArtifact.getFile().isFile()) { | ||||
| 					return attachedArtifact; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	private File getTargetFile() { | ||||
| 		String classifier = (this.classifier != null) ? this.classifier.trim() : ""; | ||||
| 		if (!classifier.isEmpty() && !classifier.startsWith("-")) { | ||||
| 			classifier = "-" + classifier; | ||||
| 		} | ||||
| 		if (!this.outputDirectory.exists()) { | ||||
| 			this.outputDirectory.mkdirs(); | ||||
| 		} | ||||
| 		return new File(this.outputDirectory, | ||||
| 				this.finalName + classifier + "." + this.project.getArtifact().getArtifactHandler().getExtension()); | ||||
| 	} | ||||
| 
 | ||||
| 	private Repackager getRepackager(File source) { | ||||
| 		return getConfiguredPackager(() -> new Repackager(source)); | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue