author | alanb |
Thu, 04 May 2017 07:26:55 +0000 | |
changeset 45004 | ea3137042a61 |
parent 44360 | a83651664fa3 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2 |
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.tools.jar; |
|
27 |
||
28 |
import java.io.*; |
|
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
29 |
import java.lang.module.Configuration; |
44267
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
30 |
import java.lang.module.FindException; |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
31 |
import java.lang.module.InvalidModuleDescriptorException; |
36511 | 32 |
import java.lang.module.ModuleDescriptor; |
33 |
import java.lang.module.ModuleDescriptor.Exports; |
|
34 |
import java.lang.module.ModuleDescriptor.Provides; |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
35 |
import java.lang.module.ModuleDescriptor.Opens; |
36511 | 36 |
import java.lang.module.ModuleDescriptor.Requires; |
37 |
import java.lang.module.ModuleDescriptor.Version; |
|
38 |
import java.lang.module.ModuleFinder; |
|
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
39 |
import java.lang.module.ModuleReader; |
36511 | 40 |
import java.lang.module.ModuleReference; |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
41 |
import java.lang.module.ResolutionException; |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
42 |
import java.lang.module.ResolvedModule; |
36511 | 43 |
import java.net.URI; |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
44 |
import java.nio.ByteBuffer; |
3218 | 45 |
import java.nio.file.Path; |
8158 | 46 |
import java.nio.file.Files; |
36511 | 47 |
import java.nio.file.Paths; |
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
48 |
import java.nio.file.StandardCopyOption; |
2 | 49 |
import java.util.*; |
36511 | 50 |
import java.util.function.Consumer; |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
51 |
import java.util.function.Supplier; |
36511 | 52 |
import java.util.regex.Pattern; |
53 |
import java.util.stream.Collectors; |
|
39313 | 54 |
import java.util.stream.Stream; |
2 | 55 |
import java.util.zip.*; |
56 |
import java.util.jar.*; |
|
21348
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
57 |
import java.util.jar.Pack200.*; |
2 | 58 |
import java.util.jar.Manifest; |
59 |
import java.text.MessageFormat; |
|
36511 | 60 |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
61 |
import jdk.internal.module.Checks; |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
62 |
import jdk.internal.module.ModuleHashes; |
43109 | 63 |
import jdk.internal.module.ModuleHashesBuilder; |
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
64 |
import jdk.internal.module.ModuleInfo; |
36511 | 65 |
import jdk.internal.module.ModuleInfoExtender; |
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
66 |
import jdk.internal.module.ModuleResolution; |
44359
c6761862ca0b
8174823: Module system implementation refresh (3/2017)
alanb
parents:
44033
diff
changeset
|
67 |
import jdk.internal.module.ModuleTarget; |
36745
51effd3e92d0
8152190: Move sun.misc.JarIndex and InvalidJarIndexException to an internal package
chegar
parents:
36511
diff
changeset
|
68 |
import jdk.internal.util.jar.JarIndex; |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
69 |
|
36745
51effd3e92d0
8152190: Move sun.misc.JarIndex and InvalidJarIndexException to an internal package
chegar
parents:
36511
diff
changeset
|
70 |
import static jdk.internal.util.jar.JarIndex.INDEX_NAME; |
3218 | 71 |
import static java.util.jar.JarFile.MANIFEST_NAME; |
36511 | 72 |
import static java.util.stream.Collectors.joining; |
3218 | 73 |
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
74 |
import static sun.tools.jar.Validator.ENTRYNAME_COMPARATOR; |
2 | 75 |
|
76 |
/** |
|
77 |
* This class implements a simple utility for creating files in the JAR |
|
78 |
* (Java Archive) file format. The JAR format is based on the ZIP file |
|
79 |
* format, with optional meta-information stored in a MANIFEST entry. |
|
80 |
*/ |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
81 |
public class Main { |
2 | 82 |
String program; |
41484
834b7539ada3
8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents:
41221
diff
changeset
|
83 |
PrintWriter out, err; |
19409 | 84 |
String fname, mname, ename; |
2 | 85 |
String zname = ""; |
86 |
String rootjar = null; |
|
1762 | 87 |
|
39313 | 88 |
private static final int BASE_VERSION = 0; |
89 |
||
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
90 |
private static class Entry { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
91 |
final String name; |
39313 | 92 |
final File file; |
93 |
final boolean isDir; |
|
94 |
||
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
95 |
Entry(File file, String name, boolean isDir) { |
39313 | 96 |
this.file = file; |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
97 |
this.isDir = isDir; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
98 |
this.name = name; |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
99 |
} |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
100 |
|
41221
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
101 |
@Override |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
102 |
public boolean equals(Object o) { |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
103 |
if (this == o) return true; |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
104 |
if (!(o instanceof Entry)) return false; |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
105 |
return this.file.equals(((Entry)o).file); |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
106 |
} |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
107 |
|
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
108 |
@Override |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
109 |
public int hashCode() { |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
110 |
return file.hashCode(); |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
111 |
} |
39313 | 112 |
} |
113 |
||
114 |
// An entryName(path)->Entry map generated during "expand", it helps to |
|
1762 | 115 |
// decide whether or not an existing entry in a jar file needs to be |
116 |
// replaced, during the "update" operation. |
|
39313 | 117 |
Map<String, Entry> entryMap = new HashMap<>(); |
1762 | 118 |
|
39313 | 119 |
// All entries need to be added/updated. |
41221
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
120 |
Set<Entry> entries = new LinkedHashSet<>(); |
39313 | 121 |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
122 |
// module-info.class entries need to be added/updated. |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
123 |
Map<String,byte[]> moduleInfos = new HashMap<>(); |
1762 | 124 |
|
39313 | 125 |
// A paths Set for each version, where each Set contains directories |
126 |
// specified by the "-C" operation. |
|
127 |
Map<Integer,Set<String>> pathsMap = new HashMap<>(); |
|
128 |
||
129 |
// There's also a files array per version |
|
130 |
Map<Integer,String[]> filesMap = new HashMap<>(); |
|
131 |
||
132 |
// Do we think this is a multi-release jar? Set to true |
|
133 |
// if --release option found followed by at least file |
|
134 |
boolean isMultiRelease; |
|
1762 | 135 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
136 |
// The last parsed --release value, if any. Used in conjunction with |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
137 |
// "-d,--describe-module" to select the operative module descriptor. |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
138 |
int releaseValue = -1; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
139 |
|
2 | 140 |
/* |
141 |
* cflag: create |
|
142 |
* uflag: update |
|
143 |
* xflag: xtract |
|
144 |
* tflag: table |
|
145 |
* vflag: verbose |
|
146 |
* flag0: no zip compression (store only) |
|
147 |
* Mflag: DO NOT generate a manifest file (just ZIP) |
|
148 |
* iflag: generate jar index |
|
21348
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
149 |
* nflag: Perform jar normalization at the end |
29914 | 150 |
* pflag: preserve/don't strip leading slash and .. component from file name |
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
151 |
* dflag: print module descriptor |
2 | 152 |
*/ |
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
153 |
boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag, dflag; |
2 | 154 |
|
36511 | 155 |
/* To support additional GNU Style informational options */ |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
156 |
Consumer<PrintWriter> info; |
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
157 |
|
36511 | 158 |
/* Modular jar related options */ |
159 |
Version moduleVersion; |
|
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
160 |
Pattern modulesToHash; |
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
161 |
ModuleResolution moduleResolution = ModuleResolution.empty(); |
38457
3d019217e322
8152650: ModuleFinder.compose should accept varargs
alanb
parents:
37779
diff
changeset
|
162 |
ModuleFinder moduleFinder = ModuleFinder.of(); |
36511 | 163 |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
164 |
static final String MODULE_INFO = "module-info.class"; |
2 | 165 |
static final String MANIFEST_DIR = "META-INF/"; |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
166 |
static final String VERSIONS_DIR = MANIFEST_DIR + "versions/"; |
2 | 167 |
static final String VERSION = "1.0"; |
43731
bc7110b230c1
8165640: Enhance jar tool to allow module-info in versioned directories but not in base in modular multi-release jar files
sherman
parents:
43712
diff
changeset
|
168 |
static final int VERSIONS_DIR_LENGTH = VERSIONS_DIR.length(); |
2 | 169 |
private static ResourceBundle rsrc; |
170 |
||
171 |
/** |
|
172 |
* If true, maintain compatibility with JDK releases prior to 6.0 by |
|
173 |
* timestamping extracted files with the time at which they are extracted. |
|
174 |
* Default is to use the time given in the archive. |
|
175 |
*/ |
|
176 |
private static final boolean useExtractionTime = |
|
177 |
Boolean.getBoolean("sun.tools.jar.useExtractionTime"); |
|
178 |
||
179 |
/** |
|
180 |
* Initialize ResourceBundle |
|
181 |
*/ |
|
182 |
static { |
|
183 |
try { |
|
184 |
rsrc = ResourceBundle.getBundle("sun.tools.jar.resources.jar"); |
|
185 |
} catch (MissingResourceException e) { |
|
186 |
throw new Error("Fatal: Resource for jar is missing"); |
|
187 |
} |
|
188 |
} |
|
189 |
||
36511 | 190 |
static String getMsg(String key) { |
2 | 191 |
try { |
192 |
return (rsrc.getString(key)); |
|
193 |
} catch (MissingResourceException e) { |
|
194 |
throw new Error("Error in message file"); |
|
195 |
} |
|
196 |
} |
|
197 |
||
36511 | 198 |
static String formatMsg(String key, String arg) { |
2 | 199 |
String msg = getMsg(key); |
200 |
String[] args = new String[1]; |
|
201 |
args[0] = arg; |
|
202 |
return MessageFormat.format(msg, (Object[]) args); |
|
203 |
} |
|
204 |
||
36511 | 205 |
static String formatMsg2(String key, String arg, String arg1) { |
2 | 206 |
String msg = getMsg(key); |
207 |
String[] args = new String[2]; |
|
208 |
args[0] = arg; |
|
209 |
args[1] = arg1; |
|
210 |
return MessageFormat.format(msg, (Object[]) args); |
|
211 |
} |
|
212 |
||
213 |
public Main(PrintStream out, PrintStream err, String program) { |
|
41484
834b7539ada3
8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents:
41221
diff
changeset
|
214 |
this.out = new PrintWriter(out, true); |
834b7539ada3
8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents:
41221
diff
changeset
|
215 |
this.err = new PrintWriter(err, true); |
834b7539ada3
8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents:
41221
diff
changeset
|
216 |
this.program = program; |
834b7539ada3
8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents:
41221
diff
changeset
|
217 |
} |
834b7539ada3
8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents:
41221
diff
changeset
|
218 |
|
834b7539ada3
8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents:
41221
diff
changeset
|
219 |
public Main(PrintWriter out, PrintWriter err, String program) { |
2 | 220 |
this.out = out; |
221 |
this.err = err; |
|
222 |
this.program = program; |
|
223 |
} |
|
224 |
||
3218 | 225 |
/** |
226 |
* Creates a new empty temporary file in the same directory as the |
|
227 |
* specified file. A variant of File.createTempFile. |
|
228 |
*/ |
|
229 |
private static File createTempFileInSameDirectoryAs(File file) |
|
230 |
throws IOException { |
|
231 |
File dir = file.getParentFile(); |
|
232 |
if (dir == null) |
|
233 |
dir = new File("."); |
|
13154
9e8a04d28ded
7175845: jar uf changes file permissions unexpectedly
sherman
parents:
13041
diff
changeset
|
234 |
return File.createTempFile("jartmp", null, dir); |
3218 | 235 |
} |
236 |
||
2 | 237 |
private boolean ok; |
238 |
||
3218 | 239 |
/** |
2 | 240 |
* Starts main program with the specified arguments. |
241 |
*/ |
|
242 |
public synchronized boolean run(String args[]) { |
|
243 |
ok = true; |
|
244 |
if (!parseArgs(args)) { |
|
245 |
return false; |
|
246 |
} |
|
44033
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
247 |
File tmpFile = null; |
2 | 248 |
try { |
249 |
if (cflag || uflag) { |
|
250 |
if (fname != null) { |
|
251 |
// The name of the zip file as it would appear as its own |
|
252 |
// zip file entry. We use this to make sure that we don't |
|
253 |
// add the zip file to itself. |
|
254 |
zname = fname.replace(File.separatorChar, '/'); |
|
255 |
if (zname.startsWith("./")) { |
|
256 |
zname = zname.substring(2); |
|
257 |
} |
|
258 |
} |
|
259 |
} |
|
260 |
if (cflag) { |
|
261 |
Manifest manifest = null; |
|
262 |
if (!Mflag) { |
|
263 |
if (mname != null) { |
|
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
264 |
try (InputStream in = new FileInputStream(mname)) { |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
265 |
manifest = new Manifest(new BufferedInputStream(in)); |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
266 |
} |
2 | 267 |
} else { |
268 |
manifest = new Manifest(); |
|
269 |
} |
|
270 |
addVersion(manifest); |
|
271 |
addCreatedBy(manifest); |
|
3218 | 272 |
if (isAmbiguousMainClass(manifest)) { |
2 | 273 |
return false; |
274 |
} |
|
275 |
if (ename != null) { |
|
276 |
addMainClass(manifest, ename); |
|
277 |
} |
|
39313 | 278 |
if (isMultiRelease) { |
279 |
addMultiRelease(manifest); |
|
280 |
} |
|
2 | 281 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
282 |
expand(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
283 |
if (!moduleInfos.isEmpty()) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
284 |
// All actual file entries (excl manifest and module-info.class) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
285 |
Set<String> jentries = new HashSet<>(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
286 |
// all packages if it's a class or resource |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
287 |
Set<String> packages = new HashSet<>(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
288 |
entries.stream() |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
289 |
.filter(e -> !e.isDir) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
290 |
.forEach( e -> { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
291 |
addPackageIfNamed(packages, e.name); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
292 |
jentries.add(e.name); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
293 |
}); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
294 |
addExtendedModuleAttributes(moduleInfos, packages); |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
295 |
|
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
296 |
// Basic consistency checks for modular jars. |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
297 |
if (!checkModuleInfo(moduleInfos.get(MODULE_INFO), jentries)) |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
298 |
return false; |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
299 |
|
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
300 |
} else if (moduleVersion != null || modulesToHash != null) { |
36511 | 301 |
error(getMsg("error.module.options.without.info")); |
302 |
return false; |
|
303 |
} |
|
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
304 |
if (vflag && fname == null) { |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
305 |
// Disable verbose output so that it does not appear |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
306 |
// on stdout along with file data |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
307 |
// error("Warning: -v option ignored"); |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
308 |
vflag = false; |
2 | 309 |
} |
21348
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
310 |
final String tmpbase = (fname == null) |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
311 |
? "tmpjar" |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
312 |
: fname.substring(fname.indexOf(File.separatorChar) + 1); |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
313 |
|
44033
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
314 |
tmpFile = createTemporaryFile(tmpbase, ".jar"); |
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
315 |
try (OutputStream out = new FileOutputStream(tmpFile)) { |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
316 |
create(new BufferedOutputStream(out, 4096), manifest); |
2 | 317 |
} |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
318 |
if (nflag) { |
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
319 |
File packFile = createTemporaryFile(tmpbase, ".pack"); |
21348
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
320 |
try { |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
321 |
Packer packer = Pack200.newPacker(); |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
322 |
Map<String, String> p = packer.properties(); |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
323 |
p.put(Packer.EFFORT, "1"); // Minimal effort to conserve CPU |
44033
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
324 |
try (JarFile jarFile = new JarFile(tmpFile.getCanonicalPath()); |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
325 |
OutputStream pack = new FileOutputStream(packFile)) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
326 |
{ |
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
327 |
packer.pack(jarFile, pack); |
21348
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
328 |
} |
44033
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
329 |
if (tmpFile.exists()) { |
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
330 |
tmpFile.delete(); |
21348
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
331 |
} |
44033
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
332 |
tmpFile = createTemporaryFile(tmpbase, ".jar"); |
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
333 |
try (OutputStream out = new FileOutputStream(tmpFile); |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
334 |
JarOutputStream jos = new JarOutputStream(out)) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
335 |
{ |
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
336 |
Unpacker unpacker = Pack200.newUnpacker(); |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
337 |
unpacker.unpack(packFile, jos); |
21348
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
338 |
} |
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
339 |
} finally { |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
340 |
Files.deleteIfExists(packFile.toPath()); |
21348
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
341 |
} |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
342 |
} |
44033
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
343 |
validateAndClose(tmpFile); |
2 | 344 |
} else if (uflag) { |
44033
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
345 |
File inputFile = null; |
2 | 346 |
if (fname != null) { |
347 |
inputFile = new File(fname); |
|
3218 | 348 |
tmpFile = createTempFileInSameDirectoryAs(inputFile); |
2 | 349 |
} else { |
350 |
vflag = false; |
|
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
351 |
tmpFile = createTemporaryFile("tmpjar", ".jar"); |
2 | 352 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
353 |
expand(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
354 |
try (FileInputStream in = (fname != null) ? new FileInputStream(inputFile) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
355 |
: new FileInputStream(FileDescriptor.in); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
356 |
FileOutputStream out = new FileOutputStream(tmpFile); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
357 |
InputStream manifest = (!Mflag && (mname != null)) ? |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
358 |
(new FileInputStream(mname)) : null; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
359 |
) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
360 |
boolean updateOk = update(in, new BufferedOutputStream(out), |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
361 |
manifest, moduleInfos, null); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
362 |
if (ok) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
363 |
ok = updateOk; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
364 |
} |
39313 | 365 |
} |
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
366 |
validateAndClose(tmpFile); |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
367 |
} else if (tflag) { |
39313 | 368 |
replaceFSC(filesMap); |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
369 |
// For the "list table contents" action, access using the |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
370 |
// ZipFile class is always most efficient since only a |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
371 |
// "one-finger" scan through the central directory is required. |
39313 | 372 |
String[] files = filesMapToFiles(filesMap); |
2 | 373 |
if (fname != null) { |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
374 |
list(fname, files); |
2 | 375 |
} else { |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
376 |
InputStream in = new FileInputStream(FileDescriptor.in); |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
377 |
try { |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
378 |
list(new BufferedInputStream(in), files); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
379 |
} finally { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
380 |
in.close(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
381 |
} |
2 | 382 |
} |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
383 |
} else if (xflag) { |
39313 | 384 |
replaceFSC(filesMap); |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
385 |
// For the extract action, when extracting all the entries, |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
386 |
// access using the ZipInputStream class is most efficient, |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
387 |
// since only a single sequential scan through the zip file is |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
388 |
// required. When using the ZipFile class, a "two-finger" scan |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
389 |
// is required, but this is likely to be more efficient when a |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
390 |
// partial extract is requested. In case the zip file has |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
391 |
// "leading garbage", we fall back from the ZipInputStream |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
392 |
// implementation to the ZipFile implementation, since only the |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
393 |
// latter can handle it. |
39313 | 394 |
|
395 |
String[] files = filesMapToFiles(filesMap); |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
396 |
if (fname != null && files != null) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
397 |
extract(fname, files); |
2 | 398 |
} else { |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
399 |
InputStream in = (fname == null) |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
400 |
? new FileInputStream(FileDescriptor.in) |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
401 |
: new FileInputStream(fname); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
402 |
try { |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
403 |
if (!extract(new BufferedInputStream(in), files) && fname != null) { |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
404 |
extract(fname, files); |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
405 |
} |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
406 |
} finally { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
407 |
in.close(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
408 |
} |
2 | 409 |
} |
410 |
} else if (iflag) { |
|
39313 | 411 |
String[] files = filesMap.get(BASE_VERSION); // base entries only, can be null |
2 | 412 |
genIndex(rootjar, files); |
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
413 |
} else if (dflag) { |
36511 | 414 |
boolean found; |
415 |
if (fname != null) { |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
416 |
try (ZipFile zf = new ZipFile(fname)) { |
44267
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
417 |
found = describeModule(zf); |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
418 |
} |
36511 | 419 |
} else { |
420 |
try (FileInputStream fin = new FileInputStream(FileDescriptor.in)) { |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
421 |
found = describeModuleFromStream(fin); |
36511 | 422 |
} |
423 |
} |
|
424 |
if (!found) |
|
425 |
error(getMsg("error.module.descriptor.not.found")); |
|
2 | 426 |
} |
427 |
} catch (IOException e) { |
|
428 |
fatalError(e); |
|
429 |
ok = false; |
|
430 |
} catch (Error ee) { |
|
431 |
ee.printStackTrace(); |
|
432 |
ok = false; |
|
433 |
} catch (Throwable t) { |
|
434 |
t.printStackTrace(); |
|
435 |
ok = false; |
|
44033
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
436 |
} finally { |
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
437 |
if (tmpFile != null && tmpFile.exists()) |
ab43ed5eab17
8174996: jar leaves temporary file when exception occur in creating jar
sherman
parents:
43731
diff
changeset
|
438 |
tmpFile.delete(); |
2 | 439 |
} |
440 |
out.flush(); |
|
441 |
err.flush(); |
|
442 |
return ok; |
|
443 |
} |
|
444 |
||
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
445 |
private void validateAndClose(File tmpfile) throws IOException { |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
446 |
if (ok && isMultiRelease) { |
43099
47f8baf1fcbd
8172767: a bulk of tests failed with FileSystemException on Windows
sherman
parents:
43095
diff
changeset
|
447 |
try (JarFile jf = new JarFile(tmpfile)) { |
47f8baf1fcbd
8172767: a bulk of tests failed with FileSystemException on Windows
sherman
parents:
43095
diff
changeset
|
448 |
ok = Validator.validate(this, jf); |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
449 |
if (!ok) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
450 |
error(formatMsg("error.validator.jarfile.invalid", fname)); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
451 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
452 |
} catch (IOException e) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
453 |
error(formatMsg2("error.validator.jarfile.exception", fname, e.getMessage())); |
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
454 |
} |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
455 |
} |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
456 |
Path path = tmpfile.toPath(); |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
457 |
try { |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
458 |
if (ok) { |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
459 |
if (fname != null) { |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
460 |
Files.move(path, Paths.get(fname), StandardCopyOption.REPLACE_EXISTING); |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
461 |
} else { |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
462 |
Files.copy(path, new FileOutputStream(FileDescriptor.out)); |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
463 |
} |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
464 |
} |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
465 |
} finally { |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
466 |
Files.deleteIfExists(path); |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
467 |
} |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
468 |
} |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
469 |
|
39313 | 470 |
private String[] filesMapToFiles(Map<Integer,String[]> filesMap) { |
471 |
if (filesMap.isEmpty()) return null; |
|
472 |
return filesMap.entrySet() |
|
473 |
.stream() |
|
474 |
.flatMap(this::filesToEntryNames) |
|
475 |
.toArray(String[]::new); |
|
476 |
} |
|
477 |
||
478 |
Stream<String> filesToEntryNames(Map.Entry<Integer,String[]> fileEntries) { |
|
479 |
int version = fileEntries.getKey(); |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
480 |
Set<String> cpaths = pathsMap.get(version); |
39313 | 481 |
return Stream.of(fileEntries.getValue()) |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
482 |
.map(f -> toVersionedName(toEntryName(f, cpaths, false), version)); |
40251
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
483 |
} |
481b890e50a3
8158295: Add a multi-release jar validation mechanism to jar tool
sdrach
parents:
39313
diff
changeset
|
484 |
|
3218 | 485 |
/** |
486 |
* Parses command line arguments. |
|
2 | 487 |
*/ |
488 |
boolean parseArgs(String args[]) { |
|
489 |
/* Preprocess and expand @file arguments */ |
|
490 |
try { |
|
491 |
args = CommandLine.parse(args); |
|
492 |
} catch (FileNotFoundException e) { |
|
493 |
fatalError(formatMsg("error.cant.open", e.getMessage())); |
|
494 |
return false; |
|
495 |
} catch (IOException e) { |
|
496 |
fatalError(e); |
|
497 |
return false; |
|
498 |
} |
|
499 |
/* parse flags */ |
|
500 |
int count = 1; |
|
501 |
try { |
|
502 |
String flags = args[0]; |
|
36511 | 503 |
|
504 |
// Note: flags.length == 2 can be treated as the short version of |
|
505 |
// the GNU option since the there cannot be any other options, |
|
506 |
// excluding -C, as per the old way. |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
507 |
if (flags.startsWith("--") || |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
508 |
(flags.startsWith("-") && flags.length() == 2)) { |
36511 | 509 |
try { |
510 |
count = GNUStyleOptions.parseOptions(this, args); |
|
511 |
} catch (GNUStyleOptions.BadArgs x) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
512 |
if (info == null) { |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
513 |
if (x.showUsage) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
514 |
usageError(x.getMessage()); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
515 |
} else { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
516 |
error(x.getMessage()); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
517 |
} |
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
518 |
return false; |
2 | 519 |
} |
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
520 |
} |
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
521 |
if (info != null) { |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
522 |
info.accept(out); |
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
523 |
return true; |
36511 | 524 |
} |
525 |
} else { |
|
526 |
// Legacy/compatibility options |
|
527 |
if (flags.startsWith("-")) { |
|
528 |
flags = flags.substring(1); |
|
529 |
} |
|
530 |
for (int i = 0; i < flags.length(); i++) { |
|
531 |
switch (flags.charAt(i)) { |
|
532 |
case 'c': |
|
533 |
if (xflag || tflag || uflag || iflag) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
534 |
usageError(getMsg("error.multiple.main.operations")); |
36511 | 535 |
return false; |
536 |
} |
|
537 |
cflag = true; |
|
538 |
break; |
|
539 |
case 'u': |
|
540 |
if (cflag || xflag || tflag || iflag) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
541 |
usageError(getMsg("error.multiple.main.operations")); |
36511 | 542 |
return false; |
543 |
} |
|
544 |
uflag = true; |
|
545 |
break; |
|
546 |
case 'x': |
|
547 |
if (cflag || uflag || tflag || iflag) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
548 |
usageError(getMsg("error.multiple.main.operations")); |
36511 | 549 |
return false; |
550 |
} |
|
551 |
xflag = true; |
|
552 |
break; |
|
553 |
case 't': |
|
554 |
if (cflag || uflag || xflag || iflag) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
555 |
usageError(getMsg("error.multiple.main.operations")); |
36511 | 556 |
return false; |
557 |
} |
|
558 |
tflag = true; |
|
559 |
break; |
|
560 |
case 'M': |
|
561 |
Mflag = true; |
|
562 |
break; |
|
563 |
case 'v': |
|
564 |
vflag = true; |
|
565 |
break; |
|
566 |
case 'f': |
|
567 |
fname = args[count++]; |
|
568 |
break; |
|
569 |
case 'm': |
|
570 |
mname = args[count++]; |
|
571 |
break; |
|
572 |
case '0': |
|
573 |
flag0 = true; |
|
574 |
break; |
|
575 |
case 'i': |
|
576 |
if (cflag || uflag || xflag || tflag) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
577 |
usageError(getMsg("error.multiple.main.operations")); |
36511 | 578 |
return false; |
579 |
} |
|
580 |
// do not increase the counter, files will contain rootjar |
|
581 |
rootjar = args[count++]; |
|
582 |
iflag = true; |
|
583 |
break; |
|
584 |
case 'n': |
|
585 |
nflag = true; |
|
586 |
break; |
|
587 |
case 'e': |
|
588 |
ename = args[count++]; |
|
589 |
break; |
|
590 |
case 'P': |
|
591 |
pflag = true; |
|
592 |
break; |
|
593 |
default: |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
594 |
usageError(formatMsg("error.illegal.option", |
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
595 |
String.valueOf(flags.charAt(i)))); |
36511 | 596 |
return false; |
5620
ed56433bf5d6
4690407: JAR tool: option -i can't be combined with other options
sherman
parents:
3288
diff
changeset
|
597 |
} |
2 | 598 |
} |
599 |
} |
|
600 |
} catch (ArrayIndexOutOfBoundsException e) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
601 |
usageError(getMsg("main.usage.summary")); |
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
602 |
return false; |
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
603 |
} |
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
604 |
if (!cflag && !tflag && !xflag && !uflag && !iflag && !dflag) { |
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
605 |
usageError(getMsg("error.bad.option")); |
2 | 606 |
return false; |
607 |
} |
|
36511 | 608 |
|
2 | 609 |
/* parse file arguments */ |
610 |
int n = args.length - count; |
|
611 |
if (n > 0) { |
|
39313 | 612 |
int version = BASE_VERSION; |
2 | 613 |
int k = 0; |
614 |
String[] nameBuf = new String[n]; |
|
39313 | 615 |
pathsMap.put(version, new HashSet<>()); |
2 | 616 |
try { |
617 |
for (int i = count; i < args.length; i++) { |
|
618 |
if (args[i].equals("-C")) { |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
619 |
if (dflag) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
620 |
// "--describe-module/-d" does not require file argument(s), |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
621 |
// but does accept --release |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
622 |
usageError(getMsg("error.bad.dflag")); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
623 |
return false; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
624 |
} |
2 | 625 |
/* change the directory */ |
626 |
String dir = args[++i]; |
|
627 |
dir = (dir.endsWith(File.separator) ? |
|
628 |
dir : (dir + File.separator)); |
|
629 |
dir = dir.replace(File.separatorChar, '/'); |
|
630 |
while (dir.indexOf("//") > -1) { |
|
631 |
dir = dir.replace("//", "/"); |
|
632 |
} |
|
39313 | 633 |
pathsMap.get(version).add(dir.replace(File.separatorChar, '/')); |
2 | 634 |
nameBuf[k++] = dir + args[++i]; |
39313 | 635 |
} else if (args[i].startsWith("--release")) { |
636 |
int v = BASE_VERSION; |
|
637 |
try { |
|
638 |
v = Integer.valueOf(args[++i]); |
|
639 |
} catch (NumberFormatException x) { |
|
640 |
error(formatMsg("error.release.value.notnumber", args[i])); |
|
641 |
// this will fall into the next error, thus returning false |
|
642 |
} |
|
643 |
if (v < 9) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
644 |
usageError(formatMsg("error.release.value.toosmall", String.valueOf(v))); |
39313 | 645 |
return false; |
646 |
} |
|
647 |
// associate the files, if any, with the previous version number |
|
648 |
if (k > 0) { |
|
649 |
String[] files = new String[k]; |
|
650 |
System.arraycopy(nameBuf, 0, files, 0, k); |
|
651 |
filesMap.put(version, files); |
|
652 |
isMultiRelease = version > BASE_VERSION; |
|
653 |
} |
|
654 |
// reset the counters and start with the new version number |
|
655 |
k = 0; |
|
656 |
nameBuf = new String[n]; |
|
657 |
version = v; |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
658 |
releaseValue = version; |
39313 | 659 |
pathsMap.put(version, new HashSet<>()); |
2 | 660 |
} else { |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
661 |
if (dflag) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
662 |
// "--describe-module/-d" does not require file argument(s), |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
663 |
// but does accept --release |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
664 |
usageError(getMsg("error.bad.dflag")); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
665 |
return false; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
666 |
} |
2 | 667 |
nameBuf[k++] = args[i]; |
668 |
} |
|
669 |
} |
|
670 |
} catch (ArrayIndexOutOfBoundsException e) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
671 |
usageError(getMsg("error.bad.file.arg")); |
2 | 672 |
return false; |
673 |
} |
|
39313 | 674 |
// associate remaining files, if any, with a version |
675 |
if (k > 0) { |
|
676 |
String[] files = new String[k]; |
|
677 |
System.arraycopy(nameBuf, 0, files, 0, k); |
|
678 |
filesMap.put(version, files); |
|
679 |
isMultiRelease = version > BASE_VERSION; |
|
680 |
} |
|
2 | 681 |
} else if (cflag && (mname == null)) { |
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
682 |
usageError(getMsg("error.bad.cflag")); |
2 | 683 |
return false; |
684 |
} else if (uflag) { |
|
19409 | 685 |
if ((mname != null) || (ename != null)) { |
2 | 686 |
/* just want to update the manifest */ |
687 |
return true; |
|
688 |
} else { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
689 |
usageError(getMsg("error.bad.uflag")); |
2 | 690 |
return false; |
691 |
} |
|
692 |
} |
|
693 |
return true; |
|
694 |
} |
|
695 |
||
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
696 |
/* |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
697 |
* Add the package of the given resource name if it's a .class |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
698 |
* or a resource in a named package. |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
699 |
*/ |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
700 |
void addPackageIfNamed(Set<String> packages, String name) { |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
701 |
if (name.startsWith(VERSIONS_DIR)) { |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
702 |
// trim the version dir prefix |
43731
bc7110b230c1
8165640: Enhance jar tool to allow module-info in versioned directories but not in base in modular multi-release jar files
sherman
parents:
43712
diff
changeset
|
703 |
int i0 = VERSIONS_DIR_LENGTH; |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
704 |
int i = name.indexOf('/', i0); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
705 |
if (i <= 0) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
706 |
warn(formatMsg("warn.release.unexpected.versioned.entry", name)); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
707 |
return; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
708 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
709 |
while (i0 < i) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
710 |
char c = name.charAt(i0); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
711 |
if (c < '0' || c > '9') { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
712 |
warn(formatMsg("warn.release.unexpected.versioned.entry", name)); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
713 |
return; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
714 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
715 |
i0++; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
716 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
717 |
name = name.substring(i + 1, name.length()); |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
718 |
} |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
719 |
String pn = toPackageName(name); |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
720 |
// add if this is a class or resource in a package |
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
43109
diff
changeset
|
721 |
if (Checks.isPackageName(pn)) { |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
722 |
packages.add(pn); |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
723 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
724 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
725 |
|
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
726 |
private String toEntryName(String name, Set<String> cpaths, boolean isDir) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
727 |
name = name.replace(File.separatorChar, '/'); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
728 |
if (isDir) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
729 |
name = name.endsWith("/") ? name : name + "/"; |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
730 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
731 |
String matchPath = ""; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
732 |
for (String path : cpaths) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
733 |
if (name.startsWith(path) && path.length() > matchPath.length()) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
734 |
matchPath = path; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
735 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
736 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
737 |
name = safeName(name.substring(matchPath.length())); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
738 |
// the old implementaton doesn't remove |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
739 |
// "./" if it was led by "/" (?) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
740 |
if (name.startsWith("./")) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
741 |
name = name.substring(2); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
742 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
743 |
return name; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
744 |
} |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
745 |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
746 |
private static String toVersionedName(String name, int version) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
747 |
return version > BASE_VERSION |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
748 |
? VERSIONS_DIR + version + "/" + name : name; |
36511 | 749 |
} |
750 |
||
751 |
private static String toPackageName(String path) { |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
752 |
int index = path.lastIndexOf('/'); |
36511 | 753 |
if (index != -1) { |
754 |
return path.substring(0, index).replace('/', '.'); |
|
755 |
} else { |
|
756 |
return ""; |
|
757 |
} |
|
758 |
} |
|
759 |
||
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
760 |
private void expand() throws IOException { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
761 |
for (int version : filesMap.keySet()) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
762 |
String[] files = filesMap.get(version); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
763 |
expand(null, files, pathsMap.get(version), version); |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
764 |
} |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
765 |
} |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
766 |
|
3218 | 767 |
/** |
2 | 768 |
* Expands list of files to process into full list of all files that |
769 |
* can be found by recursively descending directories. |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
770 |
* |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
771 |
* @param dir parent directory |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
772 |
* @param files list of files to expand |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
773 |
* @param cpaths set of directories specified by -C option for the files |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
774 |
* @throws IOException if an I/O error occurs |
2 | 775 |
*/ |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
776 |
private void expand(File dir, String[] files, Set<String> cpaths, int version) |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
777 |
throws IOException |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
778 |
{ |
36511 | 779 |
if (files == null) |
2 | 780 |
return; |
36511 | 781 |
|
2 | 782 |
for (int i = 0; i < files.length; i++) { |
783 |
File f; |
|
36511 | 784 |
if (dir == null) |
2 | 785 |
f = new File(files[i]); |
36511 | 786 |
else |
2 | 787 |
f = new File(dir, files[i]); |
36511 | 788 |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
789 |
boolean isDir = f.isDirectory(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
790 |
String name = toEntryName(f.getPath(), cpaths, isDir); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
791 |
|
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
792 |
if (version != BASE_VERSION) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
793 |
if (name.startsWith(VERSIONS_DIR)) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
794 |
// the entry starts with VERSIONS_DIR and version != BASE_VERSION, |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
795 |
// which means the "[dirs|files]" in --release v [dirs|files] |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
796 |
// includes VERSIONS_DIR-ed entries --> warning and skip (?) |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
797 |
error(formatMsg2("error.release.unexpected.versioned.entry", |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
798 |
name, String.valueOf(version))); |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
799 |
ok = false; |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
800 |
return; |
2 | 801 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
802 |
name = toVersionedName(name, version); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
803 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
804 |
|
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
805 |
if (f.isFile()) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
806 |
Entry e = new Entry(f, name, false); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
807 |
if (isModuleInfoEntry(name)) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
808 |
moduleInfos.putIfAbsent(name, Files.readAllBytes(f.toPath())); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
809 |
if (uflag) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
810 |
entryMap.put(name, e); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
811 |
} else if (entries.add(e)) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
812 |
if (uflag) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
813 |
entryMap.put(name, e); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
814 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
815 |
} else if (isDir) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
816 |
Entry e = new Entry(f, name, true); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
817 |
if (entries.add(e)) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
818 |
// utilize entryMap for the duplicate dir check even in |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
819 |
// case of cflag == true. |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
820 |
// dir name confilict/duplicate could happen with -C option. |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
821 |
// just remove the last "e" from the "entries" (zos will fail |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
822 |
// with "duplicated" entries), but continue expanding the |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
823 |
// sub tree |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
824 |
if (entryMap.containsKey(name)) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
825 |
entries.remove(e); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
826 |
} else { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
827 |
entryMap.put(name, e); |
1762 | 828 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
829 |
expand(f, f.list(), cpaths, version); |
1762 | 830 |
} |
2 | 831 |
} else { |
832 |
error(formatMsg("error.nosuch.fileordir", String.valueOf(f))); |
|
833 |
ok = false; |
|
834 |
} |
|
835 |
} |
|
836 |
} |
|
837 |
||
3218 | 838 |
/** |
2 | 839 |
* Creates a new JAR file. |
840 |
*/ |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
841 |
void create(OutputStream out, Manifest manifest) throws IOException |
2 | 842 |
{ |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
843 |
try (ZipOutputStream zos = new JarOutputStream(out)) { |
2 | 844 |
if (flag0) { |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
845 |
zos.setMethod(ZipOutputStream.STORED); |
2 | 846 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
847 |
// TODO: check module-info attributes against manifest ?? |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
848 |
if (manifest != null) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
849 |
if (vflag) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
850 |
output(getMsg("out.added.manifest")); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
851 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
852 |
ZipEntry e = new ZipEntry(MANIFEST_DIR); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
853 |
e.setTime(System.currentTimeMillis()); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
854 |
e.setSize(0); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
855 |
e.setCrc(0); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
856 |
zos.putNextEntry(e); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
857 |
e = new ZipEntry(MANIFEST_NAME); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
858 |
e.setTime(System.currentTimeMillis()); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
859 |
if (flag0) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
860 |
crc32Manifest(e, manifest); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
861 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
862 |
zos.putNextEntry(e); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
863 |
manifest.write(zos); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
864 |
zos.closeEntry(); |
36511 | 865 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
866 |
updateModuleInfo(moduleInfos, zos); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
867 |
for (Entry entry : entries) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
868 |
addFile(zos, entry); |
36511 | 869 |
} |
870 |
} |
|
2 | 871 |
} |
872 |
||
3218 | 873 |
private char toUpperCaseASCII(char c) { |
874 |
return (c < 'a' || c > 'z') ? c : (char) (c + 'A' - 'a'); |
|
875 |
} |
|
876 |
||
877 |
/** |
|
878 |
* Compares two strings for equality, ignoring case. The second |
|
879 |
* argument must contain only upper-case ASCII characters. |
|
880 |
* We don't want case comparison to be locale-dependent (else we |
|
881 |
* have the notorious "turkish i bug"). |
|
882 |
*/ |
|
883 |
private boolean equalsIgnoreCase(String s, String upper) { |
|
884 |
assert upper.toUpperCase(java.util.Locale.ENGLISH).equals(upper); |
|
885 |
int len; |
|
886 |
if ((len = s.length()) != upper.length()) |
|
887 |
return false; |
|
888 |
for (int i = 0; i < len; i++) { |
|
889 |
char c1 = s.charAt(i); |
|
890 |
char c2 = upper.charAt(i); |
|
891 |
if (c1 != c2 && toUpperCaseASCII(c1) != c2) |
|
892 |
return false; |
|
893 |
} |
|
894 |
return true; |
|
895 |
} |
|
896 |
||
897 |
/** |
|
898 |
* Updates an existing jar file. |
|
2 | 899 |
*/ |
900 |
boolean update(InputStream in, OutputStream out, |
|
1762 | 901 |
InputStream newManifest, |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
902 |
Map<String,byte[]> moduleInfos, |
1762 | 903 |
JarIndex jarIndex) throws IOException |
2 | 904 |
{ |
905 |
ZipInputStream zis = new ZipInputStream(in); |
|
906 |
ZipOutputStream zos = new JarOutputStream(out); |
|
907 |
ZipEntry e = null; |
|
908 |
boolean foundManifest = false; |
|
909 |
boolean updateOk = true; |
|
910 |
||
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
911 |
// All actual entries added/updated/existing, in the jar file (excl manifest |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
912 |
// and module-info.class ). |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
913 |
Set<String> jentries = new HashSet<>(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
914 |
|
1762 | 915 |
if (jarIndex != null) { |
916 |
addIndex(jarIndex, zos); |
|
2 | 917 |
} |
918 |
||
919 |
// put the old entries first, replace if necessary |
|
920 |
while ((e = zis.getNextEntry()) != null) { |
|
921 |
String name = e.getName(); |
|
922 |
||
3218 | 923 |
boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME); |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
924 |
boolean isModuleInfoEntry = isModuleInfoEntry(name); |
3218 | 925 |
|
926 |
if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME)) |
|
1762 | 927 |
|| (Mflag && isManifestEntry)) { |
2 | 928 |
continue; |
929 |
} else if (isManifestEntry && ((newManifest != null) || |
|
39313 | 930 |
(ename != null) || isMultiRelease)) { |
2 | 931 |
foundManifest = true; |
932 |
if (newManifest != null) { |
|
933 |
// Don't read from the newManifest InputStream, as we |
|
934 |
// might need it below, and we can't re-read the same data |
|
935 |
// twice. |
|
936 |
FileInputStream fis = new FileInputStream(mname); |
|
3218 | 937 |
boolean ambiguous = isAmbiguousMainClass(new Manifest(fis)); |
2 | 938 |
fis.close(); |
3218 | 939 |
if (ambiguous) { |
2 | 940 |
return false; |
941 |
} |
|
942 |
} |
|
943 |
// Update the manifest. |
|
944 |
Manifest old = new Manifest(zis); |
|
945 |
if (newManifest != null) { |
|
946 |
old.read(newManifest); |
|
947 |
} |
|
15682
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
948 |
if (!updateManifest(old, zos)) { |
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
949 |
return false; |
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
950 |
} |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
951 |
} else if (moduleInfos != null && isModuleInfoEntry) { |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
952 |
moduleInfos.putIfAbsent(name, zis.readAllBytes()); |
2 | 953 |
} else { |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
954 |
boolean isDir = e.isDirectory(); |
1762 | 955 |
if (!entryMap.containsKey(name)) { // copy the old stuff |
2 | 956 |
// do our own compression |
957 |
ZipEntry e2 = new ZipEntry(name); |
|
958 |
e2.setMethod(e.getMethod()); |
|
959 |
e2.setTime(e.getTime()); |
|
960 |
e2.setComment(e.getComment()); |
|
961 |
e2.setExtra(e.getExtra()); |
|
962 |
if (e.getMethod() == ZipEntry.STORED) { |
|
963 |
e2.setSize(e.getSize()); |
|
964 |
e2.setCrc(e.getCrc()); |
|
965 |
} |
|
966 |
zos.putNextEntry(e2); |
|
3218 | 967 |
copy(zis, zos); |
2 | 968 |
} else { // replace with the new files |
39313 | 969 |
Entry ent = entryMap.get(name); |
970 |
addFile(zos, ent); |
|
1762 | 971 |
entryMap.remove(name); |
41221
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
972 |
entries.remove(ent); |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
973 |
isDir = ent.isDir; |
2 | 974 |
} |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
975 |
if (!isDir) { |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
976 |
jentries.add(name); |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
977 |
} |
2 | 978 |
} |
979 |
} |
|
980 |
||
981 |
// add the remaining new files |
|
41221
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
982 |
for (Entry entry : entries) { |
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
983 |
addFile(zos, entry); |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
984 |
if (!entry.isDir) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
985 |
jentries.add(entry.name); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
986 |
} |
2 | 987 |
} |
988 |
if (!foundManifest) { |
|
989 |
if (newManifest != null) { |
|
990 |
Manifest m = new Manifest(newManifest); |
|
3218 | 991 |
updateOk = !isAmbiguousMainClass(m); |
2 | 992 |
if (updateOk) { |
15682
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
993 |
if (!updateManifest(m, zos)) { |
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
994 |
updateOk = false; |
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
995 |
} |
2 | 996 |
} |
19409 | 997 |
} else if (ename != null) { |
15682
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
998 |
if (!updateManifest(new Manifest(), zos)) { |
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
999 |
updateOk = false; |
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
1000 |
} |
2 | 1001 |
} |
1002 |
} |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1003 |
if (updateOk) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1004 |
if (moduleInfos != null && !moduleInfos.isEmpty()) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1005 |
Set<String> pkgs = new HashSet<>(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1006 |
jentries.forEach( je -> addPackageIfNamed(pkgs, je)); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1007 |
addExtendedModuleAttributes(moduleInfos, pkgs); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1008 |
updateOk = checkModuleInfo(moduleInfos.get(MODULE_INFO), jentries); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1009 |
updateModuleInfo(moduleInfos, zos); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1010 |
// TODO: check manifest main classes, etc |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1011 |
} else if (moduleVersion != null || modulesToHash != null) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1012 |
error(getMsg("error.module.options.without.info")); |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
1013 |
updateOk = false; |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
1014 |
} |
36511 | 1015 |
} |
2 | 1016 |
zis.close(); |
1017 |
zos.close(); |
|
1018 |
return updateOk; |
|
1019 |
} |
|
1020 |
||
1021 |
private void addIndex(JarIndex index, ZipOutputStream zos) |
|
1022 |
throws IOException |
|
1023 |
{ |
|
3218 | 1024 |
ZipEntry e = new ZipEntry(INDEX_NAME); |
2 | 1025 |
e.setTime(System.currentTimeMillis()); |
1026 |
if (flag0) { |
|
3218 | 1027 |
CRC32OutputStream os = new CRC32OutputStream(); |
1028 |
index.write(os); |
|
1029 |
os.updateEntry(e); |
|
2 | 1030 |
} |
1031 |
zos.putNextEntry(e); |
|
1032 |
index.write(zos); |
|
3218 | 1033 |
zos.closeEntry(); |
2 | 1034 |
} |
1035 |
||
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1036 |
private void updateModuleInfo(Map<String,byte[]> moduleInfos, ZipOutputStream zos) |
36511 | 1037 |
throws IOException |
1038 |
{ |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1039 |
String fmt = uflag ? "out.update.module-info": "out.added.module-info"; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1040 |
for (Map.Entry<String,byte[]> mi : moduleInfos.entrySet()) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1041 |
String name = mi.getKey(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1042 |
byte[] bytes = mi.getValue(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1043 |
ZipEntry e = new ZipEntry(name); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1044 |
e.setTime(System.currentTimeMillis()); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1045 |
if (flag0) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1046 |
crc32ModuleInfo(e, bytes); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1047 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1048 |
zos.putNextEntry(e); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1049 |
zos.write(bytes); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1050 |
zos.closeEntry(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1051 |
if (vflag) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1052 |
output(formatMsg(fmt, name)); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1053 |
} |
36511 | 1054 |
} |
1055 |
} |
|
1056 |
||
15682
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
1057 |
private boolean updateManifest(Manifest m, ZipOutputStream zos) |
2 | 1058 |
throws IOException |
1059 |
{ |
|
1060 |
addVersion(m); |
|
1061 |
addCreatedBy(m); |
|
1062 |
if (ename != null) { |
|
1063 |
addMainClass(m, ename); |
|
1064 |
} |
|
39313 | 1065 |
if (isMultiRelease) { |
1066 |
addMultiRelease(m); |
|
1067 |
} |
|
3218 | 1068 |
ZipEntry e = new ZipEntry(MANIFEST_NAME); |
2 | 1069 |
e.setTime(System.currentTimeMillis()); |
1070 |
if (flag0) { |
|
1071 |
crc32Manifest(e, m); |
|
1072 |
} |
|
1073 |
zos.putNextEntry(e); |
|
1074 |
m.write(zos); |
|
1075 |
if (vflag) { |
|
1076 |
output(getMsg("out.update.manifest")); |
|
1077 |
} |
|
15682
793a36de151d
8003255: (profiles) Update JAR file specification to support profiles
alanb
parents:
14504
diff
changeset
|
1078 |
return true; |
2 | 1079 |
} |
1080 |
||
29914 | 1081 |
private static final boolean isWinDriveLetter(char c) { |
1082 |
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); |
|
1083 |
} |
|
1084 |
||
1085 |
private String safeName(String name) { |
|
1086 |
if (!pflag) { |
|
1087 |
int len = name.length(); |
|
1088 |
int i = name.lastIndexOf("../"); |
|
1089 |
if (i == -1) { |
|
1090 |
i = 0; |
|
1091 |
} else { |
|
1092 |
i += 3; // strip any dot-dot components |
|
1093 |
} |
|
1094 |
if (File.separatorChar == '\\') { |
|
1095 |
// the spec requests no drive letter. skip if |
|
1096 |
// the entry name has one. |
|
1097 |
while (i < len) { |
|
1098 |
int off = i; |
|
1099 |
if (i + 1 < len && |
|
1100 |
name.charAt(i + 1) == ':' && |
|
1101 |
isWinDriveLetter(name.charAt(i))) { |
|
1102 |
i += 2; |
|
1103 |
} |
|
1104 |
while (i < len && name.charAt(i) == '/') { |
|
1105 |
i++; |
|
1106 |
} |
|
1107 |
if (i == off) { |
|
1108 |
break; |
|
1109 |
} |
|
1110 |
} |
|
1111 |
} else { |
|
1112 |
while (i < len && name.charAt(i) == '/') { |
|
1113 |
i++; |
|
1114 |
} |
|
1115 |
} |
|
1116 |
if (i != 0) { |
|
1117 |
name = name.substring(i); |
|
1118 |
} |
|
1119 |
} |
|
1120 |
return name; |
|
1121 |
} |
|
2 | 1122 |
|
1123 |
private void addVersion(Manifest m) { |
|
1124 |
Attributes global = m.getMainAttributes(); |
|
1125 |
if (global.getValue(Attributes.Name.MANIFEST_VERSION) == null) { |
|
1126 |
global.put(Attributes.Name.MANIFEST_VERSION, VERSION); |
|
1127 |
} |
|
1128 |
} |
|
1129 |
||
1130 |
private void addCreatedBy(Manifest m) { |
|
1131 |
Attributes global = m.getMainAttributes(); |
|
1132 |
if (global.getValue(new Attributes.Name("Created-By")) == null) { |
|
1133 |
String javaVendor = System.getProperty("java.vendor"); |
|
1134 |
String jdkVersion = System.getProperty("java.version"); |
|
1135 |
global.put(new Attributes.Name("Created-By"), jdkVersion + " (" + |
|
1136 |
javaVendor + ")"); |
|
1137 |
} |
|
1138 |
} |
|
1139 |
||
1140 |
private void addMainClass(Manifest m, String mainApp) { |
|
1141 |
Attributes global = m.getMainAttributes(); |
|
1142 |
||
1143 |
// overrides any existing Main-Class attribute |
|
1144 |
global.put(Attributes.Name.MAIN_CLASS, mainApp); |
|
1145 |
} |
|
1146 |
||
39313 | 1147 |
private void addMultiRelease(Manifest m) { |
1148 |
Attributes global = m.getMainAttributes(); |
|
1149 |
global.put(Attributes.Name.MULTI_RELEASE, "true"); |
|
1150 |
} |
|
1151 |
||
3218 | 1152 |
private boolean isAmbiguousMainClass(Manifest m) { |
2 | 1153 |
if (ename != null) { |
1154 |
Attributes global = m.getMainAttributes(); |
|
1155 |
if ((global.get(Attributes.Name.MAIN_CLASS) != null)) { |
|
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
1156 |
usageError(getMsg("error.bad.eflag")); |
2 | 1157 |
return true; |
1158 |
} |
|
1159 |
} |
|
1160 |
return false; |
|
1161 |
} |
|
1162 |
||
3218 | 1163 |
/** |
2 | 1164 |
* Adds a new file entry to the ZIP output stream. |
1165 |
*/ |
|
39313 | 1166 |
void addFile(ZipOutputStream zos, Entry entry) throws IOException { |
41221
eb0dc5ea2302
8165944: jar utility doesn't process more than one -C argument
sdrach
parents:
40251
diff
changeset
|
1167 |
|
39313 | 1168 |
File file = entry.file; |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1169 |
String name = entry.name; |
39313 | 1170 |
boolean isDir = entry.isDir; |
2 | 1171 |
|
1172 |
if (name.equals("") || name.equals(".") || name.equals(zname)) { |
|
1173 |
return; |
|
3218 | 1174 |
} else if ((name.equals(MANIFEST_DIR) || name.equals(MANIFEST_NAME)) |
2 | 1175 |
&& !Mflag) { |
1176 |
if (vflag) { |
|
1177 |
output(formatMsg("out.ignore.entry", name)); |
|
1178 |
} |
|
1179 |
return; |
|
36511 | 1180 |
} else if (name.equals(MODULE_INFO)) { |
1181 |
throw new Error("Unexpected module info: " + name); |
|
2 | 1182 |
} |
1183 |
||
1184 |
long size = isDir ? 0 : file.length(); |
|
1185 |
||
1186 |
if (vflag) { |
|
1187 |
out.print(formatMsg("out.adding", name)); |
|
1188 |
} |
|
1189 |
ZipEntry e = new ZipEntry(name); |
|
1190 |
e.setTime(file.lastModified()); |
|
1191 |
if (size == 0) { |
|
1192 |
e.setMethod(ZipEntry.STORED); |
|
1193 |
e.setSize(0); |
|
1194 |
e.setCrc(0); |
|
1195 |
} else if (flag0) { |
|
1196 |
crc32File(e, file); |
|
1197 |
} |
|
1198 |
zos.putNextEntry(e); |
|
1199 |
if (!isDir) { |
|
3218 | 1200 |
copy(file, zos); |
2 | 1201 |
} |
1202 |
zos.closeEntry(); |
|
1203 |
/* report how much compression occurred. */ |
|
1204 |
if (vflag) { |
|
1205 |
size = e.getSize(); |
|
1206 |
long csize = e.getCompressedSize(); |
|
1207 |
out.print(formatMsg2("out.size", String.valueOf(size), |
|
1208 |
String.valueOf(csize))); |
|
1209 |
if (e.getMethod() == ZipEntry.DEFLATED) { |
|
1210 |
long ratio = 0; |
|
1211 |
if (size != 0) { |
|
1212 |
ratio = ((size - csize) * 100) / size; |
|
1213 |
} |
|
1214 |
output(formatMsg("out.deflated", String.valueOf(ratio))); |
|
1215 |
} else { |
|
1216 |
output(getMsg("out.stored")); |
|
1217 |
} |
|
1218 |
} |
|
1219 |
} |
|
1220 |
||
3218 | 1221 |
/** |
1222 |
* A buffer for use only by copy(InputStream, OutputStream). |
|
1223 |
* Not as clean as allocating a new buffer as needed by copy, |
|
1224 |
* but significantly more efficient. |
|
2 | 1225 |
*/ |
3218 | 1226 |
private byte[] copyBuf = new byte[8192]; |
1227 |
||
1228 |
/** |
|
1229 |
* Copies all bytes from the input stream to the output stream. |
|
1230 |
* Does not close or flush either stream. |
|
1231 |
* |
|
1232 |
* @param from the input stream to read from |
|
1233 |
* @param to the output stream to write to |
|
1234 |
* @throws IOException if an I/O error occurs |
|
1235 |
*/ |
|
1236 |
private void copy(InputStream from, OutputStream to) throws IOException { |
|
1237 |
int n; |
|
1238 |
while ((n = from.read(copyBuf)) != -1) |
|
1239 |
to.write(copyBuf, 0, n); |
|
2 | 1240 |
} |
1241 |
||
3218 | 1242 |
/** |
1243 |
* Copies all bytes from the input file to the output stream. |
|
1244 |
* Does not close or flush the output stream. |
|
1245 |
* |
|
1246 |
* @param from the input file to read from |
|
1247 |
* @param to the output stream to write to |
|
1248 |
* @throws IOException if an I/O error occurs |
|
1249 |
*/ |
|
1250 |
private void copy(File from, OutputStream to) throws IOException { |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1251 |
try (InputStream in = new FileInputStream(from)) { |
3218 | 1252 |
copy(in, to); |
1253 |
} |
|
1254 |
} |
|
1255 |
||
1256 |
/** |
|
1257 |
* Copies all bytes from the input stream to the output file. |
|
1258 |
* Does not close the input stream. |
|
1259 |
* |
|
1260 |
* @param from the input stream to read from |
|
1261 |
* @param to the output file to write to |
|
1262 |
* @throws IOException if an I/O error occurs |
|
1263 |
*/ |
|
1264 |
private void copy(InputStream from, File to) throws IOException { |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1265 |
try (OutputStream out = new FileOutputStream(to)) { |
3218 | 1266 |
copy(from, out); |
1267 |
} |
|
1268 |
} |
|
1269 |
||
1270 |
/** |
|
36511 | 1271 |
* Computes the crc32 of a module-info.class. This is necessary when the |
1272 |
* ZipOutputStream is in STORED mode. |
|
1273 |
*/ |
|
1274 |
private void crc32ModuleInfo(ZipEntry e, byte[] bytes) throws IOException { |
|
1275 |
CRC32OutputStream os = new CRC32OutputStream(); |
|
1276 |
ByteArrayInputStream in = new ByteArrayInputStream(bytes); |
|
1277 |
in.transferTo(os); |
|
1278 |
os.updateEntry(e); |
|
1279 |
} |
|
1280 |
||
1281 |
/** |
|
3218 | 1282 |
* Computes the crc32 of a Manifest. This is necessary when the |
1283 |
* ZipOutputStream is in STORED mode. |
|
1284 |
*/ |
|
1285 |
private void crc32Manifest(ZipEntry e, Manifest m) throws IOException { |
|
1286 |
CRC32OutputStream os = new CRC32OutputStream(); |
|
1287 |
m.write(os); |
|
1288 |
os.updateEntry(e); |
|
1289 |
} |
|
1290 |
||
1291 |
/** |
|
1292 |
* Computes the crc32 of a File. This is necessary when the |
|
1293 |
* ZipOutputStream is in STORED mode. |
|
2 | 1294 |
*/ |
1295 |
private void crc32File(ZipEntry e, File f) throws IOException { |
|
3218 | 1296 |
CRC32OutputStream os = new CRC32OutputStream(); |
1297 |
copy(f, os); |
|
1298 |
if (os.n != f.length()) { |
|
2 | 1299 |
throw new JarException(formatMsg( |
1300 |
"error.incorrect.length", f.getPath())); |
|
1301 |
} |
|
3218 | 1302 |
os.updateEntry(e); |
2 | 1303 |
} |
1304 |
||
39313 | 1305 |
void replaceFSC(Map<Integer, String []> filesMap) { |
1306 |
filesMap.keySet().forEach(version -> { |
|
1307 |
String[] files = filesMap.get(version); |
|
1308 |
if (files != null) { |
|
1309 |
for (int i = 0; i < files.length; i++) { |
|
1310 |
files[i] = files[i].replace(File.separatorChar, '/'); |
|
1311 |
} |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1312 |
} |
39313 | 1313 |
}); |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1314 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1315 |
|
3218 | 1316 |
@SuppressWarnings("serial") |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1317 |
Set<ZipEntry> newDirSet() { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1318 |
return new HashSet<ZipEntry>() { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1319 |
public boolean add(ZipEntry e) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1320 |
return ((e == null || useExtractionTime) ? false : super.add(e)); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1321 |
}}; |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1322 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1323 |
|
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1324 |
void updateLastModifiedTime(Set<ZipEntry> zes) throws IOException { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1325 |
for (ZipEntry ze : zes) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1326 |
long lastModified = ze.getTime(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1327 |
if (lastModified != -1) { |
29914 | 1328 |
String name = safeName(ze.getName().replace(File.separatorChar, '/')); |
1329 |
if (name.length() != 0) { |
|
1330 |
File f = new File(name.replace('/', File.separatorChar)); |
|
1331 |
f.setLastModified(lastModified); |
|
1332 |
} |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1333 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1334 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1335 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1336 |
|
3218 | 1337 |
/** |
2 | 1338 |
* Extracts specified entries from JAR file. |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
1339 |
* |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
1340 |
* @return whether entries were found and successfully extracted |
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
1341 |
* (indicating this was a zip file without "leading garbage") |
2 | 1342 |
*/ |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
1343 |
boolean extract(InputStream in, String files[]) throws IOException { |
2 | 1344 |
ZipInputStream zis = new ZipInputStream(in); |
1345 |
ZipEntry e; |
|
1762 | 1346 |
// Set of all directory entries specified in archive. Disallows |
2 | 1347 |
// null entries. Disallows all entries if using pre-6.0 behavior. |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
1348 |
boolean entriesFound = false; |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1349 |
Set<ZipEntry> dirs = newDirSet(); |
2 | 1350 |
while ((e = zis.getNextEntry()) != null) { |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
1351 |
entriesFound = true; |
2 | 1352 |
if (files == null) { |
1353 |
dirs.add(extractFile(zis, e)); |
|
1354 |
} else { |
|
1355 |
String name = e.getName(); |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1356 |
for (String file : files) { |
2 | 1357 |
if (name.startsWith(file)) { |
1358 |
dirs.add(extractFile(zis, e)); |
|
1359 |
break; |
|
1360 |
} |
|
1361 |
} |
|
1362 |
} |
|
1363 |
} |
|
1364 |
||
1365 |
// Update timestamps of directories specified in archive with their |
|
1366 |
// timestamps as given in the archive. We do this after extraction, |
|
1367 |
// instead of during, because creating a file in a directory changes |
|
1368 |
// that directory's timestamp. |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1369 |
updateLastModifiedTime(dirs); |
26714
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
1370 |
|
3caa40031b3f
8058520: jar xf does not work on zip files with leading garbage
martin
parents:
25859
diff
changeset
|
1371 |
return entriesFound; |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1372 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1373 |
|
3218 | 1374 |
/** |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1375 |
* Extracts specified entries from JAR file, via ZipFile. |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1376 |
*/ |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1377 |
void extract(String fname, String files[]) throws IOException { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1378 |
ZipFile zf = new ZipFile(fname); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1379 |
Set<ZipEntry> dirs = newDirSet(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1380 |
Enumeration<? extends ZipEntry> zes = zf.entries(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1381 |
while (zes.hasMoreElements()) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1382 |
ZipEntry e = zes.nextElement(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1383 |
if (files == null) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1384 |
dirs.add(extractFile(zf.getInputStream(e), e)); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1385 |
} else { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1386 |
String name = e.getName(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1387 |
for (String file : files) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1388 |
if (name.startsWith(file)) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1389 |
dirs.add(extractFile(zf.getInputStream(e), e)); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1390 |
break; |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1391 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1392 |
} |
2 | 1393 |
} |
1394 |
} |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1395 |
zf.close(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1396 |
updateLastModifiedTime(dirs); |
2 | 1397 |
} |
1398 |
||
3218 | 1399 |
/** |
2 | 1400 |
* Extracts next entry from JAR file, creating directories as needed. If |
1401 |
* the entry is for a directory which doesn't exist prior to this |
|
1402 |
* invocation, returns that entry, otherwise returns null. |
|
1403 |
*/ |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1404 |
ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException { |
2 | 1405 |
ZipEntry rc = null; |
29914 | 1406 |
// The spec requres all slashes MUST be forward '/', it is possible |
1407 |
// an offending zip/jar entry may uses the backwards slash in its |
|
1408 |
// name. It might cause problem on Windows platform as it skips |
|
1409 |
// our "safe" check for leading slahs and dot-dot. So replace them |
|
1410 |
// with '/'. |
|
1411 |
String name = safeName(e.getName().replace(File.separatorChar, '/')); |
|
1412 |
if (name.length() == 0) { |
|
1413 |
return rc; // leading '/' or 'dot-dot' only path |
|
1414 |
} |
|
1415 |
File f = new File(name.replace('/', File.separatorChar)); |
|
2 | 1416 |
if (e.isDirectory()) { |
1417 |
if (f.exists()) { |
|
1418 |
if (!f.isDirectory()) { |
|
1419 |
throw new IOException(formatMsg("error.create.dir", |
|
1420 |
f.getPath())); |
|
1421 |
} |
|
1422 |
} else { |
|
1423 |
if (!f.mkdirs()) { |
|
1424 |
throw new IOException(formatMsg("error.create.dir", |
|
1425 |
f.getPath())); |
|
1426 |
} else { |
|
1427 |
rc = e; |
|
1428 |
} |
|
1429 |
} |
|
1430 |
||
1431 |
if (vflag) { |
|
1432 |
output(formatMsg("out.create", name)); |
|
1433 |
} |
|
1434 |
} else { |
|
1435 |
if (f.getParent() != null) { |
|
1436 |
File d = new File(f.getParent()); |
|
1437 |
if (!d.exists() && !d.mkdirs() || !d.isDirectory()) { |
|
1438 |
throw new IOException(formatMsg( |
|
1439 |
"error.create.dir", d.getPath())); |
|
1440 |
} |
|
1441 |
} |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1442 |
try { |
3218 | 1443 |
copy(is, f); |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1444 |
} finally { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1445 |
if (is instanceof ZipInputStream) |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1446 |
((ZipInputStream)is).closeEntry(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1447 |
else |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1448 |
is.close(); |
2 | 1449 |
} |
1450 |
if (vflag) { |
|
1451 |
if (e.getMethod() == ZipEntry.DEFLATED) { |
|
1452 |
output(formatMsg("out.inflated", name)); |
|
1453 |
} else { |
|
1454 |
output(formatMsg("out.extracted", name)); |
|
1455 |
} |
|
1456 |
} |
|
1457 |
} |
|
1458 |
if (!useExtractionTime) { |
|
1459 |
long lastModified = e.getTime(); |
|
1460 |
if (lastModified != -1) { |
|
1461 |
f.setLastModified(lastModified); |
|
1462 |
} |
|
1463 |
} |
|
1464 |
return rc; |
|
1465 |
} |
|
1466 |
||
3218 | 1467 |
/** |
2 | 1468 |
* Lists contents of JAR file. |
1469 |
*/ |
|
1470 |
void list(InputStream in, String files[]) throws IOException { |
|
1471 |
ZipInputStream zis = new ZipInputStream(in); |
|
1472 |
ZipEntry e; |
|
1473 |
while ((e = zis.getNextEntry()) != null) { |
|
1474 |
/* |
|
1475 |
* In the case of a compressed (deflated) entry, the entry size |
|
1476 |
* is stored immediately following the entry data and cannot be |
|
1477 |
* determined until the entry is fully read. Therefore, we close |
|
1478 |
* the entry first before printing out its attributes. |
|
1479 |
*/ |
|
1480 |
zis.closeEntry(); |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1481 |
printEntry(e, files); |
2 | 1482 |
} |
1483 |
} |
|
1484 |
||
3218 | 1485 |
/** |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1486 |
* Lists contents of JAR file, via ZipFile. |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1487 |
*/ |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1488 |
void list(String fname, String files[]) throws IOException { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1489 |
ZipFile zf = new ZipFile(fname); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1490 |
Enumeration<? extends ZipEntry> zes = zf.entries(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1491 |
while (zes.hasMoreElements()) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1492 |
printEntry(zes.nextElement(), files); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1493 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1494 |
zf.close(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1495 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1496 |
|
2 | 1497 |
/** |
3218 | 1498 |
* Outputs the class index table to the INDEX.LIST file of the |
2 | 1499 |
* root jar file. |
1500 |
*/ |
|
1501 |
void dumpIndex(String rootjar, JarIndex index) throws IOException { |
|
1502 |
File jarFile = new File(rootjar); |
|
3218 | 1503 |
Path jarPath = jarFile.toPath(); |
1504 |
Path tmpPath = createTempFileInSameDirectoryAs(jarFile).toPath(); |
|
1505 |
try { |
|
8158 | 1506 |
if (update(Files.newInputStream(jarPath), |
1507 |
Files.newOutputStream(tmpPath), |
|
36511 | 1508 |
null, null, index)) { |
3218 | 1509 |
try { |
8158 | 1510 |
Files.move(tmpPath, jarPath, REPLACE_EXISTING); |
3218 | 1511 |
} catch (IOException e) { |
1512 |
throw new IOException(getMsg("error.write.file"), e); |
|
1513 |
} |
|
1514 |
} |
|
1515 |
} finally { |
|
8158 | 1516 |
Files.deleteIfExists(tmpPath); |
2 | 1517 |
} |
1518 |
} |
|
1519 |
||
3218 | 1520 |
private HashSet<String> jarPaths = new HashSet<String>(); |
1521 |
||
1522 |
/** |
|
1523 |
* Generates the transitive closure of the Class-Path attribute for |
|
2 | 1524 |
* the specified jar file. |
1525 |
*/ |
|
3218 | 1526 |
List<String> getJarPath(String jar) throws IOException { |
1527 |
List<String> files = new ArrayList<String>(); |
|
2 | 1528 |
files.add(jar); |
3218 | 1529 |
jarPaths.add(jar); |
2 | 1530 |
|
1531 |
// take out the current path |
|
1532 |
String path = jar.substring(0, Math.max(0, jar.lastIndexOf('/') + 1)); |
|
1533 |
||
1534 |
// class path attribute will give us jar file name with |
|
1535 |
// '/' as separators, so we need to change them to the |
|
1536 |
// appropriate one before we open the jar file. |
|
1537 |
JarFile rf = new JarFile(jar.replace('/', File.separatorChar)); |
|
1538 |
||
1539 |
if (rf != null) { |
|
1540 |
Manifest man = rf.getManifest(); |
|
1541 |
if (man != null) { |
|
1542 |
Attributes attr = man.getMainAttributes(); |
|
1543 |
if (attr != null) { |
|
1544 |
String value = attr.getValue(Attributes.Name.CLASS_PATH); |
|
1545 |
if (value != null) { |
|
1546 |
StringTokenizer st = new StringTokenizer(value); |
|
1547 |
while (st.hasMoreTokens()) { |
|
1548 |
String ajar = st.nextToken(); |
|
1549 |
if (!ajar.endsWith("/")) { // it is a jar file |
|
1550 |
ajar = path.concat(ajar); |
|
1551 |
/* check on cyclic dependency */ |
|
3218 | 1552 |
if (! jarPaths.contains(ajar)) { |
2 | 1553 |
files.addAll(getJarPath(ajar)); |
1554 |
} |
|
1555 |
} |
|
1556 |
} |
|
1557 |
} |
|
1558 |
} |
|
1559 |
} |
|
1560 |
} |
|
1561 |
rf.close(); |
|
1562 |
return files; |
|
1563 |
} |
|
1564 |
||
1565 |
/** |
|
3218 | 1566 |
* Generates class index file for the specified root jar file. |
2 | 1567 |
*/ |
1568 |
void genIndex(String rootjar, String[] files) throws IOException { |
|
3218 | 1569 |
List<String> jars = getJarPath(rootjar); |
2 | 1570 |
int njars = jars.size(); |
1571 |
String[] jarfiles; |
|
1572 |
||
1573 |
if (njars == 1 && files != null) { |
|
1574 |
// no class-path attribute defined in rootjar, will |
|
1575 |
// use command line specified list of jars |
|
1576 |
for (int i = 0; i < files.length; i++) { |
|
1577 |
jars.addAll(getJarPath(files[i])); |
|
1578 |
} |
|
1579 |
njars = jars.size(); |
|
1580 |
} |
|
3218 | 1581 |
jarfiles = jars.toArray(new String[njars]); |
2 | 1582 |
JarIndex index = new JarIndex(jarfiles); |
1583 |
dumpIndex(rootjar, index); |
|
1584 |
} |
|
1585 |
||
3218 | 1586 |
/** |
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1587 |
* Prints entry information, if requested. |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1588 |
*/ |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1589 |
void printEntry(ZipEntry e, String[] files) throws IOException { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1590 |
if (files == null) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1591 |
printEntry(e); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1592 |
} else { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1593 |
String name = e.getName(); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1594 |
for (String file : files) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1595 |
if (name.startsWith(file)) { |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1596 |
printEntry(e); |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1597 |
return; |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1598 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1599 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1600 |
} |
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1601 |
} |
2 | 1602 |
|
3218 | 1603 |
/** |
2 | 1604 |
* Prints entry information. |
1605 |
*/ |
|
1606 |
void printEntry(ZipEntry e) throws IOException { |
|
1607 |
if (vflag) { |
|
1816
f310e059bd83
6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
sherman
parents:
1762
diff
changeset
|
1608 |
StringBuilder sb = new StringBuilder(); |
2 | 1609 |
String s = Long.toString(e.getSize()); |
1610 |
for (int i = 6 - s.length(); i > 0; --i) { |
|
1611 |
sb.append(' '); |
|
1612 |
} |
|
1613 |
sb.append(s).append(' ').append(new Date(e.getTime()).toString()); |
|
1614 |
sb.append(' ').append(e.getName()); |
|
1615 |
output(sb.toString()); |
|
1616 |
} else { |
|
1617 |
output(e.getName()); |
|
1618 |
} |
|
1619 |
} |
|
1620 |
||
3218 | 1621 |
/** |
1622 |
* Prints usage message. |
|
2 | 1623 |
*/ |
42463
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
1624 |
void usageError(String s) { |
39c0bbf9d03c
8170952: jar's usage message output need some cleanup
sherman
parents:
42345
diff
changeset
|
1625 |
err.println(s); |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
1626 |
err.println(getMsg("main.usage.summary.try")); |
2 | 1627 |
} |
1628 |
||
3218 | 1629 |
/** |
2 | 1630 |
* A fatal exception has been caught. No recovery possible |
1631 |
*/ |
|
1632 |
void fatalError(Exception e) { |
|
1633 |
e.printStackTrace(); |
|
1634 |
} |
|
1635 |
||
3218 | 1636 |
/** |
2 | 1637 |
* A fatal condition has been detected; message is "s". |
1638 |
* No recovery possible |
|
1639 |
*/ |
|
1640 |
void fatalError(String s) { |
|
1641 |
error(program + ": " + s); |
|
1642 |
} |
|
1643 |
||
1644 |
/** |
|
1645 |
* Print an output message; like verbose output and the like |
|
1646 |
*/ |
|
1647 |
protected void output(String s) { |
|
1648 |
out.println(s); |
|
1649 |
} |
|
1650 |
||
1651 |
/** |
|
21278 | 1652 |
* Print an error message; like something is broken |
2 | 1653 |
*/ |
39313 | 1654 |
void error(String s) { |
2 | 1655 |
err.println(s); |
1656 |
} |
|
1657 |
||
3218 | 1658 |
/** |
41754
8b7c8d5e9a0d
8164805: Fail to create a MR modular JAR with a versioned entry of a concealed package
sdrach
parents:
41484
diff
changeset
|
1659 |
* Print a warning message |
8b7c8d5e9a0d
8164805: Fail to create a MR modular JAR with a versioned entry of a concealed package
sdrach
parents:
41484
diff
changeset
|
1660 |
*/ |
8b7c8d5e9a0d
8164805: Fail to create a MR modular JAR with a versioned entry of a concealed package
sdrach
parents:
41484
diff
changeset
|
1661 |
void warn(String s) { |
8b7c8d5e9a0d
8164805: Fail to create a MR modular JAR with a versioned entry of a concealed package
sdrach
parents:
41484
diff
changeset
|
1662 |
err.println(s); |
8b7c8d5e9a0d
8164805: Fail to create a MR modular JAR with a versioned entry of a concealed package
sdrach
parents:
41484
diff
changeset
|
1663 |
} |
8b7c8d5e9a0d
8164805: Fail to create a MR modular JAR with a versioned entry of a concealed package
sdrach
parents:
41484
diff
changeset
|
1664 |
|
8b7c8d5e9a0d
8164805: Fail to create a MR modular JAR with a versioned entry of a concealed package
sdrach
parents:
41484
diff
changeset
|
1665 |
/** |
2 | 1666 |
* Main routine to start program. |
1667 |
*/ |
|
1668 |
public static void main(String args[]) { |
|
1669 |
Main jartool = new Main(System.out, System.err, "jar"); |
|
1670 |
System.exit(jartool.run(args) ? 0 : 1); |
|
1671 |
} |
|
1672 |
||
3218 | 1673 |
/** |
1674 |
* An OutputStream that doesn't send its output anywhere, (but could). |
|
1675 |
* It's here to find the CRC32 of an input file, necessary for STORED |
|
1676 |
* mode in ZIP. |
|
1677 |
*/ |
|
1678 |
private static class CRC32OutputStream extends java.io.OutputStream { |
|
1679 |
final CRC32 crc = new CRC32(); |
|
1680 |
long n = 0; |
|
1681 |
||
1682 |
CRC32OutputStream() {} |
|
2 | 1683 |
|
3218 | 1684 |
public void write(int r) throws IOException { |
1685 |
crc.update(r); |
|
1686 |
n++; |
|
1687 |
} |
|
1688 |
||
1689 |
public void write(byte[] b, int off, int len) throws IOException { |
|
1690 |
crc.update(b, off, len); |
|
1691 |
n += len; |
|
1692 |
} |
|
2 | 1693 |
|
3218 | 1694 |
/** |
1695 |
* Updates a ZipEntry which describes the data read by this |
|
1696 |
* output stream, in STORED mode. |
|
1697 |
*/ |
|
1698 |
public void updateEntry(ZipEntry e) { |
|
1699 |
e.setMethod(ZipEntry.STORED); |
|
1700 |
e.setSize(n); |
|
1701 |
e.setCrc(crc.getValue()); |
|
1702 |
} |
|
2 | 1703 |
} |
21348
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1704 |
|
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1705 |
/** |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1706 |
* Attempt to create temporary file in the system-provided temporary folder, if failed attempts |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1707 |
* to create it in the same folder as the file in parameter (if any) |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1708 |
*/ |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1709 |
private File createTemporaryFile(String tmpbase, String suffix) { |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1710 |
File tmpfile = null; |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1711 |
|
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1712 |
try { |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1713 |
tmpfile = File.createTempFile(tmpbase, suffix); |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1714 |
} catch (IOException | SecurityException e) { |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1715 |
// Unable to create file due to permission violation or security exception |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1716 |
} |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1717 |
if (tmpfile == null) { |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1718 |
// Were unable to create temporary file, fall back to temporary file in the same folder |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1719 |
if (fname != null) { |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1720 |
try { |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1721 |
File tmpfolder = new File(fname).getAbsoluteFile().getParentFile(); |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1722 |
tmpfile = File.createTempFile(fname, ".tmp" + suffix, tmpfolder); |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1723 |
} catch (IOException ioe) { |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1724 |
// Last option failed - fall gracefully |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1725 |
fatalError(ioe); |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1726 |
} |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1727 |
} else { |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1728 |
// No options left - we can not compress to stdout without access to the temporary folder |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1729 |
fatalError(new IOException(getMsg("error.create.tempfile"))); |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1730 |
} |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1731 |
} |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1732 |
return tmpfile; |
e30c5696b4c5
8020802: Need an ability to create jar files that are invariant to the pack200 packing/unpacking
kizune
parents:
19409
diff
changeset
|
1733 |
} |
36511 | 1734 |
|
1735 |
// Modular jar support |
|
1736 |
||
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1737 |
/** |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1738 |
* Associates a module descriptor's zip entry name along with its |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1739 |
* bytes and an optional URI. Used when describing modules. |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1740 |
*/ |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1741 |
interface ModuleInfoEntry { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1742 |
String name(); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1743 |
Optional<String> uriString(); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1744 |
InputStream bytes() throws IOException; |
36511 | 1745 |
} |
1746 |
||
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1747 |
static class ZipFileModuleInfoEntry implements ModuleInfoEntry { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1748 |
private final ZipFile zipFile; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1749 |
private final ZipEntry entry; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1750 |
ZipFileModuleInfoEntry(ZipFile zipFile, ZipEntry entry) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1751 |
this.zipFile = zipFile; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1752 |
this.entry = entry; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1753 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1754 |
@Override public String name() { return entry.getName(); } |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1755 |
@Override public InputStream bytes() throws IOException { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1756 |
return zipFile.getInputStream(entry); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1757 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1758 |
/** Returns an optional containing the effective URI. */ |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1759 |
@Override public Optional<String> uriString() { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1760 |
String uri = (Paths.get(zipFile.getName())).toUri().toString(); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1761 |
uri = "jar:" + uri + "/!" + entry.getName(); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1762 |
return Optional.of(uri); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1763 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1764 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1765 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1766 |
static class StreamedModuleInfoEntry implements ModuleInfoEntry { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1767 |
private final String name; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1768 |
private final byte[] bytes; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1769 |
StreamedModuleInfoEntry(String name, byte[] bytes) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1770 |
this.name = name; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1771 |
this.bytes = bytes; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1772 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1773 |
@Override public String name() { return name; } |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1774 |
@Override public InputStream bytes() throws IOException { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1775 |
return new ByteArrayInputStream(bytes); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1776 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1777 |
/** Returns an empty optional. */ |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1778 |
@Override public Optional<String> uriString() { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1779 |
return Optional.empty(); // no URI can be derived |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1780 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1781 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1782 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1783 |
/** Describes a module from a given zip file. */ |
44267
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1784 |
private boolean describeModule(ZipFile zipFile) throws IOException { |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1785 |
ZipFileModuleInfoEntry[] infos = zipFile.stream() |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1786 |
.filter(e -> isModuleInfoEntry(e.getName())) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1787 |
.sorted(Validator.ENTRY_COMPARATOR) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1788 |
.map(e -> new ZipFileModuleInfoEntry(zipFile, e)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1789 |
.toArray(ZipFileModuleInfoEntry[]::new); |
44267
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1790 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1791 |
if (infos.length == 0) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1792 |
// No module descriptor found, derive and describe the automatic module |
44267
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1793 |
String fn = zipFile.getName(); |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1794 |
ModuleFinder mf = ModuleFinder.of(Paths.get(fn)); |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1795 |
try { |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1796 |
Set<ModuleReference> mref = mf.findAll(); |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1797 |
if (mref.isEmpty()) { |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1798 |
output(formatMsg("error.unable.derive.automodule", fn)); |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1799 |
return true; |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1800 |
} |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1801 |
ModuleDescriptor md = mref.iterator().next().descriptor(); |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1802 |
output(getMsg("out.automodule") + "\n"); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1803 |
describeModule(md, null, null, ""); |
44267
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1804 |
} catch (FindException e) { |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1805 |
String msg = formatMsg("error.unable.derive.automodule", fn); |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1806 |
Throwable t = e.getCause(); |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1807 |
if (t != null) |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1808 |
msg = msg + "\n" + t.getMessage(); |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1809 |
output(msg); |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1810 |
} |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1811 |
} else { |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1812 |
return describeModuleFromEntries(infos); |
36511 | 1813 |
} |
1814 |
return true; |
|
1815 |
} |
|
1816 |
||
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1817 |
private boolean describeModuleFromStream(FileInputStream fis) |
36511 | 1818 |
throws IOException |
1819 |
{ |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1820 |
List<ModuleInfoEntry> infos = new LinkedList<>(); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1821 |
|
36511 | 1822 |
try (BufferedInputStream bis = new BufferedInputStream(fis); |
1823 |
ZipInputStream zis = new ZipInputStream(bis)) { |
|
1824 |
ZipEntry e; |
|
1825 |
while ((e = zis.getNextEntry()) != null) { |
|
43731
bc7110b230c1
8165640: Enhance jar tool to allow module-info in versioned directories but not in base in modular multi-release jar files
sherman
parents:
43712
diff
changeset
|
1826 |
String ename = e.getName(); |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1827 |
if (isModuleInfoEntry(ename)) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1828 |
infos.add(new StreamedModuleInfoEntry(ename, zis.readAllBytes())); |
36511 | 1829 |
} |
1830 |
} |
|
1831 |
} |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1832 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1833 |
if (infos.size() == 0) |
43731
bc7110b230c1
8165640: Enhance jar tool to allow module-info in versioned directories but not in base in modular multi-release jar files
sherman
parents:
43712
diff
changeset
|
1834 |
return false; |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1835 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1836 |
ModuleInfoEntry[] sorted = infos.stream() |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1837 |
.sorted(Comparator.comparing(ModuleInfoEntry::name, ENTRYNAME_COMPARATOR)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1838 |
.toArray(ModuleInfoEntry[]::new); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1839 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1840 |
return describeModuleFromEntries(sorted); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1841 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1842 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1843 |
private boolean lessThanEqualReleaseValue(ModuleInfoEntry entry) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1844 |
return intVersionFromEntry(entry) <= releaseValue ? true : false; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1845 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1846 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1847 |
private static String versionFromEntryName(String name) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1848 |
String s = name.substring(VERSIONS_DIR_LENGTH); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1849 |
return s.substring(0, s.indexOf("/")); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1850 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1851 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1852 |
private static int intVersionFromEntry(ModuleInfoEntry entry) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1853 |
String name = entry.name(); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1854 |
if (!name.startsWith(VERSIONS_DIR)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1855 |
return BASE_VERSION; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1856 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1857 |
String s = name.substring(VERSIONS_DIR_LENGTH); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1858 |
s = s.substring(0, s.indexOf('/')); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1859 |
return Integer.valueOf(s); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1860 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1861 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1862 |
/** |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1863 |
* Describes a single module descriptor, determined by the specified |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1864 |
* --release, if any, from the given ordered entries. |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1865 |
* The given infos must be ordered as per ENTRY_COMPARATOR. |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1866 |
*/ |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1867 |
private boolean describeModuleFromEntries(ModuleInfoEntry[] infos) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1868 |
throws IOException |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1869 |
{ |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1870 |
assert infos.length > 0; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1871 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1872 |
// Informative: output all non-root descriptors, if any |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1873 |
String releases = Arrays.stream(infos) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1874 |
.filter(e -> !e.name().equals(MODULE_INFO)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1875 |
.map(ModuleInfoEntry::name) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1876 |
.map(Main::versionFromEntryName) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1877 |
.collect(joining(" ")); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1878 |
if (!releases.equals("")) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1879 |
output("releases: " + releases + "\n"); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1880 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1881 |
// Describe the operative descriptor for the specified --release, if any |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1882 |
if (releaseValue != -1) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1883 |
ModuleInfoEntry entry = null; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1884 |
int i = 0; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1885 |
while (i < infos.length && lessThanEqualReleaseValue(infos[i])) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1886 |
entry = infos[i]; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1887 |
i++; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1888 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1889 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1890 |
if (entry == null) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1891 |
output(formatMsg("error.no.operative.descriptor", |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1892 |
String.valueOf(releaseValue))); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1893 |
return false; |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1894 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1895 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1896 |
String uriString = entry.uriString().orElse(""); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1897 |
try (InputStream is = entry.bytes()) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1898 |
describeModule(is, uriString); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1899 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1900 |
} else { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1901 |
// no specific --release specified, output the root, if any |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1902 |
if (infos[0].name().equals(MODULE_INFO)) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1903 |
String uriString = infos[0].uriString().orElse(""); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1904 |
try (InputStream is = infos[0].bytes()) { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1905 |
describeModule(is, uriString); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1906 |
} |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1907 |
} else { |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1908 |
// no root, output message to specify --release |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1909 |
output(getMsg("error.no.root.descriptor")); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1910 |
} |
43731
bc7110b230c1
8165640: Enhance jar tool to allow module-info in versioned directories but not in base in modular multi-release jar files
sherman
parents:
43712
diff
changeset
|
1911 |
} |
bc7110b230c1
8165640: Enhance jar tool to allow module-info in versioned directories but not in base in modular multi-release jar files
sherman
parents:
43712
diff
changeset
|
1912 |
return true; |
36511 | 1913 |
} |
1914 |
||
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
1915 |
static <T> String toString(Collection<T> set) { |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
1916 |
if (set.isEmpty()) { return ""; } |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1917 |
return " " + set.stream().map(e -> e.toString().toLowerCase(Locale.ROOT)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1918 |
.sorted().collect(joining(" ")); |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
1919 |
} |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
1920 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1921 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1922 |
private void describeModule(InputStream entryInputStream, String uriString) |
36511 | 1923 |
throws IOException |
1924 |
{ |
|
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
1925 |
ModuleInfo.Attributes attrs = ModuleInfo.read(entryInputStream, null); |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
1926 |
ModuleDescriptor md = attrs.descriptor(); |
44359
c6761862ca0b
8174823: Module system implementation refresh (3/2017)
alanb
parents:
44033
diff
changeset
|
1927 |
ModuleTarget target = attrs.target(); |
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
1928 |
ModuleHashes hashes = attrs.recordedHashes(); |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
1929 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1930 |
describeModule(md, target, hashes, uriString); |
44267
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1931 |
} |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1932 |
|
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1933 |
private void describeModule(ModuleDescriptor md, |
44360 | 1934 |
ModuleTarget target, |
44267
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1935 |
ModuleHashes hashes, |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1936 |
String uriString) |
44267
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1937 |
throws IOException |
00898a596f31
8176772: jar tool support to report automatic module names
chegar
parents:
44033
diff
changeset
|
1938 |
{ |
36511 | 1939 |
StringBuilder sb = new StringBuilder(); |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1940 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1941 |
sb.append(md.toNameAndVersion()); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1942 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1943 |
if (!uriString.equals("")) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1944 |
sb.append(" ").append(uriString); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1945 |
if (md.isOpen()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1946 |
sb.append(" open"); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1947 |
if (md.isAutomatic()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1948 |
sb.append(" automatic"); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1949 |
sb.append("\n"); |
43731
bc7110b230c1
8165640: Enhance jar tool to allow module-info in versioned directories but not in base in modular multi-release jar files
sherman
parents:
43712
diff
changeset
|
1950 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1951 |
// unqualified exports (sorted by package) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1952 |
md.exports().stream() |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1953 |
.sorted(Comparator.comparing(Exports::source)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1954 |
.filter(e -> !e.isQualified()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1955 |
.forEach(e -> sb.append("exports ").append(e.source()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1956 |
.append(toString(e.modifiers())).append("\n")); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1957 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1958 |
// dependences |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1959 |
md.requires().stream().sorted() |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1960 |
.forEach(r -> sb.append("requires ").append(r.name()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1961 |
.append(toString(r.modifiers())).append("\n")); |
36511 | 1962 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1963 |
// service use and provides |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1964 |
md.uses().stream().sorted() |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1965 |
.forEach(s -> sb.append("uses ").append(s).append("\n")); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1966 |
|
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1967 |
md.provides().stream() |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1968 |
.sorted(Comparator.comparing(Provides::service)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1969 |
.forEach(p -> sb.append("provides ").append(p.service()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1970 |
.append(" with") |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1971 |
.append(toString(p.providers())) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1972 |
.append("\n")); |
36511 | 1973 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1974 |
// qualified exports |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1975 |
md.exports().stream() |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1976 |
.sorted(Comparator.comparing(Exports::source)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1977 |
.filter(Exports::isQualified) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1978 |
.forEach(e -> sb.append("qualified exports ").append(e.source()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1979 |
.append(" to").append(toString(e.targets())) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1980 |
.append("\n")); |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
1981 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1982 |
// open packages |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1983 |
md.opens().stream() |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1984 |
.sorted(Comparator.comparing(Opens::source)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1985 |
.filter(o -> !o.isQualified()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1986 |
.forEach(o -> sb.append("opens ").append(o.source()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1987 |
.append(toString(o.modifiers())) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1988 |
.append("\n")); |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
1989 |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
1990 |
md.opens().stream() |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1991 |
.sorted(Comparator.comparing(Opens::source)) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1992 |
.filter(Opens::isQualified) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1993 |
.forEach(o -> sb.append("qualified opens ").append(o.source()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1994 |
.append(toString(o.modifiers())) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1995 |
.append(" to").append(toString(o.targets())) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1996 |
.append("\n")); |
36511 | 1997 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1998 |
// non-exported/non-open packages |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
1999 |
Set<String> concealed = new TreeSet<>(md.packages()); |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
2000 |
md.exports().stream().map(Exports::source).forEach(concealed::remove); |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
2001 |
md.opens().stream().map(Opens::source).forEach(concealed::remove); |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
2002 |
concealed.forEach(p -> sb.append("contains ").append(p).append("\n")); |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
2003 |
|
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
2004 |
md.mainClass().ifPresent(v -> sb.append("main-class ").append(v).append("\n")); |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2005 |
|
44359
c6761862ca0b
8174823: Module system implementation refresh (3/2017)
alanb
parents:
44033
diff
changeset
|
2006 |
if (target != null) { |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
2007 |
String targetPlatform = target.targetPlatform(); |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
2008 |
if (!targetPlatform.isEmpty()) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
2009 |
sb.append("platform ").append(targetPlatform).append("\n"); |
44359
c6761862ca0b
8174823: Module system implementation refresh (3/2017)
alanb
parents:
44033
diff
changeset
|
2010 |
} |
36511 | 2011 |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2012 |
if (hashes != null) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2013 |
hashes.names().stream().sorted().forEach( |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
2014 |
mod -> sb.append("hashes ").append(mod).append(" ") |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2015 |
.append(hashes.algorithm()).append(" ") |
45004
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
2016 |
.append(toHex(hashes.hashFor(mod))) |
ea3137042a61
8178380: Module system implementation refresh (5/2017)
alanb
parents:
44360
diff
changeset
|
2017 |
.append("\n")); |
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2018 |
} |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2019 |
|
36511 | 2020 |
output(sb.toString()); |
2021 |
} |
|
2022 |
||
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2023 |
private static String toHex(byte[] ba) { |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2024 |
StringBuilder sb = new StringBuilder(ba.length << 1); |
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2025 |
for (byte b: ba) { |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2026 |
sb.append(String.format("%02x", b & 0xff)); |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2027 |
} |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2028 |
return sb.toString(); |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2029 |
} |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2030 |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2031 |
static String toBinaryName(String classname) { |
36511 | 2032 |
return (classname.replace('.', '/')) + ".class"; |
2033 |
} |
|
2034 |
||
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2035 |
private boolean checkModuleInfo(byte[] moduleInfoBytes, Set<String> entries) |
36511 | 2036 |
throws IOException |
2037 |
{ |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2038 |
boolean ok = true; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2039 |
if (moduleInfoBytes != null) { // no root module-info.class if null |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2040 |
try { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2041 |
// ModuleDescriptor.read() checks open/exported pkgs vs packages |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2042 |
ModuleDescriptor md = ModuleDescriptor.read(ByteBuffer.wrap(moduleInfoBytes)); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2043 |
// A module must have the implementation class of the services it 'provides'. |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2044 |
if (md.provides().stream().map(Provides::providers).flatMap(List::stream) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2045 |
.filter(p -> !entries.contains(toBinaryName(p))) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2046 |
.peek(p -> fatalError(formatMsg("error.missing.provider", p))) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2047 |
.count() != 0) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2048 |
ok = false; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2049 |
} |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2050 |
} catch (InvalidModuleDescriptorException x) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2051 |
fatalError(x.getMessage()); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2052 |
ok = false; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2053 |
} |
36511 | 2054 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2055 |
return ok; |
36511 | 2056 |
} |
2057 |
||
2058 |
/** |
|
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2059 |
* Adds extended modules attributes to the given module-info's. The given |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2060 |
* Map values are updated in-place. Returns false if an error occurs. |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2061 |
*/ |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2062 |
private void addExtendedModuleAttributes(Map<String,byte[]> moduleInfos, |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2063 |
Set<String> packages) |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2064 |
throws IOException |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2065 |
{ |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2066 |
for (Map.Entry<String,byte[]> e: moduleInfos.entrySet()) { |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2067 |
ModuleDescriptor md = ModuleDescriptor.read(ByteBuffer.wrap(e.getValue())); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2068 |
e.setValue(extendedInfoBytes(md, e.getValue(), packages)); |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2069 |
} |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2070 |
} |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2071 |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2072 |
static boolean isModuleInfoEntry(String name) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2073 |
// root or versioned module-info.class |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2074 |
if (name.endsWith(MODULE_INFO)) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2075 |
int end = name.length() - MODULE_INFO.length(); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2076 |
if (end == 0) |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2077 |
return true; |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2078 |
if (name.startsWith(VERSIONS_DIR)) { |
43731
bc7110b230c1
8165640: Enhance jar tool to allow module-info in versioned directories but not in base in modular multi-release jar files
sherman
parents:
43712
diff
changeset
|
2079 |
int off = VERSIONS_DIR_LENGTH; |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2080 |
if (off == end) // meta-inf/versions/module-info.class |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2081 |
return false; |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2082 |
while (off < end - 1) { |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2083 |
char c = name.charAt(off++); |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2084 |
if (c < '0' || c > '9') |
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2085 |
return false; |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2086 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2087 |
return name.charAt(off) == '/'; |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2088 |
} |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2089 |
} |
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2090 |
return false; |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2091 |
} |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2092 |
|
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2093 |
/** |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2094 |
* Returns a byte array containing the given module-info.class plus any |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2095 |
* extended attributes. |
36511 | 2096 |
* |
2097 |
* If --module-version, --main-class, or other options were provided |
|
2098 |
* then the corresponding class file attributes are added to the |
|
2099 |
* module-info here. |
|
2100 |
*/ |
|
43095
336dfda4ae89
8172432: jar cleanup/update for module and mrm jar
sherman
parents:
42703
diff
changeset
|
2101 |
private byte[] extendedInfoBytes(ModuleDescriptor md, |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2102 |
byte[] miBytes, |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
2103 |
Set<String> packages) |
36511 | 2104 |
throws IOException |
2105 |
{ |
|
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2106 |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2107 |
InputStream is = new ByteArrayInputStream(miBytes); |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2108 |
ModuleInfoExtender extender = ModuleInfoExtender.newExtender(is); |
36511 | 2109 |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
2110 |
// Add (or replace) the Packages attribute |
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41754
diff
changeset
|
2111 |
extender.packages(packages); |
36511 | 2112 |
|
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2113 |
// --main-class |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2114 |
if (ename != null) |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2115 |
extender.mainClass(ename); |
36511 | 2116 |
|
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2117 |
// --module-version |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2118 |
if (moduleVersion != null) |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2119 |
extender.version(moduleVersion); |
36511 | 2120 |
|
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2121 |
// --hash-modules |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2122 |
if (modulesToHash != null) { |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2123 |
String mn = md.name(); |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2124 |
Hasher hasher = new Hasher(md, fname); |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2125 |
ModuleHashes moduleHashes = hasher.computeHashes(mn); |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2126 |
if (moduleHashes != null) { |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2127 |
extender.hashes(moduleHashes); |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2128 |
} else { |
43109 | 2129 |
warn("warning: no module is recorded in hash in " + mn); |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2130 |
} |
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2131 |
} |
36511 | 2132 |
|
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2133 |
if (moduleResolution.value() != 0) { |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2134 |
extender.moduleResolution(moduleResolution); |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2135 |
} |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2136 |
|
38468
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2137 |
extender.write(baos); |
d459a0f8fe72
8156497: Add jar tool support for Multi-Release Modular JARs
chegar
parents:
38457
diff
changeset
|
2138 |
return baos.toByteArray(); |
36511 | 2139 |
} |
2140 |
||
2141 |
/** |
|
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2142 |
* Compute and record hashes |
36511 | 2143 |
*/ |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2144 |
private class Hasher { |
43109 | 2145 |
final ModuleHashesBuilder hashesBuilder; |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2146 |
final ModuleFinder finder; |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2147 |
final Set<String> modules; |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2148 |
Hasher(ModuleDescriptor descriptor, String fname) throws IOException { |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2149 |
// Create a module finder that finds the modular JAR |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2150 |
// being created/updated |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2151 |
URI uri = Paths.get(fname).toUri(); |
42703
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2152 |
ModuleReference mref = new ModuleReference(descriptor, uri) { |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2153 |
@Override |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2154 |
public ModuleReader open() { |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2155 |
throw new UnsupportedOperationException("should not reach here"); |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2156 |
} |
20c39ea4a507
8170987: Module system implementation refresh (12/2016)
alanb
parents:
42463
diff
changeset
|
2157 |
}; |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2158 |
|
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2159 |
// Compose a module finder with the module path and |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2160 |
// the modular JAR being created or updated |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2161 |
this.finder = ModuleFinder.compose(moduleFinder, |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2162 |
new ModuleFinder() { |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2163 |
@Override |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2164 |
public Optional<ModuleReference> find(String name) { |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2165 |
if (descriptor.name().equals(name)) |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2166 |
return Optional.of(mref); |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2167 |
else |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2168 |
return Optional.empty(); |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2169 |
} |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2170 |
|
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2171 |
@Override |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2172 |
public Set<ModuleReference> findAll() { |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2173 |
return Collections.singleton(mref); |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2174 |
} |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2175 |
}); |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2176 |
|
43109 | 2177 |
// Determine the modules that matches the pattern {@code modulesToHash} |
2178 |
Set<String> roots = finder.findAll().stream() |
|
2179 |
.map(ref -> ref.descriptor().name()) |
|
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2180 |
.filter(mn -> modulesToHash.matcher(mn).find()) |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2181 |
.collect(Collectors.toSet()); |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2182 |
|
43109 | 2183 |
// use system module path unless it creates a modular JAR for |
2184 |
// a module that is present in the system image e.g. upgradeable |
|
2185 |
// module |
|
2186 |
ModuleFinder system; |
|
2187 |
String name = descriptor.name(); |
|
2188 |
if (name != null && ModuleFinder.ofSystem().find(name).isPresent()) { |
|
2189 |
system = ModuleFinder.of(); |
|
2190 |
} else { |
|
2191 |
system = ModuleFinder.ofSystem(); |
|
36511 | 2192 |
} |
43109 | 2193 |
// get a resolved module graph |
2194 |
Configuration config = |
|
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
43109
diff
changeset
|
2195 |
Configuration.empty().resolve(system, finder, roots); |
36511 | 2196 |
|
43109 | 2197 |
// filter modules resolved from the system module finder |
2198 |
this.modules = config.modules().stream() |
|
2199 |
.map(ResolvedModule::name) |
|
2200 |
.filter(mn -> roots.contains(mn) && !system.find(mn).isPresent()) |
|
2201 |
.collect(Collectors.toSet()); |
|
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2202 |
|
43109 | 2203 |
this.hashesBuilder = new ModuleHashesBuilder(config, modules); |
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2204 |
} |
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2205 |
|
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2206 |
/** |
43109 | 2207 |
* Compute hashes of the specified module. |
2208 |
* |
|
2209 |
* It records the hashing modules that depend upon the specified |
|
2210 |
* module directly or indirectly. |
|
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2211 |
*/ |
43109 | 2212 |
ModuleHashes computeHashes(String name) { |
2213 |
if (hashesBuilder == null) |
|
2214 |
return null; |
|
37779
7c84df693837
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36745
diff
changeset
|
2215 |
|
43109 | 2216 |
return hashesBuilder.computeHashes(Set.of(name)).get(name); |
36511 | 2217 |
} |
2218 |
} |
|
2 | 2219 |
} |