Source Code Cross Referenced for RepositoryClassLoader.java in  » EJB-Server-JBoss-4.2.1 » jmx » org » jboss » mx » loading » 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 JBoss 4.2.1 » jmx » org.jboss.mx.loading 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.mx.loading;
023:
024:        import java.io.ByteArrayOutputStream;
025:        import java.io.IOException;
026:        import java.io.InputStream;
027:        import java.net.MalformedURLException;
028:        import java.net.URL;
029:        import java.net.URLClassLoader;
030:        import java.security.CodeSource;
031:        import java.security.PermissionCollection;
032:        import java.security.Policy;
033:        import java.security.ProtectionDomain;
034:        import java.security.cert.Certificate;
035:        import java.util.Enumeration;
036:        import java.util.HashSet;
037:        import java.util.Vector;
038:        import java.util.Collections;
039:        import java.util.Set;
040:
041:        import javax.management.MalformedObjectNameException;
042:        import javax.management.ObjectName;
043:
044:        import org.jboss.logging.Logger;
045:        import org.jboss.util.loading.Translator;
046:        import org.jboss.util.collection.SoftSet;
047:
048:        import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;
049:        import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
050:
051:        /**
052:         * A RepositoryClassLoader.
053:         * 
054:         * @author <a href="adrian@jboss.com">Adrian Brock</a>
055:         * @version $Revision: 60321 $
056:         */
057:        public abstract class RepositoryClassLoader extends URLClassLoader {
058:            // Constants -----------------------------------------------------
059:
060:            /** The log */
061:            private static final Logger log = Logger
062:                    .getLogger(RepositoryClassLoader.class);
063:
064:            /** The value returned by {@link #getURLs}. */
065:            private static final URL[] EMPTY_URL_ARRAY = {};
066:
067:            // Attributes -----------------------------------------------------
068:
069:            /** Reference to the repository. */
070:            protected LoaderRepository repository = null;
071:            /** The location where unregister is called from */
072:            protected Exception unregisterTrace;
073:
074:            /** The relative order in which this class loader was added to the respository */
075:            private int addedOrder;
076:
077:            /** The parent classloader */
078:            protected ClassLoader parent = null;
079:
080:            /** Names of classes which have resulted in CNFEs in loadClassLocally */
081:            private Set classBlackList = Collections
082:                    .synchronizedSet(new HashSet());
083:            /** Names of resources that were not found in loadResourceLocally */
084:            private Set resourceBlackList = Collections
085:                    .synchronizedSet(new HashSet());
086:            /** A HashMap<String, URL> for resource found in loadResourceLocally */
087:            private ConcurrentReaderHashMap resourceCache = new ConcurrentReaderHashMap();
088:
089:            /** Lock */
090:            protected ReentrantLock loadLock = new ReentrantLock();
091:
092:            /** A debugging variable used to track the recursive depth of loadClass() */
093:            private int loadClassDepth;
094:
095:            // Static --------------------------------------------------------
096:
097:            // Constructors --------------------------------------------------
098:
099:            /**
100:             * Create a new LoaderRepositoryClassLoader
101:             * 
102:             * @param urls the urls
103:             * @param parent the parent classloader
104:             */
105:            protected RepositoryClassLoader(URL[] urls, ClassLoader parent) {
106:                super (urls, parent);
107:                this .parent = parent;
108:                // Check the blacklist mode
109:                String mode = ClassToStringAction.getProperty(
110:                        "org.jboss.mx.loading.blacklistMode", null);
111:                if (mode == null || mode.equalsIgnoreCase("HashSet")) {
112:                    classBlackList = Collections.synchronizedSet(new HashSet());
113:                    resourceBlackList = Collections
114:                            .synchronizedSet(new HashSet());
115:                } else if (mode.equalsIgnoreCase("SoftSet")) {
116:                    classBlackList = Collections.synchronizedSet(new SoftSet());
117:                    resourceBlackList = Collections
118:                            .synchronizedSet(new SoftSet());
119:                }
120:            }
121:
122:            // Public --------------------------------------------------------
123:
124:            /**
125:             * Get the ObjectName
126:             * 
127:             * @return the object name
128:             */
129:            public abstract ObjectName getObjectName()
130:                    throws MalformedObjectNameException;
131:
132:            /**
133:             * Get the loader repository for this classloader
134:             */
135:            public LoaderRepository getLoaderRepository() {
136:                return repository;
137:            }
138:
139:            /**
140:             * Set the loader repository
141:             * 
142:             * @param repository the repository
143:             */
144:            public void setRepository(LoaderRepository repository) {
145:                log.debug("setRepository, repository=" + repository + ", cl="
146:                        + this );
147:                this .repository = repository;
148:            }
149:
150:            /**
151:             * Get the order this classloader was added to the repository
152:             * 
153:             * @return the order
154:             */
155:            public int getAddedOrder() {
156:                return addedOrder;
157:            }
158:
159:            /**
160:             * Set the order this classloader was added to the repository
161:             * 
162:             * @param addedOrder the added order
163:             */
164:            public void setAddedOrder(int addedOrder) {
165:                this .addedOrder = addedOrder;
166:            }
167:
168:            /** 
169:             * Called to attempt to load a class from the set of URLs associated with this classloader.
170:             */
171:            public Class loadClassLocally(String name, boolean resolve)
172:                    throws ClassNotFoundException {
173:                boolean trace = log.isTraceEnabled();
174:                if (trace)
175:                    log.trace("loadClassLocally, " + this  + " name=" + name);
176:                if (name == null || name.length() == 0)
177:                    throw new ClassNotFoundException("Null or empty class name");
178:
179:                Class result = null;
180:                try {
181:                    if (isClassBlackListed(name)) {
182:                        if (trace)
183:                            log.trace("Class in blacklist, name=" + name);
184:                        throw new ClassNotFoundException(
185:                                "Class Not Found(blacklist): " + name);
186:                    }
187:
188:                    try {
189:                        result = super .loadClass(name, resolve);
190:                        return result;
191:                    } catch (ClassNotFoundException cnfe) {
192:                        addToClassBlackList(name);
193:                        // If this is an array class, use Class.forName to resolve it
194:                        if (name.charAt(0) == '[') {
195:                            result = Class.forName(name, true, this );
196:                            removeFromClassBlackList(name);
197:                            return result;
198:                        }
199:                        if (trace)
200:                            log.trace("CFNE: Adding to blacklist: " + name);
201:                        throw cnfe;
202:                    }
203:                } finally {
204:                    if (trace) {
205:                        if (result != null)
206:                            log.trace("loadClassLocally, " + this  + " name="
207:                                    + name + " class=" + result + " cl="
208:                                    + result.getClassLoader());
209:                        else
210:                            log.trace("loadClassLocally, " + this  + " name="
211:                                    + name + " not found");
212:                    }
213:                }
214:            }
215:
216:            /**
217:             * Provides the same functionality as {@link java.net.URLClassLoader#getResource}.
218:             */
219:            public URL getResourceLocally(String name) {
220:                URL resURL = (URL) resourceCache.get(name);
221:                if (resURL != null)
222:                    return resURL;
223:                if (isResourceBlackListed(name))
224:                    return null;
225:                resURL = super .getResource(name);
226:                if (log.isTraceEnabled() == true)
227:                    log.trace("getResourceLocally(" + this  + "), name=" + name
228:                            + ", resURL:" + resURL);
229:                if (resURL == null)
230:                    addToResourceBlackList(name);
231:                else
232:                    resourceCache.put(name, resURL);
233:                return resURL;
234:            }
235:
236:            /**
237:             * Get the URL associated with the UCL.
238:             * 
239:             * @return the url
240:             */
241:            public URL getURL() {
242:                URL[] urls = super .getURLs();
243:                if (urls.length > 0)
244:                    return urls[0];
245:                else
246:                    return null;
247:            }
248:
249:            public void unregister() {
250:                log.debug("Unregistering cl=" + this );
251:                if (repository != null)
252:                    repository.removeClassLoader(this );
253:                clearBlackLists();
254:                resourceCache.clear();
255:                repository = null;
256:                this .unregisterTrace = new Exception();
257:            }
258:
259:            /**
260:             * This method simply invokes the super.getURLs() method to access the
261:             * list of URLs that make up the RepositoryClassLoader classpath.
262:             * 
263:             * @return the urls that make up the classpath
264:             */
265:            public URL[] getClasspath() {
266:                return super .getURLs();
267:            }
268:
269:            /**
270:             * Return all library URLs associated with this RepositoryClassLoader
271:             *
272:             * <p>Do not remove this method without running the WebIntegrationTestSuite
273:             */
274:            public URL[] getAllURLs() {
275:                return repository.getURLs();
276:            }
277:
278:            /**
279:             * Black list a class 
280:             * 
281:             * @param name the name of the class
282:             */
283:            public void addToClassBlackList(String name) {
284:                classBlackList.add(name);
285:            }
286:
287:            /**
288:             * Remove class from black list 
289:             * 
290:             * @param name the name of the class
291:             */
292:            public void removeFromClassBlackList(String name) {
293:                classBlackList.remove(name);
294:            }
295:
296:            /**
297:             * Is the class black listed?
298:             * 
299:             * @param name the name of the class
300:             * @return true when the class is black listed, false otherwise
301:             */
302:            public boolean isClassBlackListed(String name) {
303:                return classBlackList.contains(name);
304:            }
305:
306:            /**
307:             * Clear any class black list.
308:             */
309:            public void clearClassBlackList() {
310:                classBlackList.clear();
311:            }
312:
313:            /**
314:             * Black list a resource 
315:             * 
316:             * @param name the name of the resource
317:             */
318:            public void addToResourceBlackList(String name) {
319:                resourceBlackList.add(name);
320:            }
321:
322:            /**
323:             * Remove resource from black list 
324:             * 
325:             * @param name the name of the resource
326:             */
327:            public void removeFromResourceBlackList(String name) {
328:                resourceBlackList.remove(name);
329:            }
330:
331:            /**
332:             * Is the resource black listed?
333:             * 
334:             * @param name the name of the resource
335:             * @return true when the resource is black listed, false otherwise
336:             */
337:            public boolean isResourceBlackListed(String name) {
338:                return resourceBlackList.contains(name);
339:            }
340:
341:            /**
342:             * Clear any resource blacklist.
343:             */
344:            public void clearResourceBlackList() {
345:                resourceBlackList.clear();
346:            }
347:
348:            /**
349:             * Clear all blacklists
350:             */
351:            public void clearBlackLists() {
352:                clearClassBlackList();
353:                clearResourceBlackList();
354:            }
355:
356:            // URLClassLoader overrides --------------------------------------
357:
358:            /** The only caller of this method should be the VM initiated
359:             * loadClassInternal() method. This method attempts to acquire the
360:             * UnifiedLoaderRepository2 lock and then asks the repository to
361:             * load the class.
362:             *
363:             * <p>Forwards request to {@link LoaderRepository}.
364:             */
365:            public Class loadClass(String name, boolean resolve)
366:                    throws ClassNotFoundException {
367:                boolean trace = log.isTraceEnabled();
368:                if (trace)
369:                    log.trace("loadClass " + this  + " name=" + name
370:                            + ", loadClassDepth=" + loadClassDepth);
371:                Class clazz = null;
372:                try {
373:                    if (repository != null) {
374:                        clazz = repository.getCachedClass(name);
375:                        if (clazz != null) {
376:                            if (log.isTraceEnabled()) {
377:                                StringBuffer buffer = new StringBuffer(
378:                                        "Loaded class from cache, ");
379:                                ClassToStringAction.toString(clazz, buffer);
380:                                log.trace(buffer.toString());
381:                            }
382:                            return clazz;
383:                        }
384:                    }
385:                    clazz = loadClassImpl(name, resolve, Integer.MAX_VALUE);
386:                    return clazz;
387:                } finally {
388:                    if (trace) {
389:                        if (clazz != null)
390:                            log.trace("loadClass " + this  + " name=" + name
391:                                    + " class=" + clazz + " cl="
392:                                    + clazz.getClassLoader());
393:                        else
394:                            log.trace("loadClass " + this  + " name=" + name
395:                                    + " not found");
396:                    }
397:                }
398:            }
399:
400:            /** The only caller of this method should be the VM initiated
401:             * loadClassInternal() method. This method attempts to acquire the
402:             * UnifiedLoaderRepository2 lock and then asks the repository to
403:             * load the class.
404:             *
405:             * <p>Forwards request to {@link LoaderRepository}.
406:             */
407:            public Class loadClassBefore(String name)
408:                    throws ClassNotFoundException {
409:                boolean trace = log.isTraceEnabled();
410:                if (trace)
411:                    log.trace("loadClassBefore " + this  + " name=" + name);
412:                Class clazz = null;
413:                try {
414:                    clazz = loadClassImpl(name, false, addedOrder);
415:                    return clazz;
416:                } finally {
417:                    if (trace) {
418:                        if (clazz != null)
419:                            log.trace("loadClassBefore " + this  + " name="
420:                                    + name + " class=" + clazz + " cl="
421:                                    + clazz.getClassLoader());
422:                        else
423:                            log.trace("loadClassBefore " + this  + " name="
424:                                    + name + " not found");
425:                    }
426:                }
427:            }
428:
429:            public synchronized Class loadClassImpl(String name,
430:                    boolean resolve, int stopAt) throws ClassNotFoundException {
431:                loadClassDepth++;
432:                boolean trace = log.isTraceEnabled();
433:
434:                if (trace)
435:                    log.trace("loadClassImpl, name=" + name + ", resolve="
436:                            + resolve);
437:                if (repository == null) {
438:                    // If we have been undeployed we can still try locally
439:                    try {
440:                        return super .loadClass(name, resolve);
441:                    } catch (ClassNotFoundException ignored) {
442:                    }
443:                    String msg = "Invalid use of destroyed classloader, UCL destroyed at:";
444:                    throw new ClassNotFoundException(msg, this .unregisterTrace);
445:                }
446:
447:                /* Since loadClass can be called from loadClassInternal with the monitor
448:                   already held, we need to determine if there is a ClassLoadingTask
449:                   which requires this UCL. If there is, we release the UCL monitor
450:                   so that the ClassLoadingTask can use the UCL.
451:                 */
452:                boolean acquired = attempt(1);
453:                while (acquired == false) {
454:                    /* Another thread needs this UCL to load a class so release the
455:                     monitor acquired by the synchronized method. We loop until
456:                     we can acquire the class loading lock.
457:                     */
458:                    try {
459:                        if (trace)
460:                            log.trace("Waiting for loadClass lock");
461:                        this .wait();
462:                    } catch (InterruptedException ignore) {
463:                    }
464:                    acquired = attempt(1);
465:                }
466:
467:                ClassLoadingTask task = null;
468:                try {
469:                    Thread t = Thread.currentThread();
470:                    // Register this thread as owning this UCL
471:                    if (loadLock.holds() == 1)
472:                        LoadMgr3.registerLoaderThread(this , t);
473:
474:                    // Create a class loading task and submit it to the repository
475:                    task = new ClassLoadingTask(name, this , t, stopAt);
476:                    /* Process class loading tasks needing this UCL until our task has
477:                       been completed by the thread owning the required UCL(s).
478:                     */
479:                    UnifiedLoaderRepository3 ulr3 = (UnifiedLoaderRepository3) repository;
480:                    if (LoadMgr3.beginLoadTask(task, ulr3) == false) {
481:                        while (task.threadTaskCount != 0) {
482:                            try {
483:                                LoadMgr3.nextTask(t, task, ulr3);
484:                            } catch (InterruptedException e) {
485:                                // Abort the load or retry?
486:                                break;
487:                            }
488:                        }
489:                    }
490:                } finally {
491:                    // Unregister as the UCL owner to reschedule any remaining load tasks
492:                    if (loadLock.holds() == 1)
493:                        LoadMgr3.endLoadTask(task);
494:                    // Notify any threads waiting to use this UCL
495:                    this .release();
496:                    this .notifyAll();
497:                    loadClassDepth--;
498:                }
499:
500:                if (task.loadedClass == null) {
501:                    if (task.loadException instanceof  ClassNotFoundException)
502:                        throw (ClassNotFoundException) task.loadException;
503:                    else if (task.loadException instanceof  NoClassDefFoundError)
504:                        throw (NoClassDefFoundError) task.loadException;
505:                    else if (task.loadException != null) {
506:                        if (log.isTraceEnabled())
507:                            log.trace(
508:                                    "Unexpected error during load of:" + name,
509:                                    task.loadException);
510:                        String msg = "Unexpected error during load of: " + name
511:                                + ", msg=" + task.loadException.getMessage();
512:                        ClassNotFoundException cnfe = new ClassNotFoundException(
513:                                msg, task.loadException);
514:                        throw cnfe;
515:                    }
516:                    // Assert that loadedClass is not null
517:                    else
518:                        throw new IllegalStateException(
519:                                "ClassLoadingTask.loadedTask is null, name: "
520:                                        + name);
521:                }
522:
523:                return task.loadedClass;
524:            }
525:
526:            /**
527:             * Attempts to load the resource from its URL and if not found
528:             * forwards to the request to {@link LoaderRepository}.
529:             */
530:            public URL getResource(String name) {
531:                if (repository != null)
532:                    return repository.getResource(name, this );
533:                return null;
534:            }
535:
536:            /** Find all resource URLs for the given name. This overrides the
537:             * URLClassLoader version to look for resources in the repository.
538:             *
539:             * @param name the name of the resource
540:             * @return Enumeration<URL>
541:             * @throws java.io.IOException
542:             */
543:            public Enumeration findResources(String name) throws IOException {
544:                Vector resURLs = new Vector();
545:                if (repository == null) {
546:                    String msg = "Invalid use of destroyed classloader, UCL destroyed at:";
547:                    IOException e = new IOException(msg);
548:                    e.initCause(this .unregisterTrace);
549:                    throw e;
550:                }
551:                repository.getResources(name, this , resURLs);
552:                return resURLs.elements();
553:            }
554:
555:            /**
556:             * Provides the same functionality as {@link java.net.URLClassLoader#findResources}.
557:             */
558:            public Enumeration findResourcesLocally(String name)
559:                    throws IOException {
560:                return super .findResources(name);
561:            }
562:
563:            /** Called by loadClassLocally to find the requested class within this
564:             * class loaders class path.
565:             *
566:             * @param name the name of the class
567:             * @return the resulting class
568:             * @exception ClassNotFoundException if the class could not be found
569:             */
570:            protected Class findClass(String name)
571:                    throws ClassNotFoundException {
572:                boolean trace = log.isTraceEnabled();
573:                if (trace)
574:                    log.trace("findClass, name=" + name);
575:                if (isClassBlackListed(name)) {
576:                    if (trace)
577:                        log.trace("Class in blacklist, name=" + name);
578:                    throw new ClassNotFoundException(
579:                            "Class Not Found(blacklist): " + name);
580:                }
581:
582:                Translator translator = repository.getTranslator();
583:                if (translator != null) {
584:                    // Obtain the transformed class bytecode 
585:                    try {
586:                        // Obtain the raw bytecode from the classpath
587:                        URL classUrl = getClassURL(name);
588:                        byte[] rawcode = loadByteCode(classUrl);
589:                        URL codeSourceUrl = getCodeSourceURL(name, classUrl);
590:                        ProtectionDomain pd = getProtectionDomain(codeSourceUrl);
591:                        byte[] bytecode = translator.transform(this , name,
592:                                null, pd, rawcode);
593:                        // If there was no transform use the raw bytecode
594:                        if (bytecode == null)
595:                            bytecode = rawcode;
596:                        // Define the class package and instance
597:                        definePackage(name);
598:                        return defineClass(name, bytecode, 0, bytecode.length,
599:                                pd);
600:                    } catch (ClassNotFoundException e) {
601:                        throw e;
602:                    } catch (Throwable ex) {
603:                        throw new ClassNotFoundException(name, ex);
604:                    }
605:                }
606:
607:                Class clazz = null;
608:                try {
609:                    clazz = findClassLocally(name);
610:                } catch (ClassNotFoundException e) {
611:                    if (trace)
612:                        log.trace("CFNE: Adding to blacklist: " + name);
613:                    addToClassBlackList(name);
614:                    throw e;
615:                }
616:                return clazz;
617:            }
618:
619:            /**
620:             * Find the class
621:             * 
622:             * @param name the name of the class
623:             * @return the class
624:             */
625:            protected Class findClassLocally(String name)
626:                    throws ClassNotFoundException {
627:                return super .findClass(name);
628:            }
629:
630:            /**
631:             * Define the package for the class if not already done
632:             *
633:             * @todo this properly
634:             * @param className the class name
635:             */
636:            protected void definePackage(String className) {
637:                int i = className.lastIndexOf('.');
638:                if (i == -1)
639:                    return;
640:
641:                try {
642:                    definePackage(className.substring(0, i), null, null, null,
643:                            null, null, null, null);
644:                } catch (IllegalArgumentException alreadyDone) {
645:                }
646:            }
647:
648:            /** Append the given url to the URLs used for class and resource loading
649:             * @param url the URL to load from
650:             */
651:            public void addURL(URL url) {
652:                if (url == null)
653:                    throw new IllegalArgumentException("url cannot be null");
654:
655:                if (repository.addClassLoaderURL(this , url) == true) {
656:                    log.debug("Added url: " + url + ", to ucl: " + this );
657:                    // Strip any query parameters
658:                    String query = url.getQuery();
659:                    if (query != null) {
660:                        String ext = url.toExternalForm();
661:                        String ext2 = ext.substring(0, ext.length()
662:                                - query.length() - 1);
663:                        try {
664:                            url = new URL(ext2);
665:                        } catch (MalformedURLException e) {
666:                            log.warn("Failed to strip query from: " + url, e);
667:                        }
668:                    }
669:                    super .addURL(url);
670:                    clearBlackLists();
671:                } else if (log.isTraceEnabled()) {
672:                    log.trace("Ignoring duplicate url: " + url + ", for ucl: "
673:                            + this );
674:                }
675:            }
676:
677:            /**
678:             * Return an empty URL array to force the RMI marshalling subsystem to
679:             * use the <tt>java.server.codebase</tt> property as the annotated codebase.
680:             *
681:             * <p>Do not remove this method without discussing it on the dev list.
682:             *
683:             * @return Empty URL[]
684:             */
685:            public URL[] getURLs() {
686:                return EMPTY_URL_ARRAY;
687:            }
688:
689:            public Package getPackage(String name) {
690:                return super .getPackage(name);
691:            }
692:
693:            public Package[] getPackages() {
694:                return super .getPackages();
695:            }
696:
697:            // Object overrides ----------------------------------------------
698:
699:            /**
700:             * This is here to document that this must delegate to the
701:             * super implementation to perform identity based equality. Using
702:             * URL based equality caused conflicts with the Class.forName(String,
703:             * boolean, ClassLoader).
704:             */
705:            public final boolean equals(Object other) {
706:                return super .equals(other);
707:            }
708:
709:            /**
710:             * This is here to document that this must delegate to the
711:             * super implementation to perform identity based hashing. Using
712:             * URL based hashing caused conflicts with the Class.forName(String,
713:             * boolean, ClassLoader).
714:             */
715:            public final int hashCode() {
716:                return super .hashCode();
717:            }
718:
719:            /**
720:             * Returns a string representation.
721:             */
722:            public String toString() {
723:                return super .toString() + "{ url=" + getURL() + " }";
724:            }
725:
726:            // Protected -----------------------------------------------------
727:
728:            /** Attempt to acquire the class loading lock. This lock must be acquired
729:             * before a thread enters the class loading task loop in loadClass. This
730:             * method maintains any interrupted state of the calling thread.
731:             *@see #loadClass(String, boolean)
732:             */
733:            protected boolean attempt(long waitMS) {
734:                boolean acquired = false;
735:                boolean trace = log.isTraceEnabled();
736:                // Save and clear the interrupted state of the incoming thread
737:                boolean threadWasInterrupted = Thread.interrupted();
738:                try {
739:                    acquired = loadLock.attempt(waitMS);
740:                } catch (InterruptedException e) {
741:                } finally {
742:                    // Restore the interrupted state of the thread
743:                    if (threadWasInterrupted)
744:                        Thread.currentThread().interrupt();
745:                }
746:                if (trace)
747:                    log.trace("attempt(" + loadLock.holds() + ") was: "
748:                            + acquired + " for :" + this );
749:                return acquired;
750:            }
751:
752:            /** Acquire the class loading lock. This lock must be acquired
753:             * before a thread enters the class loading task loop in loadClass.
754:             *@see #loadClass(String, boolean)
755:             */
756:            protected void acquire() {
757:                // Save and clear the interrupted state of the incoming thread
758:                boolean threadWasInterrupted = Thread.interrupted();
759:                try {
760:                    loadLock.acquire();
761:                } catch (InterruptedException e) {
762:                } finally {
763:                    // Restore the interrupted state of the thread
764:                    if (threadWasInterrupted)
765:                        Thread.currentThread().interrupt();
766:                }
767:                if (log.isTraceEnabled())
768:                    log
769:                            .trace("acquired(" + loadLock.holds() + ") for :"
770:                                    + this );
771:            }
772:
773:            /** Release the class loading lock previous acquired through the acquire
774:             * method.
775:             */
776:            protected void release() {
777:                if (log.isTraceEnabled())
778:                    log.trace("release(" + loadLock.holds() + ") for :" + this );
779:                loadLock.release();
780:                if (log.isTraceEnabled())
781:                    log.trace("released, holds: " + loadLock.holds());
782:            }
783:
784:            /** Obtain the bytecode for the indicated class from this class loaders
785:             * classpath.
786:             * 
787:             * @param classname
788:             * @return the bytecode array if found
789:             * @exception ClassNotFoundException - if the class resource could not
790:             *    be found
791:             */
792:            protected byte[] loadByteCode(String classname)
793:                    throws ClassNotFoundException, IOException {
794:                byte[] bytecode = null;
795:                URL classURL = getClassURL(classname);
796:
797:                // Load the class bytecode
798:                InputStream is = null;
799:                try {
800:                    is = classURL.openStream();
801:                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
802:                    byte[] tmp = new byte[1024];
803:                    int read = 0;
804:                    while ((read = is.read(tmp)) > 0) {
805:                        baos.write(tmp, 0, read);
806:                    }
807:                    bytecode = baos.toByteArray();
808:                } finally {
809:                    if (is != null)
810:                        is.close();
811:                }
812:
813:                return bytecode;
814:            }
815:
816:            /** Obtain the bytecode for the indicated class from this class loaders
817:             * classpath.
818:             *
819:             * @param classURL
820:             * @return the bytecode array if found
821:             * @exception ClassNotFoundException - if the class resource could not
822:             *    be found
823:             */
824:            protected byte[] loadByteCode(URL classURL)
825:                    throws ClassNotFoundException, IOException {
826:                byte[] bytecode = null;
827:                // Load the class bytecode
828:                InputStream is = null;
829:                try {
830:                    is = classURL.openStream();
831:                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
832:                    byte[] tmp = new byte[1024];
833:                    int read = 0;
834:                    while ((read = is.read(tmp)) > 0) {
835:                        baos.write(tmp, 0, read);
836:                    }
837:                    bytecode = baos.toByteArray();
838:                } finally {
839:                    if (is != null)
840:                        is.close();
841:                }
842:
843:                return bytecode;
844:            }
845:
846:            /**
847:             * Determine the protection domain. If we are a copy of the original
848:             * deployment, use the original url as the codebase.
849:             * @return the protection domain
850:             * @todo certificates and principles?
851:             */
852:            protected ProtectionDomain getProtectionDomain(URL codesourceUrl) {
853:                Certificate certs[] = null;
854:                CodeSource cs = new CodeSource(codesourceUrl, certs);
855:                PermissionCollection permissions = Policy.getPolicy()
856:                        .getPermissions(cs);
857:                if (log.isTraceEnabled())
858:                    log.trace("getProtectionDomain, url=" + codesourceUrl
859:                            + " codeSource=" + cs + " permissions="
860:                            + permissions);
861:                return new ProtectionDomain(cs, permissions);
862:            }
863:
864:            // Package Private -----------------------------------------------
865:
866:            // Private -------------------------------------------------------
867:
868:            private URL getCodeSourceURL(String classname, URL classURL)
869:                    throws java.net.MalformedURLException {
870:                String classRsrcName = classname.replace('.', '/') + ".class";
871:                String urlAsString = classURL.toString();
872:                int idx = urlAsString.indexOf(classRsrcName);
873:                if (idx == -1)
874:                    return classURL;
875:                urlAsString = urlAsString.substring(0, idx);
876:                return new URL(urlAsString);
877:            }
878:
879:            private URL getClassURL(String classname)
880:                    throws ClassNotFoundException {
881:                String classRsrcName = classname.replace('.', '/') + ".class";
882:                URL classURL = this .getResourceLocally(classRsrcName);
883:                if (classURL == null) {
884:                    String msg = "Failed to find: " + classname
885:                            + " as resource: " + classRsrcName;
886:                    throw new ClassNotFoundException(msg);
887:                }
888:                return classURL;
889:            }
890:
891:            // Inner classes -------------------------------------------------
892:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.