Browse Source

Add the index feature for jar so that it optimizes the class loading process for JDK 1.3+

Patch was submitted by Philippe Prados <philippe@prados.net>
I added UTF8 encoding as specified in the specifications and changed the logic a little bit to be closer to what is being done in the implementation of sun.misc.JarIndex in JDK 1.3


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269850 13f79535-47bb-0310-9956-ffa450edef68
master
Stephane Bailliez 23 years ago
parent
commit
a376c57ae1
2 changed files with 86 additions and 13 deletions
  1. +81
    -9
      src/main/org/apache/tools/ant/taskdefs/Jar.java
  2. +5
    -4
      src/main/org/apache/tools/ant/taskdefs/Zip.java

+ 81
- 9
src/main/org/apache/tools/ant/taskdefs/Jar.java View File

@@ -60,14 +60,9 @@ import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.ZipFileSet;
import org.apache.tools.zip.ZipOutputStream;

import java.io.IOException;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.ByteArrayInputStream;
import java.io.*;
import java.util.Enumeration;
import java.util.Vector;

/**
* Creates a JAR archive.
@@ -75,6 +70,8 @@ import java.util.Enumeration;
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
*/
public class Jar extends Zip {
/** The index file name. */
private final static String INDEX_NAME = "META-INF/INDEX.LIST";

private File manifestFile;
private Manifest manifest;
@@ -82,7 +79,11 @@ public class Jar extends Zip {
/** true if a manifest has been specified in the task */
private boolean buildFileManifest = false;

/** jar index is JDK 1.3+ only */
private boolean index = false;

/** constructor */
public Jar() {
super();
archiveType = "jar";
@@ -90,11 +91,22 @@ public class Jar extends Zip {
setEncoding("UTF8");
}

/**
* @deprecated use setFile(File) instead.
*/
public void setJarfile(File jarFile) {
log("DEPRECATED - The jarfile attribute is deprecated. Use file attribute instead.");
setFile(jarFile);
}

/**
* Set whether or not to create an index list for classes
* to speed up classloading.
*/
public void setIndex(boolean flag){
index = flag;
}

public void addConfiguredManifest(Manifest newManifest) throws ManifestException {
if (manifest == null) {
manifest = getDefaultManifest();
@@ -174,7 +186,67 @@ public class Jar extends Zip {
throw new BuildException("Invalid Manifest", e, getLocation());
}
}

protected void finalizeZipOutputStream(ZipOutputStream zOut)
throws IOException, BuildException {
if (index) {
createIndexList(zOut);
}
}

/**
* Create the index list to speed up classloading.
* This is a JDK 1.3+ specific feature and is enabled by default.
* {@link http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#JAR%20Index}
* @param zOut the zip stream representing the jar being built.
* @throws IOException thrown if there is an error while creating the
* index and adding it to the zip stream.
*/
private void createIndexList(ZipOutputStream zOut) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// encoding must be UTF8 as specified in the specs.
PrintWriter writer = new PrintWriter(new OutputStreamWriter(baos, "UTF8"));

// version-info blankline
writer.println("JarIndex-Version: 1.0");
writer.println();

// header newline
writer.println(zipFile.getName());

// JarIndex is sorting the directories by ascending order.
// it's painful to do in JDK 1.1 and it has no value but cosmetic
// since it will be read into a hashtable by the classloader.
Enumeration enum = addedDirs.keys();
while (enum.hasMoreElements()) {
String dir = (String)enum.nextElement();

// try to be smart, not to be fooled by a weird directory name
// @fixme do we need to check for directories starting by ./ ?
dir = dir.replace('\\', '/');
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);
}

writer.flush();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
super.zipFile(bais, zOut, INDEX_NAME, System.currentTimeMillis());
}




private Manifest getDefaultManifest() {
try {
String s = "/org/apache/tools/ant/defaultManifest.mf";


+ 5
- 4
src/main/org/apache/tools/ant/taskdefs/Zip.java View File

@@ -90,17 +90,18 @@ import org.apache.tools.zip.ZipEntry;
*/
public class Zip extends MatchingTask {

private File zipFile;
protected File zipFile;
private File baseDir;
private boolean doCompress = true;
private boolean doUpdate = false;
private boolean doFilesonly = false;
protected String archiveType = "zip";

// For directories:
private static long emptyCrc = new CRC32 ().getValue ();
private final static long EMPTY_CRC = new CRC32 ().getValue ();
protected String emptyBehavior = "skip";
private Vector filesets = new Vector ();
private Hashtable addedDirs = new Hashtable();
protected Hashtable addedDirs = new Hashtable();
private Vector addedFiles = new Vector();

/** true when we are adding new files into the Zip file, as opposed to
@@ -596,7 +597,7 @@ public class Zip extends MatchingTask {
ze.setSize (0);
ze.setMethod (ZipEntry.STORED);
// This is faintly ridiculous:
ze.setCrc (emptyCrc);
ze.setCrc (EMPTY_CRC);

// this is 040775 | MS-DOS directory flag in reverse byte order
ze.setExternalAttributes(0x41FD0010L);


Loading…
Cancel
Save