Write native-image argfile only if there are excludes
Refactors duplicate logic in BootZipCopyAction and Packager into separate classes. Closes gh-33363 Co-authored-by: Phillip Webb <pwebb@vmware.com>
This commit is contained in:
		
							parent
							
								
									276b288891
								
							
						
					
					
						commit
						c6536c54d8
					
				| 
						 | 
				
			
			@ -22,7 +22,6 @@ import java.io.IOException;
 | 
			
		|||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.io.OutputStreamWriter;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.GregorianCalendar;
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +30,6 @@ import java.util.LinkedHashMap;
 | 
			
		|||
import java.util.LinkedHashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
| 
						 | 
				
			
			@ -59,6 +57,8 @@ import org.springframework.boot.loader.tools.JarModeLibrary;
 | 
			
		|||
import org.springframework.boot.loader.tools.Layer;
 | 
			
		||||
import org.springframework.boot.loader.tools.LayersIndex;
 | 
			
		||||
import org.springframework.boot.loader.tools.LibraryCoordinates;
 | 
			
		||||
import org.springframework.boot.loader.tools.NativeImageArgFile;
 | 
			
		||||
import org.springframework.boot.loader.tools.ReachabilityMetadataProperties;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.util.StreamUtils;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
| 
						 | 
				
			
			@ -76,10 +76,9 @@ class BootZipCopyAction implements CopyAction {
 | 
			
		|||
	static final long CONSTANT_TIME_FOR_ZIP_ENTRIES = new GregorianCalendar(1980, Calendar.FEBRUARY, 1, 0, 0, 0)
 | 
			
		||||
			.getTimeInMillis();
 | 
			
		||||
 | 
			
		||||
	private static final String REACHABILITY_METADATA_PROPERTIES_LOCATION = "META-INF/native-image/%s/%s/%s/reachability-metadata.properties";
 | 
			
		||||
 | 
			
		||||
	private static final Pattern REACHABILITY_METADATA_PROPERTIES_LOCATION_PATTERN = Pattern
 | 
			
		||||
			.compile(REACHABILITY_METADATA_PROPERTIES_LOCATION.formatted(".*", ".*", ".*"));
 | 
			
		||||
			.compile(ReachabilityMetadataProperties.REACHABILITY_METADATA_PROPERTIES_LOCATION_TEMPLATE.formatted(".*",
 | 
			
		||||
					".*", ".*"));
 | 
			
		||||
 | 
			
		||||
	private final File output;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -355,32 +354,23 @@ class BootZipCopyAction implements CopyAction {
 | 
			
		|||
				DependencyDescriptor descriptor = BootZipCopyAction.this.resolvedDependencies
 | 
			
		||||
						.find(entry.getValue().getFile());
 | 
			
		||||
				LibraryCoordinates coordinates = (descriptor != null) ? descriptor.getCoordinates() : null;
 | 
			
		||||
				FileCopyDetails propertiesFile = (coordinates != null)
 | 
			
		||||
						? this.reachabilityMetadataProperties.get(REACHABILITY_METADATA_PROPERTIES_LOCATION.formatted(
 | 
			
		||||
								coordinates.getGroupId(), coordinates.getArtifactId(), coordinates.getVersion()))
 | 
			
		||||
						: null;
 | 
			
		||||
				FileCopyDetails propertiesFile = (coordinates != null) ? this.reachabilityMetadataProperties
 | 
			
		||||
						.get(ReachabilityMetadataProperties.getLocation(coordinates)) : null;
 | 
			
		||||
				if (propertiesFile != null) {
 | 
			
		||||
					try (InputStream inputStream = propertiesFile.open()) {
 | 
			
		||||
						Properties properties = new Properties();
 | 
			
		||||
						properties.load(inputStream);
 | 
			
		||||
						if (Boolean.parseBoolean(properties.getProperty("override"))) {
 | 
			
		||||
						ReachabilityMetadataProperties properties = ReachabilityMetadataProperties
 | 
			
		||||
								.fromInputStream(inputStream);
 | 
			
		||||
						if (properties.isOverridden()) {
 | 
			
		||||
							excludes.add(entry.getKey());
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (excludes != null) {
 | 
			
		||||
				List<String> args = new ArrayList<>();
 | 
			
		||||
				for (String exclude : excludes) {
 | 
			
		||||
					int lastSlash = exclude.lastIndexOf('/');
 | 
			
		||||
					String jar = (lastSlash != -1) ? exclude.substring(lastSlash + 1) : exclude;
 | 
			
		||||
					args.add("--exclude-config");
 | 
			
		||||
					args.add(Pattern.quote(jar));
 | 
			
		||||
					args.add("^/META-INF/native-image/.*");
 | 
			
		||||
				}
 | 
			
		||||
				ZipEntryContentWriter writer = ZipEntryContentWriter.fromLines(BootZipCopyAction.this.encoding, args);
 | 
			
		||||
				writeEntry("META-INF/native-image/argfile", writer, true);
 | 
			
		||||
			}
 | 
			
		||||
			NativeImageArgFile argFile = new NativeImageArgFile(excludes);
 | 
			
		||||
			argFile.writeIfNecessary((lines) -> {
 | 
			
		||||
				ZipEntryContentWriter writer = ZipEntryContentWriter.fromLines(BootZipCopyAction.this.encoding, lines);
 | 
			
		||||
				writeEntry(NativeImageArgFile.LOCATION, writer, true);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void writeLayersIndexIfNecessary() throws IOException {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -201,6 +201,13 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void nativeImageArgFileIsNotWrittenWhenExcludesAreEmpty() throws IOException {
 | 
			
		||||
		try (JarFile jarFile = new JarFile(createLayeredJar(false))) {
 | 
			
		||||
			assertThat(jarFile.getEntry("META-INF/native-image/argfile")).isNull();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void javaVersionIsWrittenToManifest() throws IOException {
 | 
			
		||||
		try (JarFile jarFile = new JarFile(createPopulatedJar())) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,69 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2022 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.springframework.boot.loader.tools;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
import org.springframework.util.function.ThrowingConsumer;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class to work with the native-image argfile.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Moritz Halbritter
 | 
			
		||||
 * @author Phil Webb
 | 
			
		||||
 * @since 3.0.0
 | 
			
		||||
 */
 | 
			
		||||
public final class NativeImageArgFile {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Location of the argfile.
 | 
			
		||||
	 */
 | 
			
		||||
	public static final String LOCATION = "META-INF/native-image/argfile";
 | 
			
		||||
 | 
			
		||||
	private final List<String> excludes;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructs a new instance with the given excludes.
 | 
			
		||||
	 * @param excludes dependencies for which the reachability metadata should be excluded
 | 
			
		||||
	 */
 | 
			
		||||
	public NativeImageArgFile(Collection<String> excludes) {
 | 
			
		||||
		this.excludes = List.copyOf(excludes);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Write the arguments file if it is necessary.
 | 
			
		||||
	 * @param writer consumer that should write the contents
 | 
			
		||||
	 */
 | 
			
		||||
	public void writeIfNecessary(ThrowingConsumer<List<String>> writer) {
 | 
			
		||||
		if (this.excludes.isEmpty()) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		List<String> lines = new ArrayList<>();
 | 
			
		||||
		for (String exclude : this.excludes) {
 | 
			
		||||
			int lastSlash = exclude.lastIndexOf('/');
 | 
			
		||||
			String jar = (lastSlash != -1) ? exclude.substring(lastSlash + 1) : exclude;
 | 
			
		||||
			lines.add("--exclude-config");
 | 
			
		||||
			lines.add(Pattern.quote(jar));
 | 
			
		||||
			lines.add("^/META-INF/native-image/.*");
 | 
			
		||||
		}
 | 
			
		||||
		writer.accept(lines);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +28,6 @@ import java.util.LinkedHashSet;
 | 
			
		|||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.TreeMap;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
| 
						 | 
				
			
			@ -37,8 +36,6 @@ import java.util.jar.Attributes;
 | 
			
		|||
import java.util.jar.JarEntry;
 | 
			
		||||
import java.util.jar.JarFile;
 | 
			
		||||
import java.util.jar.Manifest;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.zip.ZipEntry;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
 | 
			
		||||
| 
						 | 
				
			
			@ -61,8 +58,6 @@ import org.springframework.util.StringUtils;
 | 
			
		|||
 */
 | 
			
		||||
public abstract class Packager {
 | 
			
		||||
 | 
			
		||||
	private static final String REACHABILITY_METADATA_PROPERTIES_LOCATION = "META-INF/native-image/%s/%s/%s/reachability-metadata.properties";
 | 
			
		||||
 | 
			
		||||
	private static final String MAIN_CLASS_ATTRIBUTE = "Main-Class";
 | 
			
		||||
 | 
			
		||||
	private static final String START_CLASS_ATTRIBUTE = "Start-Class";
 | 
			
		||||
| 
						 | 
				
			
			@ -229,31 +224,24 @@ public abstract class Packager {
 | 
			
		|||
		Set<String> excludes = new LinkedHashSet<>();
 | 
			
		||||
		for (Map.Entry<String, Library> entry : writtenLibraries.entrySet()) {
 | 
			
		||||
			LibraryCoordinates coordinates = entry.getValue().getCoordinates();
 | 
			
		||||
			ZipEntry zipEntry = (coordinates != null) ? sourceJar.getEntry(REACHABILITY_METADATA_PROPERTIES_LOCATION
 | 
			
		||||
					.formatted(coordinates.getGroupId(), coordinates.getArtifactId(), coordinates.getVersion())) : null;
 | 
			
		||||
			ZipEntry zipEntry = (coordinates != null)
 | 
			
		||||
					? sourceJar.getEntry(ReachabilityMetadataProperties.getLocation(coordinates)) : null;
 | 
			
		||||
			if (zipEntry != null) {
 | 
			
		||||
				try (InputStream inputStream = sourceJar.getInputStream(zipEntry)) {
 | 
			
		||||
					Properties properties = new Properties();
 | 
			
		||||
					properties.load(inputStream);
 | 
			
		||||
					if (Boolean.parseBoolean(properties.getProperty("override"))) {
 | 
			
		||||
					ReachabilityMetadataProperties properties = ReachabilityMetadataProperties
 | 
			
		||||
							.fromInputStream(inputStream);
 | 
			
		||||
					if (properties.isOverridden()) {
 | 
			
		||||
						excludes.add(entry.getKey());
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!excludes.isEmpty()) {
 | 
			
		||||
			List<String> args = new ArrayList<>();
 | 
			
		||||
			for (String exclude : excludes) {
 | 
			
		||||
				int lastSlash = exclude.lastIndexOf('/');
 | 
			
		||||
				String jar = (lastSlash != -1) ? exclude.substring(lastSlash + 1) : exclude;
 | 
			
		||||
				args.add("--exclude-config");
 | 
			
		||||
				args.add(Pattern.quote(jar));
 | 
			
		||||
				args.add("^/META-INF/native-image/.*");
 | 
			
		||||
			}
 | 
			
		||||
			String contents = args.stream().collect(Collectors.joining("\n")) + "\n";
 | 
			
		||||
			writer.writeEntry("META-INF/native-image/argfile",
 | 
			
		||||
		NativeImageArgFile argFile = new NativeImageArgFile(excludes);
 | 
			
		||||
		argFile.writeIfNecessary((lines) -> {
 | 
			
		||||
			String contents = String.join("\n", lines) + "\n";
 | 
			
		||||
			writer.writeEntry(NativeImageArgFile.LOCATION,
 | 
			
		||||
					new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8)));
 | 
			
		||||
		}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void writeLayerIndex(AbstractJarWriter writer) throws IOException {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2022 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.springframework.boot.loader.tools;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class to work with {@code reachability-metadata.properties}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Moritz Halbritter
 | 
			
		||||
 * @since 3.0.0
 | 
			
		||||
 */
 | 
			
		||||
public final class ReachabilityMetadataProperties {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Location of the properties file. Must be formatted using
 | 
			
		||||
	 * {@link String#format(String, Object...)} with the group id, artifact id and version
 | 
			
		||||
	 * of the dependency.
 | 
			
		||||
	 */
 | 
			
		||||
	public static final String REACHABILITY_METADATA_PROPERTIES_LOCATION_TEMPLATE = "META-INF/native-image/%s/%s/%s/reachability-metadata.properties";
 | 
			
		||||
 | 
			
		||||
	private final Properties properties;
 | 
			
		||||
 | 
			
		||||
	private ReachabilityMetadataProperties(Properties properties) {
 | 
			
		||||
		this.properties = properties;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns if the dependency has been overridden.
 | 
			
		||||
	 * @return true if the dependency has been overridden
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isOverridden() {
 | 
			
		||||
		return Boolean.parseBoolean(this.properties.getProperty("override"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructs a new instance from the given {@code InputStream}.
 | 
			
		||||
	 * @param inputStream {@code InputStream} to load the properties from
 | 
			
		||||
	 * @return loaded properties
 | 
			
		||||
	 * @throws IOException if loading from the {@code InputStream} went wrong
 | 
			
		||||
	 */
 | 
			
		||||
	public static ReachabilityMetadataProperties fromInputStream(InputStream inputStream) throws IOException {
 | 
			
		||||
		Properties properties = new Properties();
 | 
			
		||||
		properties.load(inputStream);
 | 
			
		||||
		return new ReachabilityMetadataProperties(properties);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the location of the properties for the given coordinates.
 | 
			
		||||
	 * @param coordinates library coordinates for which the property file location should
 | 
			
		||||
	 * be returned
 | 
			
		||||
	 * @return location of the properties
 | 
			
		||||
	 */
 | 
			
		||||
	public static String getLocation(LibraryCoordinates coordinates) {
 | 
			
		||||
		return REACHABILITY_METADATA_PROPERTIES_LOCATION_TEMPLATE.formatted(coordinates.getGroupId(),
 | 
			
		||||
				coordinates.getArtifactId(), coordinates.getVersion());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2022 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.springframework.boot.loader.tools;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.fail;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for @{link NativeImageArgFile}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Moritz Halbritter
 | 
			
		||||
 */
 | 
			
		||||
class NativeImageArgFileTests {
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void writeIfNecessaryWhenHasExcludesWritesLines() {
 | 
			
		||||
		NativeImageArgFile argFile = new NativeImageArgFile(List.of("path/to/dependency-1.jar", "dependency-2.jar"));
 | 
			
		||||
		List<String> lines = new ArrayList<>();
 | 
			
		||||
		argFile.writeIfNecessary(lines::addAll);
 | 
			
		||||
		assertThat(lines).containsExactly("--exclude-config", "\\Qdependency-1.jar\\E", "^/META-INF/native-image/.*",
 | 
			
		||||
				"--exclude-config", "\\Qdependency-2.jar\\E", "^/META-INF/native-image/.*");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void writeIfNecessaryWhenHasNothingDoesNotCallConsumer() {
 | 
			
		||||
		NativeImageArgFile argFile = new NativeImageArgFile(Collections.emptyList());
 | 
			
		||||
		argFile.writeIfNecessary((lines) -> fail("Should not be called"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2022 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.springframework.boot.loader.tools;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for {@link ReachabilityMetadataProperties}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Moritz Halbritter
 | 
			
		||||
 */
 | 
			
		||||
class ReachabilityMetadataPropertiesTests {
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void shouldReadFromInputStream() throws IOException {
 | 
			
		||||
		String propertiesContent = "override=true\n";
 | 
			
		||||
		ReachabilityMetadataProperties properties = ReachabilityMetadataProperties
 | 
			
		||||
				.fromInputStream(new ByteArrayInputStream(propertiesContent.getBytes(StandardCharsets.UTF_8)));
 | 
			
		||||
		assertThat(properties.isOverridden()).isTrue();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void shouldFormatLocation() {
 | 
			
		||||
		String location = ReachabilityMetadataProperties
 | 
			
		||||
				.getLocation(LibraryCoordinates.of("group-id", "artifact-id", "1.0.0"));
 | 
			
		||||
		assertThat(location)
 | 
			
		||||
				.isEqualTo("META-INF/native-image/group-id/artifact-id/1.0.0/reachability-metadata.properties");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue