Q:

ClassFormatError when invoking defineClass with bytes read using JarInputStream read method

I am using the following method to read bytes from jar entries (containing class files only). There is no jar file inside the jar.
private List<byte[]> readFromJarFile(File cp) 
{
    List<byte[]> cbytes = new ArrayList<byte[]>();
    try 
    {
        java.util.jar.JarInputStream jin = new java.util.jar.JarInputStream(new java.io.FileInputStream(cp));
        java.util.jar.JarEntry je = jin.getNextJarEntry();
        while (je != null)
        {
            if (!je.isDirectory() && je.toString().endsWith(".class")) 
            {
                //assume class file size < Integer.MAX_VALUE
                System.out.printf("readFromJarFile: jar entry name %s ...%n",je.toString());
                byte[] cbyte = new byte[(int) je.getSize()];
                jin.read(cbyte,0,(int) je.getSize());
                cbytes.add(cbyte);
            }
            je = jin.getNextJarEntry();
        }
    }
    catch (java.io.IOException ie)
    {
        ie.printStackTrace();
    }

    return cbytes;
}

Now when I am calling defineClass with a byte array returned from the above method following exception is thrown.
java.lang.ClassFormatError: Unknown constant tag 0 in class file <Unknown>
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.lang.ClassLoader.defineClass(ClassLoader.java:465)
at san.tool.JPAEntityProcessor$JPAClassLoader.loadClass(JPAEntityProcessor.java:34)
at san.tool.JPAEntityProcessor.processJPAEntities(JPAEntityProcessor.java:49)
at san.tool.JPAEntityProcessorTest.testWithJarFile(JPAEntityProcessorTest.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at 

I searched this site and all other forums on the internet but couldn't find an answer. I am looking forward to some insights from the members here.
Thanks and regards
Santanu

A:

jin.read(cbyte,0,(int) je.getSize());

It is not guaranteed that read method will read je.getSize() bytes into buffer. Instead, it returns count of bytes actually read. You need to wrap read attempts into loop and read until buffer filled.
Something like this: 
int len = (int) je.getSize();
int offset = 0;
int read;
while ((read = jin.read(cbyte, offset, len - offset)) > 0) {
    offset += read;
}

UPD After a year I realized, that my original example will stuck after reading whole stream. And later "fixed" version will not actually enter the loop. So, here is short, correct and tested version.

