jlinkpublic class jlink extends Object jlink links together multiple .jar files. |
Fields Summary |
---|
private String | outfile | private Vector | mergefiles | private Vector | addfiles | private boolean | compression | byte[] | buffer |
Methods Summary |
---|
public void | addAddFile(java.lang.String fileToAdd)Adds a file to be added into the output.
if (fileToAdd == null) {
return;
}
addfiles.addElement(fileToAdd);
| public void | addAddFiles(java.lang.String[] filesToAdd)Adds several file to be added into the output.
if (filesToAdd == null) {
return;
}
for (int i = 0; i < filesToAdd.length; i++) {
addAddFile(filesToAdd[i]);
}
| private void | addDirContents(java.util.zip.ZipOutputStream output, java.io.File dir, java.lang.String prefix, boolean compress)
String[] contents = dir.list();
for (int i = 0; i < contents.length; ++i) {
String name = contents[i];
File file = new File(dir, name);
if (file.isDirectory()) {
addDirContents(output, file, prefix + name + '/", compress);
} else {
addFile(output, file, prefix, compress);
}
}
| private void | addFile(java.util.zip.ZipOutputStream output, java.io.File file, java.lang.String prefix, boolean compress)
//Make sure file exists
if (!file.exists()) {
return;
}
ZipEntry entry = new ZipEntry(getEntryName(file, prefix));
entry.setTime(file.lastModified());
entry.setSize(file.length());
if (!compress) {
entry.setCrc(calcChecksum(file));
}
FileInputStream input = new FileInputStream(file);
addToOutputStream(output, input, entry);
| public void | addMergeFile(java.lang.String fileToMerge)Adds a file to be merged into the output.
if (fileToMerge == null) {
return;
}
mergefiles.addElement(fileToMerge);
| public void | addMergeFiles(java.lang.String[] filesToMerge)Adds several files to be merged into the output.
if (filesToMerge == null) {
return;
}
for (int i = 0; i < filesToMerge.length; i++) {
addMergeFile(filesToMerge[i]);
}
| private void | addToOutputStream(java.util.zip.ZipOutputStream output, java.io.InputStream input, java.util.zip.ZipEntry ze)
try {
output.putNextEntry(ze);
} catch (ZipException zipEx) {
//This entry already exists. So, go with the first one.
input.close();
return;
}
int numBytes = -1;
while ((numBytes = input.read(buffer)) > 0) {
output.write(buffer, 0, numBytes);
}
output.closeEntry();
input.close();
| private long | calcChecksum(java.io.File f)
BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
return calcChecksum(in);
| private long | calcChecksum(java.io.InputStream in)
CRC32 crc = new CRC32();
int len = buffer.length;
int count = -1;
int haveRead = 0;
while ((count = in.read(buffer, 0, len)) > 0) {
haveRead += count;
crc.update(buffer, 0, count);
}
in.close();
return crc.getValue();
| private java.lang.String | getEntryName(java.io.File file, java.lang.String prefix)
String name = file.getName();
if (!name.endsWith(".class")) {
// see if the file is in fact a .class file, and determine its actual name.
InputStream input = null;
try {
input = new FileInputStream(file);
String className = ClassNameReader.getClassName(input);
if (className != null) {
return className.replace('.", '/") + ".class";
}
} catch (IOException ioe) {
//do nothing
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
//do nothing
}
}
}
}
System.out.println("From " + file.getPath() + " and prefix " + prefix
+ ", creating entry " + prefix + name);
return (prefix + name);
| public void | link()Performs the linking of files. Addfiles are added to the output as-is.
For example, a jar file is added to the output as a jar file. However,
mergefiles are first examined for their type. If it is a jar or zip
file, the contents will be extracted from the mergefile and entered
into the output. If a zip or jar file is encountered in a subdirectory
it will be added, not merged. If a directory is encountered, it becomes
the root entry of all the files below it. Thus, you can provide
multiple, disjoint directories, as addfiles: they will all be added in
a rational manner to outfile.
ZipOutputStream output = new ZipOutputStream(new FileOutputStream(outfile));
if (compression) {
output.setMethod(ZipOutputStream.DEFLATED);
output.setLevel(Deflater.DEFAULT_COMPRESSION);
} else {
output.setMethod(ZipOutputStream.STORED);
}
Enumeration merges = mergefiles.elements();
while (merges.hasMoreElements()) {
String path = (String) merges.nextElement();
File f = new File(path);
if (f.getName().endsWith(".jar") || f.getName().endsWith(".zip")) {
//Do the merge
mergeZipJarContents(output, f);
} else {
//Add this file to the addfiles Vector and add it
//later at the top level of the output file.
addAddFile(path);
}
}
Enumeration adds = addfiles.elements();
while (adds.hasMoreElements()) {
String name = (String) adds.nextElement();
File f = new File(name);
if (f.isDirectory()) {
//System.out.println("in jlink: adding directory contents of " + f.getPath());
addDirContents(output, f, f.getName() + '/", compression);
} else {
addFile(output, f, "", compression);
}
}
if (output != null) {
try {
output.close();
} catch (IOException ioe) {
//do nothing
}
}
| public static void | main(java.lang.String[] args)The command line entry point for jlink.
// jlink output input1 ... inputN
if (args.length < 2) {
System.out.println("usage: jlink output input1 ... inputN");
System.exit(1);
}
jlink linker = new jlink();
linker.setOutfile(args[0]);
// To maintain compatibility with the command-line version,
// we will only add files to be merged.
for (int i = 1; i < args.length; i++) {
linker.addMergeFile(args[i]);
}
try {
linker.link();
} catch (Exception ex) {
System.err.print(ex.getMessage());
}
| private void | mergeZipJarContents(java.util.zip.ZipOutputStream output, java.io.File f)
//Check to see that the file with name "name" exists.
if (!f.exists()) {
return;
}
ZipFile zipf = new ZipFile(f);
Enumeration entries = zipf.entries();
while (entries.hasMoreElements()) {
ZipEntry inputEntry = (ZipEntry) entries.nextElement();
//Ignore manifest entries. They're bound to cause conflicts between
//files that are being merged. User should supply their own
//manifest file when doing the merge.
String inputEntryName = inputEntry.getName();
int index = inputEntryName.indexOf("META-INF");
if (index < 0) {
//META-INF not found in the name of the entry. Go ahead and process it.
try {
output.putNextEntry(processEntry(zipf, inputEntry));
} catch (ZipException ex) {
//If we get here, it could be because we are trying to put a
//directory entry that already exists.
//For example, we're trying to write "com", but a previous
//entry from another mergefile was called "com".
//In that case, just ignore the error and go on to the
//next entry.
String mess = ex.getMessage();
if (mess.indexOf("duplicate") >= 0) {
//It was the duplicate entry.
continue;
} else {
// I hate to admit it, but we don't know what happened
// here. Throw the Exception.
throw ex;
}
}
InputStream in = zipf.getInputStream(inputEntry);
int len = buffer.length;
int count = -1;
while ((count = in.read(buffer, 0, len)) > 0) {
output.write(buffer, 0, count);
}
in.close();
output.closeEntry();
}
}
zipf.close();
| private java.util.zip.ZipEntry | processEntry(java.util.zip.ZipFile zip, java.util.zip.ZipEntry inputEntry)
/*
First, some notes.
On MRJ 2.2.2, getting the size, compressed size, and CRC32 from the
ZipInputStream does not work for compressed (deflated) files. Those calls return -1.
For uncompressed (stored) files, those calls do work.
However, using ZipFile.getEntries() works for both compressed and
uncompressed files.
Now, from some simple testing I did, it seems that the value of CRC-32 is
independent of the compression setting. So, it should be easy to pass this
information on to the output entry.
*/
String name = inputEntry.getName();
if (!(inputEntry.isDirectory() || name.endsWith(".class"))) {
try {
InputStream input = zip.getInputStream(zip.getEntry(name));
String className = ClassNameReader.getClassName(input);
input.close();
if (className != null) {
name = className.replace('.", '/") + ".class";
}
} catch (IOException ioe) {
//do nothing
}
}
ZipEntry outputEntry = new ZipEntry(name);
outputEntry.setTime(inputEntry.getTime());
outputEntry.setExtra(inputEntry.getExtra());
outputEntry.setComment(inputEntry.getComment());
outputEntry.setTime(inputEntry.getTime());
if (compression) {
outputEntry.setMethod(ZipEntry.DEFLATED);
//Note, don't need to specify size or crc for compressed files.
} else {
outputEntry.setMethod(ZipEntry.STORED);
outputEntry.setCrc(inputEntry.getCrc());
outputEntry.setSize(inputEntry.getSize());
}
return outputEntry;
| public void | setCompression(boolean compress)Determines whether output will be compressed.
this.compression = compress;
| public void | setOutfile(java.lang.String outfile)The file that will be created by this instance of jlink.
// CheckStyle:VisibilityModifier OFF - bc
if (outfile == null) {
return;
}
this.outfile = outfile;
|
|