* Pack200: Find and use either Oracle or Apache library at runtime;

neither required at compile time.
This commit is contained in:
zzz
2010-12-13 14:01:46 +00:00
parent f194f78953
commit 2880d61c1b
3 changed files with 64 additions and 17 deletions

View File

@ -66,8 +66,13 @@ public class ConfigUpdateHandler extends FormHandler {
Class.forName("java.util.jar.Pack200", false, ClassLoader.getSystemClassLoader());
foo = PACK200_URLS;
} catch (ClassNotFoundException cnfe) {
try {
Class.forName("org.apache.harmony.unpack200.Archive", false, ClassLoader.getSystemClassLoader());
foo = PACK200_URLS;
} catch (ClassNotFoundException cnfe2) {
foo = NO_PACK200_URLS;
}
}
DEFAULT_UPDATE_URL = foo;
}

View File

@ -6,10 +6,8 @@
<!--
<property name="javac.compilerargs" value="-warn:-unchecked,raw,unused,serial" />
-->
<!-- Add Apache Harmony's Pack200 library if you don't have java.util.jar.Pack200
See core/java/src/net/i2p/util/FileUtil.java for code changes required
to use this library instead of Sun's version.
Or to comment it all out if you don't have either.
<!-- Additional classpath. No longer required; we find pack200 classes at runtime.
See core/java/src/net/i2p/util/FileUtil.java for more info.
-->
<!--
<property name="javac.classpath" value="/PATH/TO/pack200.jar" />

View File

@ -9,6 +9,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
@ -16,13 +18,11 @@ import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
// Pack200 import
// you must also uncomment the correct line in unpack() below
// For gcj, gij, etc., comment both out
// Pack200 now loaded dynamically in unpack() below
//
// For Sun, OpenJDK, IcedTea, etc, use this
import java.util.jar.Pack200;
//import java.util.jar.Pack200;
//
// For Apache Harmony or if you put its pack200.jar in your library directory use this
//import org.apache.harmony.unpack200.Archive;
@ -231,7 +231,6 @@ public class FileUtil {
}
/**
* This won't work right if one of the two options in unpack() is commented out.
* @since 0.8.1
*/
private static boolean isPack200Supported() {
@ -240,28 +239,70 @@ public class FileUtil {
return true;
} catch (Exception e) {}
try {
Class.forName("org.apache.harmony.pack200.Archive", false, ClassLoader.getSystemClassLoader());
Class.forName("org.apache.harmony.unpack200.Archive", false, ClassLoader.getSystemClassLoader());
return true;
} catch (Exception e) {}
return false;
}
private static boolean _failedOracle;
private static boolean _failedApache;
/**
* Unpack using either Oracle or Apache's unpack200 library,
* with the classes discovered at runtime so neither is required at compile time.
*
* Caller must close streams
* @throws IOException on unpack error or if neither library is available.
* Will not throw ClassNotFoundException.
* @throws org.apache.harmony.pack200.Pack200Exception which is not an IOException
* @since 0.8.1
*/
private static void unpack(InputStream in, JarOutputStream out) throws Exception {
// For Sun, OpenJDK, IcedTea, etc, use this
Pack200.newUnpacker().unpack(in, out);
//Pack200.newUnpacker().unpack(in, out);
if (!_failedOracle) {
try {
Class p200 = Class.forName("java.util.jar.Pack200", true, ClassLoader.getSystemClassLoader());
Method newUnpacker = p200.getMethod("newUnpacker", (Class[]) null);
Object unpacker = newUnpacker.invoke(null,(Object[]) null);
Method unpack = unpacker.getClass().getMethod("unpack", new Class[] {InputStream.class, JarOutputStream.class});
// throws IOException
unpack.invoke(unpacker, new Object[] {in, out});
return;
} catch (ClassNotFoundException e) {
_failedOracle = true;
//e.printStackTrace();
} catch (NoSuchMethodException e) {
_failedOracle = true;
//e.printStackTrace();
}
}
// ------------------
// For Apache Harmony or if you put its pack200.jar in your library directory use this
//(new Archive(in, out)).unpack();
if (!_failedApache) {
try {
Class p200 = Class.forName("org.apache.harmony.unpack200.Archive", true, ClassLoader.getSystemClassLoader());
Constructor newUnpacker = p200.getConstructor(new Class[] {InputStream.class, JarOutputStream.class});
Object unpacker = newUnpacker.newInstance(new Object[] {in, out});
Method unpack = unpacker.getClass().getMethod("unpack", (Class[]) null);
// throws IOException or Pack200Exception
unpack.invoke(unpacker, (Object[]) null);
return;
} catch (ClassNotFoundException e) {
_failedApache = true;
//e.printStackTrace();
} catch (NoSuchMethodException e) {
_failedApache = true;
//e.printStackTrace();
}
}
// ------------------
// For gcj, gij, etc., use this
//throw new IOException("Pack200 not supported");
throw new IOException("Unpack200 not supported");
}
/**
@ -378,12 +419,13 @@ public class FileUtil {
}
/**
* Usage: FileUtil (delete path | copy source dest)
* Usage: FileUtil (delete path | copy source dest | unzip path.zip)
*
*/
public static void main(String args[]) {
if ( (args == null) || (args.length < 2) ) {
testRmdir();
System.err.println("Usage: delete path | copy source dest | unzip path.zip");
//testRmdir();
} else if ("delete".equals(args[0])) {
boolean deleted = FileUtil.rmdir(args[1], false);
if (!deleted)
@ -407,6 +449,7 @@ public class FileUtil {
}
}
/*****
private static void testRmdir() {
File t = new File("rmdirTest/test/subdir/blah");
boolean created = t.mkdirs();
@ -417,4 +460,5 @@ public class FileUtil {
else
System.out.println("PASS: rmdirTest deleted");
}
*****/
}