1:
38:
39:
40: package ;
41:
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68:
69:
126: public class URLClassLoader extends SecureClassLoader
127: {
128:
129:
130:
136: private static HashMap urlloaders = new HashMap();
137:
138:
143: private static HashMap factoryCache = new HashMap(5);
144:
145:
146:
147:
148: private final Vector urls = new Vector();
149:
150:
156: private final Vector urlinfos = new Vector();
157:
158:
159: private final URLStreamHandlerFactory factory;
160:
161:
166: private final AccessControlContext securityContext;
167:
168:
169:
170:
174: abstract static class URLLoader
175: {
176:
179: final URLClassLoader classloader;
180:
181:
184: final URL baseURL;
185:
186:
193: final CodeSource noCertCodeSource;
194:
195: URLLoader(URLClassLoader classloader, URL baseURL)
196: {
197: this(classloader, baseURL, baseURL);
198: }
199:
200: URLLoader(URLClassLoader classloader, URL baseURL, URL overrideURL)
201: {
202: this.classloader = classloader;
203: this.baseURL = baseURL;
204: this.noCertCodeSource = new CodeSource(overrideURL, null);
205: }
206:
207:
213: Class getClass(String className)
214: {
215: return null;
216: }
217:
218:
223: abstract Resource getResource(String s);
224:
225:
230: Manifest getManifest()
231: {
232: return null;
233: }
234:
235: Vector getClassPath()
236: {
237: return null;
238: }
239: }
240:
241:
248: abstract static class Resource
249: {
250: final URLLoader loader;
251:
252: Resource(URLLoader loader)
253: {
254: this.loader = loader;
255: }
256:
257:
261: CodeSource getCodeSource()
262: {
263: Certificate[] certs = getCertificates();
264: if (certs == null)
265: return loader.noCertCodeSource;
266: else
267: return new CodeSource(loader.baseURL, certs);
268: }
269:
270:
274: Certificate[] getCertificates()
275: {
276: return null;
277: }
278:
279:
282: abstract URL getURL();
283:
284:
288: abstract int getLength();
289:
290:
294: abstract InputStream getInputStream() throws IOException;
295: }
296:
297:
301: static final class JarURLLoader extends URLLoader
302: {
303: final JarFile jarfile;
304: final URL baseJarURL;
305:
306: Vector classPath;
307:
308: public JarURLLoader(URLClassLoader classloader, URL baseURL,
309: URL absoluteUrl)
310: {
311: super(classloader, baseURL, absoluteUrl);
312:
313:
314: String external = baseURL.toExternalForm();
315: StringBuffer sb = new StringBuffer(external.length() + 6);
316: sb.append("jar:");
317: sb.append(external);
318: sb.append("!/");
319: String jarURL = sb.toString();
320:
321: this.classPath = null;
322: URL baseJarURL = null;
323: JarFile jarfile = null;
324: try
325: {
326: baseJarURL =
327: new URL(null, jarURL, classloader.getURLStreamHandler("jar"));
328:
329: jarfile =
330: ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
331:
332: Manifest manifest;
333: Attributes attributes;
334: String classPathString;
335:
336: if ((manifest = jarfile.getManifest()) != null
337: && (attributes = manifest.getMainAttributes()) != null
338: && ((classPathString
339: = attributes.getValue(Attributes.Name.CLASS_PATH))
340: != null))
341: {
342: this.classPath = new Vector();
343:
344: StringTokenizer st = new StringTokenizer(classPathString, " ");
345: while (st.hasMoreElements ())
346: {
347: String e = st.nextToken ();
348: try
349: {
350: URL url = new URL(baseURL, e);
351: this.classPath.add(url);
352: }
353: catch (java.net.MalformedURLException xx)
354: {
355:
356: }
357: }
358: }
359: }
360: catch (IOException ioe)
361: {
362:
363: }
364:
365: this.baseJarURL = baseJarURL;
366: this.jarfile = jarfile;
367: }
368:
369:
370: Resource getResource(String name)
371: {
372: if (jarfile == null)
373: return null;
374:
375: if (name.startsWith("/"))
376: name = name.substring(1);
377:
378: JarEntry je = jarfile.getJarEntry(name);
379: if (je != null)
380: return new JarURLResource(this, name, je);
381: else
382: return null;
383: }
384:
385: Manifest getManifest()
386: {
387: try
388: {
389: return (jarfile == null) ? null : jarfile.getManifest();
390: }
391: catch (IOException ioe)
392: {
393: return null;
394: }
395: }
396:
397: Vector getClassPath()
398: {
399: return classPath;
400: }
401: }
402:
403: static final class JarURLResource extends Resource
404: {
405: private final JarEntry entry;
406: private final String name;
407:
408: JarURLResource(JarURLLoader loader, String name, JarEntry entry)
409: {
410: super(loader);
411: this.entry = entry;
412: this.name = name;
413: }
414:
415: InputStream getInputStream() throws IOException
416: {
417: return ((JarURLLoader) loader).jarfile.getInputStream(entry);
418: }
419:
420: int getLength()
421: {
422: return (int) entry.getSize();
423: }
424:
425: Certificate[] getCertificates()
426: {
427:
428:
429:
430: return ((JarEntry) ((JarURLLoader) loader).jarfile.getEntry(name))
431: .getCertificates();
432: }
433:
434: URL getURL()
435: {
436: try
437: {
438: return new URL(((JarURLLoader) loader).baseJarURL, name,
439: loader.classloader.getURLStreamHandler("jar"));
440: }
441: catch (MalformedURLException e)
442: {
443: InternalError ie = new InternalError();
444: ie.initCause(e);
445: throw ie;
446: }
447: }
448: }
449:
450:
453: static final class RemoteURLLoader extends URLLoader
454: {
455: private final String protocol;
456:
457: RemoteURLLoader(URLClassLoader classloader, URL url)
458: {
459: super(classloader, url);
460: protocol = url.getProtocol();
461: }
462:
463:
467: Resource getResource(String name)
468: {
469: try
470: {
471: URL url =
472: new URL(baseURL, name, classloader.getURLStreamHandler(protocol));
473: URLConnection connection = url.openConnection();
474:
475:
476:
477: int length = connection.getContentLength();
478: InputStream stream = connection.getInputStream();
479:
480:
481: if (connection instanceof HttpURLConnection)
482: {
483: int response =
484: ((HttpURLConnection) connection).getResponseCode();
485: if (response / 100 != 2)
486: return null;
487: }
488:
489: if (stream != null)
490: return new RemoteResource(this, name, url, stream, length);
491: else
492: return null;
493: }
494: catch (IOException ioe)
495: {
496: return null;
497: }
498: }
499: }
500:
501:
504: static final class RemoteResource extends Resource
505: {
506: private final URL url;
507: private final InputStream stream;
508: private final int length;
509:
510: RemoteResource(RemoteURLLoader loader, String name, URL url,
511: InputStream stream, int length)
512: {
513: super(loader);
514: this.url = url;
515: this.stream = stream;
516: this.length = length;
517: }
518:
519: InputStream getInputStream() throws IOException
520: {
521: return stream;
522: }
523:
524: public int getLength()
525: {
526: return length;
527: }
528:
529: public URL getURL()
530: {
531: return url;
532: }
533: }
534:
535:
539: final static class SoURLLoader extends URLLoader
540: {
541: SharedLibHelper helper;
542:
543: SoURLLoader(URLClassLoader classloader, URL url)
544: {
545: this(classloader, url, url);
546: }
547:
548: SoURLLoader(URLClassLoader classloader, URL url, URL overrideURL)
549: {
550: super(classloader, url, overrideURL);
551: helper = SharedLibHelper.findHelper(classloader, url.getFile(),
552: noCertCodeSource, true);
553: }
554:
555: Class getClass(String className)
556: {
557: return helper.findClass(className);
558: }
559:
560: Resource getResource(String name)
561: {
562: URL url = helper.findResource(name);
563: if (url == null)
564: return null;
565: return new SoResource(this, url);
566: }
567: }
568:
569: final static class SoResource extends Resource
570: {
571: SoResource(SoURLLoader loader, URL url)
572: {
573: super(loader);
574: this.url = url;
575: }
576:
577: InputStream getInputStream() throws IOException
578: {
579: URLConnection conn = url.openConnection();
580: return conn.getInputStream();
581: }
582:
583: public int getLength()
584: {
585:
586: return -1;
587: }
588:
589: public URL getURL ()
590: {
591: return url;
592: }
593:
594: final URL url;
595: }
596:
597:
601: static final class FileURLLoader extends URLLoader
602: {
603: File dir;
604:
605: FileURLLoader(URLClassLoader classloader, URL url, URL absoluteUrl)
606: {
607: super(classloader, url, absoluteUrl);
608: dir = new File(absoluteUrl.getFile());
609: }
610:
611:
612: Resource getResource(String name)
613: {
614: try
615: {
616: File file = new File(dir, name).getCanonicalFile();
617: if (file.exists() && !file.isDirectory())
618: return new FileResource(this, file);
619: }
620: catch (IOException e)
621: {
622:
623: }
624: return null;
625: }
626: }
627:
628: static final class FileResource extends Resource
629: {
630: final File file;
631:
632: FileResource(FileURLLoader loader, File file)
633: {
634: super(loader);
635: this.file = file;
636: }
637:
638: InputStream getInputStream() throws IOException
639: {
640:
641:
642: if (file.isDirectory())
643: {
644: URL url = getURL();
645: return url.openStream();
646: }
647:
648: return new FileInputStream(file);
649: }
650:
651: public int getLength()
652: {
653:
654:
655:
656: if (file.isDirectory())
657: {
658: URL url = getURL();
659: try
660: {
661: URLConnection connection = url.openConnection();
662: return connection.getContentLength();
663: }
664: catch (IOException e)
665: {
666: return -1;
667: }
668: }
669:
670: return (int) file.length();
671: }
672:
673: public URL getURL()
674: {
675: try
676: {
677: return file.toURL();
678: }
679: catch (MalformedURLException e)
680: {
681: InternalError ie = new InternalError();
682: ie.initCause(e);
683: throw ie;
684: }
685: }
686: }
687:
688:
692: static final class CoreURLLoader extends URLLoader
693: {
694: private String dir;
695:
696: CoreURLLoader(URLClassLoader classloader, URL url)
697: {
698: super(classloader, url);
699: dir = baseURL.getFile();
700: }
701:
702:
703: Resource getResource(String name)
704: {
705: Core core = Core.find (dir + name);
706: if (core != null)
707: return new CoreResource(this, name, core);
708: return null;
709: }
710: }
711:
712: static final class CoreResource extends Resource
713: {
714: private final Core core;
715: private final String name;
716:
717: CoreResource(CoreURLLoader loader, String name, Core core)
718: {
719: super(loader);
720: this.core = core;
721: this.name = name;
722: }
723:
724: InputStream getInputStream() throws IOException
725: {
726: return new CoreInputStream(core);
727: }
728:
729: public int getLength()
730: {
731: return core.length;
732: }
733:
734: public URL getURL()
735: {
736: try
737: {
738: return new URL(loader.baseURL, name,
739: loader.classloader.getURLStreamHandler("core"));
740: }
741: catch (MalformedURLException e)
742: {
743: InternalError ie = new InternalError();
744: ie.initCause(e);
745: throw ie;
746: }
747: }
748: }
749:
750:
751:
752:
766: public URLClassLoader(URL[] urls) throws SecurityException
767: {
768: super();
769: this.factory = null;
770: this.securityContext = null;
771: addURLs(urls);
772: }
773:
774:
791: public URLClassLoader(URL[] urls, ClassLoader parent)
792: throws SecurityException
793: {
794: super(parent);
795: this.factory = null;
796: this.securityContext = null;
797: addURLs(urls);
798: }
799:
800:
801:
814: URLClassLoader(ClassLoader parent, AccessControlContext securityContext)
815: {
816: super(parent);
817: this.factory = null;
818: this.securityContext = securityContext;
819: }
820:
821:
840: public URLClassLoader(URL[] urls, ClassLoader parent,
841: URLStreamHandlerFactory factory)
842: throws SecurityException
843: {
844: super(parent);
845: this.securityContext = null;
846: this.factory = factory;
847: addURLs(urls);
848:
849:
850:
851:
852: synchronized (factoryCache)
853: {
854: if (factory != null && factoryCache.get(factory) == null)
855: factoryCache.put(factory, new HashMap(5));
856: }
857: }
858:
859:
860:
861:
865: protected void addURL(URL newUrl)
866: {
867: urls.add(newUrl);
868: addURLImpl(newUrl);
869: }
870:
871: private void addURLImpl(URL newUrl)
872: {
873: synchronized (this)
874: {
875: if (newUrl == null)
876: return;
877:
878:
879: thisString = null;
880:
881:
882:
883: URLLoader loader = (URLLoader) urlloaders.get(newUrl);
884: if (loader == null)
885: {
886: String file = newUrl.getFile();
887: String protocol = newUrl.getProtocol();
888:
889:
890:
891: URL absoluteURL;
892: if ("file".equals (protocol))
893: {
894: File dir = new File(file);
895: URL absUrl;
896: try
897: {
898: absoluteURL = dir.getCanonicalFile().toURL();
899: }
900: catch (IOException ignore)
901: {
902: try
903: {
904: absoluteURL = dir.getAbsoluteFile().toURL();
905: }
906: catch (MalformedURLException _)
907: {
908:
909: absoluteURL = newUrl;
910: }
911: }
912: }
913: else
914: {
915:
916:
917: absoluteURL = newUrl;
918: }
919:
920:
921: if ("gcjlib".equals(protocol))
922: loader = new SoURLLoader(this, newUrl);
923: else if (! (file.endsWith("/") || file.endsWith(File.separator)))
924: loader = new JarURLLoader(this, newUrl, absoluteURL);
925: else if ("file".equals(protocol))
926: loader = new FileURLLoader(this, newUrl, absoluteURL);
927: else if ("core".equals(protocol))
928: loader = new CoreURLLoader(this, newUrl);
929: else
930: loader = new RemoteURLLoader(this, newUrl);
931:
932:
933: urlloaders.put(newUrl, loader);
934: }
935:
936: urlinfos.add(loader);
937:
938: Vector extraUrls = loader.getClassPath();
939: if (extraUrls != null)
940: {
941: Iterator it = extraUrls.iterator();
942: while (it.hasNext())
943: {
944: URL url = (URL)it.next();
945: URLLoader extraLoader = (URLLoader) urlloaders.get(url);
946: if (! urlinfos.contains (extraLoader))
947: addURLImpl(url);
948: }
949: }
950:
951: }
952: }
953:
954:
963: private void addURLs(URL[] newUrls)
964: {
965: for (int i = 0; i < newUrls.length; i++)
966: {
967: urls.add(newUrls[i]);
968: addURLImpl(newUrls[i]);
969: }
970: }
971:
972:
976: private String getAttributeValue(Attributes.Name name, Attributes first,
977: Attributes second)
978: {
979: String result = null;
980: if (first != null)
981: result = first.getValue(name);
982: if (result == null)
983: result = second.getValue(name);
984: return result;
985: }
986:
987:
1002: protected Package definePackage(String name, Manifest manifest, URL url)
1003: throws IllegalArgumentException
1004: {
1005:
1006:
1007: StringBuffer xform = new StringBuffer(name);
1008: for (int i = xform.length () - 1; i >= 0; --i)
1009: if (xform.charAt(i) == '.')
1010: xform.setCharAt(i, '/');
1011: xform.append('/');
1012: String xformName = xform.toString();
1013:
1014: Attributes entryAttr = manifest.getAttributes(xformName);
1015: Attributes attr = manifest.getMainAttributes();
1016:
1017: String specTitle
1018: = getAttributeValue(Attributes.Name.SPECIFICATION_TITLE,
1019: entryAttr, attr);
1020: String specVersion
1021: = getAttributeValue(Attributes.Name.SPECIFICATION_VERSION,
1022: entryAttr, attr);
1023: String specVendor
1024: = getAttributeValue(Attributes.Name.SPECIFICATION_VENDOR,
1025: entryAttr, attr);
1026: String implTitle
1027: = getAttributeValue(Attributes.Name.IMPLEMENTATION_TITLE,
1028: entryAttr, attr);
1029: String implVersion
1030: = getAttributeValue(Attributes.Name.IMPLEMENTATION_VERSION,
1031: entryAttr, attr);
1032: String implVendor
1033: = getAttributeValue(Attributes.Name.IMPLEMENTATION_VENDOR,
1034: entryAttr, attr);
1035:
1036:
1037:
1038:
1039:
1040:
1041: String sealed = attr.getValue(Attributes.Name.SEALED);
1042: if ("false".equals(sealed))
1043:
1044: url = null;
1045:
1046: return definePackage(name,
1047: specTitle, specVendor, specVersion,
1048: implTitle, implVendor, implVersion,
1049: url);
1050: }
1051:
1052:
1061: protected Class findClass(final String className)
1062: throws ClassNotFoundException
1063: {
1064:
1065: String resourceName = className.replace('.', '/') + ".class";
1066: int max = urlinfos.size();
1067: Resource resource = null;
1068: for (int i = 0; i < max && resource == null; i++)
1069: {
1070: URLLoader loader = (URLLoader)urlinfos.elementAt(i);
1071: if (loader == null)
1072: continue;
1073:
1074: Class k = loader.getClass(className);
1075: if (k != null)
1076: return k;
1077:
1078: resource = loader.getResource(resourceName);
1079: }
1080: if (resource == null)
1081: {
1082: String message = className + " not found";
1083: if (runtimeInitialized())
1084: message += " in " + this;
1085: throw new ClassNotFoundException(message);
1086: }
1087:
1088:
1089:
1090: try
1091: {
1092: byte[] data;
1093: InputStream in = resource.getInputStream();
1094: try
1095: {
1096: int length = resource.getLength();
1097: if (length != -1)
1098: {
1099:
1100:
1101: data = new byte[length];
1102: int pos = 0;
1103: while (length - pos > 0)
1104: {
1105: int len = in.read(data, pos, length - pos);
1106: if (len == -1)
1107: throw new EOFException("Not enough data reading from: "
1108: + in);
1109: pos += len;
1110: }
1111: }
1112: else
1113: {
1114:
1115:
1116: ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
1117: byte[] b = new byte[4096];
1118: int l = 0;
1119: while (l != -1)
1120: {
1121: l = in.read(b);
1122: if (l != -1)
1123: out.write(b, 0, l);
1124: }
1125: data = out.toByteArray();
1126: }
1127: }
1128: finally
1129: {
1130: in.close();
1131: }
1132: final byte[] classData = data;
1133:
1134:
1135: final CodeSource source = resource.getCodeSource();
1136:
1137:
1138: String packageName = null;
1139: int lastDot = className.lastIndexOf('.');
1140: if (lastDot != -1)
1141: packageName = className.substring(0, lastDot);
1142:
1143: if (packageName != null && getPackage(packageName) == null)
1144: {
1145:
1146: Manifest manifest = resource.loader.getManifest();
1147: if (manifest == null)
1148: definePackage(packageName, null, null, null, null, null, null,
1149: null);
1150: else
1151: definePackage(packageName, manifest, resource.loader.baseURL);
1152: }
1153:
1154:
1155: SecurityManager sm = System.getSecurityManager();
1156: Class result = null;
1157: if (sm != null && securityContext != null)
1158: {
1159: result = (Class)AccessController.doPrivileged
1160: (new PrivilegedAction()
1161: {
1162: public Object run()
1163: {
1164: return defineClass(className, classData,
1165: 0, classData.length,
1166: source);
1167: }
1168: }, securityContext);
1169: }
1170: else
1171: result = defineClass(className, classData, 0, classData.length, source);
1172:
1173:
1174: Certificate[] resourceCertificates = resource.getCertificates();
1175: if(resourceCertificates != null)
1176: super.setSigners(result, resourceCertificates);
1177:
1178: return result;
1179: }
1180: catch (IOException ioe)
1181: {
1182: ClassNotFoundException cnfe;
1183: cnfe = new ClassNotFoundException(className + " not found in " + this);
1184: cnfe.initCause(ioe);
1185: throw cnfe;
1186: }
1187: }
1188:
1189:
1190: private String thisString;
1191:
1192:
1197: public String toString()
1198: {
1199: synchronized (this)
1200: {
1201: if (thisString == null)
1202: {
1203: StringBuffer sb = new StringBuffer();
1204: sb.append(this.getClass().getName());
1205: sb.append("{urls=[" );
1206: URL[] thisURLs = getURLs();
1207: for (int i = 0; i < thisURLs.length; i++)
1208: {
1209: sb.append(thisURLs[i]);
1210: if (i < thisURLs.length - 1)
1211: sb.append(',');
1212: }
1213: sb.append(']');
1214: sb.append(", parent=");
1215: sb.append(getParent());
1216: sb.append('}');
1217: thisString = sb.toString();
1218: }
1219: return thisString;
1220: }
1221: }
1222:
1223:
1230: private Resource findURLResource(String resourceName)
1231: {
1232: int max = urlinfos.size();
1233: for (int i = 0; i < max; i++)
1234: {
1235: URLLoader loader = (URLLoader) urlinfos.elementAt(i);
1236: if (loader == null)
1237: continue;
1238:
1239: Resource resource = loader.getResource(resourceName);
1240: if (resource != null)
1241: return resource;
1242: }
1243: return null;
1244: }
1245:
1246:
1252: public URL findResource(String resourceName)
1253: {
1254: Resource resource = findURLResource(resourceName);
1255: if (resource != null)
1256: return resource.getURL();
1257:
1258:
1259: return null;
1260: }
1261:
1262:
1269: URLStreamHandler getURLStreamHandler(String protocol)
1270: {
1271: if (factory == null)
1272: return null;
1273:
1274: URLStreamHandler handler;
1275: synchronized (factoryCache)
1276: {
1277:
1278: HashMap cache = (HashMap) factoryCache.get(factory);
1279: handler = (URLStreamHandler) cache.get(protocol);
1280: if (handler == null)
1281: {
1282:
1283: handler = factory.createURLStreamHandler(protocol);
1284: cache.put(protocol, handler);
1285: }
1286: }
1287: return handler;
1288: }
1289:
1290:
1299: public Enumeration findResources(String resourceName)
1300: throws IOException
1301: {
1302: Vector resources = new Vector();
1303: int max = urlinfos.size();
1304: for (int i = 0; i < max; i++)
1305: {
1306: URLLoader loader = (URLLoader) urlinfos.elementAt(i);
1307: Resource resource = loader.getResource(resourceName);
1308: if (resource != null)
1309: resources.add(resource.getURL());
1310: }
1311: return resources.elements();
1312: }
1313:
1314:
1334: protected PermissionCollection getPermissions(CodeSource source)
1335: {
1336:
1337:
1338:
1339: PermissionCollection permissions = super.getPermissions(source);
1340:
1341:
1342: URL url = source.getLocation();
1343: String protocol = url.getProtocol();
1344: if (protocol.equals("file"))
1345: {
1346: String file = url.getFile();
1347:
1348:
1349: if (file.endsWith("/") || file.endsWith(File.separator))
1350: {
1351:
1352:
1353: permissions.add(new FilePermission(file + "-", "read"));
1354: }
1355: else
1356: {
1357:
1358:
1359: permissions.add(new FilePermission(file, "read"));
1360: }
1361: }
1362: else
1363: {
1364:
1365: String host = url.getHost();
1366: if (host != null)
1367: permissions.add(new SocketPermission(host, "connect,accept"));
1368: }
1369:
1370: return permissions;
1371: }
1372:
1373:
1379: public URL[] getURLs()
1380: {
1381: return (URL[]) urls.toArray(new URL[urls.size()]);
1382: }
1383:
1384:
1397: public static URLClassLoader newInstance(URL[] urls)
1398: throws SecurityException
1399: {
1400: return newInstance(urls, null);
1401: }
1402:
1403:
1417: public static URLClassLoader newInstance(URL[] urls, final ClassLoader parent)
1418: throws SecurityException
1419: {
1420: SecurityManager sm = System.getSecurityManager();
1421: if (sm == null)
1422: return new URLClassLoader(urls, parent);
1423: else
1424: {
1425: final Object securityContext = sm.getSecurityContext();
1426:
1427:
1428: if (! (securityContext instanceof AccessControlContext))
1429: throw new SecurityException("securityContext must be AccessControlContext: "
1430: + securityContext);
1431:
1432: URLClassLoader loader =
1433: (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction()
1434: {
1435: public Object run()
1436: {
1437: return new URLClassLoader(parent,
1438: (AccessControlContext) securityContext);
1439: }
1440: });
1441: loader.addURLs(urls);
1442: return loader;
1443: }
1444: }
1445:
1446:
1451: private static native boolean runtimeInitialized();
1452: }