Skip to content

Commit a9984fe

Browse files
committed
add module info to build info file
1 parent 65c7d72 commit a9984fe

File tree

1 file changed

+96
-7
lines changed

1 file changed

+96
-7
lines changed

build-tools/src/main/java/org/elasticsearch/gradle/plugin/GenerateTestBuildInfoTask.java

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,25 @@
1717
import org.gradle.api.tasks.InputFiles;
1818
import org.gradle.api.tasks.OutputDirectory;
1919
import org.gradle.api.tasks.TaskAction;
20+
import org.objectweb.asm.ClassReader;
21+
import org.objectweb.asm.ClassVisitor;
22+
import org.objectweb.asm.ModuleVisitor;
23+
import org.objectweb.asm.Opcodes;
2024

2125
import java.io.File;
2226
import java.io.IOException;
27+
import java.io.InputStream;
2328
import java.io.UncheckedIOException;
2429
import java.nio.charset.StandardCharsets;
2530
import java.nio.file.Files;
2631
import java.nio.file.Path;
27-
import java.util.ArrayList;
28-
import java.util.Arrays;
29-
import java.util.HashMap;
30-
import java.util.List;
31-
import java.util.Map;
32+
import java.util.*;
33+
import java.util.jar.Attributes;
34+
import java.util.jar.JarEntry;
3235
import java.util.jar.JarFile;
36+
import java.util.jar.Manifest;
37+
import java.util.regex.Matcher;
38+
import java.util.regex.Pattern;
3339

3440
public abstract class GenerateTestBuildInfoTask extends DefaultTask {
3541

@@ -51,19 +57,99 @@ public GenerateTestBuildInfoTask() {
5157

5258
@TaskAction
5359
public void generatePropertiesFile() throws IOException {
60+
// TODO: use ASM to load module-info.class as bytes
61+
// TODO: META-INF jar manifest -- automatic name property
62+
// TODO: look at jar file name -- remove version number of .jar
5463
Map<String, String> classesToModules = new HashMap<>();
5564
for (File file : getCodeLocations().get().getFiles()) {
5665
if (file.exists()) {
5766
if (file.getName().endsWith(".jar")) {
5867
try (JarFile jarFile = new JarFile(file)) {
68+
String[] moduleName = new String[1];
69+
JarEntry moduleEntry = jarFile.getJarEntry("module-info.class");
70+
if (moduleEntry != null) {
71+
try (InputStream miis = jarFile.getInputStream(moduleEntry)) {
72+
ClassReader cr = new ClassReader(miis);
73+
cr.accept(new ClassVisitor(Opcodes.ASM9) {
74+
@Override
75+
public ModuleVisitor visitModule(String name, int access, String version) {
76+
//getLogger().lifecycle("FOUND 0: " + name + " | " + file.getAbsolutePath());
77+
moduleName[0] = name;
78+
return super.visitModule(name, access, version);
79+
}
80+
}, Opcodes.ASM9);
81+
}
82+
} else {
83+
moduleEntry = jarFile.getJarEntry("META-INF/MANIFEST.MF");
84+
if (moduleEntry != null) {
85+
try (InputStream meis = jarFile.getInputStream(moduleEntry)) {
86+
Manifest manifest = new Manifest(meis);
87+
String mr = manifest.getMainAttributes().getValue(Attributes.Name.MULTI_RELEASE);
88+
if (Boolean.parseBoolean(mr)) {
89+
List<Integer> versions = jarFile.stream()
90+
.filter(
91+
je -> je.getName().startsWith("META-INF/versions/")
92+
&& je.getName().endsWith("/module-info.class")
93+
)
94+
.map(je -> Integer.parseInt(je.getName().substring(18, je.getName().length() - 18)))
95+
.toList();
96+
versions = new ArrayList<>(versions);
97+
versions.sort(Integer::compareTo);
98+
versions = versions.reversed();
99+
int major = Runtime.version().version().get(0);
100+
StringBuilder path = new StringBuilder("META-INF/versions/");
101+
for (int version : versions) {
102+
if (version <= major) {
103+
path.append(version);
104+
break;
105+
}
106+
}
107+
if (path.length() > 18) {
108+
path.append("/module-info.class");
109+
moduleEntry = jarFile.getJarEntry(path.toString());
110+
if (moduleEntry != null) {
111+
try (InputStream miis = jarFile.getInputStream(moduleEntry)) {
112+
ClassReader cr = new ClassReader(miis);
113+
cr.accept(new ClassVisitor(Opcodes.ASM9) {
114+
@Override
115+
public ModuleVisitor visitModule(String name, int access, String version) {
116+
//getLogger().lifecycle("FOUND 1: " + name + " | " + file.getAbsolutePath());
117+
moduleName[0] = name;
118+
return super.visitModule(name, access, version);
119+
}
120+
}, Opcodes.ASM9);
121+
}
122+
}
123+
}
124+
}
125+
if (moduleName[0] == null) {
126+
String amn = manifest.getMainAttributes().getValue("Automatic-Module-Name");
127+
if (amn != null) {
128+
//getLogger().lifecycle("FOUND 2: " + amn + " | " + file.getAbsolutePath());
129+
moduleName[0] = amn;
130+
}
131+
}
132+
}
133+
}
134+
if (moduleName[0] == null) {
135+
String jn = file.getName().substring(0, file.getName().length() - 4);
136+
Matcher matcher = Pattern.compile("-(\\d+(\\.|$))").matcher(jn);
137+
if (matcher.find()) {
138+
jn = jn.substring(0, matcher.start());
139+
}
140+
jn = jn.replaceAll("[^A-Za-z0-9]", ".");
141+
//getLogger().lifecycle("FOUND 3: " + jn + " | " + file.getAbsolutePath());
142+
moduleName[0] = jn;
143+
}
144+
}
59145
jarFile.stream()
60146
.filter(
61147
je -> je.getName().startsWith("META-INF") == false
62148
&& je.getName().equals("module-info.class") == false
63149
&& je.getName().endsWith(".class")
64150
)
65151
.findFirst()
66-
.ifPresent(entry -> classesToModules.put(entry.getName(), "module-goes-here"));
152+
.ifPresent(je -> classesToModules.put(je.getName(), moduleName[0]));
67153
} catch (IOException ioe) {
68154
throw new UncheckedIOException(ioe);
69155
}
@@ -75,7 +161,10 @@ public void generatePropertiesFile() throws IOException {
75161
if (find.isDirectory() && find.getName().equals("META_INF") == false) {
76162
files.addAll(Arrays.asList(find.listFiles()));
77163
} else if (find.getName().equals("module-info.class") == false && find.getName().contains("$") == false) {
78-
classesToModules.put(find.getName(), "module-goes-here");
164+
classesToModules.put(
165+
find.getAbsolutePath().substring(file.getAbsolutePath().length() + 1),
166+
"module-goes-here"
167+
);
79168
break;
80169
}
81170
}

0 commit comments

Comments
 (0)