|
14 | 14 |
|
15 | 15 | package com.google.devtools.build.android.idlclass; |
16 | 16 |
|
| 17 | +import static java.util.stream.Collectors.toCollection; |
| 18 | + |
17 | 19 | import com.beust.jcommander.JCommander; |
18 | 20 | import com.google.common.annotations.VisibleForTesting; |
19 | 21 | import com.google.common.base.Preconditions; |
20 | 22 | import com.google.common.collect.ImmutableSet; |
21 | 23 | import com.google.common.collect.Lists; |
22 | 24 | import com.google.common.collect.Sets; |
| 25 | +import com.google.common.hash.Hashing; |
23 | 26 | import com.google.devtools.build.android.AndroidOptionsUtils; |
24 | | -import com.google.devtools.build.buildjar.jarhelper.JarCreator; |
25 | 27 | import com.google.devtools.build.buildjar.proto.JavaCompilation.CompilationUnit; |
26 | 28 | import com.google.devtools.build.buildjar.proto.JavaCompilation.Manifest; |
| 29 | +import java.io.BufferedOutputStream; |
27 | 30 | import java.io.IOException; |
28 | 31 | import java.io.InputStream; |
29 | 32 | import java.nio.file.Files; |
30 | 33 | import java.nio.file.Path; |
31 | 34 | import java.nio.file.Paths; |
| 35 | +import java.nio.file.attribute.FileTime; |
| 36 | +import java.time.Instant; |
| 37 | +import java.time.LocalDateTime; |
| 38 | +import java.time.ZoneId; |
| 39 | +import java.util.ArrayList; |
32 | 40 | import java.util.Enumeration; |
33 | 41 | import java.util.List; |
34 | 42 | import java.util.Set; |
35 | 43 | import java.util.jar.JarEntry; |
36 | 44 | import java.util.jar.JarFile; |
| 45 | +import java.util.stream.Stream; |
| 46 | +import java.util.zip.ZipEntry; |
| 47 | +import java.util.zip.ZipOutputStream; |
37 | 48 |
|
38 | 49 | /** |
39 | 50 | * IdlClass post-processes the output of a Java compilation, and produces |
40 | 51 | * a jar containing only the class files for sources that were generated |
41 | 52 | * from idl processing. |
42 | 53 | */ |
43 | 54 | public class IdlClass { |
| 55 | + // Cribbed from AarGeneratorAction.java |
| 56 | + private static final Instant DEFAULT_TIMESTAMP = |
| 57 | + LocalDateTime.of(2010, 1, 1, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant(); |
44 | 58 |
|
45 | 59 | public static void main(String[] args) throws IOException { |
46 | 60 | IdlClassOptions idlClassOptions = new IdlClassOptions(); |
@@ -160,10 +174,31 @@ private static void extractIdlClasses( |
160 | 174 |
|
161 | 175 | /** Writes the generated class files to the output jar. */ |
162 | 176 | private static void writeOutputJar(Path outputJar, Path tempDir) throws IOException { |
163 | | - JarCreator output = new JarCreator(outputJar.toString()); |
164 | | - output.setCompression(true); |
165 | | - output.setNormalize(true); |
166 | | - output.addDirectory(tempDir.toString()); |
167 | | - output.execute(); |
| 177 | + // Zip up the contents of tempDir into outputJar. |
| 178 | + |
| 179 | + try (final ZipOutputStream zip = |
| 180 | + new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(outputJar)))) { |
| 181 | + zip.setMethod(ZipOutputStream.STORED); |
| 182 | + |
| 183 | + List<Path> files; |
| 184 | + try (Stream<Path> stream = Files.walk(tempDir).filter(Files::isRegularFile)) { |
| 185 | + files = stream.collect(toCollection(ArrayList::new)); |
| 186 | + } |
| 187 | + |
| 188 | + for (Path path : files) { |
| 189 | + ZipEntry entry = new ZipEntry(tempDir.relativize(path).toString()); |
| 190 | + entry.setTime(DEFAULT_TIMESTAMP.toEpochMilli()); |
| 191 | + entry.setSize(Files.size(path)); |
| 192 | + entry.setCompressedSize(Files.size(path)); |
| 193 | + entry.setCrc(Hashing.crc32().hashBytes(Files.readAllBytes(path)).asInt()); |
| 194 | + zip.putNextEntry(entry); |
| 195 | + zip.write(Files.readAllBytes(path)); |
| 196 | + zip.closeEntry(); |
| 197 | + } |
| 198 | + zip.close(); |
| 199 | + } catch (IOException e) { |
| 200 | + throw new IOException("Failed to write output jar: " + outputJar, e); |
| 201 | + } |
| 202 | + Files.setLastModifiedTime(outputJar, FileTime.from(DEFAULT_TIMESTAMP)); |
168 | 203 | } |
169 | 204 | } |
0 commit comments