Skip to content

Commit cf01987

Browse files
committed
Fix Grid UI by patching rules_jvm_external
1 parent 51095a4 commit cf01987

2 files changed

Lines changed: 220 additions & 0 deletions

File tree

WORKSPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ http_archive(
115115
],
116116
patches = [
117117
"//java:rules_jvm_external_javadoc.patch",
118+
"//java:rules_jvm_external_missing_dirs.patch",
118119
"//java:rules_jvm_external_visibility.patch",
119120
],
120121
sha256 = RULES_JVM_EXTERNAL_SHA,
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
.../rules/jvm/external/jar/MergeJars.java | 87 ++++++++++++-------
2+
tests/com/jvm/external/jar/MergeJarsTest.java | 33 ++++++-
3+
2 files changed, 87 insertions(+), 33 deletions(-)
4+
5+
diff --git a/private/tools/java/rules/jvm/external/jar/MergeJars.java b/private/tools/java/rules/jvm/external/jar/MergeJars.java
6+
index bd278d0..9aaa069 100644
7+
--- a/private/tools/java/rules/jvm/external/jar/MergeJars.java
8+
+++ b/private/tools/java/rules/jvm/external/jar/MergeJars.java
9+
@@ -19,12 +19,7 @@ package rules.jvm.external.jar;
10+
11+
import rules.jvm.external.ByteStreams;
12+
13+
-import java.io.BufferedInputStream;
14+
-import java.io.ByteArrayOutputStream;
15+
-import java.io.File;
16+
-import java.io.IOException;
17+
-import java.io.InputStream;
18+
-import java.io.OutputStream;
19+
+import java.io.*;
20+
import java.nio.file.Files;
21+
import java.nio.file.Path;
22+
import java.nio.file.Paths;
23+
@@ -32,16 +27,7 @@ import java.nio.file.attribute.FileTime;
24+
import java.security.MessageDigest;
25+
import java.security.NoSuchAlgorithmException;
26+
import java.time.Instant;
27+
-import java.util.Arrays;
28+
-import java.util.Comparator;
29+
-import java.util.HashMap;
30+
-import java.util.HashSet;
31+
-import java.util.LinkedHashSet;
32+
-import java.util.Map;
33+
-import java.util.Objects;
34+
-import java.util.Set;
35+
-import java.util.TreeMap;
36+
-import java.util.TreeSet;
37+
+import java.util.*;
38+
import java.util.jar.Attributes;
39+
import java.util.jar.JarEntry;
40+
import java.util.jar.JarOutputStream;
41+
@@ -105,6 +91,7 @@ public class MergeJars {
42+
// Just write an empty jar and leave
43+
try (OutputStream fos = Files.newOutputStream(out);
44+
JarOutputStream jos = new JarOutputStream(fos)) {
45+
+ // This space left blank deliberately
46+
}
47+
return;
48+
}
49+
@@ -193,6 +180,7 @@ public class MergeJars {
50+
entry = resetTime(entry);
51+
jos.putNextEntry(entry);
52+
jos.closeEntry();
53+
+ createdDirectories.add(entry.getName());
54+
55+
entry = new JarEntry("META-INF/MANIFEST.MF");
56+
entry = resetTime(entry);
57+
@@ -209,6 +197,7 @@ public class MergeJars {
58+
entry = resetTime(entry);
59+
jos.putNextEntry(entry);
60+
jos.closeEntry();
61+
+ createdDirectories.add(entry.getName());
62+
}
63+
for (Map.Entry<String, Set<String>> kv : allServices.entrySet()) {
64+
entry = new JarEntry("META-INF/services/" + kv.getKey());
65+
@@ -227,27 +216,39 @@ public class MergeJars {
66+
67+
// We should never enter this loop without there being any sources
68+
for (Map.Entry<String, Path> pathAndSource : fileToSourceJar.entrySet()) {
69+
- // Get the original entry
70+
- JarEntry je = new JarEntry(pathAndSource.getKey());
71+
- je = resetTime(je);
72+
- jos.putNextEntry(je);
73+
+ String name = pathAndSource.getKey();
74+
75+
- if (je.isDirectory()) {
76+
- jos.closeEntry();
77+
+ // Make sure we're not trying to create root entries.
78+
+ if (name.startsWith("/")) {
79+
+ if (name.length() == 1) {
80+
+ continue;
81+
+ }
82+
+ name = name.substring(1);
83+
+ }
84+
+
85+
+ createDirectories(jos, name, createdDirectories);
86+
+
87+
+ if (createdDirectories.contains(name)) {
88+
continue;
89+
}
90+
91+
if (!Objects.equals(previousSource, pathAndSource.getValue())) {
92+
- source.close();
93+
+ if (source != null) {
94+
+ source.close();
95+
+ }
96+
source = new ZipFile(pathAndSource.getValue().toFile());
97+
previousSource = pathAndSource.getValue();
98+
}
99+
100+
- ZipEntry original = source.getEntry(pathAndSource.getKey());
101+
+ ZipEntry original = source.getEntry(name);
102+
if (original == null) {
103+
continue;
104+
}
105+
106+
+ JarEntry je = new JarEntry(name);
107+
+ je = resetTime(je);
108+
+ jos.putNextEntry(je);
109+
+
110+
try (InputStream is = source.getInputStream(original)) {
111+
ByteStreams.copy(is, jos);
112+
}
113+
@@ -259,6 +260,37 @@ public class MergeJars {
114+
}
115+
}
116+
117+
+ private static void createDirectories(JarOutputStream jos, String name, Set<String> createdDirs) throws IOException {
118+
+ if (!name.endsWith("/")) {
119+
+ int slashIndex = name.lastIndexOf('/');
120+
+ if (slashIndex != -1) {
121+
+ createDirectories(jos, name.substring(0, slashIndex + 1), createdDirs);
122+
+ }
123+
+ return;
124+
+ }
125+
+
126+
+ if (createdDirs.contains(name)) {
127+
+ return;
128+
+ }
129+
+
130+
+ String[] segments = name.split("/");
131+
+ StringBuilder path = new StringBuilder();
132+
+ for (String segment : segments) {
133+
+ path.append(segment).append('/');
134+
+
135+
+ String newPath = path.toString();
136+
+ if (createdDirs.contains(newPath)) {
137+
+ continue;
138+
+ }
139+
+
140+
+ JarEntry entry = new JarEntry(newPath);
141+
+ entry = resetTime(entry);
142+
+ jos.putNextEntry(entry);
143+
+ jos.closeEntry();
144+
+ createdDirs.add(newPath);
145+
+ }
146+
+ }
147+
+
148+
private static Set<String> readExcludedFileNames(Set<Path> excludes) throws IOException {
149+
Set<String> paths = new HashSet<>();
150+
151+
@@ -292,13 +324,6 @@ public class MergeJars {
152+
return path;
153+
}
154+
155+
- private static void delete(Path toDelete) throws IOException {
156+
- Files.walk(toDelete)
157+
- .sorted(Comparator.reverseOrder())
158+
- .map(Path::toFile)
159+
- .forEach(File::delete);
160+
- }
161+
-
162+
// Returns the normalized timestamp for a jar entry based on its name. This is necessary since
163+
// javac will, when loading a class X, prefer a source file to a class file, if both files have
164+
// the same timestamp. Therefore, we need to adjust the timestamp for class files to slightly
165+
diff --git a/tests/com/jvm/external/jar/MergeJarsTest.java b/tests/com/jvm/external/jar/MergeJarsTest.java
166+
index b247e15..0869233 100644
167+
--- a/tests/com/jvm/external/jar/MergeJarsTest.java
168+
+++ b/tests/com/jvm/external/jar/MergeJarsTest.java
169+
@@ -20,12 +20,12 @@ import java.util.Set;
170+
import java.util.jar.Attributes;
171+
import java.util.jar.Manifest;
172+
import java.util.zip.ZipEntry;
173+
+import java.util.zip.ZipFile;
174+
import java.util.zip.ZipInputStream;
175+
import java.util.zip.ZipOutputStream;
176+
177+
import static java.nio.charset.StandardCharsets.UTF_8;
178+
-import static org.junit.Assert.assertEquals;
179+
-import static org.junit.Assert.assertTrue;
180+
+import static org.junit.Assert.*;
181+
182+
public class MergeJarsTest {
183+
184+
@@ -351,6 +351,35 @@ public class MergeJarsTest {
185+
}
186+
}
187+
188+
+ @Test
189+
+ public void shouldAddMissingDirectories() throws IOException {
190+
+ Path input = temp.newFile("example.jar").toPath();
191+
+ createJar(input, ImmutableMap.of("foo/bar/baz.txt", "Hello, World!"));
192+
+
193+
+ Path output = temp.newFile("out.jar").toPath();
194+
+
195+
+ MergeJars.main(new String[] {
196+
+ "--output", output.toAbsolutePath().toString(),
197+
+ "--sources", input.toAbsolutePath().toString(),
198+
+ });
199+
+
200+
+ Set<String> dirNames = new HashSet<>();
201+
+ try (InputStream is = Files.newInputStream(output);
202+
+ ZipInputStream zis = new ZipInputStream(is)) {
203+
+ ZipEntry entry = zis.getNextEntry();
204+
+ while (entry != null) {
205+
+ if (entry.isDirectory()) {
206+
+ dirNames.add(entry.getName());
207+
+ }
208+
+ entry = zis.getNextEntry();
209+
+ }
210+
+
211+
+ assertTrue(dirNames.toString(), dirNames.contains("foo/"));
212+
+ assertTrue(dirNames.toString(), dirNames.contains("foo/bar/"));
213+
+ }
214+
+
215+
+ }
216+
+
217+
private void createJar(Path outputTo, Map<String, String> pathToContents) throws IOException {
218+
try (OutputStream os = Files.newOutputStream(outputTo);
219+
ZipOutputStream zos = new ZipOutputStream(os)) {

0 commit comments

Comments
 (0)