1 22 package org.jboss.test.classloader.test; 23 24 import java.net.URL ; 25 import java.io.File ; 26 import java.util.List ; 27 import java.util.ArrayList ; 28 import java.util.Iterator ; 29 import org.jboss.logging.Logger; 30 import org.jboss.mx.loading.UnifiedLoaderRepository3; 31 import org.jboss.mx.loading.UnifiedClassLoader3; 32 import org.jboss.mx.loading.LoaderRepository; 33 import org.jboss.mx.loading.LoadMgr3; 34 import org.jboss.test.classloader.circularity.test.MyClassLoadingTask; 35 import org.jboss.test.util.ClassMover; 36 37 38 57 public class DeadlockTests32 58 { 59 private static Logger log = Logger.getLogger(DeadlockTests32.class); 60 private SyncEvent syncEvent = new SyncEvent(); 61 private TestClassLoader loaders[]; 62 private UnifiedLoaderRepository3 mainRep; 63 private TestClassLoader blockingLoader; 64 private String blockname; 65 66 77 public DeadlockTests32(File libDir) throws Exception 78 { 79 ClassLoader appCl = this.getClass().getClassLoader(); 80 URL u1 = new File (libDir, "dl-a.jar").toURL(); 81 URL u2 = new File (libDir, "dl-b.jar").toURL(); 82 loaders = new TestClassLoader[2]; 83 mainRep = new UnifiedLoaderRepository3(); 84 loaders[0] = new TestClassLoader(u1, appCl, mainRep); 85 loaders[1] = new TestClassLoader(u2, appCl, mainRep); 86 } 87 88 129 public void testDeadLock() throws Exception 130 { 131 log.info("RUNNING: testDeadLock"); 132 File TestAclass = ClassMover.move("org.jboss.test.classloader.test.abc.TestA"); 133 File TestBclass = ClassMover.move("org.jboss.test.classloader.test.abc.TestB"); 134 File TestB2class = ClassMover.move("org.jboss.test.classloader.test.abc.TestB2"); 135 136 139 blockingLoader = loaders[1]; 140 blockname = "org.jboss.test.classloader.test.abc.TestB"; 141 ClassLoader cl1 = loaders[0]; 142 ClassLoader cl2 = loaders[1]; 143 Runner t2 = new Runner("T2", blockname, cl2); 144 ThreadList threads = new ThreadList(); 145 threads.add(t2); 146 147 log.info("t0, Waiting for T2 to start"); 148 t2.start(); 149 Thread.sleep(2000); 150 log.info("t1, T2 should be waiting in beforeTaskLoop"); 151 152 154 Runner t1 = new Runner("T1", "org.jboss.test.classloader.test.abc.TestB2", cl1); 155 threads.add(t1); 156 log.info("t2, Waiting for T1 to start"); 157 t1.start(); 158 Thread.sleep(4000); 159 log.info("t3, Now releasing T2/CL2"); 160 syncEvent.set(); 161 log.info("t4, Waiting for T1, T2 to complete"); 162 threads.waitAll(); 163 164 ClassMover.restore(TestAclass); 165 ClassMover.restore(TestBclass); 166 ClassMover.restore(TestB2class); 167 } 168 169 210 public void testDeadLockAndCircularity() throws Exception 211 { 212 log.info("RUNNING: testDeadLockAndCircularity"); 213 File TestAclass = ClassMover.move("org.jboss.test.classloader.test.abc.TestA"); 214 File TestBclass = ClassMover.move("org.jboss.test.classloader.test.abc.TestB"); 215 File TestB3class = ClassMover.move("org.jboss.test.classloader.test.abc.TestB3"); 216 217 220 blockingLoader = loaders[1]; 221 blockname = "org.jboss.test.classloader.test.abc.TestB"; 222 ClassLoader cl1 = loaders[0]; 223 ClassLoader cl2 = loaders[1]; 224 Runner t2 = new Runner("T2", blockname, cl2); 225 ThreadList threads = new ThreadList(); 226 threads.add(t2); 227 log.info("t0, Waiting for T2 to start"); 229 t2.start(); 230 Thread.sleep(2000); 231 log.info("t1, T2 should be waiting in beforeTaskLoop"); 232 233 Runner t1 = new Runner("T1", "org.jboss.test.classloader.test.abc.TestB3", cl1); 234 threads.add(t1); 235 log.info("t2, Waiting for T1 to start"); 236 t1.start(); 237 Thread.sleep(4000); 238 log.info("t3, Now releasing T2/CL2"); 239 syncEvent.set(); 240 threads.waitAll(); 241 242 ClassMover.restore(TestAclass); 243 ClassMover.restore(TestBclass); 244 ClassMover.restore(TestB3class); 245 } 246 247 248 private class Runner extends Thread 249 { 250 private String clsname; 251 private ClassLoader loader; 252 253 public Runner(String name, String clsname, ClassLoader cl) 254 { 255 super(name); 256 this.clsname = clsname; 257 this.loader = cl; 258 } 259 260 private Throwable savedEx; 261 262 public Throwable getThrowable() 263 { 264 return savedEx; 265 } 266 267 public void showException() 268 { 269 if (savedEx != null) 270 { 271 log.error("Exception for: " + getName(), savedEx); 272 } 273 } 274 275 public void run() 276 { 277 try 278 { 279 Class cls = Class.forName(clsname, true, loader); 280 cls.newInstance(); 281 } 282 catch (Throwable ex) 283 { 284 savedEx = ex; 285 } 286 } 287 288 } 289 290 291 public void beforeTaskLoop(UnifiedClassLoader3 cl, String clsname) 292 { 293 log.info("BeforeTaskLoop: " + clsname); 294 if (cl == blockingLoader && clsname.equals(blockname)) 295 { 296 log.info("Waiting in beforeTaskLoop: " + cl + " on " + blockname); 297 try 298 { 299 syncEvent.aquire(); 300 } 301 catch (InterruptedException e) 302 { 303 log.error("Interrupted", e); 304 } 305 log.info("End beforeTaskLoop: " + cl); 306 } 307 } 308 309 public class TestClassLoader extends UnifiedClassLoader3 310 { 311 public TestClassLoader(URL url, ClassLoader parent, 312 LoaderRepository repository) 313 { 314 super(url, null, parent, null); 315 repository.addClassLoader(this); 316 } 317 318 public synchronized Class loadClassImpl(String name, boolean resolve) 319 throws ClassNotFoundException 320 { 321 boolean trace = log.isTraceEnabled(); 322 323 328 boolean acquired = attempt(1); 329 while( acquired == false ) 330 { 331 335 try 336 { 337 if( trace ) 338 log.trace("Waiting for loadClass lock"); 339 this.wait(); 340 } 341 catch(InterruptedException ignore) 342 { 343 } 344 acquired = attempt(1); 345 } 346 347 MyClassLoadingTask task = null; 348 try 349 { 350 Thread t = Thread.currentThread(); 351 if( loadLock.holds() == 1 ) 353 LoadMgr3.registerLoaderThread(this, t); 354 beforeTaskLoop(name); 356 357 task = new MyClassLoadingTask(name, this, t); 359 362 UnifiedLoaderRepository3 ulr3 = (UnifiedLoaderRepository3) repository; 363 if( LoadMgr3.beginLoadTask(task, ulr3) == false ) 364 { 365 while( task.threadTaskCount() != 0 ) 366 { 367 try 368 { 369 LoadMgr3.nextTask(t, task, ulr3); 370 } 371 catch(InterruptedException e) 372 { 373 break; 375 } 376 } 377 } 378 } 379 finally 380 { 381 if( loadLock.holds() == 1 ) 383 LoadMgr3.endLoadTask(task); 384 this.release(); 386 this.notifyAll(); 387 } 388 389 if( task.loadedClass() == null ) 390 { 391 if( task.loadException() instanceof ClassNotFoundException ) 392 throw (ClassNotFoundException ) task.loadException(); 393 else if( task.loadException() != null ) 394 { 395 if( log.isTraceEnabled() ) 396 log.trace("Unexpected error during load of:"+name, task.loadException()); 397 String msg = "Unexpected error during load of: "+name 398 + ", msg="+task.loadException().getMessage(); 399 throw new ClassNotFoundException (msg); 400 } 401 else 403 throw new IllegalStateException ("ClassLoadingTask.loadedTask is null, name: "+name); 404 } 405 406 return task.loadedClass(); 407 } 408 409 protected void beforeTaskLoop(String clsname) 410 { 411 log.info("Calling taskLoop"); 412 DeadlockTests32.this.beforeTaskLoop(this, clsname); 413 } 414 415 } 416 417 private class ThreadList 418 { 419 List list = new ArrayList (); 420 421 public ThreadList() 422 { 423 } 424 425 426 public void add(Thread t) 427 { 428 list.add(t); 429 } 430 431 public void waitAll() throws Exception 432 { 433 Iterator it = list.iterator(); 434 Throwable ex = null; 435 StringBuffer buf = new StringBuffer (); 436 while (it.hasNext()) 437 { 438 Runner t = (Runner) it.next(); 439 t.join(); 440 Throwable e = t.getThrowable(); 442 if (e != null) 443 { 444 buf.append("Failure for: ").append(t.getName()); 445 buf.append('\n').append(e); 446 if (ex == null) 447 { 448 ex = e; 449 } 450 } 451 } 452 if (ex != null) 453 { 454 log.info(buf.toString()); 455 if (ex instanceof Exception ) 456 { 457 throw (Exception ) ex; 458 } 459 else if (ex instanceof Error ) 460 { 461 throw (Error ) ex; 462 } 463 } 464 } 465 466 } 467 468 private class SyncEvent 469 { 470 private boolean cond; 471 472 public SyncEvent() 473 { 474 this(false); 475 } 476 477 public SyncEvent(boolean initialValue) 478 { 479 cond = initialValue; 480 } 481 482 483 public void aquire() throws InterruptedException 484 { 485 synchronized (this) 486 { 487 while (!cond) 488 { 489 wait(); 490 } 491 } 492 } 493 494 public synchronized void set() 495 { 496 cond = true; 497 notifyAll(); 498 } 499 500 public synchronized void unset() 501 { 502 cond = false; 503 } 504 505 } 506 } 507 | Popular Tags |