Donate. I desperately need donations to survive due to my health

Get paid by answering surveys Click here

Click here to donate

Remote/Work from Home jobs

How to identify byte array and InputStream problems in Java?

I have this code

InputStream is = getJarStream();

JarByteClassloader loader = new JarByteClassloader(ByteStreams.toByteArray(is));

Where JarByteClassloader is a Classloader

public JarByteClassloader(byte[] bytes) throws IOException {
    super(Thread.currentThread().getContextClassLoader());
    this.bytes = bytes;
}

 protected Class findClass(String name) throws ClassNotFoundException {
        try {
            JarInputStream jis = null;
            // For testing, I have two case here,
            // if the constructor with the byte[] as parameter is used no problem at all
            // but when the constructor with InputStream is used, ClassNotFoundException is thrown
            if(bytes == null) {
                byte[] bytes = ByteStreams.toByteArray(inputStream);
                jis = new JarInputStream(new ByteArrayInputStream(bytes));
                // or if this code is used
                // jis = new JarInputStream(inputStream);
                // even worst happens, a NoClassDefFoundError is thrown when class loader tries to 
                // load a class
            } else {
                jis = new JarInputStream(new ByteArrayInputStream(bytes));
            }
            JarEntry entry = jis.getNextJarEntry();
            if (entry == null){ 
                throw new ClassNotFoundException(name);
            }
            // other code omitted for similicity
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null; 
    }

The code above works fine. If this constructor is used:

JarByteClassloader loader = new JarByteClassloader(ByteStreams.toByteArray(is));

However, doing

JarByteClassloader loader = new JarByteClassloader(is);

With a second constructor,

public JarByteClassloader(InputStream is) throws IOException {
    super(Thread.currentThread().getContextClassLoader());
    this.inputStream = is;
}

Then doing,

Class c = loader.loadClass(classToLoad);

Will throw ClassNotFoundError.

(For Testing) Why is it when doing ByteStreams.toByteArray(is) in the constructor parameter works, but when doing it inside the findClass method it does not work?

Also, what could be the reason why this code

JarByteClassloader loader = new JarByteClassloader(is);

does not work here?

Comments