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