Source Code Cross Referenced for LoadMgr3.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.net.URL;
025:        import java.util.Collections;
026:        import java.util.HashMap;
027:        import java.util.Iterator;
028:        import java.util.LinkedList;
029:        import java.util.List;
030:        import java.util.Map;
031:        import java.util.Set;
032:        import java.util.WeakHashMap;
033:        import java.security.PrivilegedAction;
034:        import java.security.AccessController;
035:
036:        import org.jboss.logging.Logger;
037:        import org.jboss.mx.loading.ClassLoadingTask.ThreadTask;
038:
039:        /** A utility class used by the UnifiedClassLoader3 to manage the thread based
040:         * class loading tasks.
041:         *
042:         * @author Scott.Stark@jboss.org
043:         * @version $Revision: 63285 $
044:         */
045:        public class LoadMgr3 {
046:            private static Logger log = Logger.getLogger(LoadMgr3.class);
047:            /** Used as a synchronization monitor during the setup/teardown of the
048:               thread owning a UCL.loadClass lock
049:             */
050:            private static Object registrationLock = new Object();
051:
052:            /** A Map<UnifiedClassLoader3, Thread> of the active loadClass UCL3/threads.
053:             * This must be accessed under the registrationLock monitor.
054:             */
055:            private static HashMap loadClassThreads = new HashMap();
056:            /** A Map<Thread, LinkedList<ThreadTask> > of the class loading tasks
057:             * associated with a thread
058:             */
059:            private static Map loadTasksByThread = Collections
060:                    .synchronizedMap(new WeakHashMap());
061:
062:            private static SecurityManager sm = System.getSecurityManager();
063:
064:            /** A UCL and its relative ordering with respect to the class loading.
065:             * The UCL with the lowest order to load a class is the UCL that will
066:             * populate the repository cache and be assigned as the UCL.loadClass
067:             * return value.
068:             */
069:            public static class PkgClassLoader {
070:                public final RepositoryClassLoader ucl;
071:                public final int order;
072:
073:                public PkgClassLoader(RepositoryClassLoader ucl) {
074:                    this (ucl, Integer.MAX_VALUE);
075:                }
076:
077:                public PkgClassLoader(RepositoryClassLoader ucl, int order) {
078:                    this .ucl = ucl;
079:                    this .order = order;
080:                }
081:
082:                public String toString() {
083:                    StringBuffer buffer = new StringBuffer(100);
084:                    buffer.append(super .toString());
085:                    buffer.append("{ucl=").append(ucl);
086:                    buffer.append(" order=").append(order);
087:                    buffer.append('}');
088:                    return buffer.toString();
089:                }
090:            }
091:
092:            /** A PrivilegedAction for locating a class as a resource
093:             * 
094:             */
095:            private static class ResourceAction implements  PrivilegedAction {
096:                RepositoryClassLoader ucl;
097:                String classRsrcName;
098:
099:                ResourceAction(RepositoryClassLoader ucl, String classRsrcName) {
100:                    this .ucl = ucl;
101:                    this .classRsrcName = classRsrcName;
102:                }
103:
104:                public Object run() {
105:                    URL url = ucl.getResourceLocally(classRsrcName);
106:                    ucl = null;
107:                    classRsrcName = null;
108:                    return url;
109:                }
110:            }
111:
112:            /** Register that a thread owns the UCL3.loadClass monitor. This is called
113:             * from within UCL3.loadClass(String,boolean) and this method creates
114:             * entries in the loadClassThreads and loadTasksByThread maps.
115:             */
116:            public static void registerLoaderThread(RepositoryClassLoader ucl,
117:                    Thread t) {
118:                synchronized (registrationLock) {
119:                    Object prevThread = loadClassThreads.put(ucl, t);
120:                    if (log.isTraceEnabled())
121:                        log.trace("registerLoaderThread, ucl=" + ucl + ", t="
122:                                + t + ", prevT=" + prevThread);
123:
124:                    synchronized (loadTasksByThread) {
125:                        List taskList = (List) loadTasksByThread.get(t);
126:                        if (taskList == null) {
127:                            taskList = Collections
128:                                    .synchronizedList(new LinkedList());
129:                            loadTasksByThread.put(t, taskList);
130:                            if (log.isTraceEnabled())
131:                                log.trace("created new task list");
132:                        }
133:                    }
134:                    registrationLock.notifyAll();
135:                }
136:            }
137:
138:            /** Initiate the class loading task. This is called by UCL3.loadClass to
139:             * initiate the process of loading the requested class. This first attempts
140:             * to load the class from the repository cache, and then the class loaders
141:             * in the repsository. If the package of the class is found in the repository
142:             * then one or more ThreadTask are created to complete the ClassLoadingTask.
143:             * The ThreadTask are assigned to the threads that own the associated UCL3
144:             * monitor. If no class loader serves the class package, then the requesting
145:             * class loader is asked if it can load the class.
146:             *
147:             * @return true if the class could be loaded from the cache or requesting
148:             * UCL3, false to indicate the calling thread must process the
149:             * tasks assigned to it until the ClassLoadingTask state is FINISHED
150:             * @exception ClassNotFoundException if there is no chance the class can
151:             * be loaded from the current repository class loaders.
152:             */
153:            public static boolean beginLoadTask(ClassLoadingTask task,
154:                    UnifiedLoaderRepository3 repository)
155:                    throws ClassNotFoundException {
156:                boolean trace = log.isTraceEnabled();
157:                if (trace)
158:                    log.trace("Begin beginLoadTask, task=" + task);
159:
160:                // Try the cache before anything else.
161:                Class cls = repository.loadClassFromCache(task.classname);
162:                if (cls != null) {
163:                    task.loadedClass = cls;
164:                    task.state = ClassLoadingTask.FINISHED;
165:                    if (trace)
166:                        log
167:                                .trace("End beginLoadTask, loadClassFromCache, classname: "
168:                                        + task.classname);
169:                    return true;
170:                }
171:
172:                // Next get the set of class loaders from the packages map
173:                Set pkgSet = repository.getPackageClassLoaders(task.classname);
174:                if (pkgSet == null || pkgSet.size() == 0) {
175:                    if (task.stopOrder == Integer.MAX_VALUE) {
176:                        /* If there are no class loaders in the repository capable of handling
177:                        the request ask the class loader itself in the event that its parent(s)
178:                        can load the class.
179:                         */
180:                        try {
181:                            cls = repository.loadClassFromClassLoader(
182:                                    task.classname, false,
183:                                    task.requestingClassLoader);
184:                        } catch (LinkageError e) {
185:                            if (trace)
186:                                log.trace(
187:                                        "End beginLoadTask, LinkageError for task: "
188:                                                + task, e);
189:                            throw e;
190:                        }
191:                        if (cls != null) {
192:                            task.loadedClass = cls;
193:                            task.state = ClassLoadingTask.FINISHED;
194:                            if (trace)
195:                                log
196:                                        .trace("End beginLoadTask, loadClassFromClassLoader");
197:                            return true;
198:                        }
199:                    }
200:
201:                    // Else, fail the load
202:                    if (trace)
203:                        log.trace("End beginLoadTask, ClassNotFoundException");
204:                    String msg = "No ClassLoaders found for: " + task.classname;
205:                    throw new ClassNotFoundException(msg);
206:                }
207:
208:                /* A class loading task for each ClassLoader is needed. There can be
209:                   multiple class loaders for a pkg due to the pkg being spread out over
210:                   multiple jars, or duplicate classes due to versioning/patches, or
211:                   just bad packaging.
212:
213:                   In the case of a non-scoped deployment of multiple classes which
214:                   will provide a PkgClassLoader to define the ordering, we simply
215:                   choose an ordering based on the order the UCL3s were added to the
216:                   repository. At most one of the candidate UCL3s will load the class
217:                   in order to avoid ClassCastExceptions or LinkageErrors due to the
218:                   strong Java type system/security model.
219:
220:                   TODO: A simple ordering mechanism exists, but this probably needs
221:                   to be augmented.
222:                 */
223:                Iterator iter = pkgSet.iterator();
224:                RepositoryClassLoader theUCL = null;
225:                int order = Integer.MAX_VALUE;
226:                while (iter.hasNext()) {
227:                    Object next = iter.next();
228:                    int uclOrder;
229:                    RepositoryClassLoader ucl;
230:                    // This may be either a PkgClassLoader or a UCL3
231:                    if (next instanceof  RepositoryClassLoader) {
232:                        ucl = (RepositoryClassLoader) next;
233:                        uclOrder = ucl.getAddedOrder();
234:                    } else {
235:                        PkgClassLoader pkgUcl = (PkgClassLoader) next;
236:                        ucl = pkgUcl.ucl;
237:                        uclOrder = pkgUcl.order;
238:                    }
239:
240:                    // If we have a stop order check it
241:                    if (task.stopOrder != Integer.MAX_VALUE
242:                            && task.stopOrder <= uclOrder)
243:                        break;
244:
245:                    // Validate that the ucl has the class as a resource
246:                    String classRsrcName = task.classname.replace('.', '/')
247:                            + ".class";
248:                    URL url = null;
249:                    if (sm != null) {
250:                        ResourceAction action = new ResourceAction(ucl,
251:                                classRsrcName);
252:                        url = (URL) AccessController.doPrivileged(action);
253:                    } else {
254:                        url = ucl.getResourceLocally(classRsrcName);
255:                    }
256:
257:                    if (url != null && uclOrder < order) {
258:                        if (trace && theUCL != null)
259:                            log.trace("Replacing UCL: " + theUCL + " with UCL:"
260:                                    + ucl);
261:                        theUCL = ucl;
262:                        order = uclOrder;
263:                    }
264:                }
265:                if (theUCL == null && task.stopOrder == Integer.MAX_VALUE) {
266:                    /* If there are no class loaders in the repository capable of handling
267:                    the request ask the class loader itself in the event that its parent(s)
268:                    can load the class. But not if we have a stopOrder.
269:                     */
270:                    try {
271:                        cls = repository.loadClassFromClassLoader(
272:                                task.classname, false,
273:                                task.requestingClassLoader);
274:                    } catch (LinkageError e) {
275:                        if (trace)
276:                            log.trace(
277:                                    "End beginLoadTask, LinkageError for task: "
278:                                            + task, e);
279:                        throw e;
280:                    }
281:                    if (cls != null) {
282:                        task.loadedClass = cls;
283:                        task.state = ClassLoadingTask.FINISHED;
284:                        if (trace)
285:                            log
286:                                    .trace("End beginLoadTask, loadClassFromClassLoader");
287:                        return true;
288:                    }
289:
290:                    // Else, fail the load
291:                    if (trace)
292:                        log.trace("End beginLoadTask, ClassNotFoundException");
293:                    String msg = "No ClassLoaders found for: " + task.classname;
294:                    throw new ClassNotFoundException(msg);
295:                }
296:
297:                if (theUCL == null) {
298:                    if (trace)
299:                        log.trace("End beginLoadTask, ClassNotFoundException");
300:                    String msg = "No ClassLoaders found for: " + task.classname;
301:                    throw new ClassNotFoundException(msg);
302:                }
303:
304:                scheduleTask(task, theUCL, order, false, trace);
305:                task.state = ClassLoadingTask.FOUND_CLASS_LOADER;
306:                if (trace)
307:                    log.trace("End beginLoadTask, task=" + task);
308:
309:                return false;
310:            }
311:
312:            /** Called by threads owning a UCL3.loadLock from within UCL3.loadClass to
313:             * process ThreadTasks assigned to them. This is the mechanism by which we
314:             * avoid deadlock due to a given loadClass request requiring multiple UCLs
315:             * to be involved. Any thread active in loadClass with the monitor held
316:             * processes class loading tasks that must be handled by its UCL3. The
317:             * active set of threads loading classes form a pool of cooperating threads.
318:             */
319:            public static void nextTask(Thread t, ClassLoadingTask task,
320:                    UnifiedLoaderRepository3 repository)
321:                    throws InterruptedException {
322:                boolean trace = log.isTraceEnabled();
323:                List taskList = (List) loadTasksByThread.get(t);
324:                synchronized (taskList) {
325:                    // There may not be any ThreadTasks
326:                    while (taskList.size() == 0 && task.threadTaskCount != 0) {
327:                        /* There are no more tasks for the calling thread to execute, so the
328:                        calling thread must wait until the task.threadTaskCount reaches 0
329:                         */
330:                        if (trace)
331:                            log.trace("Begin nextTask(WAIT_ON_EVENT), task="
332:                                    + task);
333:                        try {
334:                            task.state = ClassLoadingTask.WAIT_ON_EVENT;
335:                            taskList.wait();
336:                        } catch (InterruptedException e) {
337:                            if (trace)
338:                                log.trace(
339:                                        "nextTask(WAIT_ON_EVENT), interrupted, task="
340:                                                + task, e);
341:                            // Abort this task attempt
342:                            throw e;
343:                        }
344:                        if (trace)
345:                            log
346:                                    .trace("nextTask(WAIT_ON_EVENT), notified, task="
347:                                            + task);
348:                    }
349:
350:                    if (trace)
351:                        log.trace("Continue nextTask(" + taskList.size()
352:                                + "), task=" + task);
353:
354:                    // See if the task is complete
355:                    if (task.threadTaskCount == 0) {
356:                        task.state = ClassLoadingTask.FINISHED;
357:                        log.trace("End nextTask(FINISHED), task=" + task);
358:                        return;
359:                    }
360:                }
361:
362:                ThreadTask threadTask = (ThreadTask) taskList.remove(0);
363:                ClassLoadingTask loadTask = threadTask.getLoadTask();
364:                if (trace)
365:                    log.trace("Begin nextTask(" + taskList.size()
366:                            + "), loadTask=" + loadTask);
367:
368:                RepositoryClassLoader ucl3 = threadTask.ucl;
369:                try {
370:                    if (threadTask.t == null) {
371:                        /* This is a task that has been reassigned back to the original
372:                        requesting thread ClassLoadingTask, so a new ThreadTask must
373:                        be scheduled.
374:                         */
375:                        if (trace)
376:                            log.trace("Rescheduling threadTask=" + threadTask);
377:                        scheduleTask(loadTask, ucl3, threadTask.order, true,
378:                                trace);
379:                    } else {
380:                        if (trace)
381:                            log.trace("Running threadTask=" + threadTask);
382:                        // Load the class using this thread
383:                        threadTask.run();
384:                    }
385:                } catch (Throwable e) {
386:                    boolean retry = e instanceof  ClassCircularityError
387:                            || e.getClass().equals(LinkageError.class);
388:                    int numCCE = loadTask.incNumCCE();
389:                    if (retry && numCCE <= 10) {
390:                        /* Reschedule this task after all existing tasks to allow the
391:                        current load tasks which are conflicting to complete.
392:                         */
393:                        try {
394:                            if (trace)
395:                                log.trace("Run failed with exception", e);
396:                            // Reschedule and update the loadTask.threadTaskCount
397:                            scheduleTask(loadTask, ucl3, Integer.MAX_VALUE,
398:                                    true, trace);
399:                        } catch (Throwable ex) {
400:                            loadTask.setLoadError(ex);
401:                            log
402:                                    .warn(
403:                                            "Failed to reschedule task after LinkageError",
404:                                            ex);
405:                        }
406:                        if (trace)
407:                            log.trace("Post LinkageError state, loadTask="
408:                                    + loadTask);
409:                    } else {
410:                        loadTask.setLoadError(e);
411:                        if (trace)
412:                            log.trace("Run failed with exception, loadTask="
413:                                    + loadTask, e);
414:                    }
415:                } finally {
416:                    // We must release the loadLock acquired in beginLoadTask
417:                    if (threadTask.releaseInNextTask == true) {
418:                        if (trace)
419:                            log
420:                                    .trace("Releasing loadLock and ownership of UCL: "
421:                                            + threadTask.ucl);
422:                        synchronized (registrationLock) {
423:                            loadClassThreads.remove(threadTask.ucl);
424:                        }
425:                        synchronized (threadTask.ucl) {
426:                            ucl3.release();
427:                            ucl3.notifyAll();
428:                        }
429:                    }
430:                }
431:
432:                // If the ThreadTasks are complete mark the ClassLoadingTask finished
433:                if (loadTask.threadTaskCount == 0) {
434:                    Class loadedClass = threadTask.getLoadedClass();
435:                    if (loadedClass != null) {
436:                        ClassLoader loader = loadedClass.getClassLoader();
437:                        ClassLoader wrapper = repository
438:                                .getWrappingClassLoader(loader);
439:                        if (wrapper != null)
440:                            loader = wrapper;
441:                        // Place the loaded class into the repositry cache
442:                        repository.cacheLoadedClass(threadTask.getClassname(),
443:                                loadedClass, loader);
444:                    }
445:                    /*
446:                    synchronized( loadTask )
447:                    {
448:                       if( trace )
449:                          log.trace("Notifying task of thread completion, loadTask:"+loadTask);
450:                       loadTask.state = ClassLoadingTask.FINISHED;
451:                       loadTask.notify();
452:                    }
453:                     */
454:                    List loadTaskThreadTasks = (List) loadTasksByThread
455:                            .get(loadTask.requestingThread);
456:                    synchronized (loadTaskThreadTasks) {
457:                        if (trace)
458:                            log
459:                                    .trace("Notifying task of thread completion, loadTask:"
460:                                            + loadTask);
461:                        loadTask.state = ClassLoadingTask.FINISHED;
462:                        loadTaskThreadTasks.notify();
463:                    }
464:                }
465:                if (trace)
466:                    log.trace("End nextTask(" + taskList.size()
467:                            + "), loadTask=" + loadTask);
468:            }
469:
470:            /** Complete a ClassLoadingTask. This is called by UCL3.loadClass to indicate
471:             * that the thread is existing the loadClass method.
472:             */
473:            public static void endLoadTask(ClassLoadingTask task) {
474:                boolean trace = log.isTraceEnabled();
475:                if (trace)
476:                    log.trace("Begin endLoadTask, task=" + task);
477:
478:                // Unregister as the owning thread and notify any waiting threads
479:                synchronized (registrationLock) {
480:                    loadClassThreads.remove(task.requestingClassLoader);
481:                    registrationLock.notifyAll();
482:                }
483:
484:                // Any ThreadTasks associated with this thread must be reassigned
485:                List taskList = (List) loadTasksByThread
486:                        .get(task.requestingThread);
487:                int size = taskList != null ? taskList.size() : 0;
488:                synchronized (taskList) {
489:                    for (int i = 0; i < size; i++) {
490:                        ThreadTask threadTask = (ThreadTask) taskList.remove(0);
491:                        ClassLoadingTask loadTask = threadTask.getLoadTask();
492:                        /* Synchronize on loadTask and reassign the thread task back to the
493:                        requesting thread of loadTask. We need to synchronize on loadTask
494:                        to ensure that the transfer of this task back to loadTask.requestingThread
495:                        is atomic wrt loadTask.requestingThread checking its task list.
496:                        synchronized( loadTask )
497:                        {
498:                           if( trace )
499:                              log.trace("Reassigning task: "+threadTask+", to: "+loadTask.requestingThread);
500:                           threadTask.t = null;
501:                           // Insert the task into the front of requestingThread task list
502:                           List toTaskList = (List) loadTasksByThread.get(loadTask.requestingThread);
503:                           toTaskList.add(0, threadTask);
504:                           loadTask.state = ClassLoadingTask.NEXT_EVENT;
505:                           loadTask.notify();
506:                        }
507:                         */
508:                        if (trace)
509:                            log.trace("Reassigning task: " + threadTask
510:                                    + ", to: " + loadTask.requestingThread);
511:                        threadTask.t = null;
512:                        // Insert the task into the front of requestingThread task list
513:                        List toTaskList = (List) loadTasksByThread
514:                                .get(loadTask.requestingThread);
515:                        synchronized (toTaskList) {
516:                            toTaskList.add(0, threadTask);
517:                            loadTask.state = ClassLoadingTask.NEXT_EVENT;
518:                            toTaskList.notify();
519:                        }
520:                    }
521:                }
522:            }
523:
524:            /** Invoked to create a ThreadTask to assign a thread to the task of
525:             * loading the class of ClassLoadingTask.
526:             *
527:             * @param task the orginating UCL3.loadClass task for which the thread
528:             * @param ucl the UCL3 the ThreadTask will call loadClassLocally on
529:             * @param order the heirachical ordering of the task
530:             * @param reschedule a boolean indicating if this task is being rescheduled
531:             *    with another UCL3
532:             * @param trace the Logger trace level flag
533:             * @throws ClassNotFoundException
534:             */
535:            static private void scheduleTask(ClassLoadingTask task,
536:                    RepositoryClassLoader ucl, int order, boolean reschedule,
537:                    boolean trace) throws ClassNotFoundException {
538:                Thread t = null;
539:                boolean releaseInNextTask = false;
540:                ThreadTask subtask = null;
541:                List taskList = null;
542:                synchronized (registrationLock) {
543:                    // Find the thread that owns the ucl
544:                    t = (Thread) loadClassThreads.get(ucl);
545:                    if (t == null) {
546:                        /* There is no thread in the UCL.loadClass yet that has registered
547:                           as the owning thread. We must attempt to acquire the loadLock
548:                           and if we cannot, wait until the thread entering UCL.loadClass
549:                           gets to the registerLoaderThread call. By the time we are
550:                           notified, the thread coule in fact have exited loadClass, so
551:                           we either assign the task to the thread, or take ownership of
552:                           the UCL.
553:                         */
554:                        while (t == null && ucl.attempt(1) == false) {
555:                            if (trace)
556:                                log.trace("Waiting for owner of UCL: " + ucl);
557:                            try {
558:                                registrationLock.wait();
559:                            } catch (InterruptedException e) {
560:                                String msg = "Interrupted waiting for registration notify,"
561:                                        + " classame: " + task.classname;
562:                                throw new ClassNotFoundException(msg);
563:                            }
564:
565:                            t = (Thread) loadClassThreads.get(ucl);
566:                            if (trace)
567:                                log.trace("Notified that UCL owner is: " + t);
568:                        }
569:
570:                        // Get the thread registered as owning the UCL.loadClass lock
571:                        t = (Thread) loadClassThreads.get(ucl);
572:                        if (t == null) {
573:                            // There is no such thread, register as the owner
574:                            releaseInNextTask = true;
575:                            t = task.requestingThread;
576:                            Object prevThread = loadClassThreads.put(ucl, t);
577:                            if (trace) {
578:                                log
579:                                        .trace("scheduleTask, taking ownership of ucl="
580:                                                + ucl
581:                                                + ", t="
582:                                                + t
583:                                                + ", prevT="
584:                                                + prevThread);
585:                            }
586:                        }
587:                    }
588:
589:                    // Now that we have the UCL owner thread, create and assign the task
590:                    subtask = task.newThreadTask(ucl, t, order, reschedule,
591:                            releaseInNextTask);
592:                    // Add the task to the owning thread
593:                    taskList = (List) loadTasksByThread.get(t);
594:                    synchronized (taskList) {
595:                        taskList.add(subtask);
596:                        // Order the tasks by either the heirarchial order, or the repository order
597:                        Collections.sort(taskList,
598:                                ClassLoadingTask.taskComparator);
599:                        taskList.notify();
600:                    }
601:                }
602:
603:                if (trace)
604:                    log.trace("scheduleTask(" + taskList.size()
605:                            + "), created subtask: " + subtask);
606:            }
607:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.