1 25 package net.yagga.util; 26 27 import java.net.*; 28 import java.lang.reflect.Method ; 29 import java.lang.reflect.Modifier ; 30 import java.lang.reflect.InvocationTargetException ; 31 import java.util.jar.Attributes ; 32 import java.io.IOException ; 33 import java.util.jar.*; 34 import java.util.zip.*; 35 import java.util.*; 36 import java.io.*; 37 38 52 public class BootstrapJarClassLoader extends ClassLoader 53 { 54 60 public static void main(String argv[]) { 61 62 String arg = "sample.conf"; 63 if (argv.length > 0) 64 arg = argv[0]; 65 String [] args = {arg}; 66 67 69 try { 70 BootstrapJarClassLoader jcl = new BootstrapJarClassLoader("MiniInstaller.jar"); 71 jcl.invokeClass("net.yagga.miniinstaller.MiniInstaller", args); 74 } 75 catch (ClassNotFoundException e) { 76 System.err.println("1 Class not found: " + e); 77 } 78 catch (NoSuchMethodException e) { 80 System.err.println("1 Class does not define a 'main' method: " + e); 81 } 82 catch (InvocationTargetException e) { 83 System.err.println("1 Invoke excpt: " + e); 84 System.err.println("1 Invoke excpt: " + e.getTargetException()); 85 } 86 87 } 88 89 90 private String jarFile; 91 92 private Hashtable htSizes = new Hashtable(); 94 95 101 public String getActualJarName() { 102 if(executingFromJar) 103 return jarJarFile; 104 else 105 return jarFile; 106 } 107 108 private boolean executingFromJar = false; 110 private Hashtable metaJarContent = new Hashtable(); 112 private String jarJarFile; 113 private Manifest metaManifest = null; 114 115 123 public BootstrapJarClassLoader(String jFile) { 124 super(); 125 this.jarFile = jFile; 126 127 try { 128 URL u = this.getClass().getResource("/" + jarFile); 129 URLConnection uc = u.openConnection(); 130 if (uc instanceof JarURLConnection) { 131 132 executingFromJar = true; 134 JarURLConnection juc = (JarURLConnection)uc; 135 jarJarFile = URLDecoder.decode(jarFile); 138 jarFile = juc.getJarFileURL().getFile(); 140 141 jarFile=URLDecoder.decode(jarFile); 145 146 initTopJarSizes(); 149 readJarInJar(); 151 } 152 else { 153 155 executingFromJar = false; 157 initTopJarSizes(); 158 } 160 } 163 catch (IOException ioe) { 164 System.err.println("Error getting file from file" + jarFile + ":" + ioe); 165 jarFile = ""; 166 } 167 } 168 169 176 private void readJarInJar() { 177 try { 178 byte[] jarE = readBytesFromTopJar(jarJarFile); 181 182 185 String tmpDir = System.getProperty("java.io.tmpdir"); 187 188 File jarInJarFile = new File(tmpDir, jarJarFile); 189 FileOutputStream fout = new FileOutputStream(jarInJarFile.getCanonicalPath()); 190 for (int i = 0; i < jarE.length; i++) 192 fout.write(jarE[i]); 193 fout.close(); 194 fout = null; 195 196 Hashtable sizes = new Hashtable(); 198 JarFile jf = new JarFile(jarInJarFile); 199 try { 200 Enumeration e = jf.entries(); 201 while (e.hasMoreElements()) { 202 JarEntry ze = (JarEntry)e.nextElement(); 203 sizes.put(ze.getName(), new Integer ((int)ze.getSize())); 205 } 206 metaManifest = jf.getManifest(); 208 jf.close(); 209 } 210 catch (IOException ioe) { 211 System.err.println("Error reading sizes in '" + fout + "':" + ioe); 212 } 213 214 jarInJarFile.delete(); 217 218 ByteArrayInputStream bais = new ByteArrayInputStream(jarE); 220 JarInputStream jis = new JarInputStream(bais); 221 JarEntry je = null; 222 while ((je = jis.getNextJarEntry()) != null) { 223 if (je.isDirectory()) 224 continue; 225 226 int size = (int)je.getSize(); 227 if (size == -1) 228 size = ((Integer )sizes.get(je.getName())).intValue(); 229 230 byte[] b = new byte[(int)size]; 231 int rb = 0; 232 int chunk = 0; 233 while (((int)size - rb) > 0) { 234 chunk = jis.read(b, rb, (int)size - rb); 235 if (chunk == -1) 236 break; 237 rb += chunk; 238 } 239 metaJarContent.put(je.getName(), b); 241 242 } 244 jis.close(); 245 } 246 catch (FileNotFoundException fnfe) { 247 System.err.println("ERROR:" + fnfe); 248 } 249 catch (IOException ioe) { 250 System.err.println("ERROR:" + ioe); 251 } 252 } 253 254 261 public String getMainClassName() { 262 try { 263 if (executingFromJar) { 264 return metaManifest != null ? metaManifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS) : null; 265 } 266 else { 267 JarFile jf = new JarFile(jarFile); 268 Manifest mf = jf.getManifest(); 269 return mf != null ? mf.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS) : null; 270 } 271 } 272 catch (IOException ioe) { 273 System.err.println("IOE getting main class " + ioe); 274 return null; 275 } 276 } 277 278 290 public void invokeClass(String name, String [] args) 291 throws ClassNotFoundException , 292 NoSuchMethodException , 293 InvocationTargetException { 294 Class c = loadClass(name); 295 296 Method m = c.getMethod("main", new Class []{args.getClass()}); 298 m.setAccessible(true); 300 int mods = m.getModifiers(); 301 if (m.getReturnType() != void.class || !Modifier.isStatic(mods) || 302 !Modifier.isPublic(mods)) { 303 throw new NoSuchMethodException ("main"); 304 } 305 try { 306 m.invoke(null, new Object []{args}); 307 } 308 catch (IllegalAccessException e) { 309 } 311 } 312 313 321 protected Class findClass(String className) 322 throws ClassNotFoundException { 323 String urlName = className.replace('.', '/') + ".class"; 324 326 byte b1[] = null; 328 if (executingFromJar) 329 b1 = (byte[])metaJarContent.get(urlName); 330 else 331 b1 = readBytesFromTopJar(urlName); 332 if (b1 == null) { 333 System.err.println("Class '" + className + "' not found."); 334 return null; 335 } 336 try { 337 return defineClass(className, b1, 0, b1.length); 338 } 339 catch (ClassFormatError cfe) { 340 System.err.println("'" + className + "':" + cfe); 341 } 342 return null; 343 } 344 345 351 private void initTopJarSizes() { 352 try { 353 JarFile zf = new JarFile(jarFile); 354 Enumeration e = zf.entries(); 355 while (e.hasMoreElements()) { 356 JarEntry ze = (JarEntry)e.nextElement(); 357 htSizes.put(ze.getName(), new Integer ((int)ze.getSize())); 359 } 360 zf.close(); 361 } 362 catch (IOException ioe) { 363 System.err.println("TOP Error reading sizes in '" + jarFile + "':" + ioe); 364 } 365 } 366 367 375 public byte[] readBytesFromTopJar(String entryName) { 376 try { 377 JarInputStream zis = getTopJIS(); 379 JarEntry ze = null; 380 while ((ze = zis.getNextJarEntry()) != null) { 381 if (ze.isDirectory()) 382 continue; 383 384 int size = (int)ze.getSize(); 385 if (size == -1) 386 size = ((Integer )htSizes.get(ze.getName())).intValue(); 387 388 if (ze.getName().equals(entryName)) { 390 byte[] b = new byte[(int)size]; 392 int rb = 0; 393 int chunk = 0; 394 while (((int)size - rb) > 0) { 395 chunk = zis.read(b, rb, (int)size - rb); 396 if (chunk == -1) 397 break; 398 rb += chunk; 399 } 400 zis.close(); 401 return b; 402 } 403 } 404 zis.close(); 405 } 406 catch (NullPointerException e) { 407 System.err.println("'" + jarFile + "':(done)" + e); 408 } 409 catch (FileNotFoundException e) { 410 System.err.println("'" + jarFile + "':" + e); 411 } 412 catch (IOException e) { 413 System.err.println("'" + jarFile + "':" + e); 414 } 415 return null; 416 } 417 418 424 private JarInputStream getTopJIS() { 425 try { 427 JarFile jf = new JarFile(jarFile); 428 if (jf != null) 429 return new JarInputStream(new FileInputStream(jarFile)); 430 } 431 catch (Exception e) { 432 System.err.println("ERROR:" + e); 433 } 434 try { 435 InputStream is = openResource(jarFile); 437 return new JarInputStream(is); 438 } 439 catch (IOException io) { 440 System.err.println("IOE:" + io); 441 } 442 return null; 443 } 444 445 452 private InputStream openResource(String filename) { 453 try { 454 InputStream is = BootstrapJarClassLoader.class.getResourceAsStream("/" + filename); 455 is.available(); 456 return is; 458 } 459 catch (java.io.IOException e) { 460 System.err.println("RM2: file not found:" + filename); 461 System.exit(1); 462 } 463 catch (NullPointerException e2) { 464 System.err.println("RM2: file not found!" + filename); 465 e2.printStackTrace(); 466 System.exit(1); 467 } 468 return null; 469 } 470 471 } 472 473 | Popular Tags |