KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > classloader > circularity > test > DeadlockTests3


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.test.classloader.circularity.test;
23
24 import java.net.URL JavaDoc;
25
26 import org.jboss.logging.Logger;
27
28 import org.jboss.mx.loading.UnifiedClassLoader;
29 import org.jboss.mx.loading.UnifiedClassLoader3;
30 import org.jboss.mx.loading.UnifiedLoaderRepository3;
31 import org.jboss.mx.loading.ClassLoadingTask;
32 import org.jboss.mx.loading.LoadMgr3;
33 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
34
35 /** Deadlock tests of the UnifiedClassLoader3
36  * @author Scott.Stark@jboss.org
37  * @version $Revision: 58115 $
38  */

39 public class DeadlockTests3
40 {
41    private static Logger log = Logger.getLogger(DeadlockTests3.class);
42    private CyclicBarrier t0Barrier = new CyclicBarrier(2);
43    private CyclicBarrier t1Barrier = new CyclicBarrier(2);
44
45    public DeadlockTests3()
46    {
47    }
48
49    /** The scenario is:
50     - Thread1 starts to load Base via UCL1 which has dl11.jar(Base) and waits at
51     t0Barrier after it has registered as the thread owning UCL1.
52
53     - Thread0 loads Dervied via UCL0 which has dl10.jar(pkg0.Derived). This
54     will recursively call UCL0.loadClass to load Base from UCL1 with the
55     LoadMgr.class monitor held. Thread1 will not be able to load Base because
56     Thread0 goes to sleep waiting for a ClassLoadingTask.WAIT_ON_EVENT event
57     that cannot be issued since Thread1 cannot enter LoadMgr.begingLoadTask
58     or LoadMgr.nextTask.
59
60     @throws Exception
61     */

62    public void testDeadlockCase1() throws Exception JavaDoc
63    {
64       log.info("Begin testDeadlockCase1");
65       UnifiedLoaderRepository3 repository = new UnifiedLoaderRepository3();
66       Class JavaDoc thisClass = getClass();
67       UnifiedClassLoader thisUCL = (UnifiedClassLoader) thisClass.getClassLoader();
68       URL JavaDoc origURL = thisUCL.getOrigURL();
69       log.info("Service origURL="+origURL);
70       URL JavaDoc j0 = new URL JavaDoc(origURL, "dl10.jar");
71       log.info("j0 = "+j0);
72       URL JavaDoc j1 = new URL JavaDoc(origURL, "dl11.jar");
73       log.info("j1 = "+j1);
74
75       UnifiedClassLoader3 ucl0 = new UnifiedClassLoader3(j0);
76       repository.addClassLoader(ucl0);
77       UCL1 ucl1 = new UCL1(j1, t0Barrier, t1Barrier);
78       repository.addClassLoader(ucl1);
79
80       T1 t1 = new T1(ucl1);
81       t1.start();
82       t0Barrier.barrier();
83       log.info("Passed t0Barrier");
84
85       T0 t0 = new T0(ucl0);
86       t0.start();
87       t1Barrier.barrier();
88       log.info("Passed t1Barrier");
89
90       t1.join(5000);
91       if( t1.loadedClass == null )
92          throw new Exception JavaDoc("Thread1 failed to load Base");
93       t0.join(5000);
94       if( t0.loadedClass == null )
95          throw new Exception JavaDoc("Thread0 failed to load Derived");
96       log.info("End testDeadlockCase1");
97    }
98
99    /** Load org.jboss.test.classloader.circularity.support.pkg0.Derived via
100     * UCL0
101     */

102    static class T0 extends Thread JavaDoc
103    {
104       Class JavaDoc loadedClass;
105       Throwable JavaDoc loadEx;
106       UnifiedClassLoader3 ucl0;
107       T0(UnifiedClassLoader3 ucl0)
108       {
109          super("Thread0:UCL0");
110          this.ucl0 = ucl0;
111       }
112       public void run()
113       {
114          try
115          {
116             loadedClass = ucl0.loadClass("org.jboss.test.classloader.circularity.support.pkg0.Derived");
117          }
118          catch(Throwable JavaDoc t)
119          {
120             loadEx = t;
121             log.error("T0 failed to load Derived", t);
122          }
123       }
124    }
125    /** Load org.jboss.test.classloader.circularity.support.Base via UCL1
126     */

127    static class T1 extends Thread JavaDoc
128    {
129       Class JavaDoc loadedClass;
130       Throwable JavaDoc loadEx;
131       UCL1 ucl1;
132
133       T1(UCL1 ucl1)
134       {
135          super("Thread1:UCL1");
136          this.ucl1 = ucl1;
137       }
138       public void run()
139       {
140          try
141          {
142             loadedClass = ucl1.loadClass("org.jboss.test.classloader.circularity.support.Base");
143          }
144          catch(Throwable JavaDoc t)
145          {
146             loadEx = t;
147             log.error("T1 failed to load Base", t);
148          }
149       }
150    }
151
152    static class MyClassLoadingTask extends ClassLoadingTask
153    {
154       MyClassLoadingTask(String JavaDoc classname, UnifiedClassLoader3 requestingClassLoader,
155          Thread JavaDoc requestingThread)
156       {
157          super(classname, requestingClassLoader, requestingThread);
158       }
159       int threadTaskCount()
160       {
161          return threadTaskCount;
162       }
163       int state()
164       {
165          return state;
166       }
167       Class JavaDoc loadedClass()
168       {
169          return loadedClass;
170       }
171       Throwable JavaDoc loadException()
172       {
173          return loadException;
174       }
175    }
176
177    public static class UCL1 extends UnifiedClassLoader3
178    {
179       private static final Logger log = Logger.getLogger(UCL1.class);
180       CyclicBarrier t0Barrier;
181       CyclicBarrier t1Barrier;
182       boolean passedBarriers;
183
184       public UCL1(URL JavaDoc url, CyclicBarrier t0Barrier, CyclicBarrier t1Barrier)
185       {
186          super(url);
187          this.t0Barrier = t0Barrier;
188          this.t1Barrier = t1Barrier;
189       }
190
191       /** Override to
192        */

193       public synchronized Class JavaDoc loadClass(String JavaDoc name, boolean resolve)
194          throws ClassNotFoundException JavaDoc
195       {
196          log.info("loadClass, name="+name);
197          boolean acquired = attempt(1);
198          if( acquired == false )
199             throw new IllegalStateException JavaDoc("Failed to acquire loadClass lock");
200          log.info("Acquired loadClass lock");
201
202          MyClassLoadingTask task = null;
203          try
204          {
205             Thread JavaDoc t = Thread.currentThread();
206             // Register this thread as owning this UCL
207
if( loadLock.holds() == 1 )
208                LoadMgr3.registerLoaderThread(this, t);
209
210             // Wait with the loadClass lock held
211
try
212             {
213                if( passedBarriers == false )
214                   t0Barrier.barrier();
215             }
216             catch(InterruptedException JavaDoc e)
217             {
218                throw new IllegalStateException JavaDoc("UCL1 failed to enter t0Barrier");
219             }
220             log.info("Passed t0Barrier");
221             try
222             {
223                if( passedBarriers == false )
224                   t1Barrier.barrier();
225             }
226             catch(InterruptedException JavaDoc e)
227             {
228                throw new IllegalStateException JavaDoc("UCL1 failed to enter t0Barrier");
229             }
230             log.info("Passed t1Barrier");
231             passedBarriers = true;
232
233             // Create a class loading task and submit it to the repository
234
task = new MyClassLoadingTask(name, this, t);
235             /* Process class loading tasks needing this UCL until our task has
236                been completed by the thread owning the required UCL(s).
237              */

238             UnifiedLoaderRepository3 ulr3 = (UnifiedLoaderRepository3) repository;
239             if( LoadMgr3.beginLoadTask(task, ulr3) == false )
240             {
241                while( task.threadTaskCount() != 0 )
242                {
243                   try
244                   {
245                      LoadMgr3.nextTask(t, task, ulr3);
246                   }
247                   catch(InterruptedException JavaDoc e)
248                   {
249                      // Abort the load or retry?
250
break;
251                   }
252                }
253             }
254          }
255          finally
256          {
257             // Unregister as the UCL owner to reschedule any remaining load tasks
258
if( loadLock.holds() == 1 )
259                LoadMgr3.endLoadTask(task);
260             // Notify any threads waiting to use this UCL
261
this.release();
262             this.notifyAll();
263          }
264
265          if( task.loadedClass() == null )
266          {
267             if( task.loadException() instanceof ClassNotFoundException JavaDoc )
268                throw (ClassNotFoundException JavaDoc) task.loadException();
269             else if( task.loadException() != null )
270             {
271                log.info("Unexpected error during load of:"+name, task.loadException());
272                String JavaDoc msg = "Unexpected error during load of: "+name
273                   + ", msg="+task.loadException().getMessage();
274                throw new ClassNotFoundException JavaDoc(msg);
275             }
276             // Assert that loadedClass is not null
277
else
278                throw new IllegalStateException JavaDoc("ClassLoadingTask.loadedTask is null, name: "+name);
279          }
280
281          return task.loadedClass();
282       }
283    }
284 }
285
Popular Tags