1 23 24 25 package com.sun.enterprise.loader; 26 27 import java.io.BufferedInputStream ; 28 import java.io.ByteArrayOutputStream ; 29 import java.io.File ; 30 import java.io.FileInputStream ; 31 import java.io.FilterInputStream ; 32 import java.io.IOException ; 33 import java.io.InputStream ; 34 35 import java.lang.instrument.IllegalClassFormatException ; 36 import java.net.JarURLConnection ; 37 38 import java.net.MalformedURLException ; 39 import java.net.URI ; 40 import java.net.URISyntaxException ; 41 import java.net.URL ; 42 import java.net.URLClassLoader ; 43 import java.net.URLConnection ; 44 import java.net.URLStreamHandler ; 45 import java.security.AccessController ; 46 import java.security.CodeSource ; 47 import java.security.PrivilegedAction ; 48 import java.security.PrivilegedActionException ; 49 import java.security.PrivilegedExceptionAction ; 50 import java.security.ProtectionDomain ; 51 import java.security.SecureClassLoader ; 52 import java.security.cert.Certificate ; 53 import java.text.MessageFormat ; 54 import java.util.ArrayList ; 55 import java.util.Collections ; 56 import java.util.Date ; 57 import java.util.HashMap ; 58 import java.util.Hashtable ; 59 import java.util.List ; 60 import java.util.Map ; 61 import java.util.StringTokenizer ; 62 import java.util.jar.Attributes ; 63 import java.util.jar.JarEntry ; 64 import java.util.jar.JarFile ; 65 import java.util.jar.Manifest ; 66 import java.util.logging.Level ; 67 import java.util.logging.Logger ; 68 import java.util.Vector ; 69 import java.util.Enumeration ; 70 import java.util.Iterator ; 71 72 import com.sun.appserv.server.util.PreprocessorUtil; 73 import com.sun.enterprise.util.Print; 74 import com.sun.logging.LogDomains; 75 import com.sun.enterprise.util.i18n.StringManager; 76 77 import javax.persistence.spi.ClassTransformer; 78 import java.util.zip.ZipEntry ; 79 80 91 public class EJBClassLoader 92 extends URLClassLoader 93 implements JasperAdapter, InstrumentableClassLoader { 94 95 96 static Logger _logger=LogDomains.getLogger(LogDomains.LOADER_LOGGER); 97 98 99 private List <URLEntry> urlSet = Collections.synchronizedList(new ArrayList ()); 100 101 102 private Map notFoundResources = new HashMap (); 103 104 105 private Map notFoundClasses = new HashMap (); 106 107 108 private boolean doneCalled = false; 109 110 private String doneSnapshot; 111 112 113 private Vector <SentinelInputStream> streams = null; 114 115 private ArrayList <ClassTransformer> transformers = 116 new ArrayList <ClassTransformer>(1); 117 118 private static StringManager sm = 119 StringManager.getManager(EJBClassLoader.class); 120 121 124 public EJBClassLoader() { 125 super(new URL [0]); 126 127 if (_logger.isLoggable(Level.FINE)) { 128 _logger.log(Level.FINE, 129 "ClassLoader: " + this + " is getting created."); 130 } 131 } 132 133 138 public EJBClassLoader(ClassLoader parent) { 139 super(new URL [0], parent); 140 } 141 142 public boolean isDone() { 143 return doneCalled; 144 } 145 146 150 public void done() { 151 152 if( doneCalled ) { 153 return; 154 } 155 156 doneSnapshot = "EJBClassLoader.done() called ON " + this.toString() 160 + "\n AT " + new Date () + 161 " \n BY :" + Print.printStackTraceToString(); 162 doneCalled = true; 163 164 int i = 0; 166 while (i < this.urlSet.size()) { 167 URLEntry u = (URLEntry) this.urlSet.get(i); 168 if (u.zip != null) { 169 try { 170 u.zip.reallyClose(); 171 } catch (IOException ioe) { 172 _logger.log(Level.INFO, formatMsg("loader.ejbclassloader_exc_closing_URLEntry", u.source), 173 ioe); 174 } 175 } 176 if (u.table != null) { 177 u.table.clear(); 178 u.table = null; 179 } 180 u = null; 181 i++; 182 } 183 184 closeOpenStreams(); 185 186 if (this.urlSet != null) { this.urlSet.clear(); } 188 if (this.notFoundResources != null) { this.notFoundResources.clear(); } 189 if (this.notFoundClasses != null) { this.notFoundClasses.clear(); } 190 191 this.urlSet = null; 193 this.notFoundResources = null; 194 this.notFoundClasses = null; 195 } 196 197 198 206 public synchronized void appendURL(File file) throws IOException { 207 try { 208 appendURL(file.toURI().toURL()); 209 } catch (MalformedURLException mue) { 210 _logger.log(Level.SEVERE, 211 "loader.ejbclassloader_bad_url_entry", file.toURI()); 212 213 _logger.log(Level.SEVERE, 214 "loader.ejbclassloader_malformed_url", mue); 215 IOException ioe = new IOException (); 216 ioe.initCause(mue); 217 throw ioe; 218 } 219 } 220 221 222 228 public void addURL(URL url) { 229 appendURL(url); 230 } 231 232 233 238 public synchronized void appendURL(URL url) { 239 240 try { 241 if (url == null) { 242 _logger.log(Level.INFO, 243 "loader.ejbclassloader_bad_url_entry", url); 244 return; 245 } 246 247 URLEntry entry = new URLEntry(url); 248 249 if ( !urlSet.contains(entry) ) { 250 entry.init(); 251 this.urlSet.add(entry); 253 254 if (entry.isJar) { 255 checkManifest(entry.zip, entry.file); 257 } 258 } else { 259 _logger.log(Level.FINE, 260 "[EJB-CL] Ignoring duplicate URL: " + url); 261 264 if (entry.zip != null) { 265 try { 266 entry.zip.reallyClose(); 267 } catch (IOException ioe) { 268 _logger.log(Level.INFO, formatMsg("loader.ejbclassloader_exc_closing_dup_URLEntry", url), 269 ioe); 270 } 271 } 272 } 273 274 clearNotFoundCaches(); 276 277 } catch (IOException ioe) { 278 279 _logger.log(Level.SEVERE, 280 "loader.ejbclassloader_bad_url_entry", url); 281 282 _logger.log(Level.SEVERE, 283 "loader.ejbclassloader_malformed_url", ioe); 284 } 285 } 286 287 292 public synchronized URL [] getURLs() { 293 294 URL [] url = null; 295 296 if (this.urlSet != null) { 297 url = new URL [this.urlSet.size()]; 298 299 for (int i=0; i<url.length; i++) { 300 url[i] = ((URLEntry)this.urlSet.get(i)).source; 301 } 302 } else { 303 url = new URL [0]; 304 } 305 306 return url; 307 } 308 309 320 public String getClasspath() { 321 322 StringBuffer strBuf = null; 323 324 URL [] urls = getURLs(); 325 if (urls != null) { 326 for (int i=0; i<urls.length; i++) { 327 if (urls[i].getProtocol().equals("file")) { 328 if (strBuf == null) { 329 strBuf = new StringBuffer (); 330 } 331 if (i > 0) { 332 strBuf.append(File.pathSeparator); 333 } 334 strBuf.append(urls[i].getFile()); 335 } 336 } 337 } 338 339 return (strBuf != null) ? strBuf.toString() : null; 340 } 341 342 353 public synchronized void refresh() throws IOException { 354 clearNotFoundCaches(); 355 } 359 360 public synchronized void addTransformer(ClassTransformer transformer) { 361 transformers.add(transformer); 362 } 363 364 369 public ClassLoader copy() { 370 return new DelegatingClassLoader(this); 371 } 372 373 377 private void clearNotFoundCaches() { 378 this.notFoundResources.clear(); 379 this.notFoundClasses.clear(); 380 } 381 382 388 private URL findResource0(final URLEntry res, 389 final String name) { 390 391 Object result = 392 AccessController.doPrivileged(new PrivilegedAction () { 393 public Object run() { 394 395 if (res.isJar) { 396 397 try { 398 JarEntry jarEntry = res.zip.getJarEntry(name); 399 if (jarEntry != null) { 400 405 InternalURLStreamHandler handler = new InternalURLStreamHandler(res, name); 406 URI uri = new URI ("jar", res.source + "!/" + name, null ); 407 URL ret = new URL (uri.toURL(), "" , handler); 408 handler.tieUrl(ret); 409 return ret; 410 } 411 412 } catch (Throwable thr) { 413 _logger.log(Level.INFO, 414 "loader.excep_in_ejbclassloader",thr); 415 } 416 } else { try { 418 File resourceFile = 419 new File (res.file.getCanonicalPath() 420 + File.separator + name); 421 422 if (resourceFile.exists()) { 423 return resourceFile.toURL(); 426 } 427 428 } catch (IOException e) { 429 _logger.log(Level.INFO, 430 "loader.excep_in_ejbclassloader",e); 431 } 432 } 433 434 return null; 435 436 } }); 438 439 return (URL ) result; 440 } 441 442 public URL findResource(String name) { 443 444 if( doneCalled ) { 445 _logger.log(Level.WARNING, 446 formatMsg("loader.ejbclassloader_find_resource_after_done", name, this.toString()), 447 new Throwable ()); 448 return null; 449 } 450 451 String nf = (String ) notFoundResources.get(name); 453 if (nf != null && nf.equals(name) ) { 454 return null; 455 } 456 457 int i = 0; 458 while (i < this.urlSet.size()) { 459 460 URLEntry u = (URLEntry) this.urlSet.get(i); 461 462 if (!u.hasItem(name)) { 463 i++; 464 continue; 465 } 466 467 URL url = findResource0(u, name); 468 if (url != null) return url; 469 i++; 470 } 471 472 notFoundResources.put(name, name); 474 475 return null; 476 } 477 478 482 public Enumeration <URL > findResources(String name) throws IOException { 483 if( doneCalled ) { 484 _logger.log(Level.WARNING, 485 "loader.ejbclassloader_done_already_called", 486 new Object [] { name, doneSnapshot }); 487 return null; 488 } 489 490 String nf = (String ) notFoundResources.get(name); 492 if (nf != null && nf.equals(name) ) { 493 return null; 494 } 495 496 List <URL > resourcesList = new ArrayList <URL >(); 497 498 for (Iterator iter = this.urlSet.iterator(); iter.hasNext();) { 499 URLEntry urlEntry = (URLEntry) iter.next(); 500 URL url = findResource0(urlEntry, name); 501 if (url != null) { 502 resourcesList.add(url); 503 } 504 } 505 506 if (resourcesList.size() == 0) { 507 notFoundResources.put(name, name); 509 } 510 511 return (new Vector (resourcesList)).elements(); 512 } 513 514 515 516 524 private void checkManifest(JarFile jar, File file) throws IOException { 525 526 if ( (jar == null) || (file == null) ) return; 527 528 Manifest man = jar.getManifest(); 529 if (man == null) return; 530 531 synchronized (this) { 532 String cp = man.getMainAttributes().getValue( 533 Attributes.Name.CLASS_PATH); 534 if (cp == null) return; 535 536 StringTokenizer st = new StringTokenizer (cp, " "); 537 538 while (st.hasMoreTokens()) { 539 String entry = st.nextToken(); 540 541 File newFile = new File (file.getParentFile(), entry); 542 543 try { 545 appendURL(newFile); 546 } catch (MalformedURLException ex) { 547 _logger.log(Level.SEVERE, 548 "loader.ejbclassloader_malformed_url",ex); 549 } 550 } 551 } 552 } 553 554 560 private byte[] loadClassData0(final URLEntry res, final String entryName) { 561 562 Object result = 563 AccessController.doPrivileged(new PrivilegedAction () { 564 public Object run() { 565 InputStream classStream = null; 566 try { 567 568 if (res.isJar) { JarFile zip = res.zip; 570 JarEntry entry = zip.getJarEntry(entryName); 571 if (entry != null) { 572 classStream = zip.getInputStream(entry); 573 byte[] classData = getClassData(classStream); 574 res.setProtectionDomain(EJBClassLoader.this, entry.getCertificates()); 575 return classData; 576 } 577 } else { File classFile = new File (res.file, 579 entryName.replace('/', File.separatorChar)); 580 581 if (classFile.exists()) { 582 try { 583 classStream = new FileInputStream (classFile); 584 byte[] classData = getClassData(classStream); 585 res.setProtectionDomain(EJBClassLoader.this, null); 586 return classData; 587 } finally { 588 593 if (classStream != null) { 594 try { 595 classStream.close(); 596 } catch (IOException closeIOE) { 597 _logger.log(Level.INFO, "loader.excep_in_ejbclassloader", closeIOE); 598 } 599 } 600 } 601 } 602 } 603 } catch (IOException ioe) { 604 _logger.log(Level.INFO, 605 "loader.excep_in_ejbclassloader", ioe); 606 } 607 return null; 608 } 609 }); 610 return (byte[]) result; 611 } 612 613 protected Class findClass(String name) throws ClassNotFoundException { 614 ClassData classData = findClassData(name); 615 if (PreprocessorUtil.isPreprocessorEnabled()) { 617 String entryName = name.replace('.', '/') + ".class"; 619 classData.classBytes = PreprocessorUtil.processClass(entryName, classData.classBytes); 620 } 621 622 int lastPackageSep = name.lastIndexOf('.'); 624 if ( lastPackageSep != -1 ) { 625 String packageName = name.substring(0, lastPackageSep); 626 if( getPackage(packageName) == null ) { 627 try { 628 629 definePackage(packageName, null, null, null, 641 null, null, null, null); 642 } catch(IllegalArgumentException iae) { 643 _logger.log(Level.FINE, "duplicate package " + 646 "definition attempt for " + packageName, iae); 647 } 648 } 649 } 650 651 try { 653 ArrayList <ClassTransformer> xformers = (ArrayList <ClassTransformer>) transformers.clone(); 654 for (ClassTransformer transformer : xformers) { 655 656 String internalClassName = name.replace('.','/'); 660 byte[] transformedBytes = transformer.transform(this, internalClassName, null, 661 classData.pd, classData.classBytes); 662 if(transformedBytes!=null){ _logger.logp(Level.INFO, "EJBClassLoader", 664 "findClass", "{0} actually got transformed", 665 name); 666 classData.classBytes = transformedBytes; 667 } 668 } 669 } catch (IllegalClassFormatException icfEx) { 670 throw new ClassNotFoundException (icfEx.toString(), icfEx); 671 } 672 Class clazz = null; 673 try { 674 clazz = defineClass(name, classData.classBytes, 0, classData.classBytes.length, classData.pd); 675 return clazz; 676 } catch (UnsupportedClassVersionError ucve) { 677 throw new UnsupportedClassVersionError ( 678 sm.getString("ejbClassLoader.unsupportedVersion", name, 679 System.getProperty("java.version"))); 680 } 681 } 682 683 691 protected ClassData findClassData(String name) throws ClassNotFoundException { 692 693 if( doneCalled ) { 694 _logger.log(Level.WARNING, 695 formatMsg("loader.ejbclassloader_find_class_after_done", name, this.toString()), new Throwable ()); 696 throw new ClassNotFoundException (name); 697 } 698 699 String nf = (String ) notFoundClasses.get(name); 700 if (nf != null && nf.equals(name) ) { 701 throw new ClassNotFoundException (name); 702 } 703 704 String entryName = name.replace('.', '/') + ".class"; 706 707 int i = 0; 708 while (i < urlSet.size()) { 709 URLEntry u = (URLEntry) this.urlSet.get(i); 710 711 if (!u.hasItem(entryName)) { 712 i++; 713 continue; 714 } 715 716 byte[] result = loadClassData0(u, entryName); 717 if (result != null) return new ClassData(result, u.pd); 718 i++; 719 } 720 721 notFoundClasses.put(name, name); 723 724 throw new ClassNotFoundException (name); 725 } 726 727 734 private byte[] getClassData(InputStream istream) throws IOException { 735 736 BufferedInputStream bstream = new BufferedInputStream (istream);; 737 byte[] buf = new byte[4096]; 738 ByteArrayOutputStream bout = new ByteArrayOutputStream (); 739 int num = 0; 740 try { 741 while( (num = bstream.read(buf)) != -1) { 742 bout.write(buf, 0, num); 743 } 744 } finally { 745 if (bstream != null) { 746 try { 747 bstream.close(); 748 } catch (IOException closeIOE) { 749 EJBClassLoader._logger.log(Level.INFO, "loader.excep_in_ejbclassloader", closeIOE); 750 } 751 } 752 } 753 754 return bout.toByteArray(); 755 } 756 757 762 public String toString() { 763 764 StringBuffer buffer = new StringBuffer (); 765 766 buffer.append("EJBClassLoader : \n"); 767 if( doneCalled ) { 768 buffer.append("doneCalled = true" + "\n"); 769 if( doneSnapshot != null ) { 770 buffer.append("doneSnapshot = " + doneSnapshot); 771 } 772 } else { 773 buffer.append("urlSet = " + this.urlSet + "\n"); 774 buffer.append("doneCalled = false " + "\n"); 775 } 776 buffer.append(" Parent -> " + getParent() + "\n"); 777 778 return buffer.toString(); 779 } 780 781 public InputStream getResourceAsStream(final String name) { 782 InputStream stream = super.getResourceAsStream(name); 783 786 if (stream != null) { 787 if (! (stream instanceof SentinelInputStream)) { 788 stream = new SentinelInputStream(stream); 789 } 790 } 791 return stream; 792 } 793 794 801 private static String formatMsg(String key, Object ... args) { 802 String fmt = _logger.getResourceBundle().getString(key); 803 return MessageFormat.format(fmt, args); 804 } 805 806 815 private static class ProtectedJarFile extends JarFile { 816 822 public ProtectedJarFile(File file) throws IOException { 823 super(file); 824 } 825 826 831 public void close() { 832 _logger.log(Level.WARNING, "Illegal call to close() detected", new Throwable ()); 834 } 835 836 841 public void reallyClose() throws IOException { 842 super.close(); 843 } 844 845 848 protected void finalize() throws IOException { 849 reallyClose(); 850 } 851 } 852 853 856 protected static class URLEntry { 857 858 859 URL source = null; 860 861 862 File file = null; 863 864 865 ProtectedJarFile zip = null; 866 867 868 boolean isJar = false; 869 870 Hashtable <String ,String > table = null; 871 872 873 ProtectionDomain pd = null; 874 875 URLEntry(URL url) { 876 source = url; 877 } 878 879 void init() throws IOException { 880 try { 881 file = new File (source.toURI()); 882 isJar = file.isFile(); 883 884 if (isJar) { 885 zip = new ProtectedJarFile(file); 886 } 887 888 table = new Hashtable <String ,String >(); 889 } catch (URISyntaxException use) { 891 IOException ioe= new IOException (); 892 ioe.initCause(use); 893 throw ioe; 894 } 895 } 896 897 private void cacheItems() throws IOException { 898 if (isJar) { 899 for (Enumeration e = zip.entries(); e.hasMoreElements(); ) { 901 ZipEntry curEntry = (ZipEntry ) e.nextElement(); 902 table.put(curEntry.getName(), curEntry.getName()); 903 } 904 905 } else { 906 if (file.exists()) { 908 fillTable(file, table, ""); 909 } 910 } 911 } 912 913 private void fillTable(File f, Hashtable t, String parent) throws IOException { 914 915 String localName = (parent.equals("")) ? "" : parent + "/"; 916 917 File [] children = f.listFiles(); 918 for (int i = 0; i < children.length; i++) { 919 processFile(children[i], t, localName); 920 } 921 } 922 923 935 private void processFile(File fileToProcess, Hashtable t, String parentLocalName) throws IOException { 936 String key = parentLocalName + fileToProcess.getName(); 937 if (fileToProcess.isFile()) { 938 t.put(key, key); 939 } else if (fileToProcess.isDirectory()) { 940 fillTable(fileToProcess, t, key); 941 } 942 } 943 944 945 boolean hasItem(String item) { 946 if (table.size() == 0) { 949 return true; 950 } 951 952 960 boolean result = false; 961 String target = item; 962 if (item.startsWith("./")) { 964 target = item.substring(2, item.length()); 965 } 966 967 result = table.containsKey(target); 968 if ( ! result && ! isJar) { 969 974 File targetFile = privilegedCheckForFile(target); 975 if (targetFile != null) { 976 try { 977 processFile(targetFile, table, ""); 978 result = true; 979 } catch (IOException ioe) { 980 _logger.log(Level.SEVERE, formatMsg("loader.ejbclassloader_error_processing_file", target, file.getAbsolutePath()), ioe); 981 return false; 982 } 983 } 984 } 985 return result; 986 } 987 988 997 private File privilegedCheckForFile(final String targetPath) { 998 1003 try { 1004 File result = (File ) AccessController.doPrivileged(new PrivilegedExceptionAction () { 1005 public Object run() throws Exception { 1006 1007 File targetFile = new File (file, targetPath); 1008 if ( ! targetFile.exists()) { 1009 targetFile = null; 1010 } 1011 return targetFile; 1012 } 1013 }); 1014 1015 return result; 1016 1017 } catch (PrivilegedActionException pae) { 1018 1021 _logger.log(Level.SEVERE, formatMsg("loader.ejbclassloader_error_checking_existence", targetPath, file.getAbsolutePath()), pae.getCause()); 1022 return null; 1023 } 1024 } 1025 1026 1031 public void setProtectionDomain (ClassLoader ejbClassLoader, Certificate [] signers) throws MalformedURLException { 1032 if (pd == null) { 1033 pd = new ProtectionDomain (new CodeSource (file.toURL(),signers),null, ejbClassLoader, null ); 1034 } 1035 } 1036 1037 public String toString() { 1038 return "URLEntry : " + source.toString(); 1039 } 1040 1041 1047 public boolean equals(Object obj) { 1048 1049 boolean tf = false; 1050 1051 if (obj instanceof URLEntry) { 1052 URLEntry e = (URLEntry) obj; 1053 if (source.equals(e.source)) { 1054 tf = true; 1055 } 1056 } 1057 1058 return tf; 1059 } 1060 1061 1064 public int hashCode() { 1065 return source.hashCode(); 1066 } 1067 1068 } 1069 1070 1074 private Vector <SentinelInputStream> getStreams() { 1075 if (streams == null) { 1076 streams = new Vector <SentinelInputStream>(); 1077 } 1078 return streams; 1079 } 1080 1081 1087 private void closeOpenStreams() { 1088 if (streams != null) { 1089 1090 SentinelInputStream[] toClose = streams.toArray(new SentinelInputStream[streams.size()]); 1091 for (SentinelInputStream s : toClose) { 1092 try { 1093 s.closeWithWarning(); 1094 } catch (IOException ioe) { 1095 _logger.log(Level.WARNING, "loader.ejbclassloader_error_closing_stream", ioe); 1096 } 1097 } 1098 streams.clear(); 1099 streams = null; 1100 } 1101 } 1102 1103 1110 protected class SentinelInputStream extends FilterInputStream { 1111 private boolean closed; private final Throwable throwable; 1113 1114 1121 protected SentinelInputStream(final InputStream in) { 1122 super(in); 1123 throwable = new Throwable (); 1124 getStreams().add(this); 1125 } 1126 1127 1130 public void close() throws IOException { 1131 _close(); 1132 } 1133 1134 1138 protected void finalize() throws Throwable { 1139 if (!closed && this.in != null){ 1140 try { 1141 in.close(); 1142 } 1143 catch (IOException ignored){ 1144 } 1146 report(); 1148 } 1149 super.finalize(); 1150 } 1151 1152 private void _close() throws IOException { 1153 closed = true; 1154 getStreams().remove(this); 1155 super.close(); 1156 } 1157 1158 private void closeWithWarning() throws IOException { 1159 _close(); 1160 report(); 1161 } 1162 1163 1166 private void report(){ 1167 _logger.log(Level.WARNING, "Input stream has been finalized or forced closed without being explicitly closed; stream instantiation reported in following stack trace", this.throwable); 1168 } 1169 } 1170 1177 private class InternalJarURLConnection extends JarURLConnection { 1178 private URL mURL; 1179 private URLEntry mRes; 1180 private String mName; 1181 1182 1190 public InternalJarURLConnection(URL url, URLEntry res, String name) 1191 throws MalformedURLException { 1192 super(url); 1193 mRes = res; 1194 mName = name; 1195 } 1196 1197 1200 public JarFile getJarFile() throws IOException { 1201 return mRes.zip; 1202 } 1203 1204 1207 public void connect() throws IOException { 1208 } 1210 1211 1214 public InputStream getInputStream() throws IOException { 1215 ZipEntry entry = mRes.zip.getEntry(mName); 1216 return new SentinelInputStream(mRes.zip.getInputStream(entry)); 1217 } 1218 } 1219 1220 1229 private class InternalURLStreamHandler extends URLStreamHandler { 1230 private URL mURL; 1231 private URLEntry mRes; 1232 private String mName; 1233 1234 1240 public InternalURLStreamHandler(URLEntry res, String name) { 1241 mRes = res; 1242 mName = name; 1243 } 1244 1245 1248 protected URLConnection openConnection(URL u) throws IOException { 1249 if (u != mURL) { throw new IOException ("Cannot open a foreign URL; this.url=" + mURL 1252 + "; foreign.url=" + u); 1253 } 1254 return new InternalJarURLConnection(u, mRes, mName); 1255 } 1256 1257 1264 public void tieUrl(URL url) { 1265 mURL = url; 1266 } 1267 } 1268 1269 1273 private static class ClassData { 1274 protected byte[] classBytes; 1275 protected ProtectionDomain pd; 1276 1277 ClassData(byte[] classData, ProtectionDomain pd) { 1278 this.classBytes = classData; 1279 this.pd = pd; 1280 } 1281 } 1282 1283 1293 private static class DelegatingClassLoader extends SecureClassLoader { 1294 1295 1298 private EJBClassLoader delegate = null; 1299 1300 1307 DelegatingClassLoader(EJBClassLoader applicationCL) { 1308 super(applicationCL.getParent()); this.delegate = applicationCL; 1310 } 1311 1312 1316 protected Class findClass(String name) throws ClassNotFoundException { 1317 ClassData classData = delegate.findClassData(name); 1318 int lastPackageSep = name.lastIndexOf('.'); 1320 if ( lastPackageSep != -1 ) { 1321 String packageName = name.substring(0, lastPackageSep); 1322 if( getPackage(packageName) == null ) { 1323 try { 1324 definePackage(packageName, null, null, null, 1336 null, null, null, null); 1337 } catch(IllegalArgumentException iae) { 1338 _logger.log(Level.FINE, "duplicate package " + 1341 "definition attempt for " + packageName, iae); 1342 } 1343 } 1344 } 1345 Class clazz = null; 1346 try { 1347 clazz = defineClass(name, classData.classBytes, 0, classData.classBytes.length, classData.pd); 1348 return clazz; 1349 } catch (UnsupportedClassVersionError ucve) { 1350 throw new UnsupportedClassVersionError ( 1351 sm.getString("ejbClassLoader.unsupportedVersion", name, 1352 System.getProperty("java.version"))); 1353 } 1354 } 1355 1356 protected URL findResource(String name) { 1357 return delegate.findResource(name); 1358 } 1359 1360 protected Enumeration <URL > findResources(String name) throws IOException { 1361 return delegate.findResources(name); 1362 } 1363 1364 } 1365 1366 1367} 1368 | Popular Tags |