1 22 package org.jboss.mx.loading; 23 24 import java.security.CodeSource ; 25 import java.security.ProtectionDomain ; 26 import java.util.Comparator ; 27 import java.io.StringWriter ; 28 import java.io.PrintWriter ; 29 import org.jboss.logging.Logger; 30 31 35 public class ClassLoadingTask 36 { 37 protected static Logger log = Logger.getLogger(ClassLoadingTask.class); 38 protected static Comparator 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 classname; 46 protected Thread requestingThread; 47 protected RepositoryClassLoader requestingClassLoader; 48 protected Class loadedClass; 49 protected int loadOrder = Integer.MAX_VALUE; 50 protected int stopOrder = Integer.MAX_VALUE; 51 protected Throwable loadException; 52 53 protected int threadTaskCount; 54 55 protected int state; 56 57 protected boolean trace; 58 59 protected int numCCE; 60 61 64 static class ThreadTaskComparator implements Comparator 65 { 66 public int compare(Object o1, Object 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 82 class ThreadTask 83 { 84 85 RepositoryClassLoader ucl; 86 87 Thread t; 88 91 int order; 92 boolean releaseInNextTask; 93 94 ThreadTask(RepositoryClassLoader ucl, Thread 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 toString() 104 { 105 return "{t="+t+", ucl="+ucl+", name="+classname 106 +", requestingThread="+requestingThread 107 +", order="+order+", releaseInNextTask="+releaseInNextTask 108 +"}"; 109 } 110 111 String getClassname() 112 { 113 return classname; 114 } 115 Class getLoadedClass() 116 { 117 return loadedClass; 118 } 119 ClassLoadingTask getLoadTask() 120 { 121 return ClassLoadingTask.this; 122 } 123 124 void run() throws ClassNotFoundException 125 { 126 Class 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 ; } 143 } 144 } 145 146 protected ClassLoadingTask(String classname, RepositoryClassLoader requestingClassLoader, 147 Thread requestingThread) 148 { 149 this(classname, requestingClassLoader, requestingThread, Integer.MAX_VALUE); 150 } 151 152 protected ClassLoadingTask(String classname, RepositoryClassLoader requestingClassLoader, 153 Thread 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 toString() 163 { 164 StringBuffer buffer = new StringBuffer (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 sw = new StringWriter (); 180 PrintWriter pw = new PrintWriter (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 t, int order, 189 boolean reschedule, boolean releaseInNextTask) 190 { 191 if( reschedule == false ) 193 threadTaskCount ++; 194 return new ThreadTask(ucl, t, order, releaseInNextTask); 195 } 196 197 synchronized void setLoadError(Throwable t) 198 { 199 this.threadTaskCount--; 200 if( trace ) 201 log.trace("setLoadedError, error="+t); 202 loadException = t; 203 } 204 205 206 210 private synchronized void setLoadedClass(Class theClass, int order) 211 { 212 this.threadTaskCount --; 213 if( trace ) 214 log.trace("setLoadedClass, theClass="+theClass+", order="+order); 215 216 if( this.loadedClass != null && order == loadOrder && theClass != null ) 218 { 219 StringBuffer tmp = new StringBuffer ("Duplicate class found: "+classname); 220 tmp.append('\n'); 221 ProtectionDomain pd = this.loadedClass.getProtectionDomain(); 222 CodeSource 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 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 pd = this.loadedClass.getProtectionDomain(); 242 CodeSource cs = pd != null ? pd.getCodeSource() : null; 243 ProtectionDomain pd2 = theClass.getProtectionDomain(); 244 CodeSource 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 |