📄 jar.java
字号:
try { originalManifest = getManifestFromJar(zipFile); if (originalManifest == null) { log("Updating jar since the current jar has no manifest", Project.MSG_VERBOSE); needsUpdate = true; } else { Manifest mf = createManifest(); if (!mf.equals(originalManifest)) { log("Updating jar since jar manifest has changed", Project.MSG_VERBOSE); needsUpdate = true; } } } catch (Throwable t) { log("error while reading original manifest in file: " + zipFile.toString() + t.getMessage(), Project.MSG_WARN); needsUpdate = true; } } else { // no existing archive needsUpdate = true; } createEmpty = needsUpdate; return super.getResourcesToAdd(rcs, zipFile, needsUpdate); } /** * Create an empty jar file. * @param zipFile the file to create * @return true for historic reasons * @throws BuildException on error */ protected boolean createEmptyZip(File zipFile) throws BuildException { if (!createEmpty) { return true; } if (emptyBehavior.equals("skip")) { log("Warning: skipping " + archiveType + " archive " + zipFile + " because no files were included.", Project.MSG_WARN); return true; } else if (emptyBehavior.equals("fail")) { throw new BuildException("Cannot create " + archiveType + " archive " + zipFile + ": no files were included.", getLocation()); } ZipOutputStream zOut = null; try { log("Building MANIFEST-only jar: " + getDestFile().getAbsolutePath()); zOut = new ZipOutputStream(new FileOutputStream(getDestFile())); zOut.setEncoding(getEncoding()); if (isCompress()) { zOut.setMethod(ZipOutputStream.DEFLATED); } else { zOut.setMethod(ZipOutputStream.STORED); } initZipOutputStream(zOut); finalizeZipOutputStream(zOut); } catch (IOException ioe) { throw new BuildException("Could not create almost empty JAR archive" + " (" + ioe.getMessage() + ")", ioe, getLocation()); } finally { // Close the output stream. FileUtils.close(zOut); createEmpty = false; } return true; } /** * Make sure we don't think we already have a MANIFEST next time this task * gets executed. * * @see Zip#cleanUp */ protected void cleanUp() { super.cleanUp(); checkJarSpec(); // we want to save this info if we are going to make another pass if (!doubleFilePass || !skipWriting) { manifest = null; configuredManifest = savedConfiguredManifest; filesetManifest = null; originalManifest = null; } rootEntries.removeAllElements(); } // CheckStyle:LineLength OFF - Link is too long. /** * Check against packaging spec * @see http://java.sun.com/j2se/1.3/docs/guide/versioning/spec/VersioningSpecification.html#PackageVersioning */ // CheckStyle:LineLength ON private void checkJarSpec() { String br = System.getProperty("line.separator"); StringBuffer message = new StringBuffer(); Section mainSection = (configuredManifest == null) ? null : configuredManifest.getMainSection(); if (mainSection == null) { message.append("No Implementation-Title set."); message.append("No Implementation-Version set."); message.append("No Implementation-Vendor set."); } else { if (mainSection.getAttribute("Implementation-Title") == null) { message.append("No Implementation-Title set."); } if (mainSection.getAttribute("Implementation-Version") == null) { message.append("No Implementation-Version set."); } if (mainSection.getAttribute("Implementation-Vendor") == null) { message.append("No Implementation-Vendor set."); } } if (message.length() > 0) { message.append(br); message.append("Location: ").append(getLocation()); message.append(br); if (strict.getValue().equalsIgnoreCase("fail")) { throw new BuildException(message.toString(), getLocation()); } else { log(message.toString(), strict.getLogLevel()); } } } /** * reset to default values. * * @see Zip#reset * * @since 1.44, Ant 1.5 */ public void reset() { super.reset(); emptyBehavior = "create"; configuredManifest = null; filesetManifestConfig = null; mergeManifestsMain = false; manifestFile = null; index = false; } /** * The manifest config enumerated type. */ public static class FilesetManifestConfig extends EnumeratedAttribute { /** * Get the list of valid strings. * @return the list of values - "skip", "merge" and "mergewithoutmain" */ public String[] getValues() { return new String[] {"skip", "merge", "mergewithoutmain"}; } } /** * Writes the directory entries from the first and the filenames * from the second list to the given writer, one entry per line. * * @param dirs a list of directories * @param files a list of files * @param writer the writer to write to * @throws IOException on error * @since Ant 1.6.2 */ protected final void writeIndexLikeList(List dirs, List files, PrintWriter writer) throws IOException { // JarIndex is sorting the directories by ascending order. // it has no value but cosmetic since it will be read into a // hashtable by the classloader, but we'll do so anyway. Collections.sort(dirs); Collections.sort(files); Iterator iter = dirs.iterator(); while (iter.hasNext()) { String dir = (String) iter.next(); // try to be smart, not to be fooled by a weird directory name dir = dir.replace('\\', '/'); if (dir.startsWith("./")) { dir = dir.substring(2); } while (dir.startsWith("/")) { dir = dir.substring(1); } int pos = dir.lastIndexOf('/'); if (pos != -1) { dir = dir.substring(0, pos); } // looks like nothing from META-INF should be added // and the check is not case insensitive. // see sun.misc.JarIndex if (dir.startsWith("META-INF")) { continue; } // name newline writer.println(dir); } iter = files.iterator(); while (iter.hasNext()) { writer.println(iter.next()); } } /** * try to guess the name of the given file. * * <p>If this jar has a classpath attribute in its manifest, we * can assume that it will only require an index of jars listed * there. try to find which classpath entry is most likely the * one the given file name points to.</p> * * <p>In the absence of a classpath attribute, assume the other * files will be placed inside the same directory as this jar and * use their basename.</p> * * <p>if there is a classpath and the given file doesn't match any * of its entries, return null.</p> * * @param fileName the name to look for * @param classpath the classpath to look in (may be null) * @return the matching entry, or null if the file is not found * @since Ant 1.6.2 */ protected static String findJarName(String fileName, String[] classpath) { if (classpath == null) { return (new File(fileName)).getName(); } fileName = fileName.replace(File.separatorChar, '/'); TreeMap matches = new TreeMap(new Comparator() { // longest match comes first public int compare(Object o1, Object o2) { if (o1 instanceof String && o2 instanceof String) { return ((String) o2).length() - ((String) o1).length(); } return 0; } }); for (int i = 0; i < classpath.length; i++) { if (fileName.endsWith(classpath[i])) { matches.put(classpath[i], classpath[i]); } else { int slash = classpath[i].indexOf("/"); String candidate = classpath[i]; while (slash > -1) { candidate = candidate.substring(slash + 1); if (fileName.endsWith(candidate)) { matches.put(candidate, classpath[i]); break; } slash = candidate.indexOf("/"); } } } return matches.size() == 0 ? null : (String) matches.get(matches.firstKey()); } /** * Grab lists of all root-level files and all directories * contained in the given archive. * @param file the zip file to examine * @param dirs where to place the directories found * @param files where to place the files found * @since Ant 1.7 * @throws IOException on error */ protected static void grabFilesAndDirs(String file, List dirs, List files) throws IOException { org.apache.tools.zip.ZipFile zf = null; try { zf = new org.apache.tools.zip.ZipFile(file, "utf-8"); Enumeration entries = zf.getEntries(); HashSet dirSet = new HashSet(); while (entries.hasMoreElements()) { org.apache.tools.zip.ZipEntry ze = (org.apache.tools.zip.ZipEntry) entries.nextElement(); String name = ze.getName(); // META-INF would be skipped anyway, avoid index for // manifest-only jars. if (!name.startsWith("META-INF/")) { if (ze.isDirectory()) { dirSet.add(name); } else if (name.indexOf("/") == -1) { files.add(name); } else { // a file, not in the root // since the jar may be one without directory // entries, add the parent dir of this file as // well. dirSet.add(name.substring(0, name.lastIndexOf("/") + 1)); } } } dirs.addAll(dirSet); } finally { if (zf != null) { zf.close(); } } } /** The strict enumerated type. */ public static class StrictMode extends EnumeratedAttribute { /** Public no arg constructor. */ public StrictMode() { } /** * Constructor with an arg. * @param value the enumerated value as a string. */ public StrictMode(String value) { setValue(value); } /** * Get List of valid strings. * @return the list of values. */ public String[] getValues() { return new String[]{"fail", "warn", "ignore"}; } /** * @return The log level according to the strict mode. */ public int getLogLevel() { return (getValue().equals("ignore")) ? Project.MSG_VERBOSE : Project.MSG_WARN; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -