1 22 package org.jboss.mx.loading; 23 24 import java.net.URL ; 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.Set ; 32 import java.util.WeakHashMap ; 33 import java.security.PrivilegedAction ; 34 import java.security.AccessController ; 35 36 import org.jboss.classloading.spi.DomainClassLoader; 37 import org.jboss.logging.Logger; 38 import org.jboss.mx.loading.ClassLoadingTaskDCL.ThreadTask; 39 40 41 47 public class LoadMgrDCL 48 { 49 private static Logger log = Logger.getLogger(LoadMgrDCL.class); 50 53 private static Object registrationLock = new Object (); 54 55 58 private static HashMap loadClassThreads = new HashMap (); 59 62 private static Map loadTasksByThread = Collections.synchronizedMap(new WeakHashMap ()); 63 64 private static SecurityManager sm = System.getSecurityManager(); 65 66 71 public static class PkgClassLoader 72 { 73 public final DomainClassLoaderUCLImpl ucl; 74 public final int order; 75 76 public PkgClassLoader(DomainClassLoaderUCLImpl ucl) 77 { 78 this(ucl, Integer.MAX_VALUE); 79 } 80 public PkgClassLoader(DomainClassLoaderUCLImpl ucl, int order) 81 { 82 this.ucl = ucl; 83 this.order = order; 84 } 85 86 public String toString() 87 { 88 StringBuffer buffer = new StringBuffer (100); 89 buffer.append(super.toString()); 90 buffer.append("{ucl=").append(ucl); 91 buffer.append(" order=").append(order); 92 buffer.append('}'); 93 return buffer.toString(); 94 } 95 } 96 99 private static class ResourceAction implements PrivilegedAction 100 { 101 DomainClassLoader ucl; 102 String classRsrcName; 103 ResourceAction(DomainClassLoader ucl, String classRsrcName) 104 { 105 this.ucl = ucl; 106 this.classRsrcName = classRsrcName; 107 } 108 public Object run() 109 { 110 URL url = ucl.loadResourceLocally(classRsrcName); 111 ucl = null; 112 classRsrcName = null; 113 return url; 114 } 115 } 116 117 121 public static void registerLoaderThread(DomainClassLoader ucl, Thread t) 122 { 123 synchronized( registrationLock ) 124 { 125 Object prevThread = loadClassThreads.put(ucl, t); 126 if( log.isTraceEnabled() ) 127 log.trace("registerLoaderThread, ucl="+ucl+", t="+t+", prevT="+prevThread); 128 129 synchronized( loadTasksByThread ) 130 { 131 List taskList = (List ) loadTasksByThread.get(t); 132 if( taskList == null ) 133 { 134 taskList = Collections.synchronizedList(new LinkedList ()); 135 loadTasksByThread.put(t, taskList); 136 if( log.isTraceEnabled() ) 137 log.trace("created new task list"); 138 } 139 } 140 registrationLock.notifyAll(); 141 } 142 } 143 144 159 public static boolean beginLoadTask(ClassLoadingTaskDCL task, 160 UnifiedLoaderRepositoryDCL repository) 161 throws ClassNotFoundException 162 { 163 boolean trace = log.isTraceEnabled(); 164 if( trace ) 165 log.trace("Begin beginLoadTask, task="+task); 166 167 Class cls = repository.loadClassFromCache(task.classname); 169 if( cls != null ) 170 { 171 task.loadedClass = cls; 172 task.state = ClassLoadingTaskDCL.FINISHED; 173 if( trace ) 174 log.trace("End beginLoadTask, loadClassFromCache, classname: "+task.classname); 175 return true; 176 } 177 178 Set pkgSet = repository.getPackageClassLoaders(task.classname); 180 if( pkgSet == null || pkgSet.size() == 0 ) 181 { 182 if (task.stopOrder == Integer.MAX_VALUE) 183 { 184 188 try 189 { 190 cls = repository.loadClassFromClassLoader(task.classname, false, 191 task.requestingClassLoader); 192 } 193 catch(LinkageError e) 194 { 195 if( trace ) 196 log.trace("End beginLoadTask, LinkageError for task: "+task, e); 197 throw e; 198 } 199 if( cls != null ) 200 { 201 task.loadedClass = cls; 202 task.state = ClassLoadingTaskDCL.FINISHED; 203 if( trace ) 204 log.trace("End beginLoadTask, loadClassFromClassLoader"); 205 return true; 206 } 207 } 208 209 if( trace ) 211 log.trace("End beginLoadTask, ClassNotFoundException"); 212 String msg = "No ClassLoaders found for: "+task.classname; 213 throw new ClassNotFoundException (msg); 214 } 215 216 231 Iterator iter = pkgSet.iterator(); 232 DomainClassLoaderUCLImpl theUCL = null; 233 int order = Integer.MAX_VALUE; 234 while( iter.hasNext() ) 235 { 236 Object next = iter.next(); 237 int uclOrder; 238 DomainClassLoaderUCLImpl ucl; 239 if( next instanceof DomainClassLoaderUCLImpl ) 241 { 242 ucl = (DomainClassLoaderUCLImpl) next; 243 uclOrder = 0; } 245 else 246 { 247 PkgClassLoader pkgUcl = (PkgClassLoader) next; 248 ucl = pkgUcl.ucl; 249 uclOrder = pkgUcl.order; 250 } 251 252 if (task.stopOrder != Integer.MAX_VALUE && task.stopOrder <= uclOrder) 254 break; 255 256 String classRsrcName = task.classname.replace('.', '/') + ".class"; 258 URL url = null; 259 if( sm != null ) 260 { 261 ResourceAction action = new ResourceAction(ucl, classRsrcName); 262 url = (URL ) AccessController.doPrivileged(action); 263 } 264 else 265 { 266 url = ucl.loadResourceLocally(classRsrcName); 267 } 268 269 if( url != null && uclOrder < order ) 270 { 271 if( trace && theUCL != null ) 272 log.trace("Replacing UCL: "+theUCL+" with UCL:"+ucl); 273 theUCL = ucl; 274 order = uclOrder; 275 } 276 } 277 if( theUCL == null && task.stopOrder == Integer.MAX_VALUE) 278 { 279 283 try 284 { 285 cls = repository.loadClassFromClassLoader(task.classname, false, 286 task.requestingClassLoader); 287 } 288 catch(LinkageError e) 289 { 290 if( trace ) 291 log.trace("End beginLoadTask, LinkageError for task: "+task, e); 292 throw e; 293 } 294 if( cls != null ) 295 { 296 task.loadedClass = cls; 297 task.state = ClassLoadingTaskDCL.FINISHED; 298 if( trace ) 299 log.trace("End beginLoadTask, loadClassFromClassLoader"); 300 return true; 301 } 302 303 if( trace ) 305 log.trace("End beginLoadTask, ClassNotFoundException"); 306 String msg = "No ClassLoaders found for: "+task.classname; 307 throw new ClassNotFoundException (msg); 308 } 309 310 if (theUCL == null) 311 { 312 if( trace ) 313 log.trace("End beginLoadTask, ClassNotFoundException"); 314 String msg = "No ClassLoaders found for: "+task.classname; 315 throw new ClassNotFoundException (msg); 316 } 317 318 scheduleTask(task, theUCL, order, false, trace); 319 task.state = ClassLoadingTaskDCL.FOUND_CLASS_LOADER; 320 if( trace ) 321 log.trace("End beginLoadTask, task="+task); 322 323 return false; 324 } 325 326 333 public static void nextTask(Thread t, ClassLoadingTaskDCL task, 334 UnifiedLoaderRepositoryDCL repository) 335 throws InterruptedException 336 { 337 boolean trace = log.isTraceEnabled(); 338 List taskList = (List ) loadTasksByThread.get(t); 339 synchronized( taskList ) 340 { 341 while( taskList.size() == 0 && task.threadTaskCount != 0 ) 343 { 344 347 if( trace ) 348 log.trace("Begin nextTask(WAIT_ON_EVENT), task="+task); 349 try 350 { 351 task.state = ClassLoadingTaskDCL.WAIT_ON_EVENT; 352 taskList.wait(); 353 } 354 catch(InterruptedException e) 355 { 356 if( trace ) 357 log.trace("nextTask(WAIT_ON_EVENT), interrupted, task="+task, e); 358 throw e; 360 } 361 if( trace ) 362 log.trace("nextTask(WAIT_ON_EVENT), notified, task="+task); 363 } 364 365 if( trace ) 366 log.trace("Continue nextTask("+taskList.size()+"), task="+task); 367 368 if( task.threadTaskCount == 0 ) 370 { 371 task.state = ClassLoadingTaskDCL.FINISHED; 372 log.trace("End nextTask(FINISHED), task="+task); 373 return; 374 } 375 } 376 377 ThreadTask threadTask = (ThreadTask) taskList.remove(0); 378 ClassLoadingTaskDCL loadTask = threadTask.getLoadTask(); 379 if( trace ) 380 log.trace("Begin nextTask("+taskList.size()+"), loadTask="+loadTask); 381 382 DomainClassLoaderUCLImpl ucl3 = threadTask.ucl; 383 try 384 { 385 if( threadTask.t == null ) 386 { 387 391 if( trace ) 392 log.trace("Rescheduling threadTask="+threadTask); 393 scheduleTask(loadTask, ucl3, threadTask.order, true, trace); 394 } 395 else 396 { 397 if( trace ) 398 log.trace("Running threadTask="+threadTask); 399 threadTask.run(); 401 } 402 } 403 catch(Throwable e) 404 { 405 if( e instanceof ClassCircularityError ) 406 { 407 410 try 411 { 412 if( trace ) 413 log.trace("Run failed with exception", e); 414 scheduleTask(loadTask, ucl3, Integer.MAX_VALUE, true, trace); 416 } 417 catch(ClassNotFoundException ex) 418 { 419 loadTask.setLoadError(ex); 420 log.warn("Failed to reschedule task after CCE", ex); 421 } 422 if( trace ) 423 log.trace("Post CCE state, loadTask="+loadTask); 424 } 425 else 426 { 427 loadTask.setLoadError(e); 428 if( trace ) 429 log.trace("Run failed with exception", e); 430 } 431 } 432 finally 433 { 434 if( threadTask.releaseInNextTask == true ) 436 { 437 if( trace ) 438 log.trace("Releasing loadLock and ownership of UCL: "+threadTask.ucl); 439 synchronized( registrationLock ) 440 { 441 loadClassThreads.remove(threadTask.ucl); 442 } 443 synchronized( threadTask.ucl ) 444 { 445 ucl3.release(); 446 ucl3.notifyAll(); 447 } 448 } 449 } 450 451 if( loadTask.threadTaskCount == 0 ) 453 { 454 Class loadedClass = threadTask.getLoadedClass(); 455 if( loadedClass != null ) 456 { 457 ClassLoader loader = loadedClass.getClassLoader(); 458 ClassLoader wrapper = null; 459 if (wrapper != null) 460 loader=wrapper; 461 } 464 473 List loadTaskThreadTasks = (List ) loadTasksByThread.get(loadTask.requestingThread); 474 synchronized( loadTaskThreadTasks ) 475 { 476 if( trace ) 477 log.trace("Notifying task of thread completion, loadTask:"+loadTask); 478 loadTask.state = ClassLoadingTaskDCL.FINISHED; 479 loadTaskThreadTasks.notify(); 480 } 481 } 482 if( trace ) 483 log.trace("End nextTask("+taskList.size()+"), loadTask="+loadTask); 484 } 485 486 489 public static void endLoadTask(ClassLoadingTaskDCL task) 490 { 491 boolean trace = log.isTraceEnabled(); 492 if( trace ) 493 log.trace("Begin endLoadTask, task="+task); 494 495 synchronized( registrationLock ) 497 { 498 loadClassThreads.remove(task.requestingClassLoader); 499 registrationLock.notifyAll(); 500 } 501 502 List taskList = (List ) loadTasksByThread.get(task.requestingThread); 504 int size = taskList != null ? taskList.size() : 0; 505 synchronized( taskList ) 506 { 507 for(int i = 0; i < size; i ++) 508 { 509 ThreadTask threadTask = (ThreadTask) taskList.remove(0); 510 ClassLoadingTaskDCL loadTask = threadTask.getLoadTask(); 511 527 if( trace ) 528 log.trace("Reassigning task: "+threadTask+", to: "+loadTask.requestingThread); 529 threadTask.t = null; 530 List toTaskList = (List ) loadTasksByThread.get(loadTask.requestingThread); 532 synchronized( toTaskList ) 533 { 534 toTaskList.add(0, threadTask); 535 loadTask.state = ClassLoadingTaskDCL.NEXT_EVENT; 536 toTaskList.notify(); 537 } 538 } 539 } 540 } 541 542 553 static private void scheduleTask(ClassLoadingTaskDCL task, DomainClassLoaderUCLImpl ucl, 554 int order, boolean reschedule, boolean trace) throws ClassNotFoundException 555 { 556 Thread t = null; 557 boolean releaseInNextTask = false; 558 ThreadTask subtask = null; 559 List taskList = null; 560 synchronized( registrationLock ) 561 { 562 t = (Thread ) loadClassThreads.get(ucl); 564 if( t == null ) 565 { 566 574 while( t == null && ucl.attempt(1) == false ) 575 { 576 if( trace ) 577 log.trace("Waiting for owner of UCL: "+ucl); 578 try 579 { 580 registrationLock.wait(); 581 } 582 catch(InterruptedException e) 583 { 584 String msg = "Interrupted waiting for registration notify," 585 + " classame: "+task.classname; 586 throw new ClassNotFoundException (msg); 587 } 588 589 t = (Thread ) loadClassThreads.get(ucl); 590 if( trace ) 591 log.trace("Notified that UCL owner is: "+t); 592 } 593 594 t = (Thread ) loadClassThreads.get(ucl); 596 if( t == null ) 597 { 598 releaseInNextTask = true; 600 t = task.requestingThread; 601 Object prevThread = loadClassThreads.put(ucl, t); 602 if( trace ) 603 { 604 log.trace("scheduleTask, taking ownership of ucl="+ucl 605 +", t="+t+", prevT="+prevThread); 606 } 607 } 608 } 609 610 subtask = task.newThreadTask(ucl, t, order, reschedule, 612 releaseInNextTask); 613 taskList = (List ) loadTasksByThread.get(t); 615 synchronized( taskList ) 616 { 617 taskList.add(subtask); 618 Collections.sort(taskList, task.taskComparator); 620 taskList.notify(); 621 } 622 } 623 624 if( trace ) 625 log.trace("scheduleTask("+taskList.size()+"), created subtask: "+subtask); 626 } 627 } 628 | Popular Tags |