From 2650a07dc96171a028f2c84b0cdb26e2a5287c1b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 1 Feb 2019 13:46:22 +0000 Subject: [PATCH] Leave module-info.class in root of archive when repackaging Closes gh-15810 --- .../boot/gradle/tasks/bundling/BootJar.java | 6 +++-- .../boot/gradle/tasks/bundling/BootWar.java | 5 +++- .../bundling/AbstractBootArchiveTests.java | 26 ++++++++++++++++++- .../boot/loader/tools/Repackager.java | 5 ++-- .../boot/loader/tools/RepackagerTests.java | 16 +++++++++++- 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java index a9599e459ec..43916a3c2ed 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -55,13 +55,15 @@ public class BootJar extends Jar implements BootArchive { getMainSpec().with(this.bootInf); this.bootInf.into("classes", classpathFiles(File::isDirectory)); this.bootInf.into("lib", classpathFiles(File::isFile)); + this.bootInf.filesMatching("module-info.class", (details) -> { + details.setRelativePath(details.getRelativeSourcePath()); + }); } private Action classpathFiles(Spec filter) { return (copySpec) -> copySpec .from((Callable>) () -> (this.classpath != null) ? this.classpath.filter(filter) : Collections.emptyList()); - } @Override diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootWar.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootWar.java index 71d183fb85e..96760ba93ea 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootWar.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootWar.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -54,6 +54,9 @@ public class BootWar extends War implements BootArchive { (copySpec) -> copySpec.from( (Callable>) () -> (this.providedClasspath != null) ? this.providedClasspath : Collections.emptyList())); + getRootSpec().filesMatching("module-info.class", (details) -> { + details.setRelativePath(details.getRelativeSourcePath()); + }); } @Override diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveTests.java index 6461014cd0d..85483a6d698 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -133,6 +133,30 @@ public abstract class AbstractBootArchiveTests { } } + @Test + public void moduleInfoClassIsPackagedInTheRootOfTheArchive() throws IOException { + this.task.setMainClassName("com.example.Main"); + File classpathFolder = this.temp.newFolder(); + File moduleInfoClass = new File(classpathFolder, "module-info.class"); + moduleInfoClass.getParentFile().mkdirs(); + moduleInfoClass.createNewFile(); + File applicationClass = new File(classpathFolder, + "com/example/Application.class"); + applicationClass.getParentFile().mkdirs(); + applicationClass.createNewFile(); + this.task.classpath(classpathFolder); + this.task.execute(); + try (JarFile jarFile = new JarFile(this.task.getArchivePath())) { + assertThat( + jarFile.getEntry(this.classesPath + "/com/example/Application.class")) + .isNotNull(); + assertThat(jarFile.getEntry("com/example/Application.class")).isNull(); + assertThat(jarFile.getEntry("module-info.class")).isNotNull(); + assertThat(jarFile.getEntry(this.classesPath + "/module-info.class")) + .isNull(); + } + } + @Test public void classpathCanBeSetUsingAFileCollection() throws IOException { this.task.setMainClassName("com.example.Main"); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java index 4c764dea7d8..717da6f46a4 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -381,7 +381,8 @@ public class Repackager { } if ((entry.getName().startsWith("META-INF/") && !entry.getName().equals("META-INF/aop.xml")) - || entry.getName().startsWith("BOOT-INF/")) { + || entry.getName().startsWith("BOOT-INF/") + || entry.getName().equals("module-info.class")) { return entry; } JarArchiveEntry renamedEntry = new JarArchiveEntry( diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java index 0937e36968c..e8487db9726 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -661,6 +661,20 @@ public class RepackagerTests { repackager.repackage(dest, NO_LIBRARIES); } + @Test + public void moduleInfoClassRemainsInRootOfJarWhenRepackaged() throws Exception { + this.testJarFile.addClass("A.class", ClassWithMainMethod.class); + this.testJarFile.addClass("module-info.class", ClassWithoutMainMethod.class); + File source = this.testJarFile.getFile(); + File dest = this.temporaryFolder.newFile("dest.jar"); + Repackager repackager = new Repackager(source); + repackager.repackage(dest, NO_LIBRARIES); + try (JarFile jarFile = new JarFile(dest)) { + assertThat(jarFile.getEntry("module-info.class")).isNotNull(); + assertThat(jarFile.getEntry("BOOT-INF/classes/module-info.class")).isNull(); + } + } + private File createLibrary() throws IOException { TestJarFile library = new TestJarFile(this.temporaryFolder); library.addClass("com/example/library/Library.class",