• Post Reply Bookmark Topic Watch Topic
  • New Topic

problem using getSize on classes in jar file  RSS feed

 
Bruce Sandlier
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My Java experience is rather limited (socket applets) so I have been tinkering with other topics to broaden my experience. I have written a small utility using reflection to examine class files and now I am trying to include the ability to look at classes inside a jar file.

Using the following code I can find the classes in a jar file.

The output from this code is:

C:\Devel\Java\peek>java peek jclient.jar
Found: jclient$dataStruct.class
Found: jclient$errStruct.class
Found: jclient$hdrStruct.class
Found: jclient$idStruct.class
Found: jclient$jobStruct.class
Found: jclient$locStruct.class
Found: jclient$reqStruct.class
Found: jclient.class

But when I modified the code to extract the classes I got a NegativeArraySizeException exception on each class found.

The output from this code is:

C:\Devel\Java\peek>java peek jclient.jar
Found: jclient$dataStruct.class
java.lang.NegativeArraySizeException
at peek.showJarInfo(peek.java:222)
at peek.<init>(peek.java:108)
at peek.main(peek.java:237)
Found: jclient$errStruct.class
java.lang.NegativeArraySizeException
at peek.showJarInfo(peek.java:222)
at peek.<init>(peek.java:108)
at peek.main(peek.java:237)
Found: jclient$hdrStruct.class
java.lang.NegativeArraySizeException
at peek.showJarInfo(peek.java:222)
at peek.<init>(peek.java:108)
at peek.main(peek.java:237)
Found: jclient$idStruct.class
java.lang.NegativeArraySizeException
at peek.showJarInfo(peek.java:222)
at peek.<init>(peek.java:108)
at peek.main(peek.java:237)
Found: jclient$jobStruct.class
java.lang.NegativeArraySizeException
at peek.showJarInfo(peek.java:222)
at peek.<init>(peek.java:108)
at peek.main(peek.java:237)
Found: jclient$locStruct.class
java.lang.NegativeArraySizeException
at peek.showJarInfo(peek.java:222)
at peek.<init>(peek.java:108)
at peek.main(peek.java:237)
Found: jclient$reqStruct.class
java.lang.NegativeArraySizeException
at peek.showJarInfo(peek.java:222)
at peek.<init>(peek.java:108)
at peek.main(peek.java:237)
Found: jclient.class
java.lang.NegativeArraySizeException
at peek.showJarInfo(peek.java:222)
at peek.<init>(peek.java:108)
at peek.main(peek.java:237)

Tweaking the try code

I get the following results.

C:\Devel\Java\peek>java peek jclient.jar
Found: jclient$dataStruct.class
Class: jclient$dataStruct.class len = -1
Found: jclient$errStruct.class
Class: jclient$errStruct.class len = -1
Found: jclient$hdrStruct.class
Class: jclient$hdrStruct.class len = -1
Found: jclient$idStruct.class
Class: jclient$idStruct.class len = -1
Found: jclient$jobStruct.class
Class: jclient$jobStruct.class len = -1
Found: jclient$locStruct.class
Class: jclient$locStruct.class len = -1
Found: jclient$reqStruct.class
Class: jclient$reqStruct.class len = -1
Found: jclient.class
Class: jclient.class len = -1

The doc for getSize states that it "Returns the uncompressed size of the entry data, or -1 if not known.".

Does this mean that the size isn't know? Or am I doing something wrong in my attempt to get the size?
 
Freddy Wong
Ranch Hand
Posts: 959
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, I don't quite understand what you're trying to do. I don't know if this can help you, but if let's say you want to list the classes in inside the JAR file and get the uncompressed/compressed size for each of the class inside, you can do this:

Using ZipFile:


Using ZipInputStream:
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Bruce Sandlier]: The doc for getSize states that it "Returns the uncompressed size of the entry data, or -1 if not known.".

Does this mean that the size isn't know? Or am I doing something wrong in my attempt to get the size?


It means the size isn't known. You're not doing something wrong in how you get the size, but you simply can't rely on this method to have the info you need. You'll need another strategy. I would recommend using a ByteArrayOutputStream. Just keep reading from the ZipInputStream until the read() returns -1 to indicate the stream is finished. Everything you read from the ZIS, write it to the ByteArrayOutputStream. When you're done, close the BAOS and use toByteArray() to get the data.
 
Bruce Sandlier
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim

Sorry it took me so long to respond. I've been dabbling with the code in between doing 'real work' and moving to a new floor. Your suggestion worked and I thank you for that.

Now I have another problem that I have not been able to figure out. I have done a lot of Googleing and trying various things to no avail. The call to defineClass in the following code generates the NoClassDefFoundError that follows the code.



Found: jclient$dataStruct.class
Exception in thread "main" java.lang.NoClassDefFoundError: jclient$dataStruct/class (wrong name: jclient$dataStruct)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at peek.showJarInfo(peek.java:231)
at peek.<init>(peek.java:109)
at peek.main(peek.java:245)

The class name looks good to me, but defineClass doesn't like it for some reason. If I pass null in place of cn the class is created and some of the functions in showResults work while others, like getConstructors(), throw a NoClassDefFoundError. So, it looks like I have everything right except the class name. Any thoughts on this?
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"cn" is the name of the class file in the zip, not the name of the class. You need to remove the ".class" at the end before you use it for a class name! That why the ".class" appears in the error message; the "wrong name" part tells you what name the VM actually found in the class file, and as you see it differs from the one you passed in by the ommission of the ".class".
 
Bruce Sandlier
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My code is working now. Thanks for your help.

It seems to me that the verbiage in the error message is rather misleading.
(wrong name: jclient$dataStruct) tells me that jclient$dataStruct is wrong. I kept thinking "what's wrong with that?". Something like (wrong name: jclient$dataStruct.class, expecting jclient$dataStruct) would have made it a no-brainer.

I have started Googleing for "understanding java exception messages", but if someone can direct me to a good source on this topic I would really appreciate it.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!