Merge pull request #21207 from PaddyDrury
* gh-21207: Polish "Stop limiting layer customization to external modules" Stop limiting layer customization to external modules Closes gh-21207
This commit is contained in:
		
						commit
						767156167b
					
				|  | @ -24,11 +24,10 @@ import java.util.LinkedHashMap; | |||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| import org.gradle.api.artifacts.ArtifactCollection; | ||||
| import org.gradle.api.artifacts.Configuration; | ||||
| import org.gradle.api.artifacts.component.ComponentIdentifier; | ||||
| import org.gradle.api.artifacts.component.ModuleComponentIdentifier; | ||||
| import org.gradle.api.artifacts.result.ResolvedArtifactResult; | ||||
| import org.gradle.api.artifacts.ModuleVersionIdentifier; | ||||
| import org.gradle.api.artifacts.ResolvedArtifact; | ||||
| import org.gradle.api.artifacts.ResolvedConfiguration; | ||||
| import org.gradle.api.file.FileCopyDetails; | ||||
| import org.gradle.api.specs.Spec; | ||||
| 
 | ||||
|  | @ -43,6 +42,7 @@ import org.springframework.boot.loader.tools.LibraryCoordinates; | |||
|  * @author Madhura Bhave | ||||
|  * @author Scott Frederick | ||||
|  * @author Phillip Webb | ||||
|  * @author Paddy Drury | ||||
|  * @see BootZipCopyAction | ||||
|  */ | ||||
| class LayerResolver { | ||||
|  | @ -110,7 +110,7 @@ class LayerResolver { | |||
| 			if (configuration.isCanBeResolved() | ||||
| 					&& !DEPRECATED_FOR_RESOLUTION_CONFIGURATIONS.contains(configuration.getName())) { | ||||
| 				this.configurationDependencies.put(configuration, | ||||
| 						new ResolvedConfigurationDependencies(configuration.getIncoming().getArtifacts())); | ||||
| 						new ResolvedConfigurationDependencies(configuration.getResolvedConfiguration())); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -133,16 +133,10 @@ class LayerResolver { | |||
| 
 | ||||
| 		private final Map<File, LibraryCoordinates> artifactCoordinates = new LinkedHashMap<>(); | ||||
| 
 | ||||
| 		ResolvedConfigurationDependencies(ArtifactCollection resolvedDependencies) { | ||||
| 			if (resolvedDependencies != null) { | ||||
| 				for (ResolvedArtifactResult resolvedArtifact : resolvedDependencies.getArtifacts()) { | ||||
| 					ComponentIdentifier identifier = resolvedArtifact.getId().getComponentIdentifier(); | ||||
| 					if (identifier instanceof ModuleComponentIdentifier) { | ||||
| 						this.artifactCoordinates.put(resolvedArtifact.getFile(), | ||||
| 								new ModuleComponentIdentifierLibraryCoordinates( | ||||
| 										(ModuleComponentIdentifier) identifier)); | ||||
| 					} | ||||
| 				} | ||||
| 		ResolvedConfigurationDependencies(ResolvedConfiguration resolvedConfiguration) { | ||||
| 			for (ResolvedArtifact resolvedArtifact : resolvedConfiguration.getResolvedArtifacts()) { | ||||
| 				this.artifactCoordinates.put(resolvedArtifact.getFile(), | ||||
| 						new ModuleVersionIdentifierLibraryCoordinates(resolvedArtifact.getModuleVersion().getId())); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -153,13 +147,13 @@ class LayerResolver { | |||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Adapts a {@link ModuleComponentIdentifier} to {@link LibraryCoordinates}. | ||||
| 	 * Adapts a {@link ModuleVersionIdentifier} to {@link LibraryCoordinates}. | ||||
| 	 */ | ||||
| 	private static class ModuleComponentIdentifierLibraryCoordinates implements LibraryCoordinates { | ||||
| 	private static class ModuleVersionIdentifierLibraryCoordinates implements LibraryCoordinates { | ||||
| 
 | ||||
| 		private final ModuleComponentIdentifier identifier; | ||||
| 		private final ModuleVersionIdentifier identifier; | ||||
| 
 | ||||
| 		ModuleComponentIdentifierLibraryCoordinates(ModuleComponentIdentifier identifier) { | ||||
| 		ModuleVersionIdentifierLibraryCoordinates(ModuleVersionIdentifier identifier) { | ||||
| 			this.identifier = identifier; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -170,7 +164,7 @@ class LayerResolver { | |||
| 
 | ||||
| 		@Override | ||||
| 		public String getArtifactId() { | ||||
| 			return this.identifier.getModule(); | ||||
| 			return this.identifier.getName(); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
|  |  | |||
|  | @ -53,6 +53,7 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
|  * | ||||
|  * @author Andy Wilkinson | ||||
|  * @author Madhura Bhave | ||||
|  * @author Paddy Drury | ||||
|  */ | ||||
| class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { | ||||
| 
 | ||||
|  | @ -176,6 +177,64 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { | |||
| 		assertExtractedLayers(layerNames, indexedLayers); | ||||
| 	} | ||||
| 
 | ||||
| 	@TestTemplate | ||||
| 	void multiModuleCustomLayers() throws IOException { | ||||
| 		writeSettingsGradle(); | ||||
| 		writeMainClass(); | ||||
| 		writeResource(); | ||||
| 		BuildResult build = this.gradleBuild.build("bootJar"); | ||||
| 		assertThat(build.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); | ||||
| 		Map<String, List<String>> indexedLayers; | ||||
| 		String layerToolsJar = "BOOT-INF/lib/" + JarModeLibrary.LAYER_TOOLS.getName(); | ||||
| 		try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) { | ||||
| 			assertThat(jarFile.getEntry(layerToolsJar)).isNotNull(); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/alpha-1.2.3.jar")).isNotNull(); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/bravo-1.2.3.jar")).isNotNull(); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/commons-lang3-3.9.jar")).isNotNull(); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/spring-core-5.2.5.RELEASE.jar")).isNotNull(); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/spring-jcl-5.2.5.RELEASE.jar")).isNotNull(); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/commons-io-2.7-SNAPSHOT.jar")).isNotNull(); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/classes/example/Main.class")).isNotNull(); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/classes/static/file.txt")).isNotNull(); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/layers.idx")).isNotNull(); | ||||
| 			indexedLayers = readLayerIndex(jarFile); | ||||
| 		} | ||||
| 		List<String> layerNames = Arrays.asList("dependencies", "commons-dependencies", "snapshot-dependencies", | ||||
| 				"subproject-dependencies", "static", "app"); | ||||
| 		assertThat(indexedLayers.keySet()).containsExactlyElementsOf(layerNames); | ||||
| 		Set<String> expectedSubprojectDependencies = new TreeSet<>(); | ||||
| 		expectedSubprojectDependencies.add("BOOT-INF/lib/alpha-1.2.3.jar"); | ||||
| 		expectedSubprojectDependencies.add("BOOT-INF/lib/bravo-1.2.3.jar"); | ||||
| 		Set<String> expectedDependencies = new TreeSet<>(); | ||||
| 		expectedDependencies.add("BOOT-INF/lib/spring-core-5.2.5.RELEASE.jar"); | ||||
| 		expectedDependencies.add("BOOT-INF/lib/spring-jcl-5.2.5.RELEASE.jar"); | ||||
| 		List<String> expectedSnapshotDependencies = new ArrayList<>(); | ||||
| 		expectedSnapshotDependencies.add("BOOT-INF/lib/commons-io-2.7-SNAPSHOT.jar"); | ||||
| 		(layerToolsJar.contains("SNAPSHOT") ? expectedSnapshotDependencies : expectedDependencies).add(layerToolsJar); | ||||
| 		assertThat(indexedLayers.get("subproject-dependencies")) | ||||
| 				.containsExactlyElementsOf(expectedSubprojectDependencies); | ||||
| 		assertThat(indexedLayers.get("dependencies")).containsExactlyElementsOf(expectedDependencies); | ||||
| 		assertThat(indexedLayers.get("commons-dependencies")).containsExactly("BOOT-INF/lib/commons-lang3-3.9.jar"); | ||||
| 		assertThat(indexedLayers.get("snapshot-dependencies")).containsExactlyElementsOf(expectedSnapshotDependencies); | ||||
| 		assertThat(indexedLayers.get("static")).containsExactly("BOOT-INF/classes/static/"); | ||||
| 		List<String> appLayer = new ArrayList<>(indexedLayers.get("app")); | ||||
| 		Set<String> nonLoaderEntries = new TreeSet<>(); | ||||
| 		nonLoaderEntries.add("BOOT-INF/classes/example/"); | ||||
| 		nonLoaderEntries.add("BOOT-INF/classpath.idx"); | ||||
| 		nonLoaderEntries.add("BOOT-INF/layers.idx"); | ||||
| 		nonLoaderEntries.add("META-INF/"); | ||||
| 		assertThat(appLayer).containsSubsequence(nonLoaderEntries); | ||||
| 		appLayer.removeAll(nonLoaderEntries); | ||||
| 		assertThat(appLayer).containsExactly("org/"); | ||||
| 		BuildResult listLayers = this.gradleBuild.build("listLayers"); | ||||
| 		assertThat(listLayers.task(":listLayers").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); | ||||
| 		String listLayersOutput = listLayers.getOutput(); | ||||
| 		assertThat(new BufferedReader(new StringReader(listLayersOutput)).lines()).containsSequence(layerNames); | ||||
| 		BuildResult extractLayers = this.gradleBuild.build("extractLayers"); | ||||
| 		assertThat(extractLayers.task(":extractLayers").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); | ||||
| 		assertExtractedLayers(layerNames, indexedLayers); | ||||
| 	} | ||||
| 
 | ||||
| 	private void assertExtractedLayers(List<String> layerNames, Map<String, List<String>> indexedLayers) | ||||
| 			throws IOException { | ||||
| 		Map<String, List<String>> extractedLayers = readExtractedLayers(this.gradleBuild.getProjectDir(), layerNames); | ||||
|  | @ -201,6 +260,16 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { | |||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	private void writeSettingsGradle() { | ||||
| 		try (PrintWriter writer = new PrintWriter( | ||||
| 				new FileWriter(new File(this.gradleBuild.getProjectDir(), "settings.gradle")))) { | ||||
| 			writer.println("include 'alpha', 'bravo'"); | ||||
| 		} | ||||
| 		catch (IOException ex) { | ||||
| 			throw new RuntimeException(ex); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private void writeMainClass() { | ||||
| 		File examplePackage = new File(this.gradleBuild.getProjectDir(), "src/main/java/example"); | ||||
| 		examplePackage.mkdirs(); | ||||
|  |  | |||
|  | @ -30,12 +30,14 @@ import java.util.stream.Collectors; | |||
| import java.util.zip.ZipEntry; | ||||
| 
 | ||||
| import org.gradle.api.Action; | ||||
| import org.gradle.api.artifacts.ArtifactCollection; | ||||
| import org.gradle.api.artifacts.Configuration; | ||||
| import org.gradle.api.artifacts.ResolvableDependencies; | ||||
| import org.gradle.api.artifacts.ModuleVersionIdentifier; | ||||
| import org.gradle.api.artifacts.ResolvedArtifact; | ||||
| import org.gradle.api.artifacts.ResolvedConfiguration; | ||||
| import org.gradle.api.artifacts.ResolvedModuleVersion; | ||||
| import org.gradle.api.artifacts.component.ComponentArtifactIdentifier; | ||||
| import org.gradle.api.artifacts.component.ModuleComponentIdentifier; | ||||
| import org.gradle.api.artifacts.result.ResolvedArtifactResult; | ||||
| import org.gradle.api.artifacts.component.ProjectComponentIdentifier; | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| import org.springframework.boot.gradle.tasks.bundling.BootJarTests.TestBootJar; | ||||
|  | @ -51,6 +53,7 @@ import static org.mockito.Mockito.mock; | |||
|  * @author Andy Wilkinson | ||||
|  * @author Madhura Bhave | ||||
|  * @author Scott Frederick | ||||
|  * @author Paddy Drury | ||||
|  */ | ||||
| class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | ||||
| 
 | ||||
|  | @ -99,8 +102,10 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | |||
| 		try (JarFile jarFile = new JarFile(createLayeredJar())) { | ||||
| 			List<String> entryNames = getEntryNames(jarFile); | ||||
| 			assertThat(entryNames).contains("BOOT-INF/lib/first-library.jar", "BOOT-INF/lib/second-library.jar", | ||||
| 					"BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/classes/com/example/Application.class", | ||||
| 					"BOOT-INF/classes/application.properties", "BOOT-INF/classes/static/test.css"); | ||||
| 					"BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/lib/first-project-library.jar", | ||||
| 					"BOOT-INF/lib/second-project-library-SNAPSHOT.jar", | ||||
| 					"BOOT-INF/classes/com/example/Application.class", "BOOT-INF/classes/application.properties", | ||||
| 					"BOOT-INF/classes/static/test.css"); | ||||
| 			List<String> index = entryLines(jarFile, "BOOT-INF/layers.idx"); | ||||
| 			assertThat(getLayerNames(index)).containsExactly("dependencies", "spring-boot-loader", | ||||
| 					"snapshot-dependencies", "application"); | ||||
|  | @ -108,6 +113,7 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | |||
| 			List<String> expected = new ArrayList<>(); | ||||
| 			expected.add("- \"dependencies\":"); | ||||
| 			expected.add("  - \"BOOT-INF/lib/first-library.jar\""); | ||||
| 			expected.add("  - \"BOOT-INF/lib/first-project-library.jar\""); | ||||
| 			expected.add("  - \"BOOT-INF/lib/second-library.jar\""); | ||||
| 			if (!layerToolsJar.contains("SNAPSHOT")) { | ||||
| 				expected.add("  - \"" + layerToolsJar + "\""); | ||||
|  | @ -115,6 +121,7 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | |||
| 			expected.add("- \"spring-boot-loader\":"); | ||||
| 			expected.add("  - \"org/\""); | ||||
| 			expected.add("- \"snapshot-dependencies\":"); | ||||
| 			expected.add("  - \"BOOT-INF/lib/second-project-library-SNAPSHOT.jar\""); | ||||
| 			if (layerToolsJar.contains("SNAPSHOT")) { | ||||
| 				expected.add("  - \"" + layerToolsJar + "\""); | ||||
| 			} | ||||
|  | @ -145,8 +152,10 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | |||
| 		try (JarFile jarFile = new JarFile(jar)) { | ||||
| 			List<String> entryNames = getEntryNames(jar); | ||||
| 			assertThat(entryNames).contains("BOOT-INF/lib/first-library.jar", "BOOT-INF/lib/second-library.jar", | ||||
| 					"BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/classes/com/example/Application.class", | ||||
| 					"BOOT-INF/classes/application.properties", "BOOT-INF/classes/static/test.css"); | ||||
| 					"BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/lib/first-project-library.jar", | ||||
| 					"BOOT-INF/lib/second-project-library-SNAPSHOT.jar", | ||||
| 					"BOOT-INF/classes/com/example/Application.class", "BOOT-INF/classes/application.properties", | ||||
| 					"BOOT-INF/classes/static/test.css"); | ||||
| 			List<String> index = entryLines(jarFile, "BOOT-INF/layers.idx"); | ||||
| 			assertThat(getLayerNames(index)).containsExactly("my-deps", "my-internal-deps", "my-snapshot-deps", | ||||
| 					"resources", "application"); | ||||
|  | @ -156,8 +165,10 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | |||
| 			expected.add("  - \"" + layerToolsJar + "\""); | ||||
| 			expected.add("- \"my-internal-deps\":"); | ||||
| 			expected.add("  - \"BOOT-INF/lib/first-library.jar\""); | ||||
| 			expected.add("  - \"BOOT-INF/lib/first-project-library.jar\""); | ||||
| 			expected.add("  - \"BOOT-INF/lib/second-library.jar\""); | ||||
| 			expected.add("- \"my-snapshot-deps\":"); | ||||
| 			expected.add("  - \"BOOT-INF/lib/second-project-library-SNAPSHOT.jar\""); | ||||
| 			expected.add("  - \"BOOT-INF/lib/third-library-SNAPSHOT.jar\""); | ||||
| 			expected.add("- \"resources\":"); | ||||
| 			expected.add("  - \"BOOT-INF/classes/static/\""); | ||||
|  | @ -179,6 +190,10 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | |||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/second-library.jar").getMethod()).isEqualTo(ZipEntry.STORED); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/third-library-SNAPSHOT.jar").getMethod()) | ||||
| 					.isEqualTo(ZipEntry.STORED); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/first-project-library.jar").getMethod()) | ||||
| 					.isEqualTo(ZipEntry.STORED); | ||||
| 			assertThat(jarFile.getEntry("BOOT-INF/lib/second-project-library-SNAPSHOT.jar").getMethod()) | ||||
| 					.isEqualTo(ZipEntry.STORED); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -186,7 +201,8 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | |||
| 	void whenJarIsLayeredClasspathIndexPointsToLayeredLibs() throws IOException { | ||||
| 		try (JarFile jarFile = new JarFile(createLayeredJar())) { | ||||
| 			assertThat(entryLines(jarFile, "BOOT-INF/classpath.idx")).containsExactly("- \"first-library.jar\"", | ||||
| 					"- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\""); | ||||
| 					"- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\"", "- \"first-project-library.jar\"", | ||||
| 					"- \"second-project-library-SNAPSHOT.jar\""); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -209,7 +225,8 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | |||
| 			assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index")) | ||||
| 					.isEqualTo("BOOT-INF/classpath.idx"); | ||||
| 			assertThat(entryLines(jarFile, "BOOT-INF/classpath.idx")).containsExactly("- \"first-library.jar\"", | ||||
| 					"- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\""); | ||||
| 					"- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\"", "- \"first-project-library.jar\"", | ||||
| 					"- \"second-project-library-SNAPSHOT.jar\""); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -251,34 +268,55 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { | |||
| 		File css = new File(staticResources, "test.css"); | ||||
| 		css.createNewFile(); | ||||
| 		bootJar.classpath(classesJavaMain, resourcesMain, jarFile("first-library.jar"), jarFile("second-library.jar"), | ||||
| 				jarFile("third-library-SNAPSHOT.jar")); | ||||
| 		Set<ResolvedArtifactResult> artifacts = new LinkedHashSet<>(); | ||||
| 				jarFile("third-library-SNAPSHOT.jar"), jarFile("first-project-library.jar"), | ||||
| 				jarFile("second-project-library-SNAPSHOT.jar")); | ||||
| 		Set<ResolvedArtifact> artifacts = new LinkedHashSet<>(); | ||||
| 		artifacts.add(mockLibraryArtifact("first-library.jar", "com.example", "first-library", "1.0.0")); | ||||
| 		artifacts.add(mockLibraryArtifact("second-library.jar", "com.example", "second-library", "1.0.0")); | ||||
| 		artifacts.add( | ||||
| 				mockLibraryArtifact("third-library-SNAPSHOT.jar", "com.example", "third-library", "1.0.0.SNAPSHOT")); | ||||
| 		ArtifactCollection resolvedDependencies = mock(ArtifactCollection.class); | ||||
| 		given(resolvedDependencies.getArtifacts()).willReturn(artifacts); | ||||
| 		ResolvableDependencies resolvableDependencies = mock(ResolvableDependencies.class); | ||||
| 		given(resolvableDependencies.getArtifacts()).willReturn(resolvedDependencies); | ||||
| 		artifacts | ||||
| 				.add(mockProjectArtifact("first-project-library.jar", "com.example", "first-project-library", "1.0.0")); | ||||
| 		artifacts.add(mockProjectArtifact("second-project-library-SNAPSHOT.jar", "com.example", | ||||
| 				"second-project-library", "1.0.0.SNAPSHOT")); | ||||
| 		ResolvedConfiguration resolvedConfiguration = mock(ResolvedConfiguration.class); | ||||
| 		given(resolvedConfiguration.getResolvedArtifacts()).willReturn(artifacts); | ||||
| 		Configuration configuration = mock(Configuration.class); | ||||
| 		given(configuration.isCanBeResolved()).willReturn(true); | ||||
| 		given(configuration.getIncoming()).willReturn(resolvableDependencies); | ||||
| 		given(configuration.getResolvedConfiguration()).willReturn(resolvedConfiguration); | ||||
| 		bootJar.setConfiguration(Collections.singleton(configuration)); | ||||
| 	} | ||||
| 
 | ||||
| 	private ResolvedArtifactResult mockLibraryArtifact(String fileName, String group, String module, String version) { | ||||
| 		ModuleComponentIdentifier identifier = mock(ModuleComponentIdentifier.class); | ||||
| 		given(identifier.getGroup()).willReturn(group); | ||||
| 		given(identifier.getModule()).willReturn(module); | ||||
| 		given(identifier.getVersion()).willReturn(version); | ||||
| 	private ResolvedArtifact mockLibraryArtifact(String fileName, String group, String module, String version) { | ||||
| 		ModuleComponentIdentifier moduleComponentIdentifier = mock(ModuleComponentIdentifier.class); | ||||
| 		ComponentArtifactIdentifier libraryArtifactId = mock(ComponentArtifactIdentifier.class); | ||||
| 		given(libraryArtifactId.getComponentIdentifier()).willReturn(identifier); | ||||
| 		ResolvedArtifactResult libraryArtifact = mock(ResolvedArtifactResult.class); | ||||
| 		given(libraryArtifactId.getComponentIdentifier()).willReturn(moduleComponentIdentifier); | ||||
| 		ResolvedArtifact libraryArtifact = mockArtifact(fileName, group, module, version); | ||||
| 		given(libraryArtifact.getId()).willReturn(libraryArtifactId); | ||||
| 		return libraryArtifact; | ||||
| 	} | ||||
| 
 | ||||
| 	private ResolvedArtifact mockProjectArtifact(String fileName, String group, String module, String version) { | ||||
| 		ProjectComponentIdentifier projectComponentIdentifier = mock(ProjectComponentIdentifier.class); | ||||
| 		ComponentArtifactIdentifier projectArtifactId = mock(ComponentArtifactIdentifier.class); | ||||
| 		given(projectArtifactId.getComponentIdentifier()).willReturn(projectComponentIdentifier); | ||||
| 		ResolvedArtifact projectArtifact = mockArtifact(fileName, group, module, version); | ||||
| 		given(projectArtifact.getId()).willReturn(projectArtifactId); | ||||
| 		return projectArtifact; | ||||
| 	} | ||||
| 
 | ||||
| 	private ResolvedArtifact mockArtifact(String fileName, String group, String module, String version) { | ||||
| 		ModuleVersionIdentifier moduleVersionIdentifier = mock(ModuleVersionIdentifier.class); | ||||
| 		given(moduleVersionIdentifier.getGroup()).willReturn(group); | ||||
| 		given(moduleVersionIdentifier.getName()).willReturn(module); | ||||
| 		given(moduleVersionIdentifier.getVersion()).willReturn(version); | ||||
| 		ResolvedModuleVersion moduleVersion = mock(ResolvedModuleVersion.class); | ||||
| 		given(moduleVersion.getId()).willReturn(moduleVersionIdentifier); | ||||
| 		ResolvedArtifact libraryArtifact = mock(ResolvedArtifact.class); | ||||
| 		File file = new File(this.temp, fileName).getAbsoluteFile(); | ||||
| 		System.out.println(file); | ||||
| 		given(libraryArtifact.getFile()).willReturn(file); | ||||
| 		given(libraryArtifact.getId()).willReturn(libraryArtifactId); | ||||
| 		given(libraryArtifact.getModuleVersion()).willReturn(moduleVersion); | ||||
| 		return libraryArtifact; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,60 @@ | |||
| plugins { | ||||
| 	id 'java' | ||||
| 	id 'org.springframework.boot' version '{version}' | ||||
| } | ||||
| 
 | ||||
| subprojects { | ||||
| 	apply plugin: 'java' | ||||
| 	group = 'org.example.projects' | ||||
| 	version = '1.2.3' | ||||
| } | ||||
| 
 | ||||
| bootJar { | ||||
| 	mainClassName = 'com.example.Application' | ||||
| 	layered { | ||||
| 		application { | ||||
| 			intoLayer("static") { | ||||
| 				include "META-INF/resources/**", "resources/**", "static/**", "public/**" | ||||
| 			} | ||||
| 			intoLayer("app") | ||||
| 		} | ||||
| 		dependencies { | ||||
| 			intoLayer("subproject-dependencies") { | ||||
| 				include "org.example.projects:*" | ||||
| 			} | ||||
| 			intoLayer("snapshot-dependencies") { | ||||
| 				include "*:*:*SNAPSHOT" | ||||
| 			} | ||||
| 			intoLayer("commons-dependencies") { | ||||
| 				include "org.apache.commons:*"  | ||||
| 			} | ||||
| 			intoLayer("dependencies") | ||||
| 		} | ||||
| 		layerOrder = ["dependencies", "commons-dependencies", "snapshot-dependencies", "subproject-dependencies", "static", "app"] | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| repositories { | ||||
| 	mavenCentral() | ||||
| 	maven { url "https://repository.apache.org/content/repositories/snapshots" } | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
| 	implementation(project(':alpha')) | ||||
| 	implementation(project(':bravo')) | ||||
| 	implementation("commons-io:commons-io:2.7-SNAPSHOT") | ||||
| 	implementation("org.apache.commons:commons-lang3:3.9") | ||||
| 	implementation("org.springframework:spring-core:5.2.5.RELEASE") | ||||
| } | ||||
| 
 | ||||
| task listLayers(type: JavaExec) { | ||||
| 	classpath = bootJar.outputs.files | ||||
| 	systemProperties = [ "jarmode": "layertools" ] | ||||
| 	args "list" | ||||
| } | ||||
| 
 | ||||
| task extractLayers(type: JavaExec) { | ||||
| 	classpath = bootJar.outputs.files | ||||
| 	systemProperties = [ "jarmode": "layertools" ] | ||||
| 	args "extract" | ||||
| } | ||||
		Loading…
	
		Reference in New Issue