Skip to content

Commit e8d18f3

Browse files
committed
[Build] make sure there are no duplicate classes in third party audit (#34213)
* make sure there are no duplicate classes in third party audit
1 parent 4a0db31 commit e8d18f3

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

buildSrc/src/main/java/org/elasticsearch/gradle/JdkJarHellCheck.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ private void scanForJDKJarHell(Path root) throws IOException {
4343
@Override
4444
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
4545
String entry = root.relativize(file).toString().replace('\\', '/');
46-
if (entry.endsWith(".class")) {
46+
if (entry.endsWith(".class") && entry.endsWith("module-info.class") == false) {
4747
if (ext.getResource(entry) != null) {
4848
detected.add(
4949
entry

buildSrc/src/main/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTask.java

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020

2121
import org.apache.commons.io.output.NullOutputStream;
2222
import org.elasticsearch.gradle.JdkJarHellCheck;
23-
import org.elasticsearch.test.NamingConventionsCheck;
2423
import org.gradle.api.DefaultTask;
2524
import org.gradle.api.GradleException;
2625
import org.gradle.api.JavaVersion;
2726
import org.gradle.api.artifacts.Configuration;
2827
import org.gradle.api.file.FileCollection;
28+
import org.gradle.api.file.FileTree;
2929
import org.gradle.api.tasks.Input;
3030
import org.gradle.api.tasks.InputFile;
3131
import org.gradle.api.tasks.InputFiles;
@@ -47,6 +47,7 @@
4747
import java.util.regex.Matcher;
4848
import java.util.regex.Pattern;
4949
import java.util.stream.Collectors;
50+
import java.util.stream.IntStream;
5051

5152
public class ThirdPartyAuditTask extends DefaultTask {
5253

@@ -171,19 +172,38 @@ private void extractJars(FileCollection jars) {
171172
File jarExpandDir = getJarExpandDir();
172173
// We need to clean up to make sure old dependencies don't linger
173174
getProject().delete(jarExpandDir);
174-
jars.forEach(jar ->
175+
176+
jars.forEach(jar -> {
177+
FileTree jarFiles = getProject().zipTree(jar);
175178
getProject().copy(spec -> {
179+
spec.from(jarFiles);
180+
spec.into(jarExpandDir);
181+
// exclude classes from multi release jars
182+
spec.exclude("META-INF/versions/**");
183+
});
184+
// Deal with multi release jars:
185+
// The order is important, we iterate here so we don't depend on the order in which Gradle executes the spec
186+
// We extract multi release jar classes ( if these exist ) going from 9 - the first to support them, to the
187+
// current `targetCompatibility` version.
188+
// Each extract will overwrite the top level classes that existed before it, the result is that we end up
189+
// with a single version of the class in `jarExpandDir`.
190+
// This will be the closes version to `targetCompatibility`, the same class that would be loaded in a JVM
191+
// that has `targetCompatibility` version.
192+
// This means we only scan classes that would be loaded into `targetCompatibility`, and don't look at any
193+
// pther version specific implementation of said classes.
194+
IntStream.rangeClosed(
195+
Integer.parseInt(JavaVersion.VERSION_1_9.getMajorVersion()),
196+
Integer.parseInt(targetCompatibility.getMajorVersion())
197+
).forEach(majorVersion -> getProject().copy(spec -> {
176198
spec.from(getProject().zipTree(jar));
177199
spec.into(jarExpandDir);
178-
// Exclude classes for multi release jars above target
179-
for (int i = Integer.parseInt(targetCompatibility.getMajorVersion()) + 1;
180-
i <= Integer.parseInt(JavaVersion.VERSION_HIGHER.getMajorVersion());
181-
i++
182-
) {
183-
spec.exclude("META-INF/versions/" + i + "/**");
184-
}
185-
})
186-
);
200+
String metaInfPrefix = "META-INF/versions/" + majorVersion;
201+
spec.include(metaInfPrefix + "/**");
202+
// Drop the version specific prefix
203+
spec.eachFile(details -> details.setPath(details.getPath().replace(metaInfPrefix, "")));
204+
spec.setIncludeEmptyDirs(false);
205+
}));
206+
});
187207
}
188208

189209
private void assertNoJarHell(Set<String> jdkJarHellClasses) {
@@ -276,9 +296,9 @@ private String formatClassList(Set<String> classList) {
276296
private Set<String> runJdkJarHellCheck() throws IOException {
277297
ByteArrayOutputStream standardOut = new ByteArrayOutputStream();
278298
ExecResult execResult = getProject().javaexec(spec -> {
279-
URL location = NamingConventionsCheck.class.getProtectionDomain().getCodeSource().getLocation();
299+
URL location = JdkJarHellCheck.class.getProtectionDomain().getCodeSource().getLocation();
280300
if (location.getProtocol().equals("file") == false) {
281-
throw new GradleException("Unexpected location for NamingConventionCheck class: " + location);
301+
throw new GradleException("Unexpected location for JdkJarHellCheck class: " + location);
282302
}
283303
try {
284304
spec.classpath(

0 commit comments

Comments
 (0)