KickJava   Java API By Example, From Geeks To Geeks.

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


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 import org.jboss.logging.Logger;
30
31 /** An encapsulation of a UCL3.loadClass task.
32  * @author Scott.Stark@jboss.org
33  * @version $Revision: 37459 $
34 */

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

64    static class ThreadTaskComparator implements Comparator JavaDoc
65    {
66       public int compare(Object JavaDoc o1, Object JavaDoc o2)
67       {
68          ThreadTask t1 = (ThreadTask) o1;
69          ThreadTask t2 = (ThreadTask) o2;
70          int compare = t1.order - t2.order;
71          if( compare == 0 )
72          {
73             compare = t1.ucl.getAddedOrder() - t2.ucl.getAddedOrder();
74          }
75          return compare;
76       }
77    }
78
79    /** An ecapsulation of a <Thread, UCL3> task used when requestingClassLoader
80     * needs to ask another UCL3 to perform the class loading.
81     */

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

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

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