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.logging.Logger; 37 import org.jboss.mx.loading.ClassLoadingTask.ThreadTask; 38 39 40 46 public class LoadMgr3 47 { 48 private static Logger log = Logger.getLogger(LoadMgr3.class); 49 52 private static Object registrationLock = new Object (); 53 54 57 private static HashMap loadClassThreads = new HashMap (); 58 61 private static Map loadTasksByThread = Collections.synchronizedMap(new WeakHashMap ()); 62 63 private static SecurityManager sm = System.getSecurityManager(); 64 65 70 public static class PkgClassLoader 71 { 72 public final RepositoryClassLoader ucl; 73 public final int order; 74 75 public PkgClassLoader(RepositoryClassLoader ucl) 76 { 77 this(ucl, Integer.MAX_VALUE); 78 } 79 public PkgClassLoader(RepositoryClassLoader ucl, int order) 80 { 81 this.ucl = ucl; 82 this.order = order; 83 } 84 85 public String toString() 86 { 87 StringBuffer buffer = new StringBuffer (100); 88 buffer.append(super.toString()); 89 buffer.append("{ucl=").append(ucl); 90 buffer.append(" order=").append(order); 91 buffer.append('}'); 92 return buffer.toString(); 93 } 94 } 95 98 private static class ResourceAction implements PrivilegedAction 99 { 100 RepositoryClassLoader ucl; 101 String classRsrcName; 102 ResourceAction(RepositoryClassLoader ucl, String classRsrcName) 103 { 104 this.ucl = ucl; 105 this.classRsrcName = classRsrcName; 106 } 107 public Object run() 108 { 109 URL url = ucl.getResourceLocally(classRsrcName); 110 ucl = null; 111 classRsrcName = null; 112 return url; 113 } 114 } 115 116 120 public static void registerLoaderThread(RepositoryClassLoader ucl, Thread t) 121 { 122 synchronized( registrationLock ) 123 { 124 Object prevThread = loadClassThreads.put(ucl, t); 125 if( log.isTraceEnabled() ) 126 log.trace("registerLoaderThread, ucl="+ucl+", t="+t+", prevT="+prevThread); 127 128 synchronized( loadTasksByThread ) 129 { 130 List taskList = (List ) loadTasksByThread.get(t); 131 if( taskList == null ) 132 { 133 taskList = Collections.synchronizedList(new LinkedList ()); 134 loadTasksByThread.put(t, taskList); 135 if( log.isTraceEnabled() ) 136 log.trace("created new task list"); 137 } 138 } 139 registrationLock.notifyAll(); 140 } 141 } 142 143 158 public static boolean beginLoadTask(ClassLoadingTask task, 159 UnifiedLoaderRepository3 repository) 160 throws ClassNotFoundException 161 { 162 boolean trace = log.isTraceEnabled(); 163 if( trace ) 164 log.trace("Begin beginLoadTask, task="+task); 165 166 Class cls = repository.loadClassFromCache(task.classname); 168 if( cls != null ) 169 { 170 task.loadedClass = cls; 171 task.state = ClassLoadingTask.FINISHED; 172 if( trace ) 173 log.trace("End beginLoadTask, loadClassFromCache, classname: "+task.classname); 174 return true; 175 } 176 177 Set pkgSet = repository.getPackageClassLoaders(task.classname); 179 if( pkgSet == null || pkgSet.size() == 0 ) 180 { 181 if (task.stopOrder == Integer.MAX_VALUE) 182 { 183 187 try 188 { 189 cls = repository.loadClassFromClassLoader(task.classname, false, 190 task.requestingClassLoader); 191 } 192 catch(LinkageError e) 193 { 194 if( trace ) 195 log.trace("End beginLoadTask, LinkageError for task: "+task, e); 196 throw e; 197 } 198 if( cls != null ) 199 { 200 task.loadedClass = cls; 201 task.state = ClassLoadingTask.FINISHED; 202 if( trace ) 203 log.trace("End beginLoadTask, loadClassFromClassLoader"); 204 return true; 205 } 206 } 207 208 if( trace ) 210 log.trace("End beginLoadTask, ClassNotFoundException"); 211 String msg = "No ClassLoaders found for: "+task.classname; 212 throw new ClassNotFoundException (msg); 213 } 214 215 230 Iterator iter = pkgSet.iterator(); 231 RepositoryClassLoader theUCL = null; 232 int order = Integer.MAX_VALUE; 233 while( iter.hasNext() ) 234 { 235 Object next = iter.next(); 236 int uclOrder; 237 RepositoryClassLoader ucl; 238 if( next instanceof RepositoryClassLoader ) 240 { 241 ucl = (RepositoryClassLoader) next; 242 uclOrder = ucl.getAddedOrder(); 243 } 244 else 245 { 246 PkgClassLoader pkgUcl = (PkgClassLoader) next; 247 ucl = pkgUcl.ucl; 248 uclOrder = pkgUcl.order; 249 } 250 251 if (task.stopOrder != Integer.MAX_VALUE && task.stopOrder <= uclOrder) 253 break; 254 255 String classRsrcName = task.classname.replace('.', '/') + ".class"; 257 URL url = null; 258 if( sm != null ) 259 { 260 ResourceAction action = new ResourceAction(ucl, classRsrcName); 261 url = (URL ) AccessController.doPrivileged(action); 262 } 263 else 264 { 265 url = ucl.getResourceLocally(classRsrcName); 266 } 267 268 if( url != null && uclOrder < order ) 269 { 270 if( trace && theUCL != null ) 271 log.trace("Replacing UCL: "+theUCL+" with UCL:"+ucl); 272 theUCL = ucl; 273 order = uclOrder; 274 } 275 } 276 if( theUCL == null && task.stopOrder == Integer.MAX_VALUE) 277 { 278 282 try 283 { 284 cls = repository.loadClassFromClassLoader(task.classname, false, 285 task.requestingClassLoader); 286 } 287 catch(LinkageError e) 288 { 289 if( trace ) 290 log.trace("End beginLoadTask, LinkageError for task: "+task, e); 291 throw e; 292 } 293 if( cls != null ) 294 { 295 task.loadedClass = cls; 296 task.state = ClassLoadingTask.FINISHED; 297 if( trace ) 298 log.trace("End beginLoadTask, loadClassFromClassLoader"); 299 return true; 300 } 301 302 if( trace ) 304 log.trace("End beginLoadTask, ClassNotFoundException"); 305 String msg = "No ClassLoaders found for: "+task.classname; 306 throw new ClassNotFoundException (msg); 307 } 308 309 if (theUCL == null) 310 { 311 if( trace ) 312 log.trace("End beginLoadTask, ClassNotFoundException"); 313 String msg = "No ClassLoaders found for: "+task.classname; 314 throw new ClassNotFoundException (msg); 315 } 316 317 scheduleTask(task, theUCL, order, false, trace); 318 task.state = ClassLoadingTask.FOUND_CLASS_LOADER; 319 if( trace ) 320 log.trace("End beginLoadTask, task="+task); 321 322 return false; 323 } 324 325 332 public static void nextTask(Thread t, ClassLoadingTask task, 333 UnifiedLoaderRepository3 repository) 334 throws InterruptedException 335 { 336 boolean trace = log.isTraceEnabled(); 337 List taskList = (List ) loadTasksByThread.get(t); 338 synchronized( taskList ) 339 { 340 while( taskList.size() == 0 && task.threadTaskCount != 0 ) 342 { 343 346 if( trace ) 347 log.trace("Begin nextTask(WAIT_ON_EVENT), task="+task); 348 try 349 { 350 task.state = ClassLoadingTask.WAIT_ON_EVENT; 351 taskList.wait(); 352 } 353 catch(InterruptedException e) 354 { 355 if( trace ) 356 log.trace("nextTask(WAIT_ON_EVENT), interrupted, task="+task, e); 357 throw e; 359 } 360 if( trace ) 361 log.trace("nextTask(WAIT_ON_EVENT), notified, task="+task); 362 } 363 364 if( trace ) 365 log.trace("Continue nextTask("+taskList.size()+"), task="+task); 366 367 if( task.threadTaskCount == 0 ) 369 { 370 task.state = ClassLoadingTask.FINISHED; 371 log.trace("End nextTask(FINISHED), task="+task); 372 return; 373 } 374 } 375 376 ThreadTask threadTask = (ThreadTask) taskList.remove(0); 377 ClassLoadingTask loadTask = threadTask.getLoadTask(); 378 if( trace ) 379 log.trace("Begin nextTask("+taskList.size()+"), loadTask="+loadTask); 380 381 RepositoryClassLoader ucl3 = threadTask.ucl; 382 try 383 { 384 if( threadTask.t == null ) 385 { 386 390 if( trace ) 391 log.trace("Rescheduling threadTask="+threadTask); 392 scheduleTask(loadTask, ucl3, threadTask.order, true, trace); 393 } 394 else 395 { 396 if( trace ) 397 log.trace("Running threadTask="+threadTask); 398 threadTask.run(); 400 } 401 } 402 catch(Throwable e) 403 { 404 if( e instanceof ClassCircularityError ) 405 { 406 409 try 410 { 411 if( trace ) 412 log.trace("Run failed with exception", e); 413 scheduleTask(loadTask, ucl3, Integer.MAX_VALUE, true, trace); 415 } 416 catch(ClassNotFoundException ex) 417 { 418 loadTask.setLoadError(ex); 419 log.warn("Failed to reschedule task after CCE", ex); 420 } 421 if( trace ) 422 log.trace("Post CCE state, loadTask="+loadTask); 423 } 424 else 425 { 426 loadTask.setLoadError(e); 427 if( trace ) 428 log.trace("Run failed with exception", e); 429 } 430 } 431 finally 432 { 433 if( threadTask.releaseInNextTask == true ) 435 { 436 if( trace ) 437 log.trace("Releasing loadLock and ownership of UCL: "+threadTask.ucl); 438 synchronized( registrationLock ) 439 { 440 loadClassThreads.remove(threadTask.ucl); 441 } 442 synchronized( threadTask.ucl ) 443 { 444 ucl3.release(); 445 ucl3.notifyAll(); 446 } 447 } 448 } 449 450 if( loadTask.threadTaskCount == 0 ) 452 { 453 Class loadedClass = threadTask.getLoadedClass(); 454 if( loadedClass != null ) 455 { 456 ClassLoader loader = loadedClass.getClassLoader(); 457 ClassLoader wrapper = repository.getWrappingClassLoader(loader); 458 if (wrapper != null) 459 loader=wrapper; 460 repository.cacheLoadedClass(threadTask.getClassname(), 462 loadedClass, loader); 463 } 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 = ClassLoadingTask.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(ClassLoadingTask 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 ClassLoadingTask 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 = ClassLoadingTask.NEXT_EVENT; 536 toTaskList.notify(); 537 } 538 } 539 } 540 } 541 542 553 static private void scheduleTask(ClassLoadingTask task, RepositoryClassLoader 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 |