KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mx > loading > ClassLoadingTaskDCL


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.mx.loading;
23
24 import java.security.CodeSource JavaDoc;
25 import java.security.ProtectionDomain JavaDoc;
26 import java.util.Comparator JavaDoc;
27 import java.io.StringWriter JavaDoc;
28 import java.io.PrintWriter JavaDoc;
29
30 import org.jboss.logging.Logger;
31
32 /** An encapsulation of a UCL3.loadClass task.
33  * @author Scott.Stark@jboss.org
34  * @version $Revision: 57108 $
35 */

36 public class ClassLoadingTaskDCL
37 {
38    protected static Logger log = Logger.getLogger(ClassLoadingTaskDCL.class);
39    protected static Comparator JavaDoc taskComparator = new ThreadTaskComparator();
40
41    public static final int FOUND_CLASS_LOADER = 1;
42    public static final int NEXT_EVENT = 2;
43    public static final int WAIT_ON_EVENT = 3;
44    public static final int FINISHED = 4;
45
46    protected String JavaDoc classname;
47    protected Thread JavaDoc requestingThread;
48    protected DomainClassLoaderUCLImpl requestingClassLoader;
49    protected Class JavaDoc loadedClass;
50    protected int loadOrder = Integer.MAX_VALUE;
51    protected int stopOrder = Integer.MAX_VALUE;
52    protected Throwable JavaDoc loadException;
53    /** The number of ThreadTasks remaining */
54    protected int threadTaskCount;
55    /** The state of the requestingThread */
56    protected int state;
57    /** The Logger trace level flag */
58    protected boolean trace;
59
60    protected int numCCE;
61
62    /** Compare ThreadTask first based on their order ivar, and then the
63     * relative ordering with which their UCLs were added to the ULR.
64     */

65    static class ThreadTaskComparator implements Comparator JavaDoc
66    {
67       public int compare(Object JavaDoc o1, Object JavaDoc o2)
68       {
69          ThreadTask t1 = (ThreadTask) o1;
70          ThreadTask t2 = (ThreadTask) o2;
71          int compare = t1.order - t2.order;
72          /*
73          if( compare == 0 )
74          {
75             compare = t1.ucl.getAddedOrder() - t2.ucl.getAddedOrder();
76          }
77          */

78          return compare;
79       }
80    }
81
82    /** An ecapsulation of a <Thread, UCL3> task used when requestingClassLoader
83     * needs to ask another UCL3 to perform the class loading.
84     */

85    class ThreadTask
86    {
87       /** The class loader for the classname package */
88       DomainClassLoaderUCLImpl ucl;
89       /** The thread that owns the ucl monitor */
90       Thread JavaDoc t;
91       /** The relative order of the task. If o0 < o1 then the class loaded
92          by task o0 is preferred to o1.
93        */

94       int order;
95       boolean releaseInNextTask;
96
97       ThreadTask(DomainClassLoaderUCLImpl ucl, Thread JavaDoc t, int order,
98          boolean releaseInNextTask)
99       {
100          this.ucl = ucl;
101          this.t = t;
102          this.order = order;
103          this.releaseInNextTask = releaseInNextTask;
104       }
105
106       public String JavaDoc toString()
107       {
108          return "{t="+t+", ucl="+ucl+", name="+classname
109             +", requestingThread="+requestingThread
110             +", order="+order+", releaseInNextTask="+releaseInNextTask
111             +"}";
112       }
113
114       String JavaDoc getClassname()
115       {
116          return classname;
117       }
118       Class JavaDoc getLoadedClass()
119       {
120          return loadedClass;
121       }
122       ClassLoadingTaskDCL getLoadTask()
123       {
124          return ClassLoadingTaskDCL.this;
125       }
126
127       void run() throws ClassNotFoundException JavaDoc
128       {
129          Class JavaDoc theClass = null;
130          try
131          {
132             if( loadedClass == null )
133             {
134                theClass = ucl.loadClassLocally(classname, false);
135                setLoadedClass(theClass, order);
136             }
137             else if( trace )
138             {
139                log.trace("Already found class("+loadedClass+"), skipping loadClassLocally");
140             }
141          }
142          finally
143          {
144             ;//setLoadedClass(theClass, order);
145
}
146       }
147    }
148
149    protected ClassLoadingTaskDCL(String JavaDoc classname, DomainClassLoaderUCLImpl requestingClassLoader,
150          Thread JavaDoc requestingThread)
151    {
152       this(classname, requestingClassLoader, requestingThread, Integer.MAX_VALUE);
153    }
154    
155    protected ClassLoadingTaskDCL(String JavaDoc classname, DomainClassLoaderUCLImpl requestingClassLoader,
156       Thread JavaDoc requestingThread, int stopAt)
157    {
158       this.requestingThread = requestingThread;
159       this.requestingClassLoader = requestingClassLoader;
160       this.classname = classname;
161       this.stopOrder = stopAt;
162       this.trace = log.isTraceEnabled();
163    }
164
165    public String JavaDoc toString()
166    {
167       StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(super.toString());
168       buffer.append('{');
169       buffer.append("classname: "+classname);
170       buffer.append(", requestingThread: "+requestingThread);
171       buffer.append(", requestingClassLoader: "+requestingClassLoader);
172       buffer.append(", loadedClass: "+loadedClass);
173       ClassToStringAction.toString(loadedClass, buffer);
174       buffer.append(", loadOrder: "+loadOrder);
175       buffer.append(", loadException: "+loadException);
176       buffer.append(", threadTaskCount: "+threadTaskCount);
177       buffer.append(", state: "+state);
178       buffer.append(", #CCE: "+numCCE);
179       buffer.append('}');
180       if( trace && loadException != null )
181       {
182          StringWriter JavaDoc sw = new StringWriter JavaDoc();
183          PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
184          loadException.printStackTrace(pw);
185          buffer.append("loadException details:\n");
186          buffer.append(sw.toString());
187       }
188       return buffer.toString();
189    }
190
191    ThreadTask newThreadTask(DomainClassLoaderUCLImpl ucl, Thread JavaDoc t, int order,
192       boolean reschedule, boolean releaseInNextTask)
193    {
194       // Only update the threadTaskCount if this is not a reschedule
195
if( reschedule == false )
196          threadTaskCount ++;
197       return new ThreadTask(ucl, t, order, releaseInNextTask);
198    }
199    
200    synchronized void setLoadError(Throwable JavaDoc t)
201    {
202        this.threadTaskCount--;
203         if( trace )
204             log.trace("setLoadedError, error="+t);
205        loadException = t;
206    }
207    
208
209    /** This is called from run on success or failure to mark the end
210     * of the load attempt. This must decrement the threadTaskCount or
211     * the ClassLoadingTaskDCL will never complete.
212     */

213    private synchronized void setLoadedClass(Class JavaDoc theClass, int order)
214    {
215       this.threadTaskCount --;
216       if( trace )
217          log.trace("setLoadedClass, theClass="+theClass+", order="+order);
218
219       // Warn about duplicate classes
220
if( this.loadedClass != null && order == loadOrder && theClass != null )
221       {
222          StringBuffer JavaDoc tmp = new StringBuffer JavaDoc("Duplicate class found: "+classname);
223          tmp.append('\n');
224          ProtectionDomain JavaDoc pd = this.loadedClass.getProtectionDomain();
225          CodeSource JavaDoc cs = pd != null ? pd.getCodeSource() : null;
226          tmp.append("Current CS: "+cs);
227          tmp.append('\n');
228          pd = theClass.getProtectionDomain();
229          cs = pd != null ? pd.getCodeSource() : null;
230          tmp.append("Duplicate CS: "+cs);
231          log.warn(tmp.toString());
232       }
233
234       // Accept the lowest order source of the class
235
if( theClass != null )
236       {
237          if( loadedClass == null || order <= loadOrder )
238          {
239             this.loadedClass = theClass;
240             this.loadOrder = order;
241          }
242          else
243          {
244             ProtectionDomain JavaDoc pd = this.loadedClass.getProtectionDomain();
245             CodeSource JavaDoc cs = pd != null ? pd.getCodeSource() : null;
246             ProtectionDomain JavaDoc pd2 = theClass.getProtectionDomain();
247             CodeSource JavaDoc cs2 = pd != null ? pd2.getCodeSource() : null;
248             log.debug("Ignoring source of: "+classname+" from CodeSource: "+cs2
249                +", due to order("+order+">="+loadOrder+"), "
250                +"accepted CodeSource: "+cs);
251          }
252       }
253    }
254 }
255
Popular Tags