Search code examples
javaclassloadertruezip

TrueZip class could not be instantiated


There's a little program which was running well with TrueZip 6. Recently I've updated TrueZip jars to version 7.7.9 by adding 6 packages to the project's classpath: truezip-driver-file, truezip-driver-tar, truezip-driver-zip, truezip-file, truezip-kernel and truezip-swing with all necessary dependencies (xz 1.5 etc).

There's no error during compilation, however, when I try to run in the main method:

TConfig.get().setArchiveDetector(
    new TArchiveDetector(TArchiveDetector.NULL, new Object[][] {
        { "tar", new TarDriver(IOPoolLocator.SINGLETON) },
        { "tgz|tar.gz", new TarGZipDriver(IOPoolLocator.SINGLETON) },
        { "zip|alt|alib", new ZipDrive(IOPoolLocator.SINGLETON) } })); 

It shows de.schlichtherle.truezip.socket.sl.IOPoolLocator$Boot could not be instantiated in IOPoolLocator

Boot is an inner and static final class http://grepcode.com/file/repo1.maven.org/maven2/de.schlichtherle.truezip/truezip-kernel/7.7.9/de/schlichtherle/truezip/socket/sl/IOPoolLocator.java#IOPoolLocator

I found few references but unfortunately not very helpful.


Solution

  • I had the same issue and I guess you're adding these TrueZip classpath entries in separated lines ?

    In this case, my solution is : add them in one single line with paths separated by comma ","

    Try to go deep and debug the real error from the first instantiation of class Boot in JVM :

    static final IOPool<?> pool;
    static {
        final Class<?> clazz = IOPoolLocator.class;
        final Logger logger = Logger.getLogger(clazz.getName(), clazz.getName());
        final ServiceLocator locator = new ServiceLocator(clazz.getClassLoader());
        pool = decorate((IOPool) create(locator, logger), locator, logger);
    }
    

    You'll see that finally it goes to a line which is the source of later exceptions :

    this.l1 = null != loader ? loader : ClassLoader.getSystemClassLoader();
    

    Basically it's using a ServiceLoader or ClassLoader. Now perform a test in the main method :

    aClassLoader.getResourceAsStream("/META-INF/services/de.schlichtherle.truezip.socket.spi.IOPoolService") 
    

    using different classes contained in each of your 6 jar files, you should see that only classes in truezip-kernel.jar can find IOPoolService, because all jar files are loaded by different loaders (not the same object id).