Uploaded image for project: 'Commons Compress'
  1. Commons Compress
  2. COMPRESS-627

Pack200 causes a 'archive.3E' error if it’s not in the system class loader.

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 1.21
    • 1.22
    • None
    • None

    Description

      import org.apache.commons.compress.java.util.jar.Pack200;
      import java.lang.reflect.Method;
      import java.net.URLClassLoader;
      import java.net.URL;
      import java.io.File;
      
      class Main {
        public static void main(String[] args) throws Throwable {
          URLClassLoader ucl = new URLClassLoader(new URL[] {
            new File(".").toURI().toURL(),
            new File("commons-compress-1.21.jar").toURI().toURL(),
          }, null);
      
          System.out.println("=== Unpacker ===");
          Method method;
          try {
            method = ucl.loadClass("InClassLoaderClass").getDeclaredMethod("unpacker");
            method.setAccessible(true);
            method.invoke(null);
          } catch (Throwable t) {
            t.printStackTrace();
          }
      
          System.out.println("=== Packer ===");
          try {
            method = ucl.loadClass("InClassLoaderClass").getDeclaredMethod("packer");
            method.setAccessible(true);
            method.invoke(null);
          } catch (Throwable t) {
            t.printStackTrace();
          }
        }
      }
      
      class InClassLoaderClass {
        public static void unpacker() {
          Pack200.newUnpacker();
        }
        public static void packer() {
          Pack200.newPacker();
        }
      }
      

      execute this code (same as attached Main.java) with ClassLoaderClass.class (compiled code of this file) and commons-compress-1.21.jar is on working directory will cause the following error:

      anatawa12@anatawa12-book:~/commons-compress-pack200-test $ javac -cp commons-compress-1.21.jar Main.java && java Main
      === Unpacker ===
      java.lang.reflect.InvocationTargetException
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at Main.main(Main.java:19)
      Caused by: java.lang.Error: archive.3E
      	at org.apache.commons.compress.java.util.jar.Pack200$2.run(Pack200.java:100)
      	at java.security.AccessController.doPrivileged(Native Method)
      	at org.apache.commons.compress.java.util.jar.Pack200.newUnpacker(Pack200.java:91)
      	at InClassLoaderClass.unpacker(Main.java:37)
      	... 5 more
      Caused by: java.lang.ClassNotFoundException: org.apache.commons.compress.harmony.unpack200.Pack200UnpackerAdapter
      	at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
      	at java.lang.ClassLoader.loadClass(ClassLoader.java:419)
      	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
      	at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
      	at org.apache.commons.compress.java.util.jar.Pack200$2.run(Pack200.java:98)
      	... 8 more
      === Packer ===
      java.lang.reflect.InvocationTargetException
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at Main.main(Main.java:28)
      Caused by: java.lang.Error: archive.3E
      	at org.apache.commons.compress.java.util.jar.Pack200$1.run(Pack200.java:72)
      	at java.security.AccessController.doPrivileged(Native Method)
      	at org.apache.commons.compress.java.util.jar.Pack200.newPacker(Pack200.java:61)
      	at InClassLoaderClass.packer(Main.java:40)
      	... 5 more
      Caused by: java.lang.ClassNotFoundException: org.apache.commons.compress.harmony.pack200.Pack200PackerAdapter
      	at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
      	at java.lang.ClassLoader.loadClass(ClassLoader.java:419)
      	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
      	at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
      	at org.apache.commons.compress.java.util.jar.Pack200$1.run(Pack200.java:70)
      	... 8 more
      

      In src/main/java/org/apache/commons/compress/java/util/jar/Pack200.java, Packer/Unpacker implementaion is loaded from ClassLoader.getSystemClassLoader().
      However, Apache commons compress may be loaded from other class loaders in many environments (e.g. Gradle).
       

      Attachments

        1. Main-1.java
          1 kB
          anatawa12

        Activity

          People

            Unassigned Unassigned
            anatawa12 anatawa12
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: