Source Code Cross Referenced for DynamicClassLoader.java in  » EJB-Server-resin-3.1.5 » resin » com » caucho » loader » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server resin 3.1.5 » resin » com.caucho.loader 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003:         *
0004:         * This file is part of Resin(R) Open Source
0005:         *
0006:         * Each copy or derived work must preserve the copyright notice and this
0007:         * notice unmodified.
0008:         *
0009:         * Resin Open Source is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * Resin Open Source is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
0018:         * details.
0019:         *
0020:         * You should have received a copy of the GNU General Public License
0021:         * along with Resin Open Source; if not, write to the
0022:         *
0023:         *   Free Software Foundation, Inc.
0024:         *   59 Temple Place, Suite 330
0025:         *   Boston, MA 02111-1307  USA
0026:         *
0027:         * @author Scott Ferguson
0028:         */
0029:
0030:        package com.caucho.loader;
0031:
0032:        import com.caucho.config.ConfigException;
0033:        import com.caucho.lifecycle.Lifecycle;
0034:        import com.caucho.loader.enhancer.ByteCodeEnhancer;
0035:        import com.caucho.loader.enhancer.EnhancerRuntimeException;
0036:        import com.caucho.make.AlwaysModified;
0037:        import com.caucho.make.DependencyContainer;
0038:        import com.caucho.make.Make;
0039:        import com.caucho.make.MakeContainer;
0040:        import com.caucho.management.server.*;
0041:        import com.caucho.server.util.CauchoSystem;
0042:        import com.caucho.util.ByteBuffer;
0043:        import com.caucho.util.L10N;
0044:        import com.caucho.util.TimedCache;
0045:        import com.caucho.vfs.Dependency;
0046:        import com.caucho.vfs.JarPath;
0047:        import com.caucho.vfs.Path;
0048:        import com.caucho.vfs.ReadStream;
0049:
0050:        import javax.annotation.PostConstruct;
0051:        import java.io.FilePermission;
0052:        import java.io.IOException;
0053:        import java.io.InputStream;
0054:        import java.net.*;
0055:        import java.security.*;
0056:        import java.lang.instrument.*;
0057:        import java.util.ArrayList;
0058:        import java.util.Enumeration;
0059:        import java.util.Hashtable;
0060:        import java.util.Vector;
0061:        import java.util.jar.Attributes;
0062:        import java.util.jar.Manifest;
0063:        import java.util.logging.Level;
0064:        import java.util.logging.Logger;
0065:        import java.util.regex.Pattern;
0066:
0067:        /**
0068:         * Class loader which checks for changes in class files and automatically
0069:         * picks up new jars.
0070:         *
0071:         * <p>DynamicClassLoaders can be chained creating one virtual class loader.
0072:         * From the perspective of the JDK, it's all one classloader.  Internally,
0073:         * the class loader chain searches like a classpath.
0074:         */
0075:        public class DynamicClassLoader extends java.net.URLClassLoader
0076:                implements  Dependency, Make, DynamicClassLoaderMXBean {
0077:            private static L10N _L;
0078:            private static Logger _log;
0079:
0080:            private final static URL NULL_URL;
0081:            private final static URL[] NULL_URL_ARRAY = new URL[0];
0082:
0083:            private static long _globalDependencyCheckInterval = 2000L;
0084:            private static boolean _isJarCacheEnabled;
0085:
0086:            private String _id;
0087:
0088:            private final boolean _isVerbose;
0089:            private int _verboseDepth;
0090:
0091:            // List of resource loaders
0092:            private ArrayList<Loader> _loaders = new ArrayList<Loader>();
0093:
0094:            private JarLoader _jarLoader;
0095:            private PathLoader _pathLoader;
0096:
0097:            private ArrayList<Path> _nativePath = new ArrayList<Path>();
0098:
0099:            // List of cached classes
0100:            private Hashtable<String, ClassEntry> _entryCache;
0101:
0102:            private TimedCache<String, URL> _resourceCache;
0103:
0104:            // Dependencies
0105:            private DependencyContainer _dependencies = new DependencyContainer();
0106:            private boolean _isEnableDependencyCheck = false;
0107:
0108:            // Makes
0109:            private MakeContainer _makeList;
0110:
0111:            // If true, use the servlet spec's hack to give the parent priority
0112:            // for some classes, but the child priority for other classes.
0113:            private boolean _useServletHack;
0114:
0115:            // List of packages where the parent has priority.
0116:            private String[] _parentPriorityPackages;
0117:
0118:            // List of packages where this has priority.
0119:            private String[] _priorityPackages;
0120:
0121:            // Array of listeners
0122:            // XXX: There's still some questions of what kind of reference this
0123:            // should be.  It either needs to be a WeakReference or
0124:            // a normal reference.  Anything in between makes no sense.
0125:            //
0126:            // server/10w3 indicates that it needs to be a regular reference
0127:            private ArrayList<ClassLoaderListener> _listeners;
0128:
0129:            // The security manager for the loader
0130:            private SecurityManager _securityManager;
0131:
0132:            // List of permissions allowed in this context
0133:            private ArrayList<Permission> _permissions;
0134:
0135:            // The security code source for the loader
0136:            private CodeSource _codeSource;
0137:
0138:            // Any enhancer
0139:            private ArrayList<ClassFileTransformer> _classFileTransformerList;
0140:
0141:            private URL[] _urls = NULL_URL_ARRAY;
0142:
0143:            private WeakCloseListener _closeListener;
0144:
0145:            // Lifecycle
0146:            protected final Lifecycle _lifecycle = new Lifecycle();
0147:
0148:            private boolean _hasNewLoader = true;
0149:
0150:            private long _lastNullCheck;
0151:
0152:            /**
0153:             * Create a new class loader.
0154:             *
0155:             * @param parent parent class loader
0156:             */
0157:            public DynamicClassLoader(ClassLoader parent) {
0158:                this (parent, true);
0159:            }
0160:
0161:            /**
0162:             * Create a new class loader.
0163:             *
0164:             * @param parent parent class loader
0165:             */
0166:            public DynamicClassLoader(ClassLoader parent,
0167:                    boolean enableDependencyCheck) {
0168:                super (NULL_URL_ARRAY, getInitParent(parent));
0169:
0170:                parent = getParent();
0171:
0172:                _securityManager = System.getSecurityManager();
0173:
0174:                _isEnableDependencyCheck = enableDependencyCheck;
0175:
0176:                _dependencies.setCheckInterval(_globalDependencyCheckInterval);
0177:
0178:                for (; parent != null; parent = parent.getParent()) {
0179:                    if (parent instanceof  DynamicClassLoader) {
0180:                        DynamicClassLoader loader = (DynamicClassLoader) parent;
0181:
0182:                        loader.init();
0183:
0184:                        addPermissions(loader.getPermissions());
0185:
0186:                        // loader.addListener(this);
0187:
0188:                        _dependencies.add(loader);
0189:                        _dependencies.setCheckInterval(loader
0190:                                .getDependencyCheckInterval());
0191:
0192:                        _useServletHack = loader._useServletHack;
0193:
0194:                        break;
0195:                    }
0196:                }
0197:
0198:                if (System.getProperty("resin.verbose.classpath") != null) {
0199:                    _isVerbose = true;
0200:
0201:                    int depth = 0;
0202:
0203:                    while (parent != null) {
0204:                        depth++;
0205:                        parent = parent.getParent();
0206:                    }
0207:
0208:                    _verboseDepth = depth;
0209:                } else
0210:                    _isVerbose = false;
0211:            }
0212:
0213:            /**
0214:             * Returns the initialization parent, i.e. the parent if given
0215:             * or the context class loader if not given.
0216:             */
0217:            private static ClassLoader getInitParent(ClassLoader parent) {
0218:                if (parent != null)
0219:                    return parent;
0220:                else
0221:                    return Thread.currentThread().getContextClassLoader();
0222:            }
0223:
0224:            /**
0225:             * Returns true if jar entries should be cached.
0226:             */
0227:            public static boolean isJarCacheEnabled() {
0228:                return _isJarCacheEnabled;
0229:            }
0230:
0231:            /**
0232:             * Returns true if jar entries should be cached.
0233:             */
0234:            public static void setJarCacheEnabled(boolean isEnabled) {
0235:                _isJarCacheEnabled = isEnabled;
0236:            }
0237:
0238:            private void verbose(String name, String msg) {
0239:                if (_isVerbose) {
0240:                    for (int i = _verboseDepth; _verboseDepth > 0; _verboseDepth--)
0241:                        System.err.print(' ');
0242:
0243:                    System.err.println(toString() + " " + name + " " + msg);
0244:                }
0245:            }
0246:
0247:            /**
0248:             * Returns the global dependency check interval.
0249:             */
0250:            public static long getGlobalDependencyCheckInterval() {
0251:                return _globalDependencyCheckInterval;
0252:            }
0253:
0254:            /**
0255:             * Sets the global dependency check interval.
0256:             */
0257:            public static void setGlobalDependencyCheckInterval(long interval) {
0258:                _globalDependencyCheckInterval = interval;
0259:            }
0260:
0261:            /**
0262:             * Sets the name.
0263:             */
0264:            public void setId(String id) {
0265:                _id = id;
0266:            }
0267:
0268:            /**
0269:             * Gets the name.
0270:             */
0271:            public String getId() {
0272:                return _id;
0273:            }
0274:
0275:            /**
0276:             * Returns true if the class loader is closed.
0277:             */
0278:            public boolean isDestroyed() {
0279:                return _lifecycle.isDestroyed();
0280:            }
0281:
0282:            /**
0283:             * Adds a resource loader to the end of the list.
0284:             */
0285:            public void addLoader(Loader loader) {
0286:                int p = _loaders.indexOf(loader);
0287:
0288:                // overriding loaders are inserted before the loader they override
0289:                // server/10ih
0290:                if (p >= 0) {
0291:                    Loader oldLoader = _loaders.get(p);
0292:
0293:                    if (oldLoader != loader)
0294:                        addLoader(loader, p);
0295:                } else
0296:                    addLoader(loader, _loaders.size());
0297:
0298:                _hasNewLoader = true;
0299:            }
0300:
0301:            /**
0302:             * Adds a resource loader.
0303:             */
0304:            public void addLoader(Loader loader, int offset) {
0305:                if (_lifecycle.isDestroyed())
0306:                    throw new IllegalStateException(L().l(
0307:                            "can't add loaders after initialization"));
0308:
0309:                if (log().isLoggable(Level.FINEST))
0310:                    log().finest(this  + " adding loader " + loader);
0311:
0312:                _loaders.add(offset, loader);
0313:
0314:                if (loader.getLoader() == null)
0315:                    loader.setLoader(this );
0316:
0317:                if (loader instanceof  Dependency)
0318:                    _dependencies.add((Dependency) loader);
0319:
0320:                if (loader instanceof  Make) {
0321:                    if (_makeList == null)
0322:                        _makeList = new MakeContainer();
0323:
0324:                    _makeList.add((Make) loader);
0325:                }
0326:
0327:                if (loader instanceof  ClassLoaderListener)
0328:                    addListener(new WeakLoaderListener(
0329:                            (ClassLoaderListener) loader));
0330:
0331:                _hasNewLoader = true;
0332:            }
0333:
0334:            public ArrayList<Loader> getLoaders() {
0335:                return _loaders;
0336:            }
0337:
0338:            /**
0339:             * Adds jars based on a manifest classpath.
0340:             */
0341:            public void addJarManifestClassPath(Path path) throws IOException {
0342:                Path contextPath;
0343:                Path manifestPath;
0344:
0345:                if (path.isDirectory()) {
0346:                    manifestPath = path.lookup("META-INF/MANIFEST.MF");
0347:                    contextPath = path;
0348:                } else {
0349:                    JarPath jar = JarPath.create(path);
0350:                    manifestPath = jar.lookup("META-INF/MANIFEST.MF");
0351:                    contextPath = path.getParent();
0352:                }
0353:
0354:                if (manifestPath.canRead()) {
0355:                    ReadStream is = manifestPath.openRead();
0356:                    try {
0357:                        Manifest manifest = new Manifest(is);
0358:
0359:                        Attributes main = manifest.getMainAttributes();
0360:
0361:                        String classPath = main.getValue("Class-Path");
0362:
0363:                        addManifestClassPath(classPath, contextPath);
0364:                    } catch (IOException e) {
0365:                        log().log(Level.WARNING, e.toString(), e);
0366:
0367:                        return;
0368:                    } finally {
0369:                        is.close();
0370:                    }
0371:                }
0372:            }
0373:
0374:            /**
0375:             * Adds jars based on a manifest classpath.
0376:             */
0377:            public void addManifestClassPath(String classPath, Path pwd) {
0378:                if (classPath == null)
0379:                    return;
0380:
0381:                String[] urls = Pattern.compile("[\\s,]+").split(classPath);
0382:                if (urls == null)
0383:                    return;
0384:
0385:                for (int i = 0; i < urls.length; i++) {
0386:                    String url = urls[i];
0387:
0388:                    if (url.equals(""))
0389:                        continue;
0390:
0391:                    addJar(pwd.lookup(url));
0392:                }
0393:            }
0394:
0395:            /**
0396:             * Adds a native path.
0397:             */
0398:            public void addNative(Path path) {
0399:                _nativePath.add(path);
0400:            }
0401:
0402:            /**
0403:             * Adds a jar loader.
0404:             */
0405:            public void addJar(Path jar) {
0406:                addRoot(jar);
0407:            }
0408:
0409:            /**
0410:             * Adds a root loader.
0411:             */
0412:            public void addRoot(Path root) {
0413:                if (_lifecycle.isDestroyed())
0414:                    throw new IllegalStateException(L().l(
0415:                            "can't add roots after closing"));
0416:
0417:                if (root instanceof  JarPath || root.getPath().endsWith(".jar")
0418:                        || root.getPath().endsWith(".zip")) {
0419:                    if (_jarLoader == null) {
0420:                        _jarLoader = new JarLoader();
0421:                        addLoader(_jarLoader);
0422:                    }
0423:
0424:                    _jarLoader.addJar(root);
0425:                } else {
0426:                    SimpleLoader loader = new SimpleLoader();
0427:                    loader.setPath(root);
0428:
0429:                    if (!_loaders.contains(loader))
0430:                        addLoader(loader);
0431:                }
0432:
0433:                addURL(root);
0434:            }
0435:
0436:            /**
0437:             * Adds a jar loader.
0438:             */
0439:            public void addPathClass(String className, Path path) {
0440:                if (_pathLoader == null) {
0441:                    _pathLoader = new PathLoader();
0442:                    // ejb/0i00
0443:                    _loaders.add(0, _pathLoader);
0444:                }
0445:
0446:                _pathLoader.put(className, path);
0447:            }
0448:
0449:            /**
0450:             * Adds the URL to the URLClassLoader.
0451:             */
0452:            public void addURL(Path path) {
0453:                try {
0454:                    if (path.getScheme().equals("memory"))
0455:                        return;
0456:
0457:                    if (path.getScheme().equals("jar")) {
0458:                    } else if (path.getFullPath().endsWith(".jar")) {
0459:                    } else if (!path.getURL().endsWith("/"))
0460:                        path = path.lookup("./");
0461:
0462:                    addURL(new URL(path.getURL()));
0463:                } catch (MalformedURLException e) {
0464:                    log().warning(e.toString());
0465:                } catch (Exception e) {
0466:                    log().log(Level.WARNING, e.toString(), e);
0467:                }
0468:            }
0469:
0470:            /**
0471:             * Adds the URL to the URLClassLoader.
0472:             */
0473:            @Override
0474:            public void addURL(URL url) {
0475:                addURL(_urls.length, url);
0476:            }
0477:
0478:            /**
0479:             * Adds the URL to the URLClassLoader.
0480:             */
0481:            public void addURL(int index, URL url) {
0482:                super .addURL(url);
0483:
0484:                for (int i = 0; i < _urls.length; i++) {
0485:                    if (_urls[i].equals(url))
0486:                        return;
0487:                }
0488:
0489:                URL[] newURLs = new URL[_urls.length + 1];
0490:
0491:                for (int i = 0; i < index; i++)
0492:                    newURLs[i] = _urls[i];
0493:
0494:                newURLs[index] = url;
0495:
0496:                for (int i = index + 1; i < newURLs.length; i++)
0497:                    newURLs[i] = _urls[i - 1];
0498:
0499:                _urls = newURLs;
0500:            }
0501:
0502:            /**
0503:             * Adds a class loader for instrumentation (jdk 1.6).
0504:             */
0505:            public void appendToClassPathForInstrumentation(String path) {
0506:                addRoot(com.caucho.vfs.Vfs.lookup(path));
0507:            }
0508:
0509:            /**
0510:             * Returns the URLs.
0511:             */
0512:            public URL[] getURLs() {
0513:                return _urls;
0514:            }
0515:
0516:            /**
0517:             * Sets the dependency check interval.
0518:             */
0519:            public void setDependencyCheckInterval(long interval) {
0520:                _dependencies.setCheckInterval(interval);
0521:            }
0522:
0523:            /**
0524:             * Gets the dependency check interval.
0525:             */
0526:            public long getDependencyCheckInterval() {
0527:                if (_dependencies != null)
0528:                    return _dependencies.getCheckInterval();
0529:                else
0530:                    return 0;
0531:            }
0532:
0533:            /**
0534:             * Enables the dependency checking.
0535:             */
0536:            public void setEnableDependencyCheck(boolean enable) {
0537:                _isEnableDependencyCheck = enable;
0538:            }
0539:
0540:            /**
0541:             * Adds a dependency.
0542:             */
0543:            public void addDependency(Dependency dependency) {
0544:                _dependencies.add(dependency);
0545:            }
0546:
0547:            public void addPermission(String path, String actions) {
0548:                addPermission(new FilePermission(path, actions));
0549:            }
0550:
0551:            /**
0552:             * Adds a permission to the loader.
0553:             */
0554:            public void addPermission(Permission permission) {
0555:                if (_permissions == null)
0556:                    _permissions = new ArrayList<Permission>();
0557:
0558:                _permissions.add(permission);
0559:            }
0560:
0561:            public ArrayList<Permission> getPermissions() {
0562:                return _permissions;
0563:            }
0564:
0565:            public void addPermissions(ArrayList<Permission> perms) {
0566:                if (perms == null)
0567:                    return;
0568:
0569:                if (_permissions == null)
0570:                    _permissions = new ArrayList<Permission>();
0571:
0572:                _permissions.addAll(perms);
0573:            }
0574:
0575:            /**
0576:             * Returns the security manager.
0577:             */
0578:            public SecurityManager getSecurityManager() {
0579:                return _securityManager;
0580:            }
0581:
0582:            /**
0583:             * Set true if the loader should use the servlet spec's hack.
0584:             */
0585:            public void setServletHack(boolean servletHack) {
0586:                _useServletHack = servletHack;
0587:
0588:                if (_parentPriorityPackages == null)
0589:                    _parentPriorityPackages = new String[0];
0590:            }
0591:
0592:            /**
0593:             * Adds a listener to detect class loader changes.
0594:             */
0595:            public final void addListener(ClassLoaderListener listener) {
0596:                if (_lifecycle.isDestroyed()) {
0597:                    IllegalStateException e = new IllegalStateException(
0598:                            L()
0599:                                    .l(
0600:                                            "attempted to add listener to a closed classloader {0}",
0601:                                            this ));
0602:
0603:                    log().log(Level.WARNING, e.toString(), e);
0604:
0605:                    return;
0606:                }
0607:
0608:                ArrayList<ClassLoaderListener> listeners;
0609:                WeakCloseListener closeListener = null;
0610:
0611:                synchronized (this ) {
0612:                    if (_listeners == null) {
0613:                        _listeners = new ArrayList<ClassLoaderListener>();
0614:                        closeListener = new WeakCloseListener(this );
0615:                        //_closeListener = closeListener;
0616:                    }
0617:                    listeners = _listeners;
0618:                }
0619:
0620:                if (closeListener != null) {
0621:                    for (ClassLoader parent = getParent(); parent != null; parent = parent
0622:                            .getParent()) {
0623:                        if (parent instanceof  DynamicClassLoader) {
0624:                            ((DynamicClassLoader) parent)
0625:                                    .addListener(closeListener);
0626:                            break;
0627:                        }
0628:                    }
0629:                }
0630:
0631:                synchronized (listeners) {
0632:                    for (int i = listeners.size() - 1; i >= 0; i--) {
0633:                        ClassLoaderListener oldListener = listeners.get(i);
0634:
0635:                        if (listener == oldListener) {
0636:                            return;
0637:                        } else if (oldListener == null)
0638:                            listeners.remove(i);
0639:                    }
0640:
0641:                    listeners.add(listener);
0642:                }
0643:
0644:                if (_lifecycle.isActive())
0645:                    listener.classLoaderInit(this );
0646:            }
0647:
0648:            /**
0649:             * Adds a listener to detect class loader changes.
0650:             */
0651:            public final void removeListener(ClassLoaderListener listener) {
0652:                ArrayList<ClassLoaderListener> listeners = _listeners;
0653:
0654:                if (listeners == null)
0655:                    return;
0656:
0657:                synchronized (listeners) {
0658:                    for (int i = listeners.size() - 1; i >= 0; i--) {
0659:                        ClassLoaderListener oldListener = listeners.get(i);
0660:
0661:                        if (listener == oldListener) {
0662:                            listeners.remove(i);
0663:                            return;
0664:                        } else if (oldListener == null)
0665:                            listeners.remove(i);
0666:                    }
0667:                }
0668:            }
0669:
0670:            /**
0671:             * Returns the listeners.
0672:             */
0673:            protected ArrayList<ClassLoaderListener> getListeners() {
0674:                ArrayList<ClassLoaderListener> listeners;
0675:                listeners = new ArrayList<ClassLoaderListener>();
0676:
0677:                ArrayList<ClassLoaderListener> listenerList;
0678:                listenerList = _listeners;
0679:
0680:                if (listenerList != null) {
0681:                    synchronized (listenerList) {
0682:                        for (int i = 0; i < listenerList.size(); i++) {
0683:                            ClassLoaderListener listener = listenerList.get(i);
0684:
0685:                            if (listener != null)
0686:                                listeners.add(listener);
0687:                            else {
0688:                                listenerList.remove(i);
0689:                                i--;
0690:                            }
0691:                        }
0692:                    }
0693:                }
0694:
0695:                return listeners;
0696:            }
0697:
0698:            /**
0699:             * Adds a listener to detect class loader changes.
0700:             */
0701:            protected final void sendAddLoaderEvent() {
0702:                if (_hasNewLoader) {
0703:                    _hasNewLoader = false;
0704:
0705:                    scan();
0706:
0707:                    sendAddLoaderEventImpl();
0708:                }
0709:            }
0710:
0711:            /**
0712:             * Adds a listener to detect class loader changes.
0713:             */
0714:            protected void sendAddLoaderEventImpl() {
0715:            }
0716:
0717:            /**
0718:             * Add to the list of packages that don't use the hack.
0719:             */
0720:            public void addParentPriorityPackages(String[] pkg) {
0721:                for (int i = 0; pkg != null && i < pkg.length; i++) {
0722:                    addParentPriorityPackage(pkg[i]);
0723:                }
0724:            }
0725:
0726:            /**
0727:             * Add to the list of packages that don't use the {@link #setServletHack(boolean)}.
0728:             */
0729:            public void addParentPriorityPackage(String pkg) {
0730:                if (_parentPriorityPackages == null)
0731:                    _parentPriorityPackages = new String[0];
0732:
0733:                int oldLength = _parentPriorityPackages.length;
0734:                String[] newPkgs = new String[oldLength + 1];
0735:
0736:                System.arraycopy(_parentPriorityPackages, 0, newPkgs, 0,
0737:                        oldLength);
0738:
0739:                if (!pkg.endsWith("."))
0740:                    pkg = pkg + '.';
0741:
0742:                newPkgs[oldLength] = pkg;
0743:                _parentPriorityPackages = newPkgs;
0744:            }
0745:
0746:            /**
0747:             * Add to the list of packages that take priority over the parent
0748:             */
0749:            public void addPriorityPackage(String pkg) {
0750:                if (_priorityPackages == null)
0751:                    _priorityPackages = new String[0];
0752:
0753:                int oldLength = _priorityPackages.length;
0754:                String[] newPkgs = new String[oldLength + 1];
0755:
0756:                System.arraycopy(_priorityPackages, 0, newPkgs, 0, oldLength);
0757:
0758:                if (!pkg.endsWith("."))
0759:                    pkg = pkg + '.';
0760:
0761:                newPkgs[oldLength] = pkg;
0762:                _priorityPackages = newPkgs;
0763:            }
0764:
0765:            /**
0766:             * Returns the permission collection for the given code source.
0767:             */
0768:            protected PermissionCollection getPermissions(CodeSource codeSource) {
0769:                PermissionCollection perms = super .getPermissions(codeSource);
0770:
0771:                ArrayList<Permission> permissions = _permissions;
0772:
0773:                for (int i = 0; permissions != null && i < permissions.size(); i++) {
0774:                    Permission permission = permissions.get(i);
0775:
0776:                    perms.add(permission);
0777:                }
0778:
0779:                return perms;
0780:            }
0781:
0782:            protected void addCodeBasePath(String path) {
0783:            }
0784:
0785:            /**
0786:             * Sets any enhancer.
0787:             */
0788:            public void addTransformer(ClassFileTransformer transformer) {
0789:                if (_classFileTransformerList == null)
0790:                    _classFileTransformerList = new ArrayList<ClassFileTransformer>();
0791:
0792:                _classFileTransformerList.add(transformer);
0793:            }
0794:
0795:            protected ArrayList<ClassFileTransformer> getTransformerList() {
0796:                return _classFileTransformerList;
0797:            }
0798:
0799:            /**
0800:             * Fill data for the class path.  fillClassPath() will add all 
0801:             * .jar and .zip files in the directory list.
0802:             */
0803:            public final String getClassPath() {
0804:                StringBuilder head = new StringBuilder();
0805:
0806:                buildClassPath(head);
0807:
0808:                return head.toString();
0809:            }
0810:
0811:            /**
0812:             * Fill data for the class path.  fillClassPath() will add all 
0813:             * .jar and .zip files in the directory list.
0814:             */
0815:            protected final void buildClassPath(StringBuilder head) {
0816:                ClassLoader parent = getParent();
0817:
0818:                if (parent instanceof  DynamicClassLoader)
0819:                    ((DynamicClassLoader) parent).buildClassPath(head);
0820:                else {
0821:                    head.append(CauchoSystem.getClassPath());
0822:
0823:                    for (; parent != null; parent = parent.getParent()) {
0824:                        // XXX: should be reverse order
0825:                        if (parent instanceof  URLClassLoader) {
0826:                            URLClassLoader urlLoader = (URLClassLoader) parent;
0827:
0828:                            for (URL url : urlLoader.getURLs()) {
0829:                                if (head.length() > 0)
0830:                                    head.append(CauchoSystem
0831:                                            .getPathSeparatorChar());
0832:                                head.append(url);
0833:                            }
0834:                        }
0835:                    }
0836:                }
0837:
0838:                ArrayList<Loader> loaders = getLoaders();
0839:                for (int i = 0; i < loaders.size(); i++) {
0840:                    Loader loader = loaders.get(i);
0841:
0842:                    loader.buildClassPath(head);
0843:                }
0844:            }
0845:
0846:            /**
0847:             * Fill data for the class path.  fillClassPath() will add all 
0848:             * .jar and .zip files in the directory list.
0849:             */
0850:            public final String getLocalClassPath() {
0851:                StringBuilder head = new StringBuilder();
0852:
0853:                ArrayList<Loader> loaders = getLoaders();
0854:                for (int i = 0; i < loaders.size(); i++) {
0855:                    Loader loader = loaders.get(i);
0856:
0857:                    buildClassPath(head);
0858:                }
0859:
0860:                return head.toString();
0861:            }
0862:
0863:            /**
0864:             * Returns the source path.  The source path is used for looking up
0865:             * resources.
0866:             */
0867:            public final String getSourcePath() {
0868:                StringBuilder head = new StringBuilder();
0869:
0870:                buildSourcePath(head);
0871:
0872:                return head.toString();
0873:            }
0874:
0875:            /**
0876:             * Fill data for the class path.  fillSourcePath() will add all 
0877:             * .jar and .zip files in the directory list.
0878:             */
0879:            protected final void buildSourcePath(StringBuilder head) {
0880:                ClassLoader parent = getParent();
0881:
0882:                if (parent instanceof  DynamicClassLoader)
0883:                    ((DynamicClassLoader) parent).buildSourcePath(head);
0884:                else
0885:                    head.append(CauchoSystem.getClassPath());
0886:
0887:                ArrayList<Loader> loaders = getLoaders();
0888:                for (int i = 0; i < loaders.size(); i++) {
0889:                    Loader loader = loaders.get(i);
0890:
0891:                    loader.buildSourcePath(head);
0892:                }
0893:            }
0894:
0895:            /**
0896:             * Returns the resource path with most specific first.
0897:             */
0898:            public final String getResourcePathSpecificFirst() {
0899:                ArrayList<String> pathList = new ArrayList<String>();
0900:
0901:                buildResourcePathSpecificFirst(pathList);
0902:
0903:                StringBuilder sb = new StringBuilder();
0904:                char sep = CauchoSystem.getPathSeparatorChar();
0905:
0906:                if (pathList.size() == 0)
0907:                    return "";
0908:
0909:                sb.append(pathList.get(0));
0910:                for (int i = 1; i < pathList.size(); i++) {
0911:                    sb.append(sep);
0912:                    sb.append(pathList.get(i));
0913:                }
0914:
0915:                return sb.toString();
0916:            }
0917:
0918:            /**
0919:             * Returns the resource path with most specific first.
0920:             */
0921:            protected final void buildResourcePathSpecificFirst(
0922:                    ArrayList<String> pathList) {
0923:                ClassLoader parent = getParent();
0924:
0925:                ArrayList<Loader> loaders = getLoaders();
0926:                int size = loaders != null ? loaders.size() : 0;
0927:                for (int i = 0; i < size; i++) {
0928:                    Loader loader = loaders.get(i);
0929:
0930:                    loader.buildSourcePath(pathList);
0931:                }
0932:
0933:                if (parent instanceof  DynamicClassLoader)
0934:                    ((DynamicClassLoader) parent)
0935:                            .buildResourcePathSpecificFirst(pathList);
0936:                else {
0937:                    String tail = CauchoSystem.getClassPath();
0938:
0939:                    if (tail != null) {
0940:                        char sep = CauchoSystem.getPathSeparatorChar();
0941:
0942:                        String[] values = tail.split("[" + sep + "]");
0943:
0944:                        for (int i = 0; i < values.length; i++) {
0945:                            pathList.add(values[i]);
0946:                        }
0947:                    }
0948:                }
0949:            }
0950:
0951:            /**
0952:             * Returns true if any of the classes have been modified.
0953:             */
0954:            public final boolean isModified() {
0955:                return isModified(_isEnableDependencyCheck);
0956:            }
0957:
0958:            /**
0959:             * Returns true if any of the classes have been modified.
0960:             */
0961:            public final boolean isModified(boolean enable) {
0962:                if (_lifecycle.isDestroyed()) {
0963:                    return true;
0964:                }
0965:
0966:                DependencyContainer dependencies = _dependencies;
0967:
0968:                if (dependencies == null) {
0969:                    return true;
0970:                }
0971:
0972:                if (enable) {
0973:                    boolean isModified = dependencies.isModified();
0974:
0975:                    return isModified;
0976:                } else {
0977:                    boolean isModified = isModified(getParent());
0978:
0979:                    return isModified;
0980:                }
0981:            }
0982:
0983:            /**
0984:             * Returns true if any of the classes have been modified, forcing a check.
0985:             */
0986:            public final boolean isModifiedNow() {
0987:                if (_lifecycle.isDestroyed())
0988:                    return true;
0989:
0990:                DependencyContainer dependencies = _dependencies;
0991:
0992:                if (dependencies == null)
0993:                    return true;
0994:
0995:                return dependencies.isModifiedNow();
0996:            }
0997:
0998:            /**
0999:             * Logs the reason for modification.
1000:             */
1001:            public final boolean logModified(Logger log) {
1002:                if (_lifecycle.isDestroyed())
1003:                    return true;
1004:
1005:                DependencyContainer dependencies = _dependencies;
1006:
1007:                if (dependencies != null)
1008:                    return dependencies.logModified(log);
1009:                else
1010:                    return false;
1011:            }
1012:
1013:            /**
1014:             * Returns true if any of the classes have been modified.
1015:             */
1016:            public final void resetDependencyCheckInterval() {
1017:                if (_lifecycle.isDestroyed())
1018:                    return;
1019:
1020:                DependencyContainer dependencies = _dependencies;
1021:
1022:                if (dependencies == null)
1023:                    return;
1024:
1025:                dependencies.resetDependencyCheckInterval();
1026:            }
1027:
1028:            /**
1029:             * Returns true if any of the classes have been modified.
1030:             */
1031:            public final void clearModified() {
1032:                if (_lifecycle.isDestroyed())
1033:                    return;
1034:
1035:                DependencyContainer dependencies = _dependencies;
1036:
1037:                if (dependencies == null)
1038:                    return;
1039:
1040:                dependencies.clearModified();
1041:            }
1042:
1043:            /**
1044:             * Returns true if any of the classes have been modified.
1045:             */
1046:            public static boolean isModified(ClassLoader loader) {
1047:                for (; loader != null; loader = loader.getParent()) {
1048:                    if (loader instanceof  DynamicClassLoader)
1049:                        return ((DynamicClassLoader) loader).isModified();
1050:                }
1051:
1052:                return false;
1053:            }
1054:
1055:            /**
1056:             * Makes any changed classes for the virtual class loader.
1057:             */
1058:            public final void make() throws Exception {
1059:                for (ClassLoader loader = getParent(); loader != null; loader = loader
1060:                        .getParent()) {
1061:                    if (loader instanceof  Make) {
1062:                        ((Make) loader).make();
1063:                        break;
1064:                    }
1065:                }
1066:
1067:                if (_makeList != null)
1068:                    _makeList.make();
1069:            }
1070:
1071:            /**
1072:             * Defines a new package.
1073:             */
1074:            protected Package definePackage(String name, String a1, String a2,
1075:                    String a3, String b1, String b2, String b3, URL url) {
1076:                name = name.replace('/', '.');
1077:
1078:                if (name.endsWith("."))
1079:                    name = name.substring(0, name.length() - 1);
1080:
1081:                return super .definePackage(name, a1, a2, a3, b1, b2, b3, url);
1082:            }
1083:
1084:            /**
1085:             * Initialize the class loader.
1086:             */
1087:            public void init() {
1088:                if (!_lifecycle.toActive())
1089:                    return;
1090:
1091:                try {
1092:                    ArrayList<ClassLoaderListener> listeners = getListeners();
1093:
1094:                    if (listeners != null) {
1095:                        for (int i = 0; i < listeners.size(); i++) {
1096:                            ClassLoaderListener listener = listeners.get(i);
1097:
1098:                            listener.classLoaderInit(this );
1099:                        }
1100:                    }
1101:                } catch (Exception e) {
1102:                    log().log(Level.WARNING, e.toString(), e);
1103:                }
1104:            }
1105:
1106:            /**
1107:             * Validates the class loader.
1108:             */
1109:            public void validate() throws ConfigException {
1110:                ArrayList<Loader> loaders = getLoaders();
1111:
1112:                if (loaders == null)
1113:                    throw new IllegalStateException(
1114:                            _L
1115:                                    .l(
1116:                                            "Class loader {0} is closed during initialization.",
1117:                                            this ));
1118:
1119:                for (int i = 0; i < loaders.size(); i++)
1120:                    loaders.get(i).validate();
1121:            }
1122:
1123:            public void scan() {
1124:            }
1125:
1126:            public Class<?> loadClass(String name)
1127:                    throws ClassNotFoundException {
1128:                // the Sun JDK implementation of ClassLoader delegates this call
1129:                // to loadClass(name, false), but there is no guarantee that other
1130:                // implementations do.
1131:                return loadClass(name, false);
1132:            }
1133:
1134:            /**
1135:             * Load a class using this class loader
1136:             *
1137:             * @param name the classname to load
1138:             * @param resolve if true, resolve the class
1139:             *
1140:             * @return the loaded classes
1141:             */
1142:            protected Class loadClass(String name, boolean resolve)
1143:                    throws ClassNotFoundException {
1144:                synchronized (this ) {
1145:                    Class cl = loadClassImpl(name, resolve);
1146:
1147:                    if (cl != null)
1148:                        return cl;
1149:                    else
1150:                        throw new ClassNotFoundException(name + " in " + this );
1151:                }
1152:            }
1153:
1154:            /**
1155:             * Load a class using this class loader
1156:             *
1157:             * @param name the classname to load
1158:             * @param resolve if true, resolve the class
1159:             *
1160:             * @return the loaded classes
1161:             */
1162:            protected Class loadClassImpl(String name, boolean resolve)
1163:                    throws ClassNotFoundException {
1164:                if (_entryCache != null) {
1165:                    ClassEntry entry = _entryCache.get(name);
1166:
1167:                    if (entry != null) {
1168:                        Class cl = entry.getEntryClass();
1169:
1170:                        if (cl != null)
1171:                            return cl;
1172:                    }
1173:                }
1174:
1175:                // The JVM has already cached the classes, so we don't need to
1176:                Class cl = findLoadedClass(name);
1177:
1178:                if (cl != null) {
1179:                    if (resolve)
1180:                        resolveClass(cl);
1181:                    return cl;
1182:                }
1183:
1184:                if (_lifecycle.isDestroyed()) {
1185:                    log()
1186:                            .fine(
1187:                                    L()
1188:                                            .l(
1189:                                                    "Loading class {0} when class loader {1} has been closed.",
1190:                                                    name, this ));
1191:
1192:                    return super .loadClass(name, resolve);
1193:                }
1194:
1195:                boolean normalJdkOrder = isNormalJdkOrder(name);
1196:
1197:                if (_lifecycle.isBeforeInit())
1198:                    init();
1199:
1200:                if (normalJdkOrder) {
1201:                    try {
1202:                        ClassLoader parent = getParent();
1203:
1204:                        if (parent instanceof  DynamicClassLoader)
1205:                            cl = ((DynamicClassLoader) parent).loadClassImpl(
1206:                                    name, resolve);
1207:                        else if (parent != null) {
1208:                            cl = Class.forName(name, false, parent);
1209:                        } else
1210:                            cl = findSystemClass(name);
1211:                    } catch (ClassNotFoundException e) {
1212:                    }
1213:
1214:                    if (cl == null) {
1215:                        cl = findClassImpl(name);
1216:                    }
1217:                } else {
1218:                    try {
1219:                        cl = findClass(name);
1220:                    } catch (ClassNotFoundException e) {
1221:                        ClassLoader parent = getParent();
1222:                        if (parent != null)
1223:                            cl = Class.forName(name, false, parent);
1224:                        else
1225:                            cl = findSystemClass(name);
1226:                    }
1227:                }
1228:
1229:                if (resolve && cl != null)
1230:                    resolveClass(cl);
1231:
1232:                return cl;
1233:            }
1234:
1235:            /**
1236:             * Load a class using this class loader
1237:             *
1238:             * @param name the classname using either '/' or '.'
1239:             *
1240:             * @return the loaded class
1241:             */
1242:            protected Class findClass(String name)
1243:                    throws ClassNotFoundException {
1244:                Class cl = findClassImpl(name);
1245:
1246:                if (cl != null)
1247:                    return cl;
1248:                else
1249:                    throw new ClassNotFoundException(name);
1250:            }
1251:
1252:            /**
1253:             * Load a class using this class loader
1254:             *
1255:             * @param name the classname using either '/' or '.'
1256:             *
1257:             * @return the loaded class
1258:             */
1259:            protected Class findClassImpl(String name)
1260:                    throws ClassNotFoundException {
1261:                if (_isVerbose)
1262:                    verbose(name, "findClass");
1263:
1264:                if (_lifecycle.isDestroyed()) {
1265:                    log().fine("Class loader has been closed.");
1266:                    return super .findClass(name);
1267:                }
1268:
1269:                if (_lifecycle.isBeforeInit())
1270:                    init();
1271:
1272:                /*
1273:                if (! _lifecycle.isActive())
1274:                  return super.findClass(name);
1275:                 */
1276:
1277:                name = name.replace('/', '.');
1278:
1279:                ClassEntry entry = null;
1280:
1281:                synchronized (this ) {
1282:                    entry = _entryCache == null ? null : _entryCache.get(name);
1283:
1284:                    if (entry == null)
1285:                        entry = getClassEntry(name);
1286:
1287:                    if (entry == null)
1288:                        return null;
1289:
1290:                    if (entry != null && _isVerbose)
1291:                        verbose(name, (isNormalJdkOrder(name) ? "found"
1292:                                : "found (took priority from parent)"));
1293:
1294:                    if (_isEnableDependencyCheck)
1295:                        entry.addDependencies(_dependencies);
1296:
1297:                    // Currently, the entry must be in the entry cache for synchronization
1298:                    // to work.  The same entry must be returned for two separate threads
1299:                    // trying to load the class at the same time.
1300:
1301:                    if (_entryCache == null)
1302:                        _entryCache = new Hashtable<String, ClassEntry>(8);
1303:
1304:                    _entryCache.put(name, entry);
1305:                }
1306:
1307:                try {
1308:                    return loadClass(entry);
1309:                } catch (RuntimeException e) {
1310:                    throw e;
1311:                } catch (ClassNotFoundException e) {
1312:                    throw e;
1313:                } catch (Exception e) {
1314:                    log().log(Level.FINE, e.toString(), e);
1315:
1316:                    throw new ClassNotFoundException(name + " [" + e + "]", e);
1317:                }
1318:            }
1319:
1320:            /**
1321:             * Returns the matching class entry.
1322:             */
1323:            protected ClassEntry getClassEntry(String name)
1324:                    throws ClassNotFoundException {
1325:                String pathName = name.replace('.', '/') + ".class";
1326:
1327:                ArrayList<Loader> loaders = getLoaders();
1328:                for (int i = 0; i < loaders.size(); i++) {
1329:                    Loader loader = loaders.get(i);
1330:
1331:                    ClassEntry entry = loader.getClassEntry(name, pathName);
1332:
1333:                    if (entry != null)
1334:                        return entry;
1335:                }
1336:
1337:                return null;
1338:            }
1339:
1340:            /**
1341:             * Loads the class from the loader.  The loadClass must be in the
1342:             * top classLoader because the defineClass must be owned by the top.
1343:             */
1344:            protected Class loadClass(ClassEntry entry) throws IOException,
1345:                    ClassNotFoundException {
1346:                synchronized (entry) {
1347:                    Class cl = entry.getEntryClass();
1348:
1349:                    if (cl != null)
1350:                        return cl;
1351:
1352:                    entry.preLoad();
1353:
1354:                    String name = entry.getName();
1355:                    int p = name.lastIndexOf('.');
1356:                    if (p > 0) {
1357:                        String packageName = name.substring(0, p);
1358:                        Package pkg = getPackage(packageName);
1359:
1360:                        ClassPackage classPackage = entry.getClassPackage();
1361:
1362:                        if (pkg != null) {
1363:                        } else if (classPackage != null) {
1364:                            definePackage(packageName, classPackage
1365:                                    .getSpecificationTitle(), classPackage
1366:                                    .getSpecificationVersion(), classPackage
1367:                                    .getSpecificationVendor(), classPackage
1368:                                    .getImplementationTitle(), classPackage
1369:                                    .getImplementationVersion(), classPackage
1370:                                    .getImplementationVendor(), null);
1371:                        } else {
1372:                            definePackage(packageName, null, null, null, null,
1373:                                    null, null, null);
1374:                        }
1375:                    }
1376:
1377:                    ByteBuffer buffer = new ByteBuffer();
1378:
1379:                    entry.load(buffer);
1380:
1381:                    byte[] bBuf = buffer.getBuffer();
1382:                    int bLen = buffer.length();
1383:
1384:                    if (_classFileTransformerList != null) {
1385:                        Class redefineClass = null;
1386:                        String className = name.replace('.', '/');
1387:
1388:                        if (bBuf.length != bLen) {
1389:                            byte[] tempBuf = new byte[bLen];
1390:                            System.arraycopy(bBuf, 0, tempBuf, 0, bLen);
1391:                            bBuf = tempBuf;
1392:                        }
1393:
1394:                        ProtectionDomain protectionDomain = null;
1395:
1396:                        for (int i = 0; i < _classFileTransformerList.size(); i++) {
1397:                            ClassFileTransformer transformer = _classFileTransformerList
1398:                                    .get(i);
1399:
1400:                            try {
1401:                                byte[] enhancedBuffer = transformer.transform(
1402:                                        this , className, redefineClass,
1403:                                        protectionDomain, bBuf);
1404:
1405:                                if (enhancedBuffer != null) {
1406:                                    bBuf = enhancedBuffer;
1407:                                    bLen = enhancedBuffer.length;
1408:
1409:                                    if (_isVerbose || true)
1410:                                        verbose(name, String
1411:                                                .valueOf(transformer));
1412:                                }
1413:                                /* RSN-109
1414:                                   } catch (RuntimeException e) {
1415:                                   throw e;
1416:                                   } catch (Error e) {
1417:                                   throw e;
1418:                                 */
1419:                            } catch (EnhancerRuntimeException e) {
1420:                                throw e;
1421:                            } catch (Throwable e) {
1422:                                log().log(Level.WARNING, e.toString(), e);
1423:                            }
1424:                        }
1425:                    }
1426:
1427:                    try {
1428:                        cl = defineClass(entry.getName(), bBuf, 0, bLen, entry
1429:                                .getCodeSource());
1430:                    } catch (RuntimeException e) {
1431:                        log().log(Level.FINE,
1432:                                entry.getName() + " [" + e.toString() + "]", e);
1433:
1434:                        throw e;
1435:                    } catch (Exception e) {
1436:                        log().log(Level.FINE,
1437:                                entry.getName() + " [" + e.toString() + "]", e);
1438:
1439:                        ClassNotFoundException exn;
1440:                        exn = new ClassNotFoundException(entry.getName() + " ["
1441:                                + e + "]", e);
1442:                        //exn.initCause(e);
1443:
1444:                        throw exn;
1445:                    }
1446:
1447:                    entry.setEntryClass(cl);
1448:
1449:                    if (entry.postLoad()) {
1450:                        _dependencies.add(AlwaysModified.create());
1451:                        _dependencies.setModified(true);
1452:                    }
1453:
1454:                    return cl;
1455:                }
1456:            }
1457:
1458:            /**
1459:             * Gets the named resource
1460:             *
1461:             * @param name name of the resource
1462:             */
1463:            public URL getResource(String name) {
1464:                if (_resourceCache == null) {
1465:                    long expireInterval = getDependencyCheckInterval();
1466:
1467:                    _resourceCache = new TimedCache<String, URL>(256,
1468:                            expireInterval);
1469:                }
1470:
1471:                URL url = _resourceCache.get(name);
1472:
1473:                if (url == NULL_URL)
1474:                    return null;
1475:                else if (url != null)
1476:                    return url;
1477:
1478:                if (name.startsWith("/"))
1479:                    name = name.substring(1);
1480:
1481:                if (name.endsWith("/"))
1482:                    name = name.substring(0, name.length() - 1);
1483:
1484:                boolean isNormalJdkOrder = isNormalJdkOrder(name);
1485:
1486:                if (isNormalJdkOrder) {
1487:                    url = getParentResource(name);
1488:
1489:                    if (url != null)
1490:                        return url;
1491:                }
1492:
1493:                ArrayList<Loader> loaders = getLoaders();
1494:
1495:                for (int i = 0; loaders != null && i < loaders.size(); i++) {
1496:                    Loader loader = loaders.get(i);
1497:
1498:                    url = loader.getResource(name);
1499:
1500:                    if (url != null) {
1501:                        _resourceCache.put(name, url);
1502:
1503:                        return url;
1504:                    }
1505:                }
1506:
1507:                if (!isNormalJdkOrder) {
1508:                    url = getParentResource(name);
1509:
1510:                    if (url != null)
1511:                        return url;
1512:                }
1513:
1514:                _resourceCache.put(name, NULL_URL);
1515:
1516:                return null;
1517:            }
1518:
1519:            private URL getParentResource(String name) {
1520:                ClassLoader parent = getParent();
1521:
1522:                ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
1523:
1524:                URL url;
1525:
1526:                if (parent != null) {
1527:                    url = parent.getResource(name);
1528:
1529:                    if (url != null) {
1530:                        _resourceCache.put(name, url);
1531:
1532:                        return url;
1533:                    }
1534:                } else if (this  != systemLoader) {
1535:                    url = getSystemResource(name);
1536:
1537:                    if (url != null) {
1538:                        _resourceCache.put(name, url);
1539:
1540:                        return url;
1541:                    }
1542:                }
1543:
1544:                return null;
1545:            }
1546:
1547:            /**
1548:             * Opens a stream to a resource somewhere in the classpath
1549:             *
1550:             * @param name the path to the resource
1551:             *
1552:             * @return an input stream to the resource
1553:             */
1554:            public InputStream getResourceAsStream(String name) {
1555:                if (name.startsWith("/"))
1556:                    name = name.substring(1);
1557:
1558:                if (name.endsWith("/"))
1559:                    name = name.substring(0, name.length() - 1);
1560:
1561:                boolean isNormalJdkOrder = isNormalJdkOrder(name);
1562:                InputStream is = null;
1563:
1564:                if (isNormalJdkOrder) {
1565:                    is = getParentResourceAsStream(name);
1566:
1567:                    if (is != null)
1568:                        return is;
1569:                }
1570:
1571:                ArrayList<Loader> loaders = getLoaders();
1572:
1573:                for (int i = 0; loaders != null && i < loaders.size(); i++) {
1574:                    Loader loader = loaders.get(i);
1575:
1576:                    is = loader.getResourceAsStream(name);
1577:
1578:                    if (is != null)
1579:                        return is;
1580:                }
1581:
1582:                if (!isNormalJdkOrder) {
1583:                    is = getParentResourceAsStream(name);
1584:                }
1585:
1586:                return is;
1587:            }
1588:
1589:            private InputStream getParentResourceAsStream(String name) {
1590:                ClassLoader parent = getParent();
1591:
1592:                ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
1593:
1594:                InputStream is;
1595:
1596:                if (parent != null) {
1597:                    is = parent.getResourceAsStream(name);
1598:
1599:                    if (is != null)
1600:                        return is;
1601:                } else if (this  != systemLoader) {
1602:                    is = getSystemResourceAsStream(name);
1603:
1604:                    if (is != null) {
1605:                        return is;
1606:                    }
1607:                }
1608:
1609:                return null;
1610:            }
1611:
1612:            /**
1613:             * Returns an enumeration of matching resources.
1614:             */
1615:            public Enumeration<URL> findResources(String name) {
1616:                if (name.startsWith("/"))
1617:                    name = name.substring(1);
1618:
1619:                // server/249b
1620:                /*
1621:                if (name.endsWith("/"))
1622:                  name = name.substring(0, name.length() - 1);
1623:                 */
1624:
1625:                Vector<URL> resources = new Vector<URL>();
1626:
1627:                ArrayList<Loader> loaders = getLoaders();
1628:                for (int i = 0; i < loaders.size(); i++) {
1629:                    Loader loader = loaders.get(i);
1630:
1631:                    loader.getResources(resources, name);
1632:                }
1633:
1634:                return resources.elements();
1635:            }
1636:
1637:            /**
1638:             * Returns the full library path for the name.
1639:             */
1640:            public String findLibrary(String name) {
1641:                String systemName = System.mapLibraryName(name);
1642:
1643:                ArrayList<Loader> loaders = getLoaders();
1644:                for (int i = 0; i < loaders.size(); i++) {
1645:                    Loader loader = loaders.get(i);
1646:
1647:                    Path path = loader.getPath(systemName);
1648:
1649:                    if (path != null && path.canRead()) {
1650:                        return path.getNativePath();
1651:                    }
1652:                }
1653:
1654:                for (int i = 0; i < _nativePath.size(); i++) {
1655:                    Path path = _nativePath.get(i);
1656:
1657:                    if (path.canRead())
1658:                        return path.getNativePath();
1659:                }
1660:
1661:                return super .findLibrary(name);
1662:            }
1663:
1664:            /**
1665:             * Returns the matching single-level path.
1666:             */
1667:            public Path findPath(String name) {
1668:                ArrayList<Loader> loaders = getLoaders();
1669:                for (int i = 0; i < loaders.size(); i++) {
1670:                    Loader loader = loaders.get(i);
1671:
1672:                    Path path = loader.getPath(name);
1673:
1674:                    if (path != null && path.canRead()) {
1675:                        return path;
1676:                    }
1677:                }
1678:
1679:                return null;
1680:            }
1681:
1682:            /**
1683:             * Returns true if the class loader should use the normal order,
1684:             * i.e. looking at the parents first.
1685:             */
1686:            private boolean isNormalJdkOrder(String className) {
1687:                if (_priorityPackages != null) {
1688:                    String canonName = className.replace('/', '.');
1689:
1690:                    for (String priorityPackage : _priorityPackages) {
1691:                        if (canonName.startsWith(priorityPackage))
1692:                            return false;
1693:                    }
1694:                }
1695:
1696:                if (!_useServletHack)
1697:                    return true;
1698:
1699:                String canonName = className.replace('/', '.');
1700:                String[] pkgs = _parentPriorityPackages;
1701:
1702:                for (int i = 0; pkgs != null && i < pkgs.length; i++) {
1703:                    if (canonName.startsWith(pkgs[i]))
1704:                        return true;
1705:                }
1706:
1707:                return false;
1708:            }
1709:
1710:            /**
1711:             * stops the class loader.
1712:             */
1713:            public void stop() {
1714:            }
1715:
1716:            /**
1717:             * Destroys the class loader.
1718:             */
1719:            public void destroy() {
1720:                try {
1721:                    stop();
1722:                } catch (Throwable e) {
1723:                }
1724:
1725:                if (!_lifecycle.toDestroying())
1726:                    return;
1727:
1728:                try {
1729:                    ClassLoader parent = getParent();
1730:                    for (; parent != null; parent = parent.getParent()) {
1731:                        if (parent instanceof  DynamicClassLoader) {
1732:                            DynamicClassLoader loader = (DynamicClassLoader) parent;
1733:
1734:                            if (_closeListener != null)
1735:                                loader.removeListener(_closeListener);
1736:                        }
1737:                    }
1738:
1739:                    ArrayList<ClassLoaderListener> listeners = _listeners;
1740:                    _listeners = null;
1741:
1742:                    Thread thread = Thread.currentThread();
1743:                    ClassLoader oldLoader = thread.getContextClassLoader();
1744:
1745:                    try {
1746:                        // Use reverse order so the last resources will be destroyed first.
1747:                        if (listeners != null) {
1748:                            for (int i = listeners.size() - 1; i >= 0; i--) {
1749:                                ClassLoaderListener listener = listeners.get(i);
1750:
1751:                                try {
1752:                                    thread.setContextClassLoader(this );
1753:
1754:                                    listener.classLoaderDestroy(this );
1755:                                } catch (Throwable e) {
1756:                                    log().log(Level.WARNING, e.toString(), e);
1757:                                }
1758:                            }
1759:                        }
1760:                    } finally {
1761:                        thread.setContextClassLoader(oldLoader);
1762:                    }
1763:
1764:                    ArrayList<Loader> loaders = getLoaders();
1765:                    for (int i = loaders.size() - 1; i >= 0; i--) {
1766:                        Loader loader = loaders.get(i);
1767:
1768:                        try {
1769:                            loader.destroy();
1770:                        } catch (Throwable e) {
1771:                            log().log(Level.WARNING, e.toString(), e);
1772:                        }
1773:                    }
1774:                } finally {
1775:                    _closeListener = null;
1776:                    _listeners = null;
1777:                    _entryCache = null;
1778:                    _makeList = null;
1779:                    _loaders = null;
1780:                    _jarLoader = null;
1781:                    _dependencies = null;
1782:                    _permissions = null;
1783:                    _securityManager = null;
1784:                    _codeSource = null;
1785:                    _classFileTransformerList = null;
1786:
1787:                    _lifecycle.toDestroy();
1788:                }
1789:            }
1790:
1791:            /**
1792:             * Sets the old loader if not destroyed.
1793:             */
1794:            public static void setOldLoader(Thread thread, ClassLoader oldLoader) {
1795:                if (!(oldLoader instanceof  DynamicClassLoader)) {
1796:                    thread.setContextClassLoader(oldLoader);
1797:                    return;
1798:                }
1799:
1800:                DynamicClassLoader dynLoader = (DynamicClassLoader) oldLoader;
1801:
1802:                if (!dynLoader.isDestroyed())
1803:                    thread.setContextClassLoader(oldLoader);
1804:                else
1805:                    thread.setContextClassLoader(ClassLoader
1806:                            .getSystemClassLoader());
1807:            }
1808:
1809:            public ClassLoader getInstrumentableClassLoader() {
1810:                return this ;
1811:            }
1812:
1813:            public ClassLoader getThrowawayClassLoader() {
1814:                return getNewTempClassLoader();
1815:            }
1816:
1817:            public ClassLoader getNewTempClassLoader() {
1818:                return new TempDynamicClassLoader(this );
1819:            }
1820:
1821:            /**
1822:             * Copies the loader.
1823:             */
1824:            protected void replace(DynamicClassLoader source) {
1825:                _id = source._id;
1826:
1827:                _loaders.addAll(source._loaders);
1828:                _jarLoader = source._jarLoader;
1829:
1830:                _dependencies = source._dependencies;
1831:
1832:                _makeList = source._makeList;
1833:                _useServletHack = source._useServletHack;
1834:                _parentPriorityPackages = source._parentPriorityPackages;
1835:
1836:                if (source._listeners != null) {
1837:                    if (_listeners == null)
1838:                        _listeners = new ArrayList<ClassLoaderListener>();
1839:
1840:                    _listeners.addAll(source._listeners);
1841:                    source._listeners.clear();
1842:                }
1843:
1844:                _securityManager = source._securityManager;
1845:                if (source._permissions != null) {
1846:                    if (_permissions == null)
1847:                        _permissions = new ArrayList<Permission>();
1848:
1849:                    _permissions.addAll(source._permissions);
1850:                }
1851:
1852:                _codeSource = source._codeSource;
1853:
1854:                _lifecycle.copyState(source._lifecycle);
1855:            }
1856:
1857:            public String toString() {
1858:                if (_id != null)
1859:                    return getClass().getSimpleName() + "[" + _id + "]";
1860:                else
1861:                    return getClass().getSimpleName() + getLoaders();
1862:            }
1863:
1864:            private static L10N L() {
1865:                if (_L == null)
1866:                    _L = new L10N(DynamicClassLoader.class);
1867:
1868:                return _L;
1869:            }
1870:
1871:            private static Logger log() {
1872:                if (_log == null)
1873:                    _log = Logger.getLogger(DynamicClassLoader.class.getName());
1874:
1875:                return _log;
1876:            }
1877:
1878:            // XXX: GC issues
1879:            /*n
1880:            protected void finalize()
1881:            {
1882:              destroy();
1883:            }
1884:             */
1885:
1886:            static {
1887:                URL url = null;
1888:
1889:                try {
1890:                    url = new URL("file:/caucho/null");
1891:                } catch (Throwable e) {
1892:                }
1893:
1894:                NULL_URL = url;
1895:            }
1896:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.