1 34 package lsjar; 35 36 import java.io.*; 37 import java.util.Enumeration ; 38 import java.util.StringTokenizer ; 39 import java.util.zip.*; 40 import java.util.jar.*; 41 42 import org.apache.bcel.classfile.*; 43 44 54 public class Lsjar { 55 private static void printVersion() { 56 System.out.println("lsjar - list a jar file - ver 0.9.3"); 57 } 58 59 private static void printUsage() { 60 printVersion(); 61 System.out.println("-- list files in jar file"); 62 System.out.println("[usage] java -jar lsjar.jar xxxx.jar"); 63 System.out.println("-- show class file in jar file"); 64 System.out.println("[usage] java -jar lsjar.jar {options} xxxx.jar path/file.class"); 65 System.out.println(" options"); 66 System.out.println(" -verbose : verbose mode"); 67 System.out.println(" -constant : show constant pool"); 68 System.out.println(" -code : show method code"); 69 } 71 72 public static void main(String [] argv) { 73 String [] file_name = new String [argv.length]; 74 int files=0; 75 boolean code=false, constants=false, verbose=true; 76 String name=null; 77 78 for (int i=0; i < argv.length; i++) { 80 if (argv[i].charAt(0) == '-') { if(argv[i].equals("-constant")) { 82 constants = true; 83 } else if(argv[i].equals("-code")) { 84 code = true; 85 } else if(argv[i].equals("-verbose")) { 86 verbose = false; 87 } else { 88 System.err.println("Unknown switch " + argv[i] + " ignored."); 89 } 90 } else { file_name[files++] = argv[i]; 92 } 93 } 94 95 try { 96 if (files == 0) { 97 printUsage(); 98 } else { 99 if (file_name[0].endsWith(".jar")) { 100 String jarfn = file_name[0]; 101 files --; 102 System.arraycopy(file_name, 1, file_name, 0, files); 103 proc(jarfn, file_name, files, code, constants, verbose); 104 } 105 } 106 } catch(IOException e) { 107 System.err.println(e.getMessage()); 108 } catch(Exception e) { 109 System.err.println(e); 110 } 111 } 112 113 private static void proc(String jarfn, String [] file_name, int files, boolean code, boolean constants, boolean verbose) throws IOException { 114 if (files == 0) { 115 JarFile jar = new JarFile(jarfn); 116 Enumeration en = jar.entries(); 117 while (en.hasMoreElements()) { 118 ZipEntry et = (ZipEntry)en.nextElement(); 119 long sz = et.getSize(); 120 long csz = et.getCompressedSize(); 121 String etname = et.getName(); 122 printEntryLine(sz, csz, etname); 123 } 124 return; 125 } 126 127 String name; 128 for (int i=0; i < files; i++) { 129 String entname = null; 130 long entsize = 0; 131 long entcsz = 0; 132 ClassParser cpr = null; 133 JavaClass java_class; 134 135 name = file_name[i]; 136 137 if (jarfn != null) { 138 if (!new File(jarfn).exists()) { 139 System.out.println("can not found " + jarfn); 140 continue; 141 } 142 143 ZipFile zip = new ZipFile(jarfn); 144 ZipEntry entry = zip.getEntry(name); 145 if (entry == null) { 146 System.out.println("can not found " + name); 147 continue; 148 } 149 entcsz = entry.getCompressedSize(); 150 entsize = entry.getSize(); 151 entname = entry.getName(); 152 153 try { 154 cpr = new ClassParser(jarfn, name); 155 } catch (Exception ex) { 156 System.out.println("can not found " + name + " in " + jarfn); 157 continue; 158 } 159 } else { 160 if (!new File(name).exists()) { 161 System.out.println("can not found " + name); 162 continue; 163 } 164 cpr = new ClassParser(name); 165 if (cpr == null) { 166 System.out.println("can not found file " + name); 167 continue; 168 } 169 } 170 java_class = cpr.parse(); 171 172 if (entname != null) { 173 printEntryLine(entsize, entcsz, entname); 174 } 175 176 System.out.println(formatClass(java_class)); 178 if (constants) { System.out.println(java_class.getConstantPool()); 180 } 181 182 if (code) { printCode(java_class.getMethods(), verbose); 184 } 185 } 186 } 187 188 private static void printEntryLine(long sz, long csz, String name) { 189 int cmp = 0; 190 191 if (sz != 0) { 192 cmp = (int)((100L * csz) / sz); 193 } 194 195 String s = Long.toString(sz); 196 for (int i=s.length(); i<8; i++) { 197 System.out.print(' '); 198 } 199 System.out.print(sz); 200 System.out.print(' '); 201 202 String cs = Integer.toString(cmp); 203 for (int i=cs.length(); i<3; i++) { 204 System.out.print(' '); 205 } 206 System.out.print(cs); 207 System.out.print('%'); 208 System.out.print(' '); 209 210 System.out.println(name); 211 } 212 213 private static String formatClass(JavaClass jcls) { 214 StringBuffer buf = new StringBuffer (); 215 216 int access_flags = jcls.getAccessFlags(); 217 String class_name = jcls.getClassName(); 218 String superclass_name = jcls.getSuperclassName(); 219 220 String access = Utility.accessToString(access_flags, true); 221 access = access.equals("") ? "" : (access + " "); 222 223 buf.append(access); 224 buf.append(Utility.classOrInterface(access_flags)); 225 buf.append(" "); 226 buf.append(class_name); 227 buf.append(" extends "); 228 buf.append(Utility.compactClassName(superclass_name, false)); 229 buf.append("\n"); 230 231 { 233 String [] interface_names = jcls.getInterfaceNames(); 234 int size = interface_names.length; 235 if (size > 0) { 236 buf.append("implements\t\t"); 237 238 for (int i=0; i < size; i++) { 239 buf.append(interface_names[i]); 240 if (i < size - 1) { 241 buf.append(", "); 242 } 243 } 244 245 buf.append('\n'); 246 } 247 } 248 249 { 251 buf.append("filename\t\t"); 252 buf.append(jcls.getFileName()); 253 buf.append("\n"); 254 255 buf.append("compiled from\t\t"); 256 buf.append(jcls.getSourceFileName()); 257 buf.append("\n"); 258 259 buf.append("compiler version\t"); 260 buf.append(jcls.getMajor()); 261 buf.append("."); 262 buf.append(jcls.getMinor()); 263 buf.append("\n"); 264 265 buf.append("access flags\t\t"); 266 buf.append(jcls.getAccessFlags()); 267 buf.append("\n"); 268 269 buf.append("constant pool\t\t"); 270 buf.append(jcls.getConstantPool().getLength()); 271 buf.append(" entries"); 272 buf.append("\n"); 273 274 buf.append("ACC_SUPER flag\t\t"); 275 buf.append(jcls.isSuper()); 276 buf.append("\n"); 277 } 278 279 { 281 Attribute[] attributes = jcls.getAttributes(); 282 if (attributes.length > 0) { 283 buf.append("\nAttribute(s):\n"); 284 for (int i=0; i < attributes.length; i++) { 285 buf.append(indent(attributes[i])); 286 } 287 } 288 } 289 290 { 292 Field[] fields = jcls.getFields(); 293 if (fields.length > 0) { 294 buf.append("\n" + fields.length + " fields:\n"); 295 for (int i=0; i < fields.length; i++) { 296 buf.append("\t"); 297 buf.append(fields[i]); 298 buf.append("\n"); 299 } 300 } 301 } 302 303 { 305 Method[] methods = jcls.getMethods(); 306 if (methods.length > 0) { 307 buf.append("\n" + methods.length + " methods:\n"); 308 for (int i=0; i < methods.length; i++) { 309 buf.append(" "); 310 int codelen = 0; 311 Code code = methods[i].getCode(); 312 if (code != null) { 313 codelen = code.getCode().length; 314 } 315 buf.append(codelen); 316 buf.append("\t"); 317 buf.append(methods[i]); 318 buf.append("\n"); 319 } 320 } 321 } 322 323 return buf.toString(); 324 } 325 326 private static final String indent(Object obj) { 327 StringTokenizer tok = new StringTokenizer (obj.toString(), "\n"); 328 StringBuffer buf = new StringBuffer (); 329 330 while (tok.hasMoreTokens()) { 331 buf.append("\t"); 332 buf.append(tok.nextToken()); 333 buf.append("\n"); 334 } 335 336 return buf.toString(); 337 } 338 339 private static void printCode(Method[] methods, boolean verbose) { 341 for (int i=0; i < methods.length; i++) { 342 System.out.println(methods[i]); 344 345 Code code = methods[i].getCode(); 346 if (code != null) { 347 System.out.println(code.toString(verbose)); 348 } 349 } 350 } 351 } 352 | Popular Tags |