src/jdk.jartool/share/classes/sun/tools/jar/Main.java
Print this page
@@ -69,11 +69,10 @@
import static jdk.internal.util.jar.JarIndex.INDEX_NAME;
import static java.util.jar.JarFile.MANIFEST_NAME;
import static java.util.stream.Collectors.joining;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-import static sun.tools.jar.Validator.ENTRYNAME_COMPARATOR;
/**
* This class implements a simple utility for creating files in the JAR
* (Java Archive) file format. The JAR format is based on the ZIP file
* format, with optional meta-information stored in a MANIFEST entry.
@@ -442,12 +441,12 @@
return ok;
}
private void validateAndClose(File tmpfile) throws IOException {
if (ok && isMultiRelease) {
- try (JarFile jf = new JarFile(tmpfile)) {
- ok = Validator.validate(this, jf);
+ try (ZipFile zf = new ZipFile(tmpfile)) {
+ ok = Validator.validate(this, zf);
if (!ok) {
error(formatMsg("error.validator.jarfile.invalid", fname));
}
} catch (IOException e) {
error(formatMsg2("error.validator.jarfile.exception", fname, e.getMessage()));
@@ -1782,11 +1781,11 @@
/** Describes a module from a given zip file. */
private boolean describeModule(ZipFile zipFile) throws IOException {
ZipFileModuleInfoEntry[] infos = zipFile.stream()
.filter(e -> isModuleInfoEntry(e.getName()))
- .sorted(Validator.ENTRY_COMPARATOR)
+ .sorted(ENTRY_COMPARATOR)
.map(e -> new ZipFileModuleInfoEntry(zipFile, e))
.toArray(ZipFileModuleInfoEntry[]::new);
if (infos.length == 0) {
// No module descriptor found, derive and describe the automatic module
@@ -2214,6 +2213,50 @@
return null;
return hashesBuilder.computeHashes(Set.of(name)).get(name);
}
}
+
+ // sort base entries before versioned entries, and sort entry classes with
+ // nested classes so that the outter class appears before the associated
+ // nested class
+ static Comparator<String> ENTRYNAME_COMPARATOR = (s1, s2) -> {
+
+ if (s1.equals(s2)) return 0;
+ boolean b1 = s1.startsWith(VERSIONS_DIR);
+ boolean b2 = s2.startsWith(VERSIONS_DIR);
+ if (b1 && !b2) return 1;
+ if (!b1 && b2) return -1;
+ int n = 0; // starting char for String compare
+ if (b1 && b2) {
+ // normally strings would be sorted so "10" goes before "9", but
+ // version number strings need to be sorted numerically
+ n = VERSIONS_DIR.length(); // skip the common prefix
+ int i1 = s1.indexOf('/', n);
+ int i2 = s2.indexOf('/', n);
+ if (i1 == -1) throw new Validator.InvalidJarException(s1);
+ if (i2 == -1) throw new Validator.InvalidJarException(s2);
+ // shorter version numbers go first
+ if (i1 != i2) return i1 - i2;
+ // otherwise, handle equal length numbers below
+ }
+ int l1 = s1.length();
+ int l2 = s2.length();
+ int lim = Math.min(l1, l2);
+ for (int k = n; k < lim; k++) {
+ char c1 = s1.charAt(k);
+ char c2 = s2.charAt(k);
+ if (c1 != c2) {
+ // change natural ordering so '.' comes before '$'
+ // i.e. outer classes come before nested classes
+ if (c1 == '$' && c2 == '.') return 1;
+ if (c1 == '.' && c2 == '$') return -1;
+ return c1 - c2;
+ }
+ }
+ return l1 - l2;
+ };
+
+ static Comparator<ZipEntry> ENTRY_COMPARATOR =
+ Comparator.comparing(ZipEntry::getName, ENTRYNAME_COMPARATOR);
+
}