KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > config > StandardDSOClientConfigHelper


1 /*
2  * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.object.config;
6
7 import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
8
9 import com.tc.asm.ClassAdapter;
10 import com.tc.asm.ClassVisitor;
11 import com.tc.asm.ClassWriter;
12 import com.tc.asm.Opcodes;
13 import com.tc.asm.commons.SerialVersionUIDAdder;
14 import com.tc.aspectwerkz.expression.ExpressionContext;
15 import com.tc.aspectwerkz.expression.ExpressionVisitor;
16 import com.tc.aspectwerkz.reflect.ClassInfo;
17 import com.tc.aspectwerkz.reflect.ConstructorInfo;
18 import com.tc.aspectwerkz.reflect.MemberInfo;
19 import com.tc.aspectwerkz.reflect.MethodInfo;
20 import com.tc.config.schema.NewCommonL1Config;
21 import com.tc.config.schema.builder.DSOApplicationConfigBuilder;
22 import com.tc.config.schema.setup.ConfigurationSetupException;
23 import com.tc.config.schema.setup.L1TVSConfigurationSetupManager;
24 import com.tc.config.schema.setup.TVSConfigurationSetupManagerFactory;
25 import com.tc.geronimo.transform.HostGBeanAdapter;
26 import com.tc.geronimo.transform.MultiParentClassLoaderAdapter;
27 import com.tc.geronimo.transform.ProxyMethodInterceptorAdapter;
28 import com.tc.geronimo.transform.TomcatClassLoaderAdapter;
29 import com.tc.jboss.transform.MainAdapter;
30 import com.tc.jboss.transform.UCLAdapter;
31 import com.tc.logging.CustomerLogging;
32 import com.tc.logging.TCLogger;
33 import com.tc.object.LiteralValues;
34 import com.tc.object.Portability;
35 import com.tc.object.PortabilityImpl;
36 import com.tc.object.SerializationUtil;
37 import com.tc.object.bytecode.AbstractListMethodCreator;
38 import com.tc.object.bytecode.ByteCodeUtil;
39 import com.tc.object.bytecode.ClassAdapterFactory;
40 import com.tc.object.bytecode.DSOUnsafeAdapter;
41 import com.tc.object.bytecode.JavaLangReflectArrayAdapter;
42 import com.tc.object.bytecode.JavaLangReflectFieldAdapter;
43 import com.tc.object.bytecode.ManagerHelper;
44 import com.tc.object.bytecode.ManagerHelperFactory;
45 import com.tc.object.bytecode.THashMapAdapter;
46 import com.tc.object.bytecode.TransparencyClassAdapter;
47 import com.tc.object.bytecode.TreeMapAdapter;
48 import com.tc.object.bytecode.UnsafeAdapter;
49 import com.tc.object.bytecode.aspectwerkz.AsmConstructorInfo;
50 import com.tc.object.bytecode.aspectwerkz.AsmMethodInfo;
51 import com.tc.object.bytecode.aspectwerkz.ClassInfoFactory;
52 import com.tc.object.bytecode.aspectwerkz.ExpressionHelper;
53 import com.tc.object.config.schema.DSOInstrumentationLoggingOptions;
54 import com.tc.object.config.schema.DSORuntimeLoggingOptions;
55 import com.tc.object.config.schema.DSORuntimeOutputOptions;
56 import com.tc.object.config.schema.ExcludedInstrumentedClass;
57 import com.tc.object.config.schema.IncludeOnLoad;
58 import com.tc.object.config.schema.IncludedInstrumentedClass;
59 import com.tc.object.config.schema.InstrumentedClass;
60 import com.tc.object.config.schema.NewDSOApplicationConfig;
61 import com.tc.object.config.schema.NewSpringApplicationConfig;
62 import com.tc.object.lockmanager.api.LockLevel;
63 import com.tc.object.logging.InstrumentationLogger;
64 import com.tc.object.tools.BootJar;
65 import com.tc.object.tools.BootJarException;
66 import com.tc.tomcat.transform.BootstrapAdapter;
67 import com.tc.tomcat.transform.CatalinaAdapter;
68 import com.tc.tomcat.transform.ContainerBaseAdapter;
69 import com.tc.tomcat.transform.JspWriterImplAdapter;
70 import com.tc.tomcat.transform.WebAppLoaderAdapter;
71 import com.tc.util.Assert;
72 import com.tc.util.ClassUtils;
73 import com.tc.util.ClassUtils.ClassSpec;
74 import com.tc.util.runtime.Vm;
75 import com.tc.weblogic.transform.EJBCodeGeneratorAdapter;
76 import com.tc.weblogic.transform.GenericClassLoaderAdapter;
77 import com.tc.weblogic.transform.ServerAdapter;
78 import com.tc.weblogic.transform.ServletResponseImplAdapter;
79 import com.tc.weblogic.transform.TerracottaServletResponseImplAdapter;
80 import com.tc.weblogic.transform.WebAppServletContextAdapter;
81 import com.tcclient.util.DSOUnsafe;
82 import com.terracottatech.config.DsoApplication;
83 import com.terracottatech.config.Module;
84 import com.terracottatech.config.Modules;
85 import com.terracottatech.config.SpringApplication;
86
87 import java.io.IOException JavaDoc;
88 import java.lang.reflect.Modifier JavaDoc;
89 import java.text.ParseException JavaDoc;
90 import java.util.ArrayList JavaDoc;
91 import java.util.Collection JavaDoc;
92 import java.util.Collections JavaDoc;
93 import java.util.HashMap JavaDoc;
94 import java.util.HashSet JavaDoc;
95 import java.util.Iterator JavaDoc;
96 import java.util.LinkedList JavaDoc;
97 import java.util.List JavaDoc;
98 import java.util.Map JavaDoc;
99 import java.util.Set JavaDoc;
100
101 public class StandardDSOClientConfigHelper implements DSOClientConfigHelper {
102
103   private static final String JavaDoc CGLIB_PATTERN = "$$EnhancerByCGLIB$$";
104
105   private static final LiteralValues literalValues = new LiteralValues();
106
107   private static final TCLogger logger = CustomerLogging
108                                                                                         .getDSOGenericLogger();
109   private static final InstrumentationDescriptor DEAFULT_INSTRUMENTATION_DESCRIPTOR = new NullInstrumentationDescriptor();
110
111   private final ManagerHelperFactory mgrHelperFactory = new ManagerHelperFactory();
112   private final DSOClientConfigHelperLogger helperLogger;
113
114   private final L1TVSConfigurationSetupManager configSetupManager;
115
116   private Lock[] locks = new Lock[0];
117   private final Map roots = new ConcurrentHashMap();
118   private final Map types = new HashMap();
119
120   private final Set JavaDoc applicationNames = Collections
121                                                                                         .synchronizedSet(new HashSet JavaDoc());
122   private final List JavaDoc synchronousWriteApplications = new ArrayList JavaDoc();
123   private final CompoundExpressionMatcher permanentExcludesMatcher;
124   private final CompoundExpressionMatcher nonportablesMatcher;
125   private final List JavaDoc autoLockExcludes = new ArrayList JavaDoc();
126   private final List JavaDoc distributedMethods = new LinkedList JavaDoc(); // <DistributedMethodSpec>
127
private final Map userDefinedBootSpecs = new HashMap();
128
129   private final ClassInfoFactory classInfoFactory;
130   private final ExpressionHelper expressionHelper;
131
132   private final Map adaptableCache = new HashMap();
133
134   /**
135    * A list of InstrumentationDescriptor representing include/exclude patterns
136    */

137   private final LinkedList JavaDoc instrumentationDescriptors = new LinkedList JavaDoc();
138
139   /**
140    * A map of class names to TransparencyClassSpec for individual classes
141    */

142   private final Map classSpecs = Collections
143                                                                                         .synchronizedMap(new HashMap());
144
145   private final Map customAdapters = new ConcurrentHashMap();
146
147   private final Map aspectModules = Collections
148                                                                                         .synchronizedMap(new HashMap());
149
150   private final List JavaDoc springConfigs = Collections
151                                                                                         .synchronizedList(new ArrayList JavaDoc());
152
153   private final boolean supportSharingThroughReflection;
154
155   private final Portability portability;
156
157   private int faultCount = -1;
158
159   private ModuleSpec[] moduleSpecs = null;
160
161   private final ModulesContext modulesContext = new ModulesContext();
162
163   private volatile boolean allowCGLIBInstrumentation = false;
164
165   public StandardDSOClientConfigHelper(L1TVSConfigurationSetupManager configSetupManager)
166       throws ConfigurationSetupException {
167     this(configSetupManager, true);
168   }
169
170   public StandardDSOClientConfigHelper(boolean initializedModulesOnlyOnce,
171                                        L1TVSConfigurationSetupManager configSetupManager)
172       throws ConfigurationSetupException {
173     this(configSetupManager, true);
174     if (initializedModulesOnlyOnce) {
175       modulesContext.initializedModulesOnlyOnce();
176     }
177   }
178
179   public StandardDSOClientConfigHelper(L1TVSConfigurationSetupManager configSetupManager, boolean interrogateBootJar)
180       throws ConfigurationSetupException {
181     this.portability = new PortabilityImpl(this);
182     this.configSetupManager = configSetupManager;
183     helperLogger = new DSOClientConfigHelperLogger(logger);
184     this.classInfoFactory = new ClassInfoFactory();
185     this.expressionHelper = new ExpressionHelper();
186     modulesContext.setModules(configSetupManager.commonL1Config().modules() != null ? configSetupManager
187         .commonL1Config().modules() : Modules.Factory.newInstance());
188
189     permanentExcludesMatcher = new CompoundExpressionMatcher();
190     // TODO:: come back and add all possible non-portable/non-adaptable classes here. This is by no means exhaustive !
191

192     // XXX:: There is a bug in aspectwerkz com.tc..* matches both com.tc and com.tctest classes. As a work around
193
// this is commented and isTCPatternMatchingHack() method is added instead. When that bug is fixed, uncomment
194
// this and remove isTCPatternMatchingHack();
195
// addPermanentExcludePattern("com.tc..*");
196
// addPermanentExcludePattern("com.terracottatech..*");
197
addPermanentExcludePattern("java.awt.Component");
198     addPermanentExcludePattern("java.lang.Thread");
199     addPermanentExcludePattern("java.lang.ThreadLocal");
200     addPermanentExcludePattern("java.lang.ThreadGroup");
201     addPermanentExcludePattern("java.lang.Process");
202     addPermanentExcludePattern("java.lang.ClassLoader");
203     addPermanentExcludePattern("java.lang.Runtime");
204     addPermanentExcludePattern("java.io.FileReader");
205     addPermanentExcludePattern("java.io.FileWriter");
206     addPermanentExcludePattern("java.io.FileDescriptor");
207     addPermanentExcludePattern("java.io.FileInputStream");
208     addPermanentExcludePattern("java.io.FileOutputStream");
209     addPermanentExcludePattern("java.net.DatagramSocket");
210     addPermanentExcludePattern("java.net.DatagramSocketImpl");
211     addPermanentExcludePattern("java.net.MulticastSocket");
212     addPermanentExcludePattern("java.net.ServerSocket");
213     addPermanentExcludePattern("java.net.Socket");
214     addPermanentExcludePattern("java.net.SocketImpl");
215     addPermanentExcludePattern("java.nio.channels.DatagramChannel");
216     addPermanentExcludePattern("java.nio.channels.FileChannel");
217     addPermanentExcludePattern("java.nio.channels.FileLock");
218     addPermanentExcludePattern("java.nio.channels.ServerSocketChannel");
219     addPermanentExcludePattern("java.nio.channels.SocketChannel");
220     addPermanentExcludePattern("java.util.logging.FileHandler");
221     addPermanentExcludePattern("java.util.logging.SocketHandler");
222     addUnsupportedJavaUtilConcurrentTypes();
223
224     addAutoLockExcludePattern("* java.lang.Throwable.*(..)");
225
226     nonportablesMatcher = new CompoundExpressionMatcher();
227     addNonportablePattern("javax.servlet.GenericServlet");
228
229     NewDSOApplicationConfig appConfig = configSetupManager
230         .dsoApplicationConfigFor(TVSConfigurationSetupManagerFactory.DEFAULT_APPLICATION_NAME);
231     NewSpringApplicationConfig springConfig = configSetupManager
232         .springApplicationConfigFor(TVSConfigurationSetupManagerFactory.DEFAULT_APPLICATION_NAME);
233
234     supportSharingThroughReflection = appConfig.supportSharingThroughReflection().getBoolean();
235     try {
236       doAutoconfig(interrogateBootJar);
237     } catch (Exception JavaDoc e) {
238       throw new ConfigurationSetupException(e.getLocalizedMessage(), e);
239     }
240
241     ConfigLoader loader = new ConfigLoader(this, logger);
242     loader.loadDsoConfig((DsoApplication) appConfig.getBean());
243     loader.loadSpringConfig((SpringApplication) springConfig.getBean());
244
245     logger.debug("web-applications: " + this.applicationNames);
246     logger.debug("synchronous-write web-applications: " + this.synchronousWriteApplications);
247     logger.debug("roots: " + this.roots);
248     logger.debug("transients: " + this.types);
249     logger.debug("locks: " + this.locks);
250     logger.debug("distributed-methods: " + this.distributedMethods);
251
252     rewriteHashtableAutLockSpecIfNecessary();
253   }
254
255   public void allowCGLIBInstrumentation() {
256     this.allowCGLIBInstrumentation = true;
257   }
258
259   private void addUnsupportedJavaUtilConcurrentTypes() {
260     addPermanentExcludePattern("java.util.concurrent.AbstractExecutorService");
261     addPermanentExcludePattern("java.util.concurrent.ArrayBlockingQueue*");
262     addPermanentExcludePattern("java.util.concurrent.ConcurrentLinkedQueue*");
263     addPermanentExcludePattern("java.util.concurrent.ConcurrentSkipListMap*");
264     addPermanentExcludePattern("java.util.concurrent.ConcurrentSkipListSet*");
265     addPermanentExcludePattern("java.util.concurrent.CopyOnWriteArrayList*");
266     addPermanentExcludePattern("java.util.concurrent.CopyOnWriteArraySet*");
267     addPermanentExcludePattern("java.util.concurrent.CountDownLatch*");
268     addPermanentExcludePattern("java.util.concurrent.DelayQueue*");
269     addPermanentExcludePattern("java.util.concurrent.Exchanger*");
270     addPermanentExcludePattern("java.util.concurrent.ExecutorCompletionService*");
271     addPermanentExcludePattern("java.util.concurrent.LinkedBlockingDeque*");
272     addPermanentExcludePattern("java.util.concurrent.PriorityBlockingQueue*");
273     addPermanentExcludePattern("java.util.concurrent.ScheduledThreadPoolExecutor*");
274     addPermanentExcludePattern("java.util.concurrent.Semaphore*");
275     addPermanentExcludePattern("java.util.concurrent.SynchronousQueue*");
276     addPermanentExcludePattern("java.util.concurrent.ThreadPoolExecutor*");
277
278     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicBoolean*");
279     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicIntegerArray*");
280     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicIntegerFieldUpdater*");
281     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicLongArray*");
282     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicLongFieldUpdater*");
283     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicMarkableReference*");
284     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicReference*");
285     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicReferenceArray*");
286     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicReferenceFieldUpdater*");
287     addPermanentExcludePattern("java.util.concurrent.atomic.AtomicStampedReference*");
288
289     addPermanentExcludePattern("java.util.concurrent.locks.AbstractQueuedLongSynchronizer*");
290     addPermanentExcludePattern("java.util.concurrent.locks.AbstractQueuedSynchronizer*");
291     addPermanentExcludePattern("java.util.concurrent.locks.LockSupport*");
292     addPermanentExcludePattern("java.util.concurrent.locks.ReentrantReadWriteLock*");
293   }
294
295   public Portability getPortability() {
296     return this.portability;
297   }
298
299   private void addAutoLockExcludePattern(String JavaDoc expression) {
300     String JavaDoc executionExpression = ExpressionHelper.expressionPattern2ExecutionExpression(expression);
301     ExpressionVisitor visitor = expressionHelper.createExpressionVisitor(executionExpression);
302     autoLockExcludes.add(visitor);
303   }
304
305   private void addPermanentExcludePattern(String JavaDoc pattern) {
306     permanentExcludesMatcher.add(new ClassExpressionMatcherImpl(expressionHelper, pattern));
307   }
308
309   private void addNonportablePattern(String JavaDoc pattern) {
310     nonportablesMatcher.add(new ClassExpressionMatcherImpl(expressionHelper, pattern));
311   }
312
313   private InstrumentationDescriptor newInstrumentationDescriptor(InstrumentedClass classDesc) {
314     return new InstrumentationDescriptorImpl(classDesc, //
315
new ClassExpressionMatcherImpl(expressionHelper, //
316
classDesc.classExpression()));
317   }
318
319   // This is used only for tests right now
320
public void addIncludePattern(String JavaDoc expression) {
321     addIncludePattern(expression, false, false, false);
322   }
323
324   public NewCommonL1Config getNewCommonL1Config() {
325     return configSetupManager.commonL1Config();
326   }
327
328   // This is used only for tests right now
329
public void addIncludePattern(String JavaDoc expression, boolean honorTransient) {
330     addIncludePattern(expression, honorTransient, false, false);
331   }
332
333   public void addIncludePattern(String JavaDoc expression, boolean honorTransient, boolean oldStyleCallConstructorOnLoad,
334                                 boolean honorVolatile) {
335     IncludeOnLoad onLoad = new IncludeOnLoad();
336     if (oldStyleCallConstructorOnLoad) {
337       onLoad.setToCallConstructorOnLoad(true);
338     }
339     addInstrumentationDescriptor(new IncludedInstrumentedClass(expression, honorTransient, honorVolatile, onLoad));
340
341     clearAdaptableCache();
342   }
343
344   public void addIncludeAndLockIfRequired(String JavaDoc expression, boolean honorTransient,
345                                           boolean oldStyleCallConstructorOnLoad, boolean honorVolatile,
346                                           String JavaDoc lockExpression) {
347     // The addition of the lock expression and the include need to be atomic -- see LKC-2616
348
synchronized (this.instrumentationDescriptors) {
349       // TODO see LKC-1893. Need to check for primitive types, logically managed classes, etc.
350
if (!hasIncludeExcludePattern(getClassInfo(expression))) {
351         // only add include if not specified in tc-config
352
addIncludePattern(expression, honorTransient, oldStyleCallConstructorOnLoad, honorVolatile);
353         addWriteAutolock(lockExpression);
354       }
355     }
356   }
357
358   // This is used only for tests right now
359
public void addExcludePattern(String JavaDoc expression) {
360     addInstrumentationDescriptor(new ExcludedInstrumentedClass(expression));
361   }
362
363   public void addInstrumentationDescriptor(InstrumentedClass classDesc) {
364     synchronized (this.instrumentationDescriptors) {
365       this.instrumentationDescriptors.addFirst(newInstrumentationDescriptor(classDesc));
366     }
367   }
368
369   public boolean hasIncludeExcludePatterns() {
370     synchronized (this.instrumentationDescriptors) {
371       return !this.instrumentationDescriptors.isEmpty();
372     }
373   }
374
375   public boolean hasIncludeExcludePattern(ClassInfo classInfo) {
376     return getInstrumentationDescriptorFor(classInfo) != DEAFULT_INSTRUMENTATION_DESCRIPTOR;
377   }
378
379   public DSORuntimeLoggingOptions runtimeLoggingOptions() {
380     return this.configSetupManager.dsoL1Config().runtimeLoggingOptions();
381   }
382
383   public DSORuntimeOutputOptions runtimeOutputOptions() {
384     return this.configSetupManager.dsoL1Config().runtimeOutputOptions();
385   }
386
387   public DSOInstrumentationLoggingOptions instrumentationLoggingOptions() {
388     return this.configSetupManager.dsoL1Config().instrumentationLoggingOptions();
389   }
390
391   private void doAutoconfig(boolean interrogateBootJar) {
392     // Table model stuff
393
addIncludePattern("javax.swing.event.TableModelEvent", true);
394     TransparencyClassSpec spec = getOrCreateSpec("javax.swing.event.TableModelEvent");
395
396     addIncludePattern("javax.swing.table.AbstractTableModel", true);
397     spec = getOrCreateSpec("javax.swing.table.AbstractTableModel");
398     spec.addDistributedMethodCall("fireTableChanged", "(Ljavax/swing/event/TableModelEvent;)V", false);
399     spec.addTransient("listenerList");
400
401     spec = getOrCreateSpec("javax.swing.table.DefaultTableModel");
402     spec.setCallConstructorOnLoad(true);
403     LockDefinition ld = new LockDefinition("tcdefaultTableLock", ConfigLockLevel.WRITE);
404     ld.commit();
405     addLock("* javax.swing.table.DefaultTableModel.set*(..)", ld);
406     addLock("* javax.swing.table.DefaultTableModel.insert*(..)", ld);
407     addLock("* javax.swing.table.DefaultTableModel.move*(..)", ld);
408     addLock("* javax.swing.table.DefaultTableModel.remove*(..)", ld);
409
410     ld = new LockDefinition("tcdefaultTableLock", ConfigLockLevel.READ);
411     ld.commit();
412     addLock("* javax.swing.table.DefaultTableModel.get*(..)", ld);
413
414     spec = getOrCreateSpec("javax.swing.DefaultListModel");
415     spec.setCallConstructorOnLoad(true);
416
417     ld = new LockDefinition("tcdefaultListLock", ConfigLockLevel.WRITE);
418     ld.commit();
419     addLock("* javax.swing.DefaultListModel.*(..)", ld);
420
421     addIncludePattern("java.awt.Color", true);
422     spec = getOrCreateSpec("java.awt.Color");
423     spec.addTransient("cs");
424
425     spec = getOrCreateSpec("java.awt.event.MouseMotionAdapter");
426     spec = getOrCreateSpec("java.awt.event.MouseAdapter");
427
428     // java.awt.point
429
spec = getOrCreateSpec("java.awt.Point");
430     spec = getOrCreateSpec("java.awt.geom.Point2D");
431     spec = getOrCreateSpec("java.awt.geom.Point2D$Double");
432     spec = getOrCreateSpec("java.awt.geom.Point2D$Float");
433     // end java.awt.Point
434

435     // java.awt.geom.Line
436
spec = getOrCreateSpec("java.awt.geom.Line2D");
437     spec = getOrCreateSpec("java.awt.geom.Line2D$Double");
438     spec = getOrCreateSpec("java.awt.geom.Line2D$Float");
439     // end java.awt.geom.Line
440

441     // java.awt.Rectangle
442
spec = getOrCreateSpec("java.awt.Rectangle");
443     spec = getOrCreateSpec("java.awt.geom.Rectangle2D");
444     spec = getOrCreateSpec("java.awt.geom.RectangularShape");
445     spec = getOrCreateSpec("java.awt.geom.Rectangle2D$Double");
446     spec = getOrCreateSpec("java.awt.geom.Rectangle2D$Float");
447     spec = getOrCreateSpec("java.awt.geom.RoundRectangle2D");
448     spec = getOrCreateSpec("java.awt.geom.RoundRectangle2D$Double");
449     spec = getOrCreateSpec("java.awt.geom.RoundRectangle2D$Float");
450     // end java.awt.Rectangle
451

452     // java.awt.geom.Ellipse2D
453
spec = getOrCreateSpec("java.awt.geom.Ellipse2D");
454     spec = getOrCreateSpec("java.awt.geom.Ellipse2D$Double");
455     spec = getOrCreateSpec("java.awt.geom.Ellipse2D$Float");
456     // end java.awt.geom.Ellipse2D
457

458     // java.awt.geom.Path2D
459
if (Vm.isJDK16()) {
460       spec = getOrCreateSpec("java.awt.geom.Path2D");
461       spec = getOrCreateSpec("java.awt.geom.Path2D$Double");
462       spec = getOrCreateSpec("java.awt.geom.Path2D$Float");
463     }
464     // end java.awt.geom.Path2D
465

466     // java.awt.geom.GeneralPath
467
spec = getOrCreateSpec("java.awt.geom.GeneralPath");
468     // end java.awt.geom.GeneralPath
469

470     // java.awt.BasicStroke
471
spec = getOrCreateSpec("java.awt.BasicStroke");
472     // end java.awt.BasicStroke
473

474     // java.awt.Dimension
475
spec = getOrCreateSpec("java.awt.Dimension");
476     spec = getOrCreateSpec("java.awt.geom.Dimension2D");
477     // end java.awt.Dimension
478

479     addIncludePattern("javax.swing.tree.TreePath", false);
480     spec = getOrCreateSpec("javax.swing.tree.TreePath");
481
482     addIncludePattern("javax.swing.tree.DefaultMutableTreeNode", false);
483     spec = getOrCreateSpec("javax.swing.tree.DefaultMutableTreeNode");
484
485     spec = getOrCreateSpec("javax.swing.tree.DefaultTreeModel");
486     ld = new LockDefinition("tctreeLock", ConfigLockLevel.WRITE);
487     ld.commit();
488     addLock("* javax.swing.tree.DefaultTreeModel.get*(..)", ld);
489     addLock("* javax.swing.tree.DefaultTreeModel.set*(..)", ld);
490     addLock("* javax.swing.tree.DefaultTreeModel.insert*(..)", ld);
491
492     spec.addTransient("listenerList");
493     spec.addDistributedMethodCall("fireTreeNodesChanged",
494                                   "(Ljava/lang/Object;[Ljava/lang/Object;[I[Ljava/lang/Object;)V", false);
495     spec.addDistributedMethodCall("fireTreeNodesInserted",
496                                   "(Ljava/lang/Object;[Ljava/lang/Object;[I[Ljava/lang/Object;)V", false);
497     spec.addDistributedMethodCall("fireTreeNodesRemoved",
498                                   "(Ljava/lang/Object;[Ljava/lang/Object;[I[Ljava/lang/Object;)V", false);
499     spec.addDistributedMethodCall("fireTreeStructureChanged",
500                                   "(Ljava/lang/Object;[Ljava/lang/Object;[I[Ljava/lang/Object;)V", false);
501     spec
502         .addDistributedMethodCall("fireTreeStructureChanged", "(Ljava/lang/Object;Ljavax/swing/tree/TreePath;)V", false);
503
504     spec = getOrCreateSpec("javax.swing.AbstractListModel");
505     spec.addTransient("listenerList");
506     spec.addDistributedMethodCall("fireContentsChanged", "(Ljava/lang/Object;II)V", false);
507     spec.addDistributedMethodCall("fireIntervalAdded", "(Ljava/lang/Object;II)V", false);
508     spec.addDistributedMethodCall("fireIntervalRemoved", "(Ljava/lang/Object;II)V", false);
509
510     spec = getOrCreateSpec("java.util.Arrays");
511     spec.addDoNotInstrument("copyOfRange");
512     spec.addDoNotInstrument("copyOf");
513
514     spec = getOrCreateSpec("java.util.Arrays$ArrayList");
515
516     spec = getOrCreateSpec("java.util.TreeMap", "com.tc.object.applicator.TreeMapApplicator");
517     spec.setUseNonDefaultConstructor(true);
518     spec.addMethodAdapter(SerializationUtil.PUT_SIGNATURE, new TreeMapAdapter.PutAdapter());
519     spec.addMethodAdapter("deleteEntry(Ljava/util/TreeMap$Entry;)V", new TreeMapAdapter.DeleteEntryAdapter());
520     spec.addAlwaysLogSpec(SerializationUtil.CLEAR_SIGNATURE);
521     spec.addEntrySetWrapperSpec(SerializationUtil.ENTRY_SET_SIGNATURE);
522
523     spec = getOrCreateSpec("java.util.HashMap", "com.tc.object.applicator.PartialHashMapApplicator");
524
525     spec = getOrCreateSpec("java.util.LinkedHashMap", "com.tc.object.applicator.LinkedHashMapApplicator");
526     spec.setUseNonDefaultConstructor(true);
527
528     spec = getOrCreateSpec("java.util.Hashtable", "com.tc.object.applicator.PartialHashMapApplicator");
529     /*
530      * spec.addSupportMethodCreator(new HashtableMethodCreator());
531      * spec.addHashtablePutLogSpec(SerializationUtil.PUT_SIGNATURE);
532      * spec.addHashtableRemoveLogSpec(SerializationUtil.REMOVE_KEY_SIGNATURE);
533      * spec.addHashtableClearLogSpec(SerializationUtil.CLEAR_SIGNATURE);
534      * spec.addMethodAdapter("entrySet()Ljava/util/Set;", new HashtableAdapter.EntrySetAdapter());
535      * spec.addMethodAdapter("keySet()Ljava/util/Set;", new HashtableAdapter.KeySetAdapter());
536      * spec.addMethodAdapter("values()Ljava/util/Collection;", new HashtableAdapter.ValuesAdapter());
537      */

538     // addWriteAutolock("synchronized * java.util.Hashtable.*(..)");
539
// addReadAutolock(new String[] { "synchronized * java.util.Hashtable.get(..)",
540
// "synchronized * java.util.Hashtable.hashCode(..)", "synchronized * java.util.Hashtable.contains*(..)",
541
// "synchronized * java.util.Hashtable.elements(..)", "synchronized * java.util.Hashtable.equals(..)",
542
// "synchronized * java.util.Hashtable.isEmpty(..)", "synchronized * java.util.Hashtable.keys(..)",
543
// "synchronized * java.util.Hashtable.size(..)", "synchronized * java.util.Hashtable.toString(..)" });
544
spec = getOrCreateSpec("java.util.Properties", "com.tc.object.applicator.PartialHashMapApplicator");
545     addWriteAutolock("synchronized * java.util.Properties.*(..)");
546
547     spec = getOrCreateSpec("com.tcclient.util.MapEntrySetWrapper$EntryWrapper");
548
549     spec = getOrCreateSpec("java.util.IdentityHashMap", "com.tc.object.applicator.HashMapApplicator");
550     spec.addAlwaysLogSpec(SerializationUtil.PUT_SIGNATURE);
551     spec.addAlwaysLogSpec(SerializationUtil.REMOVE_KEY_SIGNATURE);
552     spec.addAlwaysLogSpec(SerializationUtil.CLEAR_SIGNATURE);
553
554     spec = getOrCreateSpec("java.util.BitSet");
555     spec.setHonorTransient(false);
556
557     if (Vm.isJDK15Compliant()) {
558       spec = getOrCreateSpec("java.util.EnumMap");
559       spec.setHonorTransient(false);
560       spec = getOrCreateSpec("java.util.EnumSet");
561       spec = getOrCreateSpec("java.util.RegularEnumSet");
562       spec = getOrCreateSpec("java.util.RegularEnumSet$EnumSetIterator");
563     }
564
565     spec = getOrCreateSpec("java.util.Collections");
566     spec = getOrCreateSpec("java.util.Collections$EmptyList", "com.tc.object.applicator.ListApplicator");
567     spec = getOrCreateSpec("java.util.Collections$EmptyMap", "com.tc.object.applicator.HashMapApplicator");
568     spec = getOrCreateSpec("java.util.Collections$EmptySet", "com.tc.object.applicator.HashSetApplicator");
569
570     spec = getOrCreateSpec("java.util.Collections$UnmodifiableCollection");
571     spec.setHonorTransient(true);
572     spec = getOrCreateSpec("java.util.Collections$1");
573     spec.setHonorJDKSubVersionSpecific(true);
574     spec = getOrCreateSpec("java.util.Collections$2");
575     spec.setHonorJDKSubVersionSpecific(true);
576     spec = getOrCreateSpec("java.util.Collections$UnmodifiableList$1");
577     spec.setHonorJDKSubVersionSpecific(true);
578     spec = getOrCreateSpec("java.util.Collections$UnmodifiableList");
579     spec.setHonorTransient(true);
580     spec = getOrCreateSpec("java.util.Collections$UnmodifiableMap");
581     spec.setHonorTransient(true);
582     spec = getOrCreateSpec("java.util.Collections$UnmodifiableRandomAccessList");
583     spec.setHonorTransient(true);
584     spec = getOrCreateSpec("java.util.Collections$UnmodifiableSet");
585     spec.setHonorTransient(true);
586     spec = getOrCreateSpec("java.util.Collections$UnmodifiableSortedMap");
587     spec.setHonorTransient(true);
588     spec = getOrCreateSpec("java.util.Collections$UnmodifiableSortedSet");
589     spec.setHonorTransient(true);
590
591     spec = getOrCreateSpec("java.util.Collections$SingletonSet");
592     spec.setHonorTransient(true);
593     spec = getOrCreateSpec("java.util.Collections$SingletonList");
594     spec.setHonorTransient(true);
595     spec = getOrCreateSpec("java.util.Collections$SingletonMap");
596     spec.setHonorTransient(true);
597
598     spec = getOrCreateSpec("java.util.Collections$SynchronizedSet");
599     // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
600
spec.setHonorTransient(true);
601     spec = getOrCreateSpec("java.util.Collections$SynchronizedCollection");
602     // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
603
spec.setHonorTransient(true);
604     spec = getOrCreateSpec("java.util.Collections$SynchronizedList");
605     // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
606
spec.setHonorTransient(true);
607     spec = getOrCreateSpec("java.util.Collections$SynchronizedSortedMap");
608     // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
609
spec.setHonorTransient(true);
610     spec = getOrCreateSpec("java.util.Collections$SynchronizedSortedSet");
611     // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
612
spec.setHonorTransient(true);
613     spec = getOrCreateSpec("java.util.Collections$SynchronizedMap");
614     // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
615
spec.setHonorTransient(true);
616     spec = getOrCreateSpec("java.util.Collections$SynchronizedRandomAccessList");
617     // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
618
spec.setHonorTransient(true);
619
620     addJavaUtilCollectionPreInstrumentedSpec();
621
622     spec = getOrCreateSpec("com.tcclient.util.SortedViewSetWrapper");
623     spec.setHonorTransient(true);
624
625     // These classes are not PORTABLE by themselves, but logical classes subclasses them.
626
// We dont want them to get tc fields, TransparentAccess interfaces etc. but we do want them
627
// to be instrumented for Array manipulations, clone(), wait(), notify() calls etc.
628
spec = getOrCreateSpec("java.util.AbstractCollection");
629     spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
630     spec.addArrayCopyMethodCodeSpec(SerializationUtil.TO_ARRAY_SIGNATURE);
631     spec = getOrCreateSpec("java.util.AbstractList");
632     spec.setHonorTransient(true);
633     spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
634     spec.addSupportMethodCreator(new AbstractListMethodCreator());
635     spec = getOrCreateSpec("java.util.AbstractSet");
636     spec = getOrCreateSpec("java.util.AbstractSequentialList");
637     spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
638     spec = getOrCreateSpec("java.util.Dictionary");
639     spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
640
641     // AbstractMap is special because it actually has some fields so it needs to be instrumented and not just ADAPTABLE
642
spec = getOrCreateSpec("java.util.AbstractMap");
643     spec.setHonorTransient(true);
644
645     // spec = getOrCreateSpec("java.lang.Number");
646
// This hack is needed to make Number work in all platforms. Without this hack, if you add Number in bootjar, the
647
// JVM crashes.
648
// spec.generateNonStaticTCFields(false);
649

650     spec = getOrCreateSpec("java.lang.Exception");
651     spec = getOrCreateSpec("java.lang.RuntimeException");
652     spec = getOrCreateSpec("java.lang.InterruptedException");
653     spec = getOrCreateSpec("java.awt.AWTException");
654     spec = getOrCreateSpec("java.io.IOException");
655     spec = getOrCreateSpec("java.io.FileNotFoundException");
656     spec = getOrCreateSpec("java.lang.Error");
657     spec = getOrCreateSpec("java.util.ConcurrentModificationException");
658     spec = getOrCreateSpec("java.util.NoSuchElementException");
659
660     spec = getOrCreateSpec("java.util.EventObject");
661     // spec.setHonorTransient(true);
662

663     spec = getOrCreateSpec("com.tcclient.object.Client");
664     spec = getOrCreateSpec("com.tcclient.object.DistributedMethodCall");
665
666     spec = getOrCreateSpec("java.io.File");
667
668     spec = getOrCreateSpec("java.util.Date", "com.tc.object.applicator.DateApplicator");
669     spec.addAlwaysLogSpec(SerializationUtil.SET_TIME_SIGNATURE);
670     spec.addDateMethodLogSpec(SerializationUtil.SET_YEAR_SIGNATURE);
671     spec.addDateMethodLogSpec(SerializationUtil.SET_MONTH_SIGNATURE);
672     spec.addDateMethodLogSpec(SerializationUtil.SET_DATE_SIGNATURE);
673     spec.addDateMethodLogSpec(SerializationUtil.SET_HOURS_SIGNATURE);
674     spec.addDateMethodLogSpec(SerializationUtil.SET_MINUTES_SIGNATURE);
675     spec.addDateMethodLogSpec(SerializationUtil.SET_SECONDS_SIGNATURE);
676
677     spec = getOrCreateSpec("java.sql.Date", "com.tc.object.applicator.DateApplicator");
678     spec = getOrCreateSpec("java.sql.Time", "com.tc.object.applicator.DateApplicator");
679     spec = getOrCreateSpec("java.sql.Timestamp", "com.tc.object.applicator.DateApplicator");
680     spec.addDateMethodLogSpec(SerializationUtil.SET_TIME_SIGNATURE, MethodSpec.TIMESTAMP_SET_TIME_METHOD_WRAPPER_LOG);
681     spec.addAlwaysLogSpec(SerializationUtil.SET_NANOS_SIGNATURE);
682
683     addPermanentExcludePattern("java.util.WeakHashMap");
684     addPermanentExcludePattern("java.lang.ref.*");
685
686     spec = getOrCreateSpec("java.lang.reflect.AccessibleObject");
687     spec.addTransient("securityCheckCache");
688
689     addReflectionPreInstrumentedSpec();
690
691     addJDK15PreInstrumentedSpec();
692
693     /* ******* ALL ABOVE SPECS ARE PRE-INSTRUMENTED ******* */
694     markAllSpecsPreInstrumented();
695
696     addJDK15InstrumentedSpec();
697
698     // Generic Session classes
699
spec = getOrCreateSpec("com.terracotta.session.SessionData");
700     spec.setHonorTransient(true);
701     spec = getOrCreateSpec("com.terracotta.session.util.Timestamp");
702     spec.setHonorTransient(true);
703
704     spec = getOrCreateSpec("java.lang.Object");
705     spec.setCallConstructorOnLoad(true);
706
707     // Autolocking FastHashMap.
708
// addIncludePattern("org.apache.commons.collections.FastHashMap*", true);
709
// addWriteAutolock("* org.apache.commons.collections.FastHashMap*.*(..)");
710
// addReadAutolock(new String[] { "* org.apache.commons.collections.FastHashMap.clone(..)",
711
// "* org.apache.commons.collections.FastHashMap*.contains*(..)",
712
// "* org.apache.commons.collections.FastHashMap.equals(..)",
713
// "* org.apache.commons.collections.FastHashMap.get(..)",
714
// "* org.apache.commons.collections.FastHashMap*.hashCode(..)",
715
// "* org.apache.commons.collections.FastHashMap*.isEmpty(..)",
716
// "* org.apache.commons.collections.FastHashMap*.size(..)" });
717

718     spec = getOrCreateSpec("gnu.trove.THashMap", "com.tc.object.applicator.HashMapApplicator");
719     spec.addTHashMapPutLogSpec(SerializationUtil.PUT_SIGNATURE);
720     spec.addTHashRemoveAtLogSpec(SerializationUtil.TROVE_REMOVE_AT_SIGNATURE);
721     spec.addAlwaysLogSpec(SerializationUtil.CLEAR_SIGNATURE);
722     spec.addEntrySetWrapperSpec(SerializationUtil.ENTRY_SET_SIGNATURE);
723     spec.addKeySetWrapperSpec(SerializationUtil.KEY_SET_SIGNATURE);
724     spec.addValuesWrapperSpec(SerializationUtil.VALUES_SIGNATURE);
725     spec.addMethodAdapter(SerializationUtil.TRANSFORM_VALUES_SIGNATURE, new THashMapAdapter.TransformValuesAdapter());
726
727     spec = getOrCreateSpec("gnu.trove.THashSet", "com.tc.object.applicator.HashSetApplicator");
728     spec.addTHashSetAddLogSpec(SerializationUtil.ADD_SIGNATURE);
729     spec.addTHashSetRemoveAtLogSpec(SerializationUtil.REMOVE_SIGNATURE);
730     spec.addAlwaysLogSpec(SerializationUtil.CLEAR_SIGNATURE);
731
732     spec = getOrCreateSpec("gnu.trove.ToObjectArrayProcedure");
733     spec.addArrayCopyMethodCodeSpec(SerializationUtil.TO_ARRAY_SIGNATURE);
734
735     spec = getOrCreateSpec("javax.servlet.GenericServlet");
736     spec.setHonorTransient(true);
737     spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
738
739     // BEGIN: weblogic stuff
740
addAspectModule("weblogic.servlet.internal", "com.tc.weblogic.SessionAspectModule");
741     addWeblogicCustomAdapters();
742     // END: weblogic stuff
743

744     // BEGIN: tomcat stuff
745
addTomcatCustomAdapters();
746     // END: tomcat stuff
747

748     // Geronimo + WebsphereCE stuff
749
addCustomAdapter("org.apache.geronimo.kernel.basic.ProxyMethodInterceptor", new ProxyMethodInterceptorAdapter());
750     addCustomAdapter("org.apache.geronimo.kernel.config.MultiParentClassLoader", new MultiParentClassLoaderAdapter());
751     addCustomAdapter("org.apache.geronimo.tomcat.HostGBean", new HostGBeanAdapter());
752     addCustomAdapter("org.apache.geronimo.tomcat.TomcatClassLoader", new TomcatClassLoaderAdapter());
753
754     // JBoss adapters
755
addCustomAdapter("org.jboss.mx.loading.UnifiedClassLoader", new UCLAdapter());
756     addCustomAdapter("org.jboss.Main", new MainAdapter());
757
758     // TODO for the Event Swing sample only
759
ld = new LockDefinition("setTextArea", ConfigLockLevel.WRITE);
760     ld.commit();
761     addLock("* test.event.*.setTextArea(..)", ld);
762
763     doAutoconfigForSpring();
764     doAutoconfigForSpringWebFlow();
765
766     if (interrogateBootJar) {
767       // pre-load specs from boot jar
768
BootJar bootJar = null;
769       try {
770         bootJar = BootJar.getDefaultBootJarForReading();
771
772         Set JavaDoc allPreInstrumentedClasses = bootJar.getAllPreInstrumentedClasses();
773         for (Iterator JavaDoc i = allPreInstrumentedClasses.iterator(); i.hasNext();) {
774           // Create specs for any instrumented classes in the boot jar (such thay they can be shared)
775
getOrCreateSpec((String JavaDoc) i.next());
776         }
777       } catch (Throwable JavaDoc e) {
778         logger.error(e);
779
780         // don't needlessly wrap errors and runtimes
781
if (e instanceof RuntimeException JavaDoc) { throw (RuntimeException JavaDoc) e; }
782         if (e instanceof Error JavaDoc) { throw (Error JavaDoc) e; }
783
784         throw new RuntimeException JavaDoc(e);
785       } finally {
786         try {
787           if (bootJar != null) {
788             bootJar.close();
789           }
790         } catch (Exception JavaDoc e) {
791           logger.error(e);
792         }
793       }
794     }
795   }
796
797   /**
798    * Configure defaults for Spring Runtime
799    */

800   private void doAutoconfigForSpring() {
801     addIncludePattern("org.springframework.context.ApplicationEvent", false, false, false);
802     addIncludePattern("com.tcspring.ApplicationContextEventProtocol", true, true, true);
803
804     addIncludePattern("com.tcspring.ComplexBeanId", true, true, true);
805     // addIncludePattern("com.tcspring.BeanContainer", true, true, true);
806
getOrCreateSpec("com.tcspring.BeanContainer").addTransient("isInitialized"); // .setHonorTransient(true);
807

808     // scoped beans
809
// addTransient("org.springframework.web.context.request.ServletRequestAttributes$DestructionCallbackBindingListener",
810
// "aw$MIXIN_0");
811
addIncludePattern("com.tcspring.SessionProtocol$DestructionCallbackBindingListener", true, true, true);
812     addIncludePattern("com.tcspring.ScopedBeanDestructionCallBack", true, true, true);
813
814     // Spring AOP introduction/mixin classes
815
addIncludePattern("org.springframework.aop.support.IntroductionInfoSupport", true, true, true);
816     addIncludePattern("org.springframework.aop.support.DelegatingIntroductionInterceptor", true, true, true);
817     addIncludePattern("org.springframework.aop.support.DefaultIntroductionAdvisor", true, true, true);
818     addIncludePattern("gnu.trove..*", false, false, true);
819     addIncludePattern("java.lang.reflect.Proxy", false, false, false);
820     addIncludePattern("com.tc.aspectwerkz.proxy..*", false, false, true);
821
822     // TODO remove if we find a better way using ProxyApplicator etc.
823
addIncludePattern("$Proxy..*", false, false, true);
824
825     // backport concurrent classes
826
addIncludePattern("edu.emory.mathcs.backport.java.util.AbstractCollection", false, false, false);
827     addIncludePattern("edu.emory.mathcs.backport.java.util.AbstractQueue", false, false, false);
828     addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue", false, false, false);
829     addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue$Node", false, false, false);
830     addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.FutureTask", false, false, false);
831
832     addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.ConcurrentLinkedQueue", false, false, false);
833     addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.PriorityBlockingQueue", false, false, false);
834     addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.ArrayBlockingQueue", false, false, false);
835     addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList", false, false, false);
836
837     LockDefinition ld = new LockDefinition("addApplicationListener", ConfigLockLevel.WRITE);
838     ld.commit();
839     addLock("* org.springframework.context.event.AbstractApplicationEventMulticaster.addApplicationListener(..)", ld);
840
841     // used by WebFlow
842
addIncludePattern("org.springframework.core.enums.*", false, false, false);
843     addIncludePattern("org.springframework.binding..*", true, false, false);
844     addIncludePattern("org.springframework.validation..*", true, false, false);
845   }
846
847   private void doAutoconfigForSpringWebFlow() {
848     addAspectModule("org.springframework.webflow", "com.tc.object.config.SpringWebFlowAspectModule");
849     addIncludePattern("com.tcspring.DSOConversationLock", false, false, false);
850
851     addIncludePattern("org.springframework.webflow..*", true, false, false);
852
853     addIncludePattern("org.springframework.webflow.conversation.impl.ConversationEntry", false, false, false);
854     addIncludePattern("org.springframework.webflow.core.collection.LocalAttributeMap", false, false, false);
855     addIncludePattern("org.springframework.webflow.conversation.impl.*", false, false, false);
856
857     // getOrCreateSpec("org.springframework.webflow.engine.impl.FlowSessionImpl").setHonorTransient(false).addTransient("flow");
858
// flow : Flow
859
// flowId : String
860
// state : State
861
// stateId : String
862
// .addTransient("parent") // : FlowSessionImpl
863
// .addTransient("scope") // : LocalAttributeMap
864
// .addTransient("status"); // : FlowSessionStatus
865

866     // all "transient" for all subclasses except "State.id"
867
// getOrCreateSpec("org.springframework.webflow.engine.State") //
868
// .addTransient("logger").addTransient("flow") //
869
// .addTransient("entryActionList") //
870
// .addTransient("exceptionHandlerSet"); //
871
// getOrCreateSpec("org.springframework.webflow.engine.EndState") //
872
// .addTransient("viewSelector") //
873
// .addTransient("outputMapper"); //
874
// getOrCreateSpec("org.springframework.webflow.engine.TransitionableState") // abstract
875
// .addTransient("transitions")
876
// .addTransient("exitActionList");
877
// getOrCreateSpec("org.springframework.webflow.engine.ActionState") //
878
// .addTransient("actionList");
879
// getOrCreateSpec("org.springframework.webflow.engine.SubflowState") //
880
// .addTransient("subflow") //
881
// .addTransient("attributeMapper"); //
882
// getOrCreateSpec("org.springframework.webflow.engine.ViewState") //
883
// .addTransient("viewSelector") //
884
// .addTransient("renderActionList");
885
// // getOrCreateSpec("org.springframework.webflow.engine.DecisionState"); no fields
886

887     // TODO investigate if better granularity of above classes is required
888
// org.springframework.webflow.execution.repository.support.DefaultFlowExecutionRepository
889
// org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository
890
// org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository
891
// org.springframework.webflow.execution.repository.support.DefaultFlowExecutionRepositoryFactory
892
// org.springframework.webflow.execution.repository.support.DelegatingFlowExecutionRepositoryFactory
893
// org.springframework.webflow.execution.repository.support.FlowExecutionRepositoryServices
894
// org.springframework.webflow.execution.repository.support.SharedMapFlowExecutionRepositoryFactory
895
// org.springframework.webflow.execution.repository.conversation.impl.LocalConversationService
896
// org.springframework.webflow.util.RandomGuidUidGenerator
897
// org.springframework.webflow.registry.FlowRegistryImpl
898
// etc...
899
}
900
901   private void addReflectionPreInstrumentedSpec() {
902     if (supportSharingThroughReflection) {
903       getOrCreateSpec("java.lang.reflect.Field");
904       addCustomAdapter("java.lang.reflect.Field", new JavaLangReflectFieldAdapter());
905
906       getOrCreateSpec("java.lang.reflect.Array");
907       addCustomAdapter("java.lang.reflect.Array", new JavaLangReflectArrayAdapter());
908     }
909   }
910
911   private void addLogicalAdaptedLinkedBlockingQueueSpec() {
912     TransparencyClassSpec spec = getOrCreateSpec("java.util.AbstractQueue");
913     spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
914
915     spec = getOrCreateSpec("java.util.concurrent.LinkedBlockingQueue",
916                            "com.tc.object.applicator.LinkedBlockingQueueApplicator");
917   }
918
919   private void addJavaUtilConcurrentHashMapSpec() {
920     TransparencyClassSpec spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap",
921                                                  "com.tc.object.applicator.ConcurrentHashMapApplicator");
922     spec.setHonorTransient(true);
923     spec.setPostCreateMethod("__tc_rehash");
924
925     spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap$Segment");
926     spec.setCallConstructorOnLoad(true);
927     spec.setHonorTransient(true);
928   }
929
930   private void addJavaUtilConcurrentFutureTaskSpec() {
931     if (Vm.isJDK16()) {
932       getOrCreateSpec("java.util.concurrent.locks.AbstractOwnableSynchronizer");
933     }
934     TransparencyClassSpec spec = getOrCreateSpec("java.util.concurrent.FutureTask$Sync");
935     addWriteAutolock("* java.util.concurrent.FutureTask$Sync.*(..)");
936     spec.setHonorTransient(true);
937     spec.addDistributedMethodCall("managedInnerCancel", "()V", false);
938
939     getOrCreateSpec("java.util.concurrent.FutureTask");
940
941     getOrCreateSpec("java.util.concurrent.Executors$RunnableAdapter");
942   }
943
944   private void addJDK15InstrumentedSpec() {
945     if (Vm.getMegaVersion() >= 1 && Vm.getMajorVersion() > 4) {
946       TransparencyClassSpec spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantLock$ConditionObject");
947       spec.setCallConstructorOnLoad(true);
948       spec.setHonorTransient(true);
949     }
950   }
951
952   private void addJavaUtilCollectionPreInstrumentedSpec() {
953     // The details of the instrumentation spec is specified in BootJarTool.
954
getOrCreateSpec("java.util.HashSet", "com.tc.object.applicator.HashSetApplicator");
955
956     getOrCreateSpec("java.util.LinkedHashSet", "com.tc.object.applicator.HashSetApplicator");
957
958     getOrCreateSpec("java.util.TreeSet", "com.tc.object.applicator.TreeSetApplicator");
959
960     getOrCreateSpec("java.util.LinkedList", "com.tc.object.applicator.ListApplicator");
961
962     getOrCreateSpec("java.util.Stack", "com.tc.object.applicator.ListApplicator");
963
964     getOrCreateSpec("java.util.Vector", "com.tc.object.applicator.ListApplicator");
965     // addWriteAutolock("synchronized * java.util.Vector.*(..)");
966
// addReadAutolock(new String[] { "synchronized * java.util.Vector.capacity(..)",
967
// "synchronized * java.util.Vector.clone(..)", "synchronized * java.util.Vector.containsAll(..)",
968
// "synchronized * java.util.Vector.elementAt(..)", "synchronized * java.util.Vector.equals(..)",
969
// "synchronized * java.util.Vector.firstElement(..)", "synchronized * java.util.Vector.get(..)",
970
// "synchronized * java.util.Vector.hashCode(..)", "synchronized * java.util.Vector.indexOf(..)",
971
// "synchronized * java.util.Vector.isEmpty(..)", "synchronized * java.util.Vector.lastElement(..)",
972
// "synchronized * java.util.Vector.lastIndexOf(..)", "synchronized * java.util.Vector.size(..)",
973
// "synchronized * java.util.Vector.subList(..)", "synchronized * java.util.Vector.toString(..)", });
974

975     getOrCreateSpec("java.util.ArrayList", "com.tc.object.applicator.ListApplicator");
976   }
977
978   private void addJDK15PreInstrumentedSpec() {
979     if (Vm.getMegaVersion() >= 1 && Vm.getMajorVersion() > 4) {
980       TransparencyClassSpec spec = getOrCreateSpec("sun.misc.Unsafe");
981       addCustomAdapter("sun.misc.Unsafe", new UnsafeAdapter());
982       spec = getOrCreateSpec(DSOUnsafe.CLASS_DOTS);
983       addCustomAdapter(DSOUnsafe.CLASS_DOTS, new DSOUnsafeAdapter());
984
985       spec = getOrCreateSpec("java.util.concurrent.CyclicBarrier");
986
987       spec = getOrCreateSpec("java.util.concurrent.CyclicBarrier$Generation");
988       spec.setHonorJDKSubVersionSpecific(true);
989
990       spec = getOrCreateSpec("java.util.concurrent.atomic.AtomicInteger");
991       spec.setHonorVolatile(true);
992       spec = getOrCreateSpec("java.util.concurrent.atomic.AtomicLong");
993       spec.setHonorVolatile(true);
994
995       spec = getOrCreateSpec("java.util.concurrent.TimeUnit");
996
997       /*****************************************************************************************************************
998        * This section of spec are specified in the BootJarTool also. They are placed again so that the honorTransient *
999        * flag will be honored during runtime. *
1000       ****************************************************************************************************************/

1001
1002      addJavaUtilConcurrentHashMapSpec();
1003
1004      addLogicalAdaptedLinkedBlockingQueueSpec();
1005
1006      addJavaUtilConcurrentFutureTaskSpec();
1007
1008      spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantLock");
1009      spec.setHonorTransient(true);
1010      spec.setCallConstructorOnLoad(true);
1011
1012      /*****************************************************************************************************************
1013       * This section of spec are specified in the BootJarTool also. They are placed again so that the honorTransient *
1014       * flag will be honored during runtime. *
1015       ****************************************************************************************************************/

1016    }
1017  }
1018
1019  private void addTomcatCustomAdapters() {
1020    addCustomAdapter("org.apache.jasper.runtime.JspWriterImpl", new JspWriterImplAdapter());
1021    addCustomAdapter("org.apache.catalina.loader.WebappLoader", new WebAppLoaderAdapter());
1022    addCustomAdapter("org.apache.catalina.startup.Catalina", new CatalinaAdapter());
1023    addCustomAdapter("org.apache.catalina.core.ContainerBase", new ContainerBaseAdapter());
1024    addCustomAdapter("org.apache.catalina.startup.Bootstrap", new BootstrapAdapter());
1025  }
1026
1027  private void addWeblogicCustomAdapters() {
1028    addCustomAdapter("weblogic.Server", new ServerAdapter());
1029    addCustomAdapter("weblogic.utils.classloaders.GenericClassLoader", new GenericClassLoaderAdapter());
1030    addCustomAdapter("weblogic.ejb20.ejbc.EjbCodeGenerator", new EJBCodeGeneratorAdapter());
1031    addCustomAdapter("weblogic.servlet.internal.WebAppServletContext", new WebAppServletContextAdapter());
1032    addCustomAdapter("weblogic.servlet.internal.ServletResponseImpl", new ServletResponseImplAdapter());
1033    addCustomAdapter("weblogic.servlet.internal.TerracottaServletResponseImpl",
1034                     new TerracottaServletResponseImplAdapter());
1035  }
1036
1037  public void addCustomAdapter(String JavaDoc name, ClassAdapterFactory factory) {
1038    try {
1039      // Constructor cstr = adapter.getConstructor(ADAPTER_CSTR_SIGNATURE);
1040
Object JavaDoc prev = this.customAdapters.put(name, factory);
1041      Assert.assertNull(prev);
1042    } catch (Exception JavaDoc e) {
1043      throw new RuntimeException JavaDoc(e);
1044    }
1045  }
1046
1047  private void markAllSpecsPreInstrumented() {
1048    for (Iterator JavaDoc i = classSpecs.values().iterator(); i.hasNext();) {
1049      TransparencyClassSpec s = (TransparencyClassSpec) i.next();
1050      s.markPreInstrumented();
1051    }
1052  }
1053
1054  public DSOInstrumentationLoggingOptions getInstrumentationLoggingOptions() {
1055    return this.configSetupManager.dsoL1Config().instrumentationLoggingOptions();
1056  }
1057
1058  public Iterator JavaDoc getAllUserDefinedBootSpecs() {
1059    return this.userDefinedBootSpecs.values().iterator();
1060  }
1061
1062  public void setFaultCount(int count) {
1063    this.faultCount = count;
1064  }
1065
1066  public boolean isLockMethod(int access, String JavaDoc className, String JavaDoc methodName, String JavaDoc description, String JavaDoc[] exceptions) {
1067    helperLogger.logIsLockMethodBegin(access, className, methodName, description);
1068
1069    LockDefinition lockDefinitions[] = lockDefinitionsFor(access, className, methodName, description, exceptions);
1070
1071    for (int j = 0; j < lockDefinitions.length; j++) {
1072      if (lockDefinitions[j].isAutolock()) {
1073        if (isNotStaticAndIsSynchronized(access)) {
1074          helperLogger.logIsLockMethodAutolock();
1075          return true;
1076        }
1077      } else {
1078        return true;
1079      }
1080    }
1081
1082    helperLogger.logIsLockMethodNoMatch(className, methodName);
1083    return false;
1084  }
1085
1086  public boolean matches(final Lock lock, final MemberInfo methodInfo) {
1087    return matches(lock.getMethodJoinPointExpression(), methodInfo);
1088  }
1089
1090  public boolean matches(final String JavaDoc expression, final MemberInfo methodInfo) {
1091    String JavaDoc executionExpression = ExpressionHelper.expressionPattern2ExecutionExpression(expression);
1092    if (logger.isDebugEnabled()) logger
1093        .debug("==>Testing for match: " + executionExpression + " against " + methodInfo);
1094    ExpressionContext ctxt = expressionHelper.createExecutionExpressionContext(methodInfo);
1095    ExpressionVisitor visitor = expressionHelper.createExpressionVisitor(executionExpression);
1096    return visitor.match(ctxt);
1097  }
1098
1099  private MethodInfo getMethodInfo(int modifiers, String JavaDoc className, String JavaDoc methodName, String JavaDoc description,
1100                                   String JavaDoc[] exceptions) {
1101    // TODO: This probably needs caching.
1102
return new AsmMethodInfo(classInfoFactory, modifiers, className, methodName, description, exceptions);
1103  }
1104
1105  private ConstructorInfo getConstructorInfo(int modifiers, String JavaDoc className, String JavaDoc methodName, String JavaDoc description,
1106                                             String JavaDoc[] exceptions) {
1107    return new AsmConstructorInfo(classInfoFactory, modifiers, className, methodName, description, exceptions);
1108  }
1109
1110  private MemberInfo getMemberInfo(int modifiers, String JavaDoc className, String JavaDoc methodName, String JavaDoc description,
1111                                   String JavaDoc[] exceptions) {
1112    if (false && "<init>".equals(methodName)) {
1113      // XXX: ConstructorInfo seems to really break things. Plus, locks in
1114
// constructors don't work yet.
1115
// When locks in constructors work, we'll have to sort this problem out.
1116
return getConstructorInfo(modifiers, className, methodName, description, exceptions);
1117    } else {
1118      return getMethodInfo(modifiers, className, methodName, description, exceptions);
1119    }
1120  }
1121
1122  private static boolean isNotStaticAndIsSynchronized(int modifiers) {
1123    return !Modifier.isStatic(modifiers) && Modifier.isSynchronized(modifiers);
1124  }
1125
1126  /**
1127   * This is a simplified interface from DSOApplicationConfig. This is used for programmatically generating config.
1128   */

1129  public void addRoot(String JavaDoc rootName, String JavaDoc rootFieldName) {
1130    ClassSpec classSpec;
1131    try {
1132      classSpec = ClassUtils.parseFullyQualifiedFieldName(rootFieldName);
1133    } catch (ParseException JavaDoc e) {
1134      throw new RuntimeException JavaDoc(e);
1135    }
1136    addRoot(classSpec.getFullyQualifiedClassName(), classSpec.getShortFieldName(), rootName, false);
1137  }
1138
1139  private void addRoot(String JavaDoc className, String JavaDoc fieldName, Root newRoot, boolean addSpecForClass) {
1140    if (addSpecForClass) {
1141      this.getOrCreateSpec(className);
1142    }
1143
1144    synchronized (roots) {
1145      Map rootsForClass = (Map) roots.get(className);
1146      if (rootsForClass == null) {
1147        rootsForClass = new ConcurrentHashMap();
1148        roots.put(className, rootsForClass);
1149      }
1150
1151      rootsForClass.put(fieldName, newRoot);
1152    }
1153  }
1154
1155  public void addRoot(String JavaDoc className, String JavaDoc fieldName, String JavaDoc rootName, boolean addSpecForClass) {
1156    addRoot(className, fieldName, new Root(className, fieldName, rootName), addSpecForClass);
1157  }
1158
1159  public void addRoot(String JavaDoc className, String JavaDoc fieldName, String JavaDoc rootName, boolean dsoFinal, boolean addSpecForClass) {
1160    addRoot(className, fieldName, new Root(className, fieldName, rootName, dsoFinal), addSpecForClass);
1161  }
1162
1163  public String JavaDoc rootNameFor(String JavaDoc className, String JavaDoc fieldName) {
1164    Map rootsForClass = (Map) roots.get(className);
1165    if (rootsForClass == null) { throw Assert.failure("No roots at all for class " + className); }
1166
1167    Root root = (Root) rootsForClass.get(fieldName);
1168    if (root == null) { throw Assert.failure("No such root for fieldName " + fieldName + " in class " + className); }
1169
1170    return root.getRootName();
1171  }
1172
1173  public boolean isRoot(String JavaDoc className, String JavaDoc fieldName) {
1174    Map rootsForClass = (Map) roots.get(className);
1175    if (rootsForClass == null) { return false; }
1176    return rootsForClass.containsKey(fieldName);
1177  }
1178
1179  public boolean isRootDSOFinal(String JavaDoc className, String JavaDoc fieldName, boolean isPrimitive) {
1180    Map rootsForClass = (Map) roots.get(className);
1181    if (rootsForClass == null) { throw Assert.failure("No roots at all for class " + className); }
1182    Root root = (Root) rootsForClass.get(fieldName);
1183    if (root == null) { throw Assert.failure("No such root for fieldName " + fieldName + " in class " + className); }
1184
1185    return root.isDsoFinal(isPrimitive);
1186  }
1187
1188  private boolean classContainsAnyRoots(String JavaDoc className) {
1189    return roots.containsKey(className);
1190  }
1191
1192  private void rewriteHashtableAutLockSpecIfNecessary() {
1193    // addReadAutolock(new String[] { "synchronized * java.util.Hashtable.get(..)",
1194
// "synchronized * java.util.Hashtable.hashCode(..)", "synchronized * java.util.Hashtable.contains*(..)",
1195
// "synchronized * java.util.Hashtable.elements(..)", "synchronized * java.util.Hashtable.equals(..)",
1196
// "synchronized * java.util.Hashtable.isEmpty(..)", "synchronized * java.util.Hashtable.keys(..)",
1197
// "synchronized * java.util.Hashtable.size(..)", "synchronized * java.util.Hashtable.toString(..)" });
1198

1199    Set JavaDoc readOnlyLockMethodSpec = new HashSet JavaDoc();
1200
1201    int access = Opcodes.ACC_PUBLIC;
1202    String JavaDoc className = "java.util.Hashtable";
1203    String JavaDoc methodName = "get";
1204    String JavaDoc description = "(Ljava/lang/Object;)Ljava/lang/Object;";
1205    MemberInfo methodInfo = getMemberInfo(access, className, methodName, description, null);
1206    readOnlyLockMethodSpec.add(methodInfo);
1207
1208    methodName = "hashCode";
1209    description = "()I";
1210    methodInfo = getMemberInfo(access, className, methodName, description, null);
1211    readOnlyLockMethodSpec.add(methodInfo);
1212
1213    methodName = "contains";
1214    description = "(Ljava/lang/Object;)Z";
1215    methodInfo = getMemberInfo(access, className, methodName, description, null);
1216    readOnlyLockMethodSpec.add(methodInfo);
1217
1218    methodName = "containsKey";
1219    description = "(Ljava/lang/Object;)Z";
1220    methodInfo = getMemberInfo(access, className, methodName, description, null);
1221    readOnlyLockMethodSpec.add(methodInfo);
1222
1223    methodName = "elements";
1224    description = "()Ljava/util/Enumeration;";
1225    methodInfo = getMemberInfo(access, className, methodName, description, null);
1226    readOnlyLockMethodSpec.add(methodInfo);
1227
1228    methodName = "equals";
1229    description = "(Ljava/lang/Object;)Z";
1230    methodInfo = getMemberInfo(access, className, methodName, description, null);
1231    readOnlyLockMethodSpec.add(methodInfo);
1232
1233    methodName = "isEmpty";
1234    description = "()Z";
1235    methodInfo = getMemberInfo(access, className, methodName, description, null);
1236    readOnlyLockMethodSpec.add(methodInfo);
1237
1238    methodName = "keys";
1239    description = "()Ljava/util/Enumeration;";
1240    methodInfo = getMemberInfo(access, className, methodName, description, null);
1241    readOnlyLockMethodSpec.add(methodInfo);
1242
1243    methodName = "size";
1244    description = "()I";
1245    methodInfo = getMemberInfo(access, className, methodName, description, null);
1246    readOnlyLockMethodSpec.add(methodInfo);
1247
1248    methodName = "toString";
1249    description = "()Ljava/lang/String;";
1250    methodInfo = getMemberInfo(access, className, methodName, description, null);
1251    readOnlyLockMethodSpec.add(methodInfo);
1252
1253    for (Iterator JavaDoc itr = readOnlyLockMethodSpec.iterator(); itr.hasNext();) {
1254      methodInfo = (MemberInfo) itr.next();
1255
1256      for (int i = 0; i < locks.length; i++) {
1257        Lock lock = locks[i];
1258        if (matches(lock, methodInfo)) {
1259          LockDefinition ld = lock.getLockDefinition();
1260          if (ld.isAutolock() && ld.getLockLevel() != ConfigLockLevel.READ) {
1261            addReadAutolock("* " + className + "." + methodInfo.getName() + "(..)");
1262          }
1263          break;
1264        }
1265      }
1266    }
1267  }
1268
1269  public synchronized LockDefinition[] lockDefinitionsFor(int access, String JavaDoc className, String JavaDoc methodName,
1270                                                          String JavaDoc description, String JavaDoc[] exceptions) {
1271    MemberInfo methodInfo = getMemberInfo(access, className, methodName, description, exceptions);
1272    boolean isAutoLocksExcluded = matchesAutoLockExcludes(methodInfo);
1273    List JavaDoc lockDefs = new ArrayList JavaDoc();
1274    // for (int i = 0; i < this.locks.length; i++) {
1275
for (int i = locks.length - 1; i >= 0; i--) {
1276      if (matches(this.locks[i], methodInfo)) {
1277        LockDefinition definition = this.locks[i].getLockDefinition();
1278        if (!(definition.isAutolock() && isAutoLocksExcluded)) {
1279          lockDefs.add(definition);
1280          if (definition.isAutolock()) {
1281            isAutoLocksExcluded = true;
1282          }
1283        }
1284      }
1285    }
1286    LockDefinition[] rv = new LockDefinition[lockDefs.size()];
1287    lockDefs.toArray(rv);
1288    return rv;
1289  }
1290
1291  private boolean matchesAutoLockExcludes(MemberInfo methodInfo) {
1292    ExpressionContext ctxt = expressionHelper.createExecutionExpressionContext(methodInfo);
1293    for (Iterator JavaDoc i = autoLockExcludes.iterator(); i.hasNext();) {
1294      ExpressionVisitor visitor = (ExpressionVisitor) i.next();
1295      if (visitor.match(ctxt)) return true;
1296    }
1297    return false;
1298  }
1299
1300  public int getFaultCount() {
1301    return faultCount < 0 ? this.configSetupManager.dsoL1Config().faultCount().getInt() : faultCount;
1302  }
1303
1304  private synchronized Boolean JavaDoc readAdaptableCache(String JavaDoc name) {
1305    return (Boolean JavaDoc) adaptableCache.get(name);
1306  }
1307
1308  private synchronized boolean cacheIsAdaptable(String JavaDoc name, boolean adaptable) {
1309    adaptableCache.put(name, adaptable ? Boolean.TRUE : Boolean.FALSE);
1310    return adaptable;
1311  }
1312
1313  private synchronized void clearAdaptableCache() {
1314    this.adaptableCache.clear();
1315  }
1316
1317  public void addWriteAutolock(String JavaDoc methodPattern) {
1318    addAutolock(methodPattern, ConfigLockLevel.WRITE);
1319  }
1320
1321  public void addSynchronousWriteAutolock(String JavaDoc methodPattern) {
1322    addAutolock(methodPattern, ConfigLockLevel.SYNCHRONOUS_WRITE);
1323  }
1324
1325  public void addReadAutolock(String JavaDoc methodPattern) {
1326    addAutolock(methodPattern, ConfigLockLevel.READ);
1327  }
1328
1329  public synchronized void addAutolock(String JavaDoc methodPattern, ConfigLockLevel type) {
1330    LockDefinition lockDefinition = new LockDefinition(LockDefinition.TC_AUTOLOCK_NAME, type);
1331    lockDefinition.commit();
1332    addLock(methodPattern, lockDefinition);
1333  }
1334
1335  public synchronized void addLock(String JavaDoc methodPattern, LockDefinition lockDefinition) {
1336    Lock[] result = new Lock[locks.length + 1];
1337    System.arraycopy(locks, 0, result, 0, locks.length);
1338    result[locks.length] = new Lock(methodPattern, lockDefinition);
1339    locks = result;
1340  }
1341
1342  public boolean shouldBeAdapted(ClassInfo classInfo) {
1343    String JavaDoc fullClassName = classInfo.getName();
1344    Boolean JavaDoc cache = readAdaptableCache(fullClassName);
1345    if (cache != null) { return cache.booleanValue(); }
1346
1347    // @see isTCPatternMatchingHack() note elsewhere
1348
if (isTCPatternMatchingHack(classInfo) || permanentExcludesMatcher.match(classInfo)) {
1349      // permanent Excludes
1350
return cacheIsAdaptable(fullClassName, false);
1351    }
1352
1353    if (fullClassName.indexOf(CGLIB_PATTERN) >= 0) {
1354      if (!allowCGLIBInstrumentation) {
1355        logger.error("Refusing to instrument CGLIB generated proxy type " + fullClassName
1356                     + " (CGLIB terracotta plugin not installed)");
1357        return cacheIsAdaptable(fullClassName, false);
1358      }
1359    }
1360
1361    String JavaDoc outerClassname = outerClassnameWithoutInner(fullClassName);
1362    if (isLogical(outerClassname)) {
1363      // We make inner classes of logical classes not instrumented while logical
1364
// bases are instrumented...UNLESS there is a explicit spec for said inner class
1365
boolean adaptable = getSpec(fullClassName) != null || outerClassname.equals(fullClassName);
1366      return cacheIsAdaptable(fullClassName, adaptable);
1367    }
1368
1369    // If a root is defined then we automagically instrument
1370
if (classContainsAnyRoots(fullClassName)) { return cacheIsAdaptable(fullClassName, true); }
1371
1372    // custom adapters trump config.
1373
if (hasCustomAdapter(fullClassName)) { return cacheIsAdaptable(fullClassName, true); }
1374
1375    // existing class specs trump config
1376
if (hasSpec(fullClassName)) { return cacheIsAdaptable(fullClassName, true); }
1377
1378    InstrumentationDescriptor desc = getInstrumentationDescriptorFor(classInfo);
1379    return cacheIsAdaptable(fullClassName, desc.isInclude());
1380  }
1381
1382  private boolean isTCPatternMatchingHack(ClassInfo classInfo) {
1383    String JavaDoc fullClassName = classInfo.getName();
1384    return fullClassName.startsWith("com.tc.") || fullClassName.startsWith("com.terracottatech.");
1385  }
1386
1387  public boolean isNeverAdaptable(ClassInfo classInfo) {
1388    return isTCPatternMatchingHack(classInfo) || permanentExcludesMatcher.match(classInfo)
1389           || nonportablesMatcher.match(classInfo);
1390  }
1391
1392  private InstrumentationDescriptor getInstrumentationDescriptorFor(ClassInfo classInfo) {
1393    synchronized (this.instrumentationDescriptors) {
1394      for (Iterator JavaDoc i = this.instrumentationDescriptors.iterator(); i.hasNext();) {
1395        InstrumentationDescriptor rv = (InstrumentationDescriptor) i.next();
1396        if (rv.matches(classInfo)) { return rv; }
1397      }
1398    }
1399    return DEAFULT_INSTRUMENTATION_DESCRIPTOR;
1400  }
1401
1402  public boolean hasCustomAdapter(String JavaDoc fullName) {
1403    return customAdapters.containsKey(fullName);
1404  }
1405
1406  private String JavaDoc outerClassnameWithoutInner(String JavaDoc fullName) {
1407    int indexOfInner = fullName.indexOf('$');
1408    return indexOfInner < 0 ? fullName : fullName.substring(0, indexOfInner);
1409  }
1410
1411  public boolean isTransient(int modifiers, String JavaDoc classname, String JavaDoc field) {
1412    if (ByteCodeUtil.isParent(field)) return true;
1413    if (Modifier.isTransient(modifiers) && isHonorJavaTransient(classname)) return true;
1414    Type type = (Type) types.get(classname);
1415    if (type != null) { return (type.containsTransient(field)); }
1416    return false;
1417  }
1418
1419  public boolean isVolatile(int modifiers, String JavaDoc classname, String JavaDoc field) {
1420    return (Modifier.isVolatile(modifiers) && isHonorJavaVolatile(classname));
1421  }
1422
1423  private boolean isHonorJavaTransient(String JavaDoc className) {
1424    TransparencyClassSpec spec = getSpec(className);
1425    if (spec != null && spec.isHonorTransientSet()) { return spec.isHonorJavaTransient(); }
1426    return getInstrumentationDescriptorFor(getClassInfo(className)).isHonorTransient();
1427  }
1428
1429  private boolean isHonorJavaVolatile(String JavaDoc className) {
1430    TransparencyClassSpec spec = getSpec(className);
1431    if (spec != null && spec.isHonorVolatileSet()) { return spec.isHonorVolatile(); }
1432    return getInstrumentationDescriptorFor(getClassInfo(className)).isHonorVolatile();
1433  }
1434
1435  public boolean isCallConstructorOnLoad(String JavaDoc className) {
1436    TransparencyClassSpec spec = getSpec(className);
1437    if (spec != null && spec.isCallConstructorSet()) { return spec.isCallConstructorOnLoad(); }
1438    return getInstrumentationDescriptorFor(getClassInfo(className)).isCallConstructorOnLoad();
1439  }
1440
1441  private ClassInfo getClassInfo(String JavaDoc className) {
1442    // XXX need to get a real ClassInfo
1443
return classInfoFactory.getClassInfo(className);
1444  }
1445
1446  public String JavaDoc getPostCreateMethodIfDefined(String JavaDoc className) {
1447    TransparencyClassSpec spec = getSpec(className);
1448    if (spec != null) {
1449      return spec.getPostCreateMethod();
1450    } else {
1451      return null;
1452    }
1453  }
1454
1455  public String JavaDoc getOnLoadScriptIfDefined(String JavaDoc className) {
1456    TransparencyClassSpec spec = getSpec(className);
1457    if (spec != null && spec.isExecuteScriptOnLoadSet()) { return spec.getOnLoadExecuteScript(); }
1458    return getInstrumentationDescriptorFor(getClassInfo(className)).getOnLoadScriptIfDefined();
1459  }
1460
1461  public String JavaDoc getOnLoadMethodIfDefined(String JavaDoc className) {
1462    TransparencyClassSpec spec = getSpec(className);
1463    if (spec != null && spec.isCallMethodOnLoadSet()) { return spec.getOnLoadMethod(); }
1464    return getInstrumentationDescriptorFor(getClassInfo(className)).getOnLoadMethodIfDefined();
1465  }
1466
1467  public Class JavaDoc getTCPeerClass(Class JavaDoc clazz) {
1468    if (moduleSpecs != null) {
1469      for (int i = 0; i < moduleSpecs.length; i++) {
1470        clazz = moduleSpecs[i].getPeerClass(clazz);
1471      }
1472    }
1473    return clazz;
1474  }
1475
1476  public boolean isDSOSessions(String JavaDoc name) {
1477    for (Iterator JavaDoc it = applicationNames.iterator(); it.hasNext();) {
1478      String JavaDoc appName = (String JavaDoc) it.next();
1479      if (name.matches(appName.replaceAll("\\*", "\\.\\*"))) return true;
1480    }
1481    return false;
1482  }
1483
1484  public TransparencyClassAdapter createDsoClassAdapterFor(ClassVisitor writer, ClassInfo classInfo,
1485                                                           InstrumentationLogger lgr, ClassLoader JavaDoc caller,
1486                                                           final boolean forcePortable) {
1487    String JavaDoc className = classInfo.getName();
1488    ManagerHelper mgrHelper = mgrHelperFactory.createHelper();
1489    TransparencyClassSpec spec = getOrCreateSpec(className);
1490
1491    if (forcePortable) {
1492      if (spec.getInstrumentationAction() == TransparencyClassSpec.NOT_SET) {
1493        spec.setInstrumentationAction(TransparencyClassSpec.PORTABLE);
1494      } else {
1495        logger.info("Not making " + className + " forcefully portable");
1496      }
1497    }
1498
1499    return new TransparencyClassAdapter(classInfo, basicGetOrCreateSpec(className, null, false), writer, mgrHelper,
1500                                        lgr, caller, portability);
1501  }
1502
1503  public ClassAdapter createClassAdapterFor(ClassWriter writer, ClassInfo classInfo, InstrumentationLogger lgr,
1504                                            ClassLoader JavaDoc caller) {
1505    return this.createClassAdapterFor(writer, classInfo, lgr, caller, false);
1506  }
1507
1508  public ClassAdapter createClassAdapterFor(ClassWriter writer, ClassInfo classInfo, InstrumentationLogger lgr,
1509                                            ClassLoader JavaDoc caller, final boolean forcePortable) {
1510    ClassAdapterFactory adapter = (ClassAdapterFactory) this.customAdapters.get(classInfo.getName());
1511    if (adapter != null) {
1512      return adapter.create(writer, caller);
1513    } else {
1514      ManagerHelper mgrHelper = mgrHelperFactory.createHelper();
1515      TransparencyClassSpec spec = getOrCreateSpec(classInfo.getName());
1516
1517      if (forcePortable) {
1518        if (spec.getInstrumentationAction() == TransparencyClassSpec.NOT_SET) {
1519          spec.setInstrumentationAction(TransparencyClassSpec.PORTABLE);
1520        } else {
1521          logger.info("Not making " + classInfo.getName() + " forcefully portable");
1522        }
1523      }
1524
1525      ClassAdapter dsoAdapter = new TransparencyClassAdapter(classInfo, spec, writer, mgrHelper, lgr, caller,
1526                                                             portability);
1527      ClassAdapterFactory factory = spec.getCustomClassAdapter();
1528      ClassVisitor cv;
1529      if (factory == null) {
1530        cv = dsoAdapter;
1531      } else {
1532        cv = factory.create(dsoAdapter, caller);
1533      }
1534
1535      return new SerialVersionUIDAdder(cv);
1536    }
1537  }
1538
1539  private TransparencyClassSpec basicGetOrCreateSpec(String JavaDoc className, String JavaDoc applicator, boolean rememberSpec) {
1540    synchronized (classSpecs) {
1541      TransparencyClassSpec spec = getSpec(className);
1542      if (spec == null) {
1543        if (applicator != null) {
1544          spec = new TransparencyClassSpec(className, this, applicator);
1545        } else {
1546          spec = new TransparencyClassSpec(className, this);
1547        }
1548        if (rememberSpec) {
1549          addSpec(spec);
1550        }
1551      }
1552      return spec;
1553    }
1554  }
1555
1556  public TransparencyClassSpec getOrCreateSpec(String JavaDoc className) {
1557    return basicGetOrCreateSpec(className, null, true);
1558  }
1559
1560  public TransparencyClassSpec getOrCreateSpec(final String JavaDoc className, final String JavaDoc applicator) {
1561    if (applicator == null) throw new AssertionError JavaDoc();
1562    return basicGetOrCreateSpec(className, applicator, true);
1563  }
1564
1565  private void addSpec(TransparencyClassSpec spec) {
1566    synchronized (classSpecs) {
1567      Assert.eval(!classSpecs.containsKey(spec.getClassName()));
1568      classSpecs.put(spec.getClassName(), spec);
1569    }
1570  }
1571
1572  public boolean isLogical(String JavaDoc className) {
1573    TransparencyClassSpec spec = getSpec(className);
1574    return spec != null && spec.isLogical();
1575  }
1576
1577  // TODO: Need to optimize this by identifying the module to query instead of querying all the modules.
1578
public boolean isPortableModuleClass(Class JavaDoc clazz) {
1579    if (moduleSpecs != null) {
1580      for (int i = 0; i < moduleSpecs.length; i++) {
1581        if (moduleSpecs[i].isPortableClass(clazz)) { return true; }
1582      }
1583    }
1584    return false;
1585  }
1586
1587  public Class JavaDoc getChangeApplicator(Class JavaDoc clazz) {
1588    ChangeApplicatorSpec applicatorSpec = null;
1589    TransparencyClassSpec spec = getSpec(clazz.getName());
1590    if (spec != null) {
1591      applicatorSpec = spec.getChangeApplicatorSpec();
1592    }
1593
1594    if (applicatorSpec == null) {
1595      if (moduleSpecs != null) {
1596        for (int i = 0; i < moduleSpecs.length; i++) {
1597          Class JavaDoc applicatorClass = moduleSpecs[i].getChangeApplicatorSpec().getChangeApplicator(clazz);
1598          if (applicatorClass != null) { return applicatorClass; }
1599        }
1600      }
1601      return null;
1602    }
1603    return applicatorSpec.getChangeApplicator(clazz);
1604  }
1605
1606  // TODO: Need to optimize this by identifying the module to query instead of querying all the modules.
1607
public boolean isUseNonDefaultConstructor(Class JavaDoc clazz) {
1608    String JavaDoc className = clazz.getName();
1609    if (literalValues.isLiteral(className)) { return true; }
1610    TransparencyClassSpec spec = getSpec(className);
1611    if (spec != null) { return spec.isUseNonDefaultConstructor(); }
1612    if (moduleSpecs != null) {
1613      for (int i = 0; i < moduleSpecs.length; i++) {
1614        if (moduleSpecs[i].isUseNonDefaultConstructor(clazz)) { return true; }
1615      }
1616    }
1617    return false;
1618  }
1619
1620  public void setModuleSpecs(ModuleSpec[] moduleSpecs) {
1621    this.moduleSpecs = moduleSpecs;
1622  }
1623
1624  /*
1625   * public String getChangeApplicatorClassNameFor(String className) { TransparencyClassSpec spec = getSpec(className);
1626   * if (spec == null) return null; return spec.getChangeApplicatorClassName(); }
1627   */

1628
1629  public boolean hasSpec(String JavaDoc className) {
1630    return getSpec(className) != null;
1631  }
1632
1633  /**
1634   * This is used in BootJarTool. In BootJarTool, it changes the package of our implementation of ReentrantLock and
1635   * FutureTask to the java.util.concurrent package. In order to change the different adapter together, we need to
1636   * create a spec with our package and remove the spec after the instrumentation is done.
1637   */

1638  public void removeSpec(String JavaDoc className) {
1639    className = className.replace('/', '.');
1640    classSpecs.remove(className);
1641  }
1642
1643  public TransparencyClassSpec getSpec(String JavaDoc className) {
1644    // NOTE: This method doesn't create a spec for you. If you want that use getOrCreateSpec()
1645
className = className.replace('/', '.');
1646    TransparencyClassSpec rv = (TransparencyClassSpec) classSpecs.get(className);
1647
1648    if (rv == null) {
1649      rv = (TransparencyClassSpec) userDefinedBootSpecs.get(className);
1650    } else {
1651      // shouldn't have a spec in both of the spec collections
1652
Assert.assertNull(userDefinedBootSpecs.get(className));
1653    }
1654
1655    return rv;
1656  }
1657
1658  public void verifyBootJarContents() throws IncompleteBootJarException, UnverifiedBootJarException {
1659    logger.info("Verifying boot jar contents...");
1660    int missingCount = 0;
1661    int preInstrumentedCount = 0;
1662    int bootJarPopulation = 0;
1663    try {
1664      BootJar bootJar = BootJar.getDefaultBootJarForReading();
1665      Set JavaDoc bjClasses = bootJar.getAllPreInstrumentedClasses();
1666      bootJarPopulation = bjClasses.size();
1667      TransparencyClassSpec[] allSpecs = getAllSpecs();
1668      for (int i = 0; i < allSpecs.length; i++) {
1669        TransparencyClassSpec classSpec = allSpecs[i];
1670        String JavaDoc message = "";
1671        if (classSpec.isPreInstrumented()) {
1672          message = "* " + classSpec.getClassName() + "... ";
1673          preInstrumentedCount++;
1674          if (bjClasses.contains(classSpec.getClassName()) || classSpec.isHonorJDKSubVersionSpecific()) {
1675            message += "ok";
1676          } else {
1677            message += "missing";
1678            missingCount++;
1679          }
1680          logger.info(message);
1681        }
1682      }
1683    } catch (BootJarException bjex) {
1684      throw new UnverifiedBootJarException(
1685                                           "BootJarException occurred while attempting to verify the contents of the boot jar.",
1686                                           bjex);
1687    } catch (IOException JavaDoc ioex) {
1688      throw new UnverifiedBootJarException(
1689                                           "IOException occurred while attempting to verify the contents of the boot jar.",
1690                                           ioex);
1691    }
1692    logger.info("Number of classes in the DSO boot jar:" + bootJarPopulation);
1693    logger.info("Number of classes expected to be in the DSO boot jar:" + preInstrumentedCount);
1694    logger.info("Number of classes found missing from the DSO boot jar:" + missingCount);
1695    if (missingCount > 0) { throw new IncompleteBootJarException("Incomplete DSO boot jar; " + missingCount
1696                                                                 + " pre-instrumented class(es) found missing."); }
1697  }
1698
1699  public synchronized TransparencyClassSpec[] getAllSpecs() {
1700    TransparencyClassSpec[] allspecs = new TransparencyClassSpec[classSpecs.values().size()];
1701    classSpecs.values().toArray(allspecs);
1702    return allspecs;
1703  }
1704
1705  public void addDistributedMethodCall(DistributedMethodSpec dms) {
1706    this.distributedMethods.add(dms);
1707  }
1708
1709  public DistributedMethodSpec getDmiSpec(int modifiers, String JavaDoc className, String JavaDoc methodName, String JavaDoc description,
1710                                          String JavaDoc[] exceptions) {
1711    if (Modifier.isStatic(modifiers) || "<init>".equals(methodName) || "<clinit>".equals(methodName)) { return null; }
1712    MemberInfo methodInfo = getMemberInfo(modifiers, className, methodName, description, exceptions);
1713    for (Iterator JavaDoc i = distributedMethods.iterator(); i.hasNext();) {
1714      DistributedMethodSpec dms = (DistributedMethodSpec) i.next();
1715      if (matches(dms.getMethodExpression(), methodInfo)) { return dms; }
1716    }
1717    return null;
1718  }
1719
1720  public void addTransient(String JavaDoc className, String JavaDoc fieldName) {
1721    TransparencyClassSpec spec = this.getOrCreateSpec(className);
1722    spec.addTransient(fieldName);
1723  }
1724
1725  public void addTransientType(String JavaDoc className, String JavaDoc fieldName) {
1726    Type type = (Type) this.types.get(className);
1727    if (type == null) {
1728      type = new Type();
1729      type.setName(className);
1730      this.types.put(className, type);
1731    }
1732    type.addTransient(fieldName);
1733  }
1734
1735  public String JavaDoc toString() {
1736    return "<StandardDSOClientConfigHelper: " + configSetupManager + ">";
1737  }
1738
1739  public void writeTo(DSOApplicationConfigBuilder appConfigBuilder) {
1740    throw new UnsupportedOperationException JavaDoc();
1741  }
1742
1743  public void addAspectModule(String JavaDoc pattern, String JavaDoc moduleName) {
1744    List JavaDoc modules = (List JavaDoc) this.aspectModules.get(pattern);
1745    if (modules == null) {
1746      modules = new ArrayList JavaDoc();
1747      this.aspectModules.put(pattern, modules);
1748    }
1749    modules.add(moduleName);
1750  }
1751
1752  public Map getAspectModules() {
1753    return this.aspectModules;
1754  }
1755
1756  public void addDSOSpringConfig(DSOSpringConfigHelper config) {
1757    this.springConfigs.add(config);
1758
1759    if (!this.aspectModules.containsKey("org.springframework")) {
1760      addAspectModule("org.springframework", "com.tc.object.config.SpringAspectModule");
1761    }
1762  }
1763
1764  public Collection JavaDoc getDSOSpringConfigs() {
1765    return this.springConfigs;
1766  }
1767
1768  public String JavaDoc getLogicalExtendingClassName(String JavaDoc className) {
1769    TransparencyClassSpec spec = getSpec(className);
1770    if (spec == null || !spec.isLogical()) { return null; }
1771    return spec.getLogicalExtendingClassName();
1772  }
1773
1774  public void addApplicationName(String JavaDoc name) {
1775    applicationNames.add(name);
1776  }
1777
1778  public void addSynchronousWriteApplication(String JavaDoc name) {
1779    this.synchronousWriteApplications.add(name);
1780  }
1781
1782  public void addUserDefinedBootSpec(String JavaDoc className, TransparencyClassSpec spec) {
1783    userDefinedBootSpecs.put(className, spec);
1784  }
1785
1786  public void addNewModule(String JavaDoc name, String JavaDoc version) {
1787    Module newModule = modulesContext.modules.addNewModule();
1788    newModule.setName(name);
1789    newModule.setVersion(version);
1790  }
1791
1792  public Modules getModulesForInitialization() {
1793    return modulesContext.getModulesForInitialization();
1794  }
1795
1796  private static class ModulesContext {
1797
1798    private boolean alwaysInitializedModules = true; // set to false only when in test
1799
private boolean modulesInitialized = false; // set to true only when in test
1800

1801    private Modules modules;
1802
1803    // This is used only in test
1804
void initializedModulesOnlyOnce() {
1805      this.alwaysInitializedModules = false;
1806    }
1807
1808    void setModules(Modules modules) {
1809      this.modules = modules;
1810    }
1811
1812    Modules getModulesForInitialization() {
1813      if (alwaysInitializedModules) {
1814        return this.modules;
1815      } else {
1816        // this could happen only in test
1817
if (modulesInitialized) {
1818          return Modules.Factory.newInstance();
1819        } else {
1820          modulesInitialized = true;
1821          return this.modules;
1822        }
1823      }
1824    }
1825  }
1826
1827  public int getSessionLockType(String JavaDoc appName) {
1828    for (Iterator JavaDoc iter = synchronousWriteApplications.iterator(); iter.hasNext();) {
1829      String JavaDoc webApp = (String JavaDoc) iter.next();
1830      if (webApp.equals(appName)) { return LockLevel.SYNCHRONOUS_WRITE; }
1831    }
1832    return LockLevel.WRITE;
1833  }
1834
1835}
1836
Popular Tags