0001: /*
0002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
0003: * notice. All rights reserved.
0004: */
0005: package com.tc.object.config;
0006:
0007: import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
0008: import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArrayList;
0009:
0010: import com.tc.asm.ClassAdapter;
0011: import com.tc.asm.ClassVisitor;
0012: import com.tc.asm.ClassWriter;
0013: import com.tc.aspectwerkz.expression.ExpressionContext;
0014: import com.tc.aspectwerkz.expression.ExpressionVisitor;
0015: import com.tc.aspectwerkz.reflect.ClassInfo;
0016: import com.tc.aspectwerkz.reflect.FieldInfo;
0017: import com.tc.aspectwerkz.reflect.MemberInfo;
0018: import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo;
0019: import com.tc.config.schema.NewCommonL1Config;
0020: import com.tc.config.schema.builder.DSOApplicationConfigBuilder;
0021: import com.tc.config.schema.setup.ConfigurationSetupException;
0022: import com.tc.config.schema.setup.L1TVSConfigurationSetupManager;
0023: import com.tc.config.schema.setup.TVSConfigurationSetupManagerFactory;
0024: import com.tc.geronimo.transform.HostGBeanAdapter;
0025: import com.tc.geronimo.transform.MultiParentClassLoaderAdapter;
0026: import com.tc.geronimo.transform.ProxyMethodInterceptorAdapter;
0027: import com.tc.geronimo.transform.TomcatClassLoaderAdapter;
0028: import com.tc.jboss.transform.MainAdapter;
0029: import com.tc.jboss.transform.UCLAdapter;
0030: import com.tc.logging.CustomerLogging;
0031: import com.tc.logging.TCLogger;
0032: import com.tc.object.LiteralValues;
0033: import com.tc.object.Portability;
0034: import com.tc.object.PortabilityImpl;
0035: import com.tc.object.SerializationUtil;
0036: import com.tc.object.bytecode.AbstractListMethodCreator;
0037: import com.tc.object.bytecode.ByteCodeUtil;
0038: import com.tc.object.bytecode.ClassAdapterBase;
0039: import com.tc.object.bytecode.ClassAdapterFactory;
0040: import com.tc.object.bytecode.DelegateMethodAdapter;
0041: import com.tc.object.bytecode.ManagerHelper;
0042: import com.tc.object.bytecode.ManagerHelperFactory;
0043: import com.tc.object.bytecode.SafeSerialVersionUIDAdder;
0044: import com.tc.object.bytecode.THashMapAdapter;
0045: import com.tc.object.bytecode.TransparencyClassAdapter;
0046: import com.tc.object.bytecode.TreeMapAdapter;
0047: import com.tc.object.bytecode.aspectwerkz.ExpressionHelper;
0048: import com.tc.object.config.schema.DSOInstrumentationLoggingOptions;
0049: import com.tc.object.config.schema.DSORuntimeLoggingOptions;
0050: import com.tc.object.config.schema.DSORuntimeOutputOptions;
0051: import com.tc.object.config.schema.ExcludedInstrumentedClass;
0052: import com.tc.object.config.schema.IncludeOnLoad;
0053: import com.tc.object.config.schema.IncludedInstrumentedClass;
0054: import com.tc.object.config.schema.InstrumentedClass;
0055: import com.tc.object.config.schema.NewDSOApplicationConfig;
0056: import com.tc.object.config.schema.NewSpringApplicationConfig;
0057: import com.tc.object.glassfish.transform.RuntimeModelAdapter;
0058: import com.tc.object.lockmanager.api.LockLevel;
0059: import com.tc.object.logging.InstrumentationLogger;
0060: import com.tc.object.tools.BootJar;
0061: import com.tc.object.tools.BootJarException;
0062: import com.tc.tomcat.transform.BootstrapAdapter;
0063: import com.tc.tomcat.transform.CatalinaAdapter;
0064: import com.tc.tomcat.transform.ContainerBaseAdapter;
0065: import com.tc.tomcat.transform.JspWriterImplAdapter;
0066: import com.tc.tomcat.transform.WebAppLoaderAdapter;
0067: import com.tc.util.Assert;
0068: import com.tc.util.ClassUtils;
0069: import com.tc.util.ClassUtils.ClassSpec;
0070: import com.tc.util.runtime.Vm;
0071: import com.tc.weblogic.transform.EJBCodeGeneratorAdapter;
0072: import com.tc.weblogic.transform.EventsManagerAdapter;
0073: import com.tc.weblogic.transform.FilterManagerAdapter;
0074: import com.tc.weblogic.transform.GenericClassLoaderAdapter;
0075: import com.tc.weblogic.transform.ServerAdapter;
0076: import com.tc.weblogic.transform.ServletResponseImplAdapter;
0077: import com.tc.weblogic.transform.WebAppServletContextAdapter;
0078: import com.terracottatech.config.DsoApplication;
0079: import com.terracottatech.config.Module;
0080: import com.terracottatech.config.Modules;
0081: import com.terracottatech.config.SpringApplication;
0082:
0083: import java.io.IOException;
0084: import java.lang.reflect.Modifier;
0085: import java.net.URL;
0086: import java.text.ParseException;
0087: import java.util.ArrayList;
0088: import java.util.Collection;
0089: import java.util.Collections;
0090: import java.util.HashMap;
0091: import java.util.HashSet;
0092: import java.util.Iterator;
0093: import java.util.LinkedList;
0094: import java.util.List;
0095: import java.util.Map;
0096: import java.util.Set;
0097:
0098: public class StandardDSOClientConfigHelperImpl implements
0099: StandardDSOClientConfigHelper, DSOClientConfigHelper {
0100:
0101: private static final String CGLIB_PATTERN = "$$EnhancerByCGLIB$$";
0102:
0103: private static final LiteralValues literalValues = new LiteralValues();
0104:
0105: private static final TCLogger logger = CustomerLogging
0106: .getDSOGenericLogger();
0107:
0108: private static final InstrumentationDescriptor DEAFULT_INSTRUMENTATION_DESCRIPTOR = new NullInstrumentationDescriptor();
0109:
0110: private final ManagerHelperFactory mgrHelperFactory = new ManagerHelperFactory();
0111: private final DSOClientConfigHelperLogger helperLogger;
0112:
0113: private final L1TVSConfigurationSetupManager configSetupManager;
0114:
0115: private final List locks = new CopyOnWriteArrayList();
0116: private final List roots = new CopyOnWriteArrayList();
0117: private final Set transients = Collections
0118: .synchronizedSet(new HashSet());
0119:
0120: private final Set applicationNames = Collections
0121: .synchronizedSet(new HashSet());
0122: private final List synchronousWriteApplications = new ArrayList();
0123: private final CompoundExpressionMatcher permanentExcludesMatcher;
0124: private final CompoundExpressionMatcher nonportablesMatcher;
0125: private final List autoLockExcludes = new CopyOnWriteArrayList();
0126: private final List distributedMethods = new CopyOnWriteArrayList(); // <DistributedMethodSpec>
0127: private final Map userDefinedBootSpecs = new HashMap();
0128:
0129: // private final ClassInfoFactory classInfoFactory;
0130: private final ExpressionHelper expressionHelper;
0131:
0132: private final Map adaptableCache = new HashMap();
0133:
0134: /**
0135: * A list of InstrumentationDescriptor representing include/exclude patterns
0136: */
0137: private final LinkedList instrumentationDescriptors = new LinkedList();
0138:
0139: /**
0140: * A map of class names to TransparencyClassSpec for individual classes
0141: */
0142: private final Map classSpecs = Collections
0143: .synchronizedMap(new HashMap());
0144:
0145: private final Map customAdapters = new ConcurrentHashMap();
0146:
0147: private final ClassReplacementMapping classReplacements = new ClassReplacementMappingImpl();
0148:
0149: private final Map classResources = new ConcurrentHashMap();
0150:
0151: private final Map aspectModules = Collections
0152: .synchronizedMap(new HashMap());
0153:
0154: private final List springConfigs = Collections
0155: .synchronizedList(new ArrayList());
0156:
0157: private final boolean supportSharingThroughReflection;
0158:
0159: private final Portability portability;
0160:
0161: private int faultCount = -1;
0162:
0163: private ModuleSpec[] moduleSpecs = null;
0164:
0165: private final ModulesContext modulesContext = new ModulesContext();
0166:
0167: private volatile boolean allowCGLIBInstrumentation = false;
0168:
0169: public StandardDSOClientConfigHelperImpl(
0170: L1TVSConfigurationSetupManager configSetupManager)
0171: throws ConfigurationSetupException {
0172: this (configSetupManager, true);
0173: }
0174:
0175: public StandardDSOClientConfigHelperImpl(
0176: boolean initializedModulesOnlyOnce,
0177: L1TVSConfigurationSetupManager configSetupManager)
0178: throws ConfigurationSetupException {
0179: this (configSetupManager, true);
0180: if (initializedModulesOnlyOnce) {
0181: modulesContext.initializedModulesOnlyOnce();
0182: }
0183: }
0184:
0185: public StandardDSOClientConfigHelperImpl(
0186: L1TVSConfigurationSetupManager configSetupManager,
0187: boolean interrogateBootJar)
0188: throws ConfigurationSetupException {
0189: this .portability = new PortabilityImpl(this );
0190: this .configSetupManager = configSetupManager;
0191: helperLogger = new DSOClientConfigHelperLogger(logger);
0192: // this.classInfoFactory = new ClassInfoFactory();
0193: this .expressionHelper = new ExpressionHelper();
0194: modulesContext.setModules(configSetupManager.commonL1Config()
0195: .modules() != null ? configSetupManager
0196: .commonL1Config().modules() : Modules.Factory
0197: .newInstance());
0198:
0199: permanentExcludesMatcher = new CompoundExpressionMatcher();
0200:
0201: // CDV-441 -- This exclude should come before any patterns that do matching that might
0202: // mandate more class loading (e.g. a superclass/interface match (Foo+))
0203: addPermanentExcludePattern("org.jboss.net.protocol..*");
0204:
0205: // TODO:: come back and add all possible non-portable/non-adaptable classes here. This is by no means exhaustive !
0206:
0207: // XXX:: There is a bug in aspectwerkz com.tc..* matches both com.tc and com.tctest classes. As a work around
0208: // this is commented and isTCPatternMatchingHack() method is added instead. When that bug is fixed, uncomment
0209: // this and remove isTCPatternMatchingHack();
0210: // addPermanentExcludePattern("com.tc..*");
0211: // addPermanentExcludePattern("com.terracottatech..*");
0212:
0213: /**
0214: * // ---------------------------- // implicit config-bundle - JAG // ----------------------------
0215: * addPermanentExcludePattern("java.awt.Component"); addPermanentExcludePattern("java.lang.Thread");
0216: * addPermanentExcludePattern("java.lang.ThreadLocal"); addPermanentExcludePattern("java.lang.ThreadGroup");
0217: * addPermanentExcludePattern("java.lang.Process"); addPermanentExcludePattern("java.lang.ClassLoader");
0218: * addPermanentExcludePattern("java.lang.Runtime"); addPermanentExcludePattern("java.io.FileReader");
0219: * addPermanentExcludePattern("java.io.FileWriter"); addPermanentExcludePattern("java.io.FileDescriptor");
0220: * addPermanentExcludePattern("java.io.FileInputStream"); addPermanentExcludePattern("java.io.FileOutputStream");
0221: * addPermanentExcludePattern("java.net.DatagramSocket"); addPermanentExcludePattern("java.net.DatagramSocketImpl");
0222: * addPermanentExcludePattern("java.net.MulticastSocket"); addPermanentExcludePattern("java.net.ServerSocket");
0223: * addPermanentExcludePattern("java.net.Socket"); addPermanentExcludePattern("java.net.SocketImpl");
0224: * addPermanentExcludePattern("java.nio.channels.DatagramChannel");
0225: * addPermanentExcludePattern("java.nio.channels.FileChannel");
0226: * addPermanentExcludePattern("java.nio.channels.FileLock");
0227: * addPermanentExcludePattern("java.nio.channels.ServerSocketChannel");
0228: * addPermanentExcludePattern("java.nio.channels.SocketChannel");
0229: * addPermanentExcludePattern("java.util.logging.FileHandler");
0230: * addPermanentExcludePattern("java.util.logging.SocketHandler"); // Fix for CDV-357: Getting verifier errors when
0231: * instrumenting obfuscated classes // These classes are obfuscated and as such can't be instrumented.
0232: * addPermanentExcludePattern("com.sun.crypto.provider..*");
0233: */
0234:
0235: /**
0236: * // ---------------------------- // implicit config-bundle - JAG // ----------------------------
0237: * addUnsupportedJavaUtilConcurrentTypes();
0238: */
0239:
0240: /**
0241: * // ---------------------------- // implicit config-bundle - JAG // ----------------------------
0242: * addAutoLockExcludePattern("* java.lang.Throwable.*(..)");
0243: */
0244:
0245: nonportablesMatcher = new CompoundExpressionMatcher();
0246: /**
0247: * // ---------------------------- // implicit config-bundle - JAG // ----------------------------
0248: * //addNonportablePattern("javax.servlet.GenericServlet");
0249: */
0250:
0251: NewDSOApplicationConfig appConfig = configSetupManager
0252: .dsoApplicationConfigFor(TVSConfigurationSetupManagerFactory.DEFAULT_APPLICATION_NAME);
0253: NewSpringApplicationConfig springConfig = configSetupManager
0254: .springApplicationConfigFor(TVSConfigurationSetupManagerFactory.DEFAULT_APPLICATION_NAME);
0255:
0256: supportSharingThroughReflection = appConfig
0257: .supportSharingThroughReflection().getBoolean();
0258: try {
0259: doPreInstrumentedAutoconfig(interrogateBootJar);
0260: doAutoconfig(interrogateBootJar);
0261: } catch (Exception e) {
0262: throw new ConfigurationSetupException(e
0263: .getLocalizedMessage(), e);
0264: }
0265:
0266: ConfigLoader loader = new ConfigLoader(this , logger);
0267: loader.loadDsoConfig((DsoApplication) appConfig.getBean());
0268: loader.loadSpringConfig((SpringApplication) springConfig
0269: .getBean());
0270:
0271: logger.debug("web-applications: " + this .applicationNames);
0272: logger.debug("synchronous-write web-applications: "
0273: + this .synchronousWriteApplications);
0274: logger.debug("roots: " + this .roots);
0275: logger.debug("locks: " + this .locks);
0276: logger.debug("distributed-methods: " + this .distributedMethods);
0277:
0278: rewriteHashtableAutoLockSpecIfNecessary();
0279: removeTomcatAdapters();
0280: }
0281:
0282: public void allowCGLIBInstrumentation() {
0283: this .allowCGLIBInstrumentation = true;
0284: }
0285:
0286: public boolean reflectionEnabled() {
0287: return this .supportSharingThroughReflection;
0288: }
0289:
0290: /**
0291: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- private void
0292: * addUnsupportedJavaUtilConcurrentTypes() {
0293: * addPermanentExcludePattern("java.util.concurrent.AbstractExecutorService");
0294: * addPermanentExcludePattern("java.util.concurrent.ArrayBlockingQueue*");
0295: * addPermanentExcludePattern("java.util.concurrent.ConcurrentLinkedQueue*");
0296: * addPermanentExcludePattern("java.util.concurrent.ConcurrentSkipListMap*");
0297: * addPermanentExcludePattern("java.util.concurrent.ConcurrentSkipListSet*");
0298: * addPermanentExcludePattern("java.util.concurrent.CopyOnWriteArrayList*");
0299: * addPermanentExcludePattern("java.util.concurrent.CopyOnWriteArraySet*");
0300: * addPermanentExcludePattern("java.util.concurrent.CountDownLatch*");
0301: * addPermanentExcludePattern("java.util.concurrent.DelayQueue*");
0302: * addPermanentExcludePattern("java.util.concurrent.Exchanger*");
0303: * addPermanentExcludePattern("java.util.concurrent.ExecutorCompletionService*");
0304: * addPermanentExcludePattern("java.util.concurrent.LinkedBlockingDeque*");
0305: * addPermanentExcludePattern("java.util.concurrent.PriorityBlockingQueue*");
0306: * addPermanentExcludePattern("java.util.concurrent.ScheduledThreadPoolExecutor*");
0307: * addPermanentExcludePattern("java.util.concurrent.Semaphore*");
0308: * addPermanentExcludePattern("java.util.concurrent.SynchronousQueue*");
0309: * addPermanentExcludePattern("java.util.concurrent.ThreadPoolExecutor*");
0310: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicBoolean*");
0311: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicIntegerArray*");
0312: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicIntegerFieldUpdater*");
0313: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicLongArray*");
0314: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicLongFieldUpdater*");
0315: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicMarkableReference*");
0316: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicReference*");
0317: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicReferenceArray*");
0318: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicReferenceFieldUpdater*");
0319: * addPermanentExcludePattern("java.util.concurrent.atomic.AtomicStampedReference*");
0320: * addPermanentExcludePattern("java.util.concurrent.locks.AbstractQueuedLongSynchronizer*");
0321: * addPermanentExcludePattern("java.util.concurrent.locks.AbstractQueuedSynchronizer*");
0322: * addPermanentExcludePattern("java.util.concurrent.locks.LockSupport*"); }
0323: */
0324:
0325: public Portability getPortability() {
0326: return this .portability;
0327: }
0328:
0329: public void addAutoLockExcludePattern(String expression) {
0330: String executionExpression = ExpressionHelper
0331: .expressionPattern2ExecutionExpression(expression);
0332: ExpressionVisitor visitor = expressionHelper
0333: .createExpressionVisitor(executionExpression);
0334: autoLockExcludes.add(visitor);
0335: }
0336:
0337: public void addPermanentExcludePattern(String pattern) {
0338: permanentExcludesMatcher.add(new ClassExpressionMatcherImpl(
0339: expressionHelper, pattern));
0340: }
0341:
0342: public LockDefinition createLockDefinition(String name,
0343: ConfigLockLevel level) {
0344: return new LockDefinitionImpl(name, level);
0345: }
0346:
0347: public void addNonportablePattern(String pattern) {
0348: nonportablesMatcher.add(new ClassExpressionMatcherImpl(
0349: expressionHelper, pattern));
0350: }
0351:
0352: private InstrumentationDescriptor newInstrumentationDescriptor(
0353: InstrumentedClass classDesc) {
0354: return new InstrumentationDescriptorImpl(classDesc, //
0355: new ClassExpressionMatcherImpl(expressionHelper, //
0356: classDesc.classExpression()));
0357: }
0358:
0359: // This is used only for tests right now
0360: public void addIncludePattern(String expression) {
0361: addIncludePattern(expression, false, false, false);
0362: }
0363:
0364: public NewCommonL1Config getNewCommonL1Config() {
0365: return configSetupManager.commonL1Config();
0366: }
0367:
0368: // This is used only for tests right now
0369: public void addIncludePattern(String expression,
0370: boolean honorTransient) {
0371: addIncludePattern(expression, honorTransient, false, false);
0372: }
0373:
0374: public void addIncludePattern(String expression,
0375: boolean honorTransient,
0376: boolean oldStyleCallConstructorOnLoad, boolean honorVolatile) {
0377: IncludeOnLoad onLoad = new IncludeOnLoad();
0378: if (oldStyleCallConstructorOnLoad) {
0379: onLoad.setToCallConstructorOnLoad(true);
0380: }
0381: addInstrumentationDescriptor(new IncludedInstrumentedClass(
0382: expression, honorTransient, honorVolatile, onLoad));
0383:
0384: clearAdaptableCache();
0385: }
0386:
0387: public void addIncludeAndLockIfRequired(String expression,
0388: boolean honorTransient,
0389: boolean oldStyleCallConstructorOnLoad,
0390: boolean honorVolatile, String lockExpression,
0391: ClassInfo classInfo) {
0392: if (hasSpec(classInfo)) {
0393: return;
0394: }
0395:
0396: // The addition of the lock expression and the include need to be atomic -- see LKC-2616
0397: synchronized (this .instrumentationDescriptors) {
0398: // TODO see LKC-1893. Need to check for primitive types, logically managed classes, etc.
0399: if (!hasIncludeExcludePattern(classInfo)) {
0400: // only add include if not specified in tc-config
0401: addIncludePattern(expression, honorTransient,
0402: oldStyleCallConstructorOnLoad, honorVolatile);
0403: addWriteAutolock(lockExpression);
0404: }
0405: }
0406: }
0407:
0408: // This is used only for tests right now
0409: public void addExcludePattern(String expression) {
0410: addInstrumentationDescriptor(new ExcludedInstrumentedClass(
0411: expression));
0412: }
0413:
0414: public void addInstrumentationDescriptor(InstrumentedClass classDesc) {
0415: synchronized (this .instrumentationDescriptors) {
0416: this .instrumentationDescriptors
0417: .addFirst(newInstrumentationDescriptor(classDesc));
0418: }
0419: }
0420:
0421: public boolean hasIncludeExcludePatterns() {
0422: synchronized (this .instrumentationDescriptors) {
0423: return !this .instrumentationDescriptors.isEmpty();
0424: }
0425: }
0426:
0427: public boolean hasIncludeExcludePattern(ClassInfo classInfo) {
0428: return getInstrumentationDescriptorFor(classInfo) != DEAFULT_INSTRUMENTATION_DESCRIPTOR;
0429: }
0430:
0431: public DSORuntimeLoggingOptions runtimeLoggingOptions() {
0432: return this .configSetupManager.dsoL1Config()
0433: .runtimeLoggingOptions();
0434: }
0435:
0436: public DSORuntimeOutputOptions runtimeOutputOptions() {
0437: return this .configSetupManager.dsoL1Config()
0438: .runtimeOutputOptions();
0439: }
0440:
0441: public DSOInstrumentationLoggingOptions instrumentationLoggingOptions() {
0442: return this .configSetupManager.dsoL1Config()
0443: .instrumentationLoggingOptions();
0444: }
0445:
0446: /**
0447: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- private void
0448: * addSwingAndAWTConfig() { TransparencyClassSpec spec = null; LockDefinition ld = null; // Color
0449: * addIncludePattern("java.awt.Color", true); spec = getOrCreateSpec("java.awt.Color"); spec.addTransient("cs"); //
0450: * TreePath addIncludePattern("javax.swing.tree.TreePath", false); getOrCreateSpec("javax.swing.tree.TreePath"); //
0451: * DefaultMutableTreeNode addIncludePattern("javax.swing.tree.DefaultMutableTreeNode", false);
0452: * getOrCreateSpec("javax.swing.tree.DefaultMutableTreeNode"); // DefaultTreeModel spec =
0453: * getOrCreateSpec("javax.swing.tree.DefaultTreeModel"); ld = createLockDefinition("tcdefaultTreeLock",
0454: * ConfigLockLevel.WRITE); ld.commit(); addLock("* javax.swing.tree.DefaultTreeModel.get*(..)", ld); addLock("*
0455: * javax.swing.tree.DefaultTreeModel.set*(..)", ld); addLock("* javax.swing.tree.DefaultTreeModel.insert*(..)", ld);
0456: * spec.addTransient("listenerList"); spec.addDistributedMethodCall("fireTreeNodesChanged",
0457: * "(Ljava/lang/Object;[Ljava/lang/Object;[I[Ljava/lang/Object;)V", false);
0458: * spec.addDistributedMethodCall("fireTreeNodesInserted",
0459: * "(Ljava/lang/Object;[Ljava/lang/Object;[I[Ljava/lang/Object;)V", false);
0460: * spec.addDistributedMethodCall("fireTreeNodesRemoved",
0461: * "(Ljava/lang/Object;[Ljava/lang/Object;[I[Ljava/lang/Object;)V", false);
0462: * spec.addDistributedMethodCall("fireTreeStructureChanged",
0463: * "(Ljava/lang/Object;[Ljava/lang/Object;[I[Ljava/lang/Object;)V", false); spec
0464: * .addDistributedMethodCall("fireTreeStructureChanged", "(Ljava/lang/Object;Ljavax/swing/tree/TreePath;)V", false); //
0465: * AbstractListModel spec = getOrCreateSpec("javax.swing.AbstractListModel"); spec.addTransient("listenerList");
0466: * spec.addDistributedMethodCall("fireContentsChanged", "(Ljava/lang/Object;II)V", false);
0467: * spec.addDistributedMethodCall("fireIntervalAdded", "(Ljava/lang/Object;II)V", false);
0468: * spec.addDistributedMethodCall("fireIntervalRemoved", "(Ljava/lang/Object;II)V", false); // MouseMotionAdapter,
0469: * MouseAdapter getOrCreateSpec("java.awt.event.MouseMotionAdapter"); getOrCreateSpec("java.awt.event.MouseAdapter"); //
0470: * Point getOrCreateSpec("java.awt.Point"); getOrCreateSpec("java.awt.geom.Point2D");
0471: * getOrCreateSpec("java.awt.geom.Point2D$Double"); getOrCreateSpec("java.awt.geom.Point2D$Float"); // Line
0472: * getOrCreateSpec("java.awt.geom.Line2D"); getOrCreateSpec("java.awt.geom.Line2D$Double");
0473: * getOrCreateSpec("java.awt.geom.Line2D$Float"); // Rectangle getOrCreateSpec("java.awt.Rectangle");
0474: * getOrCreateSpec("java.awt.geom.Rectangle2D"); getOrCreateSpec("java.awt.geom.RectangularShape");
0475: * getOrCreateSpec("java.awt.geom.Rectangle2D$Double"); getOrCreateSpec("java.awt.geom.Rectangle2D$Float");
0476: * getOrCreateSpec("java.awt.geom.RoundRectangle2D"); getOrCreateSpec("java.awt.geom.RoundRectangle2D$Double");
0477: * getOrCreateSpec("java.awt.geom.RoundRectangle2D$Float"); // Ellipse2D getOrCreateSpec("java.awt.geom.Ellipse2D");
0478: * getOrCreateSpec("java.awt.geom.Ellipse2D$Double"); getOrCreateSpec("java.awt.geom.Ellipse2D$Float"); //
0479: * java.awt.geom.Path2D if (Vm.isJDK16Compliant()) { getOrCreateSpec("java.awt.geom.Path2D");
0480: * getOrCreateSpec("java.awt.geom.Path2D$Double"); getOrCreateSpec("java.awt.geom.Path2D$Float"); } // GeneralPath
0481: * getOrCreateSpec("java.awt.geom.GeneralPath"); // // BasicStroke getOrCreateSpec("java.awt.BasicStroke"); //
0482: * Dimension getOrCreateSpec("java.awt.Dimension"); getOrCreateSpec("java.awt.geom.Dimension2D"); //
0483: * ================================================================== // TableModelEvent
0484: * addIncludePattern("javax.swing.event.TableModelEvent", true); getOrCreateSpec("javax.swing.event.TableModelEvent"); //
0485: * AbstractTableModel addIncludePattern("javax.swing.table.AbstractTableModel", true); spec =
0486: * getOrCreateSpec("javax.swing.table.AbstractTableModel"); spec.addDistributedMethodCall("fireTableChanged",
0487: * "(Ljavax/swing/event/TableModelEvent;)V", false); spec.addTransient("listenerList"); // DefaultTableModel spec =
0488: * getOrCreateSpec("javax.swing.table.DefaultTableModel"); spec.setCallConstructorOnLoad(true); ld =
0489: * createLockDefinition("tcdefaultTableLock", ConfigLockLevel.WRITE); ld.commit(); addLock("*
0490: * javax.swing.table.DefaultTableModel.set*(..)", ld); addLock("* javax.swing.table.DefaultTableModel.insert*(..)",
0491: * ld); addLock("* javax.swing.table.DefaultTableModel.move*(..)", ld); addLock("*
0492: * javax.swing.table.DefaultTableModel.remove*(..)", ld); ld = createLockDefinition("tcdefaultTableLock",
0493: * ConfigLockLevel.READ); ld.commit(); addLock("* javax.swing.table.DefaultTableModel.get*(..)", ld); //
0494: * DefaultListModel spec = getOrCreateSpec("javax.swing.DefaultListModel"); spec.setCallConstructorOnLoad(true); ld =
0495: * createLockDefinition("tcdefaultListLock", ConfigLockLevel.WRITE); ld.commit(); addLock("*
0496: * javax.swing.DefaultListModel.*(..)", ld); // ==================================================== }
0497: */
0498:
0499: private void doPreInstrumentedAutoconfig(boolean interrogateBootJar) {
0500: /**
0501: * // ---------------------------- // implicit config-bundle - JAG // ----------------------------
0502: * addSwingAndAWTConfig();
0503: */
0504:
0505: TransparencyClassSpec spec = null;
0506:
0507: /**
0508: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- spec =
0509: * getOrCreateSpec("java.util.Arrays"); spec.addDoNotInstrument("copyOfRange"); spec.addDoNotInstrument("copyOf");
0510: * spec = getOrCreateSpec("java.util.Arrays$ArrayList");
0511: */
0512:
0513: spec = getOrCreateSpec("java.util.TreeMap",
0514: "com.tc.object.applicator.TreeMapApplicator");
0515: spec.setUseNonDefaultConstructor(true);
0516: spec.addMethodAdapter(SerializationUtil.PUT_SIGNATURE,
0517: new TreeMapAdapter.PutAdapter());
0518: spec.addMethodAdapter(
0519: "deleteEntry(Ljava/util/TreeMap$Entry;)V",
0520: new TreeMapAdapter.DeleteEntryAdapter());
0521: spec.addAlwaysLogSpec(SerializationUtil.CLEAR_SIGNATURE);
0522: spec
0523: .addEntrySetWrapperSpec(SerializationUtil.ENTRY_SET_SIGNATURE);
0524:
0525: spec = getOrCreateSpec("java.util.HashMap",
0526: "com.tc.object.applicator.PartialHashMapApplicator");
0527:
0528: spec = getOrCreateSpec("java.util.LinkedHashMap",
0529: "com.tc.object.applicator.LinkedHashMapApplicator");
0530: spec.setUseNonDefaultConstructor(true);
0531:
0532: spec = getOrCreateSpec("java.util.Hashtable",
0533: "com.tc.object.applicator.PartialHashMapApplicator");
0534:
0535: /**
0536: * spec.addSupportMethodCreator(new HashtableMethodCreator());
0537: * spec.addHashtablePutLogSpec(SerializationUtil.PUT_SIGNATURE);
0538: * spec.addHashtableRemoveLogSpec(SerializationUtil.REMOVE_KEY_SIGNATURE);
0539: * spec.addHashtableClearLogSpec(SerializationUtil.CLEAR_SIGNATURE);
0540: * spec.addMethodAdapter("entrySet()Ljava/util/Set;", new HashtableAdapter.EntrySetAdapter());
0541: * spec.addMethodAdapter("keySet()Ljava/util/Set;", new HashtableAdapter.KeySetAdapter());
0542: * spec.addMethodAdapter("values()Ljava/util/Collection;", new HashtableAdapter.ValuesAdapter());
0543: */
0544:
0545: /**
0546: * addWriteAutolock("synchronized * java.util.Hashtable.*(..)"); addReadAutolock(new String[] { "synchronized *
0547: * java.util.Hashtable.get(..)", "synchronized * java.util.Hashtable.hashCode(..)", "synchronized *
0548: * java.util.Hashtable.contains*(..)", "synchronized * java.util.Hashtable.elements(..)", "synchronized *
0549: * java.util.Hashtable.equals(..)", "synchronized * java.util.Hashtable.isEmpty(..)", "synchronized *
0550: * java.util.Hashtable.keys(..)", "synchronized * java.util.Hashtable.size(..)", "synchronized *
0551: * java.util.Hashtable.toString(..)" });
0552: */
0553: spec = getOrCreateSpec("java.util.Properties",
0554: "com.tc.object.applicator.PartialHashMapApplicator");
0555: addWriteAutolock("synchronized * java.util.Properties.*(..)");
0556:
0557: spec = getOrCreateSpec("com.tcclient.util.MapEntrySetWrapper$EntryWrapper");
0558:
0559: spec = getOrCreateSpec("java.util.IdentityHashMap",
0560: "com.tc.object.applicator.HashMapApplicator");
0561: spec.addAlwaysLogSpec(SerializationUtil.PUT_SIGNATURE);
0562: spec.addAlwaysLogSpec(SerializationUtil.REMOVE_KEY_SIGNATURE);
0563: spec.addAlwaysLogSpec(SerializationUtil.CLEAR_SIGNATURE);
0564:
0565: spec = getOrCreateSpec("java.util.BitSet");
0566: spec.setHonorTransient(false);
0567:
0568: if (Vm.isJDK15Compliant()) {
0569: spec = getOrCreateSpec("java.util.EnumMap");
0570: spec.setHonorTransient(false);
0571: spec = getOrCreateSpec("java.util.EnumSet");
0572: spec = getOrCreateSpec("java.util.RegularEnumSet");
0573: spec = getOrCreateSpec("java.util.RegularEnumSet$EnumSetIterator");
0574: }
0575:
0576: spec = getOrCreateSpec("java.util.Collections");
0577: spec = getOrCreateSpec("java.util.Collections$EmptyList",
0578: "com.tc.object.applicator.ListApplicator");
0579: spec = getOrCreateSpec("java.util.Collections$EmptyMap",
0580: "com.tc.object.applicator.HashMapApplicator");
0581: spec = getOrCreateSpec("java.util.Collections$EmptySet",
0582: "com.tc.object.applicator.HashSetApplicator");
0583:
0584: spec = getOrCreateSpec("java.util.Collections$UnmodifiableCollection");
0585: spec.setHonorTransient(true);
0586: spec = getOrCreateSpec("java.util.Collections$1");
0587: spec.setHonorJDKSubVersionSpecific(true);
0588: spec = getOrCreateSpec("java.util.Collections$2");
0589: spec.setHonorJDKSubVersionSpecific(true);
0590: spec = getOrCreateSpec("java.util.Collections$UnmodifiableList$1");
0591: spec.setHonorJDKSubVersionSpecific(true);
0592: spec = getOrCreateSpec("java.util.Collections$UnmodifiableList");
0593: spec.setHonorTransient(true);
0594: spec = getOrCreateSpec("java.util.Collections$UnmodifiableMap");
0595: spec.setHonorTransient(true);
0596: spec = getOrCreateSpec("java.util.Collections$UnmodifiableRandomAccessList");
0597: spec.setHonorTransient(true);
0598: spec = getOrCreateSpec("java.util.Collections$UnmodifiableSet");
0599: spec.setHonorTransient(true);
0600: spec = getOrCreateSpec("java.util.Collections$UnmodifiableSortedMap");
0601: spec.setHonorTransient(true);
0602: spec = getOrCreateSpec("java.util.Collections$UnmodifiableSortedSet");
0603: spec.setHonorTransient(true);
0604:
0605: spec = getOrCreateSpec("java.util.Collections$SingletonSet");
0606: spec.setHonorTransient(true);
0607: spec = getOrCreateSpec("java.util.Collections$SingletonList");
0608: spec.setHonorTransient(true);
0609: spec = getOrCreateSpec("java.util.Collections$SingletonMap");
0610: spec.setHonorTransient(true);
0611:
0612: spec = getOrCreateSpec("java.util.Collections$SynchronizedSet");
0613: // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
0614: spec.setHonorTransient(true);
0615: spec = getOrCreateSpec("java.util.Collections$SynchronizedCollection");
0616: // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
0617: spec.setHonorTransient(true);
0618: spec = getOrCreateSpec("java.util.Collections$SynchronizedList");
0619: // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
0620: spec.setHonorTransient(true);
0621: spec = getOrCreateSpec("java.util.Collections$SynchronizedSortedMap");
0622: // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
0623: spec.setHonorTransient(true);
0624: spec = getOrCreateSpec("java.util.Collections$SynchronizedSortedSet");
0625: // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
0626: spec.setHonorTransient(true);
0627: spec = getOrCreateSpec("java.util.Collections$SynchronizedMap");
0628: // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
0629: spec.setHonorTransient(true);
0630: spec = getOrCreateSpec("java.util.Collections$SynchronizedRandomAccessList");
0631: // autoLockAllMethods(spec, ConfigLockLevel.WRITE);
0632: spec.setHonorTransient(true);
0633:
0634: addJavaUtilCollectionPreInstrumentedSpec();
0635:
0636: spec = getOrCreateSpec("com.tcclient.util.SortedViewSetWrapper");
0637: spec.setHonorTransient(true);
0638:
0639: // These classes are not PORTABLE by themselves, but logical classes subclasses them.
0640: // We dont want them to get tc fields, TransparentAccess interfaces etc. but we do want them
0641: // to be instrumented for Array manipulations, clone(), wait(), notify() calls etc.
0642: spec = getOrCreateSpec("java.util.AbstractCollection");
0643: spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
0644: spec
0645: .addArrayCopyMethodCodeSpec(SerializationUtil.TO_ARRAY_SIGNATURE);
0646: spec = getOrCreateSpec("java.util.AbstractList");
0647: spec.setHonorTransient(true);
0648: spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
0649: spec.addSupportMethodCreator(new AbstractListMethodCreator());
0650: spec = getOrCreateSpec("java.util.AbstractSet");
0651: spec = getOrCreateSpec("java.util.AbstractSequentialList");
0652: spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
0653: spec = getOrCreateSpec("java.util.Dictionary");
0654: spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
0655:
0656: // AbstractMap is special because it actually has some fields so it needs to be instrumented and not just ADAPTABLE
0657: spec = getOrCreateSpec("java.util.AbstractMap");
0658: spec.setHonorTransient(true);
0659:
0660: // spec = getOrCreateSpec("java.lang.Number");
0661: // This hack is needed to make Number work in all platforms. Without this hack, if you add Number in bootjar, the
0662: // JVM crashes.
0663: // spec.generateNonStaticTCFields(false);
0664:
0665: /**
0666: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- spec =
0667: * getOrCreateSpec("java.lang.Exception"); spec = getOrCreateSpec("java.lang.RuntimeException"); spec =
0668: * getOrCreateSpec("java.lang.InterruptedException"); spec = getOrCreateSpec("java.awt.AWTException"); spec =
0669: * getOrCreateSpec("java.io.IOException"); spec = getOrCreateSpec("java.io.FileNotFoundException"); spec =
0670: * getOrCreateSpec("java.lang.Error"); spec = getOrCreateSpec("java.util.ConcurrentModificationException"); spec =
0671: * getOrCreateSpec("java.util.NoSuchElementException");
0672: */
0673: // =================================================================
0674: /**
0675: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- spec =
0676: * getOrCreateSpec("java.util.EventObject");
0677: */
0678:
0679: spec = getOrCreateSpec("com.tcclient.object.DistributedMethodCall");
0680:
0681: /**
0682: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- spec =
0683: * getOrCreateSpec("java.io.File"); spec.setHonorTransient(true);
0684: */
0685: spec = getOrCreateSpec("java.util.Date",
0686: "com.tc.object.applicator.DateApplicator");
0687: spec.addAlwaysLogSpec(SerializationUtil.SET_TIME_SIGNATURE);
0688: spec.addDateMethodLogSpec(SerializationUtil.SET_YEAR_SIGNATURE);
0689: spec
0690: .addDateMethodLogSpec(SerializationUtil.SET_MONTH_SIGNATURE);
0691: spec.addDateMethodLogSpec(SerializationUtil.SET_DATE_SIGNATURE);
0692: spec
0693: .addDateMethodLogSpec(SerializationUtil.SET_HOURS_SIGNATURE);
0694: spec
0695: .addDateMethodLogSpec(SerializationUtil.SET_MINUTES_SIGNATURE);
0696: spec
0697: .addDateMethodLogSpec(SerializationUtil.SET_SECONDS_SIGNATURE);
0698:
0699: spec = getOrCreateSpec("java.sql.Date",
0700: "com.tc.object.applicator.DateApplicator");
0701: spec = getOrCreateSpec("java.sql.Time",
0702: "com.tc.object.applicator.DateApplicator");
0703: spec = getOrCreateSpec("java.sql.Timestamp",
0704: "com.tc.object.applicator.DateApplicator");
0705: spec.addDateMethodLogSpec(SerializationUtil.SET_TIME_SIGNATURE,
0706: MethodSpec.TIMESTAMP_SET_TIME_METHOD_WRAPPER_LOG);
0707: spec.addAlwaysLogSpec(SerializationUtil.SET_NANOS_SIGNATURE);
0708:
0709: spec = getOrCreateSpec("java.net.URL",
0710: "com.tc.object.applicator.URLApplicator");
0711: spec.setHonorTransient(true);
0712: spec.addAlwaysLogSpec(SerializationUtil.URL_SET_SIGNATURE);
0713:
0714: /**
0715: * // ---------------------------- // implicit config-bundle - JAG // ----------------------------
0716: * addPermanentExcludePattern("java.util.WeakHashMap+"); addPermanentExcludePattern("java.lang.ref.*");
0717: */
0718:
0719: /**
0720: * // ---------------------------- // implicit config-bundle - JAG // ----------------------------
0721: */
0722: // addJDK15PreInstrumentedSpec();
0723: // This section of spec are specified in the BootJarTool also
0724: // They are placed again so that the honorTransient
0725: // flag will be honored during runtime.
0726: // SECTION BEGINS
0727: if (Vm.getMegaVersion() >= 1 && Vm.getMajorVersion() > 4) {
0728: addJavaUtilConcurrentHashMapSpec(); // should be in jdk15-preinst-config bundle
0729: addLogicalAdaptedLinkedBlockingQueueSpec(); // should be in jdk15-preinst-config bundle
0730: }
0731: // SECTION ENDS
0732:
0733: markAllSpecsPreInstrumented();
0734: }
0735:
0736: private void doAutoconfig(boolean interrogateBootJar) {
0737: TransparencyClassSpec spec;
0738:
0739: addJDK15InstrumentedSpec();
0740:
0741: // Generic Session classes
0742: spec = getOrCreateSpec("com.terracotta.session.SessionData");
0743: spec.setHonorTransient(true);
0744: spec = getOrCreateSpec("com.terracotta.session.util.Timestamp");
0745: spec.setHonorTransient(true);
0746:
0747: spec = getOrCreateSpec("java.lang.Object");
0748: spec.setCallConstructorOnLoad(true);
0749:
0750: // Autolocking FastHashMap.
0751: // addIncludePattern("org.apache.commons.collections.FastHashMap*", true);
0752: // addWriteAutolock("* org.apache.commons.collections.FastHashMap*.*(..)");
0753: // addReadAutolock(new String[] { "* org.apache.commons.collections.FastHashMap.clone(..)",
0754: // "* org.apache.commons.collections.FastHashMap*.contains*(..)",
0755: // "* org.apache.commons.collections.FastHashMap.equals(..)",
0756: // "* org.apache.commons.collections.FastHashMap.get(..)",
0757: // "* org.apache.commons.collections.FastHashMap*.hashCode(..)",
0758: // "* org.apache.commons.collections.FastHashMap*.isEmpty(..)",
0759: // "* org.apache.commons.collections.FastHashMap*.size(..)" });
0760:
0761: spec = getOrCreateSpec("gnu.trove.THashMap",
0762: "com.tc.object.applicator.HashMapApplicator");
0763: spec.addTHashMapPutLogSpec(SerializationUtil.PUT_SIGNATURE);
0764: spec
0765: .addTHashRemoveAtLogSpec(SerializationUtil.TROVE_REMOVE_AT_SIGNATURE);
0766: spec.addAlwaysLogSpec(SerializationUtil.CLEAR_SIGNATURE);
0767: spec
0768: .addEntrySetWrapperSpec(SerializationUtil.ENTRY_SET_SIGNATURE);
0769: spec.addKeySetWrapperSpec(SerializationUtil.KEY_SET_SIGNATURE);
0770: spec.addValuesWrapperSpec(SerializationUtil.VALUES_SIGNATURE);
0771: spec.addMethodAdapter(
0772: SerializationUtil.TRANSFORM_VALUES_SIGNATURE,
0773: new THashMapAdapter.TransformValuesAdapter());
0774:
0775: spec = getOrCreateSpec("gnu.trove.THashSet",
0776: "com.tc.object.applicator.HashSetApplicator");
0777: spec.addTHashSetAddLogSpec(SerializationUtil.ADD_SIGNATURE);
0778: spec
0779: .addTHashSetRemoveAtLogSpec(SerializationUtil.REMOVE_SIGNATURE);
0780: spec.addAlwaysLogSpec(SerializationUtil.CLEAR_SIGNATURE);
0781: spec
0782: .addArrayCopyMethodCodeSpec(SerializationUtil.TO_ARRAY_SIGNATURE);
0783:
0784: spec = getOrCreateSpec("gnu.trove.ToObjectArrayProcedure");
0785: spec
0786: .addArrayCopyMethodCodeSpec(SerializationUtil.TO_ARRAY_SIGNATURE);
0787:
0788: spec = getOrCreateSpec("javax.servlet.GenericServlet");
0789: spec.setHonorTransient(true);
0790: spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
0791:
0792: // BEGIN: weblogic stuff
0793: addAspectModule("weblogic.servlet.internal",
0794: "com.tc.weblogic.SessionAspectModule");
0795: addWeblogicCustomAdapters();
0796: // END: weblogic stuff
0797:
0798: // BEGIN: tomcat stuff
0799: // don't install tomcat-specific adaptors if this sys prop is defined
0800: final boolean doTomcat = System
0801: .getProperty("com.tc.tomcat.disabled") == null;
0802: if (doTomcat)
0803: addTomcatCustomAdapters();
0804: // END: tomcat stuff
0805:
0806: // Geronimo + WebsphereCE stuff
0807: addCustomAdapter(
0808: "org.apache.geronimo.kernel.basic.ProxyMethodInterceptor",
0809: new ProxyMethodInterceptorAdapter());
0810: addCustomAdapter(
0811: "org.apache.geronimo.kernel.config.MultiParentClassLoader",
0812: new MultiParentClassLoaderAdapter());
0813: addCustomAdapter("org.apache.geronimo.tomcat.HostGBean",
0814: new HostGBeanAdapter());
0815: addCustomAdapter(
0816: "org.apache.geronimo.tomcat.TomcatClassLoader",
0817: new TomcatClassLoaderAdapter());
0818:
0819: // JBoss adapters
0820: addCustomAdapter("org.jboss.mx.loading.UnifiedClassLoader",
0821: new UCLAdapter());
0822: addCustomAdapter("org.jboss.Main", new MainAdapter());
0823:
0824: // Glassfish adapters
0825: addCustomAdapter(
0826: "com.sun.jdo.api.persistence.model.RuntimeModel",
0827: new RuntimeModelAdapter());
0828:
0829: // TODO for the Event Swing sample only
0830: LockDefinition ld = new LockDefinitionImpl("setTextArea",
0831: ConfigLockLevel.WRITE);
0832: ld.commit();
0833: addLock("* test.event.*.setTextArea(..)", ld);
0834:
0835: /**
0836: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- //
0837: * doAutoconfigForSpring(); // doAutoconfigForSpringWebFlow();
0838: */
0839:
0840: if (interrogateBootJar) {
0841: // pre-load specs from boot jar
0842: BootJar bootJar = null;
0843: try {
0844: bootJar = BootJar.getDefaultBootJarForReading();
0845:
0846: Set allPreInstrumentedClasses = bootJar
0847: .getAllPreInstrumentedClasses();
0848: for (Iterator i = allPreInstrumentedClasses.iterator(); i
0849: .hasNext();) {
0850: // Create specs for any instrumented classes in the boot jar (such thay they can be shared)
0851: getOrCreateSpec((String) i.next());
0852: }
0853: } catch (Throwable e) {
0854: logger.error(e);
0855:
0856: // don't needlessly wrap errors and runtimes
0857: if (e instanceof RuntimeException) {
0858: throw (RuntimeException) e;
0859: }
0860: if (e instanceof Error) {
0861: throw (Error) e;
0862: }
0863:
0864: throw new RuntimeException(e);
0865: } finally {
0866: try {
0867: if (bootJar != null) {
0868: bootJar.close();
0869: }
0870: } catch (Exception e) {
0871: logger.error(e);
0872: }
0873: }
0874: }
0875: }
0876:
0877: /**
0878: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- private void
0879: * doAutoconfigForSpring() { addIncludePattern("org.springframework.context.ApplicationEvent", false, false, false);
0880: * addIncludePattern("com.tcspring.ApplicationContextEventProtocol", true, true, true);
0881: * addIncludePattern("com.tcspring.ComplexBeanId", true, true, true); //
0882: * addIncludePattern("com.tcspring.BeanContainer", true, true, true);
0883: * getOrCreateSpec("com.tcspring.BeanContainer").addTransient("isInitialized"); // .setHonorTransient(true); // scoped
0884: * beans //
0885: * addTransient("org.springframework.web.context.request.ServletRequestAttributes$DestructionCallbackBindingListener", //
0886: * "aw$MIXIN_0"); addIncludePattern("com.tcspring.SessionProtocol$DestructionCallbackBindingListener", true, true,
0887: * true); addIncludePattern("com.tcspring.ScopedBeanDestructionCallBack", true, true, true); // Spring AOP
0888: * introduction/mixin classes addIncludePattern("org.springframework.aop.support.IntroductionInfoSupport", true, true,
0889: * true); addIncludePattern("org.springframework.aop.support.DelegatingIntroductionInterceptor", true, true, true);
0890: * addIncludePattern("org.springframework.aop.support.DefaultIntroductionAdvisor", true, true, true);
0891: * addIncludePattern("gnu.trove..*", false, false, true); addIncludePattern("java.lang.reflect.Proxy", false, false,
0892: * false); addIncludePattern("com.tc.aspectwerkz.proxy..*", false, false, true); // TODO remove if we find a better
0893: * way using ProxyApplicator etc. addIncludePattern("$Proxy..*", false, false, true); // backport concurrent classes
0894: * addIncludePattern("edu.emory.mathcs.backport.java.util.AbstractCollection", false, false, false);
0895: * addIncludePattern("edu.emory.mathcs.backport.java.util.AbstractQueue", false, false, false);
0896: * addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue", false, false, false);
0897: * addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue$Node", false, false, false);
0898: * addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.FutureTask", false, false, false);
0899: * addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.ConcurrentLinkedQueue", false, false, false);
0900: * addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.PriorityBlockingQueue", false, false, false);
0901: * addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.ArrayBlockingQueue", false, false, false);
0902: * addIncludePattern("edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList", false, false, false);
0903: * LockDefinition ld = new LockDefinitionImpl("addApplicationListener", ConfigLockLevel.WRITE); ld.commit();
0904: * addLock("* org.springframework.context.event.AbstractApplicationEventMulticaster.addApplicationListener(..)", ld); //
0905: * used by WebFlow addIncludePattern("org.springframework.core.enums.*", false, false, false);
0906: * addIncludePattern("org.springframework.binding..*", true, false, false);
0907: * addIncludePattern("org.springframework.validation..*", true, false, false); }
0908: */
0909:
0910: /**
0911: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- private void
0912: * doAutoconfigForSpringWebFlow() { addAspectModule("org.springframework.webflow",
0913: * "com.tc.object.config.SpringWebFlowAspectModule"); addIncludePattern("com.tcspring.DSOConversationLock", false,
0914: * false, false); addIncludePattern("org.springframework.webflow..*", true, false, false);
0915: * addIncludePattern("org.springframework.webflow.conversation.impl.ConversationEntry", false, false, false);
0916: * addIncludePattern("org.springframework.webflow.core.collection.LocalAttributeMap", false, false, false);
0917: * addIncludePattern("org.springframework.webflow.conversation.impl.*", false, false, false); //
0918: * getOrCreateSpec("org.springframework.webflow.engine.impl.FlowSessionImpl").setHonorTransient(false).addTransient("flow"); //
0919: * flow : Flow // flowId : String // state : State // stateId : String // .addTransient("parent") // : FlowSessionImpl //
0920: * .addTransient("scope") // : LocalAttributeMap // .addTransient("status"); // : FlowSessionStatus // all "transient"
0921: * for all subclasses except "State.id" // getOrCreateSpec("org.springframework.webflow.engine.State") // //
0922: * .addTransient("logger").addTransient("flow") // // .addTransient("entryActionList") // //
0923: * .addTransient("exceptionHandlerSet"); // // getOrCreateSpec("org.springframework.webflow.engine.EndState") // //
0924: * .addTransient("viewSelector") // // .addTransient("outputMapper"); // //
0925: * getOrCreateSpec("org.springframework.webflow.engine.TransitionableState") // abstract //
0926: * .addTransient("transitions") // .addTransient("exitActionList"); //
0927: * getOrCreateSpec("org.springframework.webflow.engine.ActionState") // // .addTransient("actionList"); //
0928: * getOrCreateSpec("org.springframework.webflow.engine.SubflowState") // // .addTransient("subflow") // //
0929: * .addTransient("attributeMapper"); // // getOrCreateSpec("org.springframework.webflow.engine.ViewState") // //
0930: * .addTransient("viewSelector") // // .addTransient("renderActionList"); // //
0931: * getOrCreateSpec("org.springframework.webflow.engine.DecisionState"); no fields // TODO investigate if better
0932: * granularity of above classes is required //
0933: * org.springframework.webflow.execution.repository.support.DefaultFlowExecutionRepository //
0934: * org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository //
0935: * org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository //
0936: * org.springframework.webflow.execution.repository.support.DefaultFlowExecutionRepositoryFactory //
0937: * org.springframework.webflow.execution.repository.support.DelegatingFlowExecutionRepositoryFactory //
0938: * org.springframework.webflow.execution.repository.support.FlowExecutionRepositoryServices //
0939: * org.springframework.webflow.execution.repository.support.SharedMapFlowExecutionRepositoryFactory //
0940: * org.springframework.webflow.execution.repository.conversation.impl.LocalConversationService //
0941: * org.springframework.webflow.util.RandomGuidUidGenerator // org.springframework.webflow.registry.FlowRegistryImpl //
0942: * etc... }
0943: */
0944:
0945: private void addJDK15InstrumentedSpec() {
0946: if (Vm.getMegaVersion() >= 1 && Vm.getMajorVersion() > 4) {
0947: TransparencyClassSpec spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantReadWriteLock");
0948: spec.setPreCreateMethod("validateInUnLockState");
0949: spec.setCallConstructorOnLoad(true);
0950: spec.setHonorTransient(true);
0951:
0952: spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantReadWriteLock$DsoLock");
0953: spec.setHonorTransient(true);
0954: spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantReadWriteLock$ReadLockTC");
0955: spec.setCallMethodOnLoad("init");
0956: spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantReadWriteLock$WriteLockTC");
0957: spec.setCallMethodOnLoad("init");
0958:
0959: spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock");
0960: spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock");
0961:
0962: spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantReadWriteLock$Sync");
0963: spec.setHonorTransient(true);
0964: spec.setCallConstructorOnLoad(true);
0965: spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantReadWriteLock$FairSync");
0966: spec.setCallConstructorOnLoad(true);
0967: spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync");
0968: spec.setCallConstructorOnLoad(true);
0969:
0970: spec = getOrCreateSpec("com.tcclient.util.concurrent.locks.ConditionObject");
0971: spec.disableWaitNotifyCodeSpec("signal()V");
0972: spec.disableWaitNotifyCodeSpec("signalAll()V");
0973: spec.setHonorTransient(true);
0974: spec.setCallConstructorOnLoad(true);
0975:
0976: spec = getOrCreateSpec("com.tcclient.util.concurrent.locks.ConditionObject$SyncCondition");
0977: spec.setCallConstructorOnLoad(true);
0978:
0979: spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantLock");
0980: spec.addTransient("sync");
0981: spec.setPreCreateMethod("validateInUnLockState");
0982: spec.setCallConstructorOnLoad(true);
0983: spec.setHonorTransient(true);
0984:
0985: addAbstractSynchronizerSpec();
0986: }
0987: }
0988:
0989: private void addAbstractSynchronizerSpec() {
0990: TransparencyClassSpec spec = getOrCreateSpec("java.util.concurrent.locks.AbstractQueuedSynchronizer");
0991: spec.setHonorTransient(true);
0992: spec.addTransient("state");
0993: spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
0994:
0995: spec = getOrCreateSpec("java.util.concurrent.locks.AbstractQueuedSynchronizer$Node");
0996: spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
0997: spec.markPreInstrumented();
0998:
0999: if (Vm.isJDK16Compliant()) {
1000: spec = getOrCreateSpec("java.util.concurrent.locks.AbstractOwnableSynchronizer");
1001: spec
1002: .setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
1003: }
1004: }
1005:
1006: private void addJavaUtilCollectionPreInstrumentedSpec() {
1007: // The details of the instrumentation spec is specified in BootJarTool.
1008: getOrCreateSpec("java.util.HashSet",
1009: "com.tc.object.applicator.HashSetApplicator");
1010:
1011: getOrCreateSpec("java.util.LinkedHashSet",
1012: "com.tc.object.applicator.HashSetApplicator");
1013:
1014: getOrCreateSpec("java.util.TreeSet",
1015: "com.tc.object.applicator.TreeSetApplicator");
1016:
1017: getOrCreateSpec("java.util.LinkedList",
1018: "com.tc.object.applicator.ListApplicator");
1019:
1020: getOrCreateSpec("java.util.Stack",
1021: "com.tc.object.applicator.ListApplicator");
1022:
1023: getOrCreateSpec("java.util.Vector",
1024: "com.tc.object.applicator.ListApplicator");
1025: // addWriteAutolock("synchronized * java.util.Vector.*(..)");
1026: // addReadAutolock(new String[] { "synchronized * java.util.Vector.capacity(..)",
1027: // "synchronized * java.util.Vector.clone(..)", "synchronized * java.util.Vector.containsAll(..)",
1028: // "synchronized * java.util.Vector.elementAt(..)", "synchronized * java.util.Vector.equals(..)",
1029: // "synchronized * java.util.Vector.firstElement(..)", "synchronized * java.util.Vector.get(..)",
1030: // "synchronized * java.util.Vector.hashCode(..)", "synchronized * java.util.Vector.indexOf(..)",
1031: // "synchronized * java.util.Vector.isEmpty(..)", "synchronized * java.util.Vector.lastElement(..)",
1032: // "synchronized * java.util.Vector.lastIndexOf(..)", "synchronized * java.util.Vector.size(..)",
1033: // "synchronized * java.util.Vector.subList(..)", "synchronized * java.util.Vector.toString(..)", });
1034:
1035: getOrCreateSpec("java.util.ArrayList",
1036: "com.tc.object.applicator.ListApplicator");
1037: }
1038:
1039: /**
1040: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- private void
1041: * addJDK15PreInstrumentedSpec() { if (Vm.getMegaVersion() >= 1 && Vm.getMajorVersion() > 4) { //TransparencyClassSpec
1042: * spec = getOrCreateSpec("sun.misc.Unsafe"); //addCustomAdapter("sun.misc.Unsafe", new UnsafeAdapter()); //spec =
1043: * getOrCreateSpec(DSOUnsafe.CLASS_DOTS); //addCustomAdapter(DSOUnsafe.CLASS_DOTS, new DSOUnsafeAdapter()); //spec =
1044: * getOrCreateSpec("java.util.concurrent.CyclicBarrier"); //spec =
1045: * getOrCreateSpec("java.util.concurrent.CyclicBarrier$Generation"); //spec.setHonorJDKSubVersionSpecific(true);
1046: * //spec = getOrCreateSpec("java.util.concurrent.TimeUnit"); // This section of spec are specified in the BootJarTool
1047: * also. They are placed again so that the honorTransient * // flag will be honored during runtime. *
1048: * addJavaUtilConcurrentHashMapSpec(); addLogicalAdaptedLinkedBlockingQueueSpec();
1049: * addJavaUtilConcurrentFutureTaskSpec(); //spec = getOrCreateSpec("java.util.concurrent.locks.ReentrantLock");
1050: * //spec.setHonorTransient(true); //spec.setCallConstructorOnLoad(true); // This section of spec are specified in the
1051: * BootJarTool also. They are placed again so that the honorTransient * // flag will be honored during runtime. * } }
1052: */
1053:
1054: /**
1055: * // ---------------------------- // implicit config-bundle - JAG // ---------------------------- private void
1056: * addJavaUtilConcurrentFutureTaskSpec() { if (Vm.getMegaVersion() >= 1 && Vm.getMajorVersion() >= 6) {
1057: * getOrCreateSpec("java.util.concurrent.locks.AbstractOwnableSynchronizer"); } TransparencyClassSpec spec =
1058: * getOrCreateSpec("java.util.concurrent.FutureTask$Sync"); addWriteAutolock("*
1059: * java.util.concurrent.FutureTask$Sync.*(..)"); spec.setHonorTransient(true);
1060: * spec.addDistributedMethodCall("managedInnerCancel", "()V", false);
1061: * getOrCreateSpec("java.util.concurrent.FutureTask");
1062: * getOrCreateSpec("java.util.concurrent.Executors$RunnableAdapter"); }
1063: */
1064:
1065: private void addJavaUtilConcurrentHashMapSpec() {
1066: TransparencyClassSpec spec = getOrCreateSpec(
1067: "java.util.concurrent.ConcurrentHashMap",
1068: "com.tc.object.applicator.ConcurrentHashMapApplicator");
1069: spec.setHonorTransient(true);
1070: spec.setPostCreateMethod("__tc_rehash");
1071:
1072: spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap$Segment");
1073: spec.setCallConstructorOnLoad(true);
1074: spec.setHonorTransient(true);
1075:
1076: spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap$HashEntry");
1077: spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap$ValueIterator");
1078: spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap$EntryIterator");
1079: spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap$Values");
1080: spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap$KeySet");
1081: spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap$HashIterator");
1082: if (Vm.isJDK16Compliant()) {
1083: spec = getOrCreateSpec("java.util.concurrent.ConcurrentHashMap$WriteThroughEntry");
1084: spec = getOrCreateSpec("java.util.AbstractMap$SimpleEntry");
1085: }
1086: }
1087:
1088: private void addLogicalAdaptedLinkedBlockingQueueSpec() {
1089: TransparencyClassSpec spec = getOrCreateSpec("java.util.AbstractQueue");
1090: spec.setInstrumentationAction(TransparencyClassSpec.ADAPTABLE);
1091:
1092: spec = getOrCreateSpec(
1093: "java.util.concurrent.LinkedBlockingQueue",
1094: "com.tc.object.applicator.LinkedBlockingQueueApplicator");
1095: }
1096:
1097: private void addTomcatCustomAdapters() {
1098: addCustomAdapter("org.apache.jasper.runtime.JspWriterImpl",
1099: new JspWriterImplAdapter());
1100: addCustomAdapter("org.apache.catalina.loader.WebappLoader",
1101: new WebAppLoaderAdapter());
1102: addCustomAdapter("org.apache.catalina.startup.Catalina",
1103: new CatalinaAdapter());
1104: addCustomAdapter("org.apache.catalina.startup.Bootstrap",
1105: new BootstrapAdapter());
1106: addCustomAdapter("org.apache.catalina.core.ContainerBase",
1107: new ContainerBaseAdapter());
1108: addCustomAdapter(
1109: "org.apache.catalina.connector.SessionRequest55",
1110: new DelegateMethodAdapter(
1111: "org.apache.catalina.connector.Request",
1112: "valveReq"));
1113: addCustomAdapter(
1114: "org.apache.catalina.connector.SessionResponse55",
1115: new DelegateMethodAdapter(
1116: "org.apache.catalina.connector.Response",
1117: "valveRes"));
1118: }
1119:
1120: private void removeTomcatAdapters() {
1121: // XXX: hack for starting Glassfish w/o session support
1122: if (applicationNames.isEmpty()) {
1123: removeCustomAdapter("org.apache.catalina.core.ContainerBase");
1124: }
1125: }
1126:
1127: private void addWeblogicCustomAdapters() {
1128: addCustomAdapter("weblogic.Server", new ServerAdapter());
1129: addCustomAdapter(
1130: "weblogic.utils.classloaders.GenericClassLoader",
1131: new GenericClassLoaderAdapter());
1132: addCustomAdapter("weblogic.ejb20.ejbc.EjbCodeGenerator",
1133: new EJBCodeGeneratorAdapter());
1134: addCustomAdapter(
1135: "weblogic.ejb.container.ejbc.EjbCodeGenerator",
1136: new EJBCodeGeneratorAdapter());
1137: addCustomAdapter(
1138: "weblogic.servlet.internal.WebAppServletContext",
1139: new WebAppServletContextAdapter());
1140: addCustomAdapter("weblogic.servlet.internal.EventsManager",
1141: new EventsManagerAdapter());
1142: addCustomAdapter("weblogic.servlet.internal.FilterManager",
1143: new FilterManagerAdapter());
1144: addCustomAdapter(
1145: "weblogic.servlet.internal.ServletResponseImpl",
1146: new ServletResponseImplAdapter());
1147: addCustomAdapter(
1148: "weblogic.servlet.internal.TerracottaServletResponseImpl",
1149: new DelegateMethodAdapter(
1150: "weblogic.servlet.internal.ServletResponseImpl",
1151: "nativeResponse"));
1152: }
1153:
1154: public boolean removeCustomAdapter(String name) {
1155: synchronized (customAdapters) {
1156: Object prev = this .customAdapters.remove(name);
1157: return prev != null;
1158: }
1159: }
1160:
1161: public void addCustomAdapter(final String name,
1162: final ClassAdapterFactory factory) {
1163: synchronized (customAdapters) {
1164: if (customAdapters.containsKey(name)) {
1165: return;
1166: }
1167: Object prev = this .customAdapters.put(name, factory);
1168: Assert.assertNull(prev);
1169: }
1170: }
1171:
1172: public boolean hasCustomAdapter(ClassInfo classInfo) {
1173: synchronized (customAdapters) {
1174: return customAdapters.containsKey(classInfo.getName());
1175: }
1176: }
1177:
1178: public ClassAdapterFactory getCustomAdapter(ClassInfo classInfo) {
1179: synchronized (customAdapters) {
1180: return (ClassAdapterFactory) customAdapters.get(classInfo
1181: .getName());
1182: }
1183: }
1184:
1185: public void addClassReplacement(final String originalClassName,
1186: final String replacementClassName,
1187: final URL replacementResource) {
1188: synchronized (classReplacements) {
1189: String prev = this .classReplacements.addMapping(
1190: originalClassName, replacementClassName,
1191: replacementResource);
1192: Assert.assertNull(prev);
1193: }
1194: }
1195:
1196: public ClassReplacementMapping getClassReplacementMapping() {
1197: return classReplacements;
1198: }
1199:
1200: public void addClassResource(final String className,
1201: final URL resource) {
1202: URL prev = (URL) this .classResources.put(className, resource);
1203: if ((prev != null) && (!prev.equals(resource))) {
1204: // we want to know if modules more than one module is trying to export the same class
1205: throw new AssertionError(
1206: "Attempting to replace mapping for " + className
1207: + ", from " + prev + " to " + resource);
1208: }
1209: }
1210:
1211: public URL getClassResource(String className) {
1212: return (URL) this .classResources.get(className);
1213: }
1214:
1215: private void markAllSpecsPreInstrumented() {
1216: for (Iterator i = classSpecs.values().iterator(); i.hasNext();) {
1217: TransparencyClassSpec s = (TransparencyClassSpec) i.next();
1218: s.markPreInstrumented();
1219: }
1220: }
1221:
1222: public DSOInstrumentationLoggingOptions getInstrumentationLoggingOptions() {
1223: return this .configSetupManager.dsoL1Config()
1224: .instrumentationLoggingOptions();
1225: }
1226:
1227: public Iterator getAllUserDefinedBootSpecs() {
1228: return this .userDefinedBootSpecs.values().iterator();
1229: }
1230:
1231: public void setFaultCount(int count) {
1232: this .faultCount = count;
1233: }
1234:
1235: public boolean isLockMethod(MemberInfo memberInfo) {
1236: helperLogger.logIsLockMethodBegin(memberInfo.getModifiers(),
1237: memberInfo.getDeclaringType().getName(), //
1238: memberInfo.getName(), memberInfo.getSignature());
1239:
1240: LockDefinition lockDefinitions[] = lockDefinitionsFor(memberInfo);
1241:
1242: for (int j = 0; j < lockDefinitions.length; j++) {
1243: if (lockDefinitions[j].isAutolock()) {
1244: if (isNotStaticAndIsSynchronized(memberInfo
1245: .getModifiers())) {
1246: helperLogger.logIsLockMethodAutolock();
1247: return true;
1248: }
1249: } else {
1250: return true;
1251: }
1252: }
1253:
1254: helperLogger.logIsLockMethodNoMatch(memberInfo
1255: .getDeclaringType().getName(), memberInfo.getName());
1256: return false;
1257: }
1258:
1259: public boolean matches(final Lock lock, final MemberInfo methodInfo) {
1260: return matches(lock.getMethodJoinPointExpression(), methodInfo);
1261: }
1262:
1263: public boolean matches(final String expression,
1264: final MemberInfo methodInfo) {
1265: String executionExpression = ExpressionHelper
1266: .expressionPattern2ExecutionExpression(expression);
1267: if (logger.isDebugEnabled())
1268: logger.debug("==>Testing for match: " + executionExpression
1269: + " against " + methodInfo);
1270: ExpressionVisitor visitor = expressionHelper
1271: .createExpressionVisitor(executionExpression);
1272: return visitor.match(expressionHelper
1273: .createExecutionExpressionContext(methodInfo));
1274: }
1275:
1276: // private MethodInfo getMethodInfo(int modifiers, String className, String methodName, String description,
1277: // String[] exceptions) {
1278: // // TODO: This probably needs caching.
1279: // return new AsmMethodInfo(classInfoFactory, modifiers, className, methodName, description, exceptions);
1280: // }
1281:
1282: // private ConstructorInfo getConstructorInfo(int modifiers, String className, String methodName, String description,
1283: // String[] exceptions) {
1284: // return new AsmConstructorInfo(classInfoFactory, modifiers, className, methodName, description, exceptions);
1285: // }
1286:
1287: // private MemberInfo getMemberInfo(int modifiers, String className, String methodName, String description,
1288: // String[] exceptions) {
1289: // if (false && "<init>".equals(methodName)) {
1290: // // XXX: ConstructorInfo seems to really break things. Plus, locks in
1291: // // constructors don't work yet.
1292: // // When locks in constructors work, we'll have to sort this problem out.
1293: // return getConstructorInfo(modifiers, className, methodName, description, exceptions);
1294: // } else {
1295: // return getMethodInfo(modifiers, className, methodName, description, exceptions);
1296: // }
1297: // }
1298:
1299: private static boolean isNotStaticAndIsSynchronized(int modifiers) {
1300: return !Modifier.isStatic(modifiers)
1301: && Modifier.isSynchronized(modifiers);
1302: }
1303:
1304: /**
1305: * This is a simplified interface from DSOApplicationConfig. This is used for programmatically generating config.
1306: */
1307: public void addRoot(String rootName, String rootFieldName) {
1308: ClassSpec classSpec;
1309: try {
1310: classSpec = ClassUtils
1311: .parseFullyQualifiedFieldName(rootFieldName);
1312: } catch (ParseException e) {
1313: throw new RuntimeException(e);
1314: }
1315: addRoot(new Root(classSpec.getFullyQualifiedClassName(),
1316: classSpec.getShortFieldName(), rootName), false);
1317: }
1318:
1319: public void addRoot(Root root, boolean addSpecForClass) {
1320: if (addSpecForClass) {
1321: this .getOrCreateSpec(root.getClassName());
1322: }
1323:
1324: roots.add(root);
1325: }
1326:
1327: public String rootNameFor(FieldInfo fi) {
1328: Root r = findMatchingRootDefinition(fi);
1329: if (r != null) {
1330: return r.getRootName(fi);
1331: }
1332: throw Assert.failure("No such root for fieldName "
1333: + fi.getName() + " in class "
1334: + fi.getDeclaringType().getName());
1335: }
1336:
1337: public boolean isRoot(FieldInfo fi) {
1338: return findMatchingRootDefinition(fi) != null;
1339: }
1340:
1341: public boolean isRootDSOFinal(FieldInfo fi) {
1342: Root r = findMatchingRootDefinition(fi);
1343: if (r != null) {
1344: return r.isDsoFinal(fi.getType().isPrimitive());
1345: }
1346: throw Assert.failure("No such root for fieldName "
1347: + fi.getName() + " in class "
1348: + fi.getDeclaringType().getName());
1349: }
1350:
1351: private Root findMatchingRootDefinition(FieldInfo fi) {
1352: for (Iterator i = roots.iterator(); i.hasNext();) {
1353: Root r = (Root) i.next();
1354: if (r.matches(fi, expressionHelper)) {
1355: return r;
1356: }
1357: }
1358: return null;
1359: }
1360:
1361: private boolean classContainsAnyRoots(ClassInfo classInfo) {
1362: FieldInfo[] fields = classInfo.getFields();
1363: for (int i = 0; i < fields.length; i++) {
1364: FieldInfo fieldInfo = fields[i];
1365: if (findMatchingRootDefinition(fieldInfo) != null) {
1366: return true;
1367: }
1368: }
1369:
1370: return false;
1371: }
1372:
1373: public String[] getMissingRootDeclarations(ClassInfo classInfo) {
1374: final List missingRoots = new ArrayList();
1375: for (final Iterator i = roots.iterator(); i.hasNext();) {
1376: final Root root = (Root) i.next();
1377:
1378: // TODO: do we need to support checking for roots defined using expressions?
1379: if (root.isExpression())
1380: continue;
1381: if (!root.matches(classInfo, expressionHelper))
1382: continue;
1383:
1384: final String fieldName = root.getFieldName();
1385: final FieldInfo[] fields = classInfo.getFields();
1386: boolean found = false;
1387: for (int n = 0; (n < fields.length) && !found; n++) {
1388: FieldInfo fieldInfo = fields[n];
1389: found = fieldInfo.getName().equals(fieldName);
1390: }
1391:
1392: if (!found) {
1393: final String declaration = root.getClassName() + "."
1394: + root.getFieldName();
1395: missingRoots.add(declaration);
1396:
1397: }
1398: }
1399: return (String[]) missingRoots.toArray(new String[0]);
1400: }
1401:
1402: private void rewriteHashtableAutoLockSpecIfNecessary() {
1403: // addReadAutolock(new String[] { "synchronized * java.util.Hashtable.get(..)",
1404: // "synchronized * java.util.Hashtable.hashCode(..)", "synchronized * java.util.Hashtable.contains*(..)",
1405: // "synchronized * java.util.Hashtable.elements(..)", "synchronized * java.util.Hashtable.equals(..)",
1406: // "synchronized * java.util.Hashtable.isEmpty(..)", "synchronized * java.util.Hashtable.keys(..)",
1407: // "synchronized * java.util.Hashtable.size(..)", "synchronized * java.util.Hashtable.toString(..)" });
1408:
1409: String className = "java.util.Hashtable";
1410: ClassInfo classInfo = AsmClassInfo.getClassInfo(className,
1411: getClass().getClassLoader());
1412:
1413: String patterns = "get(Ljava/lang/Object;)Ljava/lang/Object;|" + //
1414: "hashCode()I|" + //
1415: "contains(Ljava/lang/Object;)Z|" + //
1416: "containsKey(Ljava/lang/Object;)Z|" + //
1417: "elements()Ljava/util/Enumeration;|" + //
1418: "equals(Ljava/lang/Object;)Z|" + //
1419: "isEmpty()Z|" + //
1420: "keys()Ljava/util/Enumeration;|" + //
1421: "size()I|" + //
1422: "toString()Ljava/lang/String;";
1423:
1424: MemberInfo[] methods = classInfo.getMethods();
1425: for (int j = 0; j < methods.length; j++) {
1426: MemberInfo methodInfo = methods[j];
1427: if (patterns.indexOf(methodInfo.getName()
1428: + methodInfo.getSignature()) > -1) {
1429: for (Iterator i = locks.iterator(); i.hasNext();) {
1430: Lock lock = (Lock) i.next();
1431: if (matches(lock, methodInfo)) {
1432: LockDefinition ld = lock.getLockDefinition();
1433: if (ld.isAutolock()
1434: && ld.getLockLevel() != ConfigLockLevel.READ) {
1435: addReadAutolock("* " + className + "."
1436: + methodInfo.getName() + "(..)");
1437: }
1438: break;
1439: }
1440: }
1441: }
1442: }
1443: }
1444:
1445: public LockDefinition[] lockDefinitionsFor(MemberInfo memberInfo) {
1446: final boolean isAutoLocksExcluded = matchesAutoLockExcludes(memberInfo);
1447: boolean foundMatchingAutoLock = false;
1448:
1449: List lockDefs = new ArrayList();
1450:
1451: for (Iterator i = locks.iterator(); i.hasNext();) {
1452: Lock lock = (Lock) i.next();
1453: if (matches(lock, memberInfo)) {
1454: LockDefinition definition = lock.getLockDefinition();
1455:
1456: if (definition.isAutolock()) {
1457: if (!isAutoLocksExcluded && !foundMatchingAutoLock) {
1458: foundMatchingAutoLock = true;
1459: lockDefs.add(definition);
1460: }
1461: } else {
1462: lockDefs.add(definition);
1463: }
1464: }
1465: }
1466:
1467: LockDefinition[] rv = new LockDefinition[lockDefs.size()];
1468: lockDefs.toArray(rv);
1469: return rv;
1470: }
1471:
1472: private boolean matchesAutoLockExcludes(MemberInfo methodInfo) {
1473: ExpressionContext ctxt = expressionHelper
1474: .createExecutionExpressionContext(methodInfo);
1475: for (Iterator i = autoLockExcludes.iterator(); i.hasNext();) {
1476: ExpressionVisitor visitor = (ExpressionVisitor) i.next();
1477: if (visitor.match(ctxt))
1478: return true;
1479: }
1480: return false;
1481: }
1482:
1483: public int getFaultCount() {
1484: return faultCount < 0 ? this .configSetupManager.dsoL1Config()
1485: .faultCount().getInt() : faultCount;
1486: }
1487:
1488: private synchronized Boolean readAdaptableCache(String name) {
1489: return (Boolean) adaptableCache.get(name);
1490: }
1491:
1492: private synchronized boolean cacheIsAdaptable(String name,
1493: boolean adaptable) {
1494: adaptableCache.put(name, adaptable ? Boolean.TRUE
1495: : Boolean.FALSE);
1496: return adaptable;
1497: }
1498:
1499: private synchronized void clearAdaptableCache() {
1500: this .adaptableCache.clear();
1501: }
1502:
1503: public void addWriteAutolock(String methodPattern) {
1504: addAutolock(methodPattern, ConfigLockLevel.WRITE);
1505: }
1506:
1507: public void addSynchronousWriteAutolock(String methodPattern) {
1508: addAutolock(methodPattern, ConfigLockLevel.SYNCHRONOUS_WRITE);
1509: }
1510:
1511: public void addReadAutolock(String methodPattern) {
1512: addAutolock(methodPattern, ConfigLockLevel.READ);
1513: }
1514:
1515: public void addAutolock(String methodPattern, ConfigLockLevel type) {
1516: LockDefinition lockDefinition = new LockDefinitionImpl(
1517: LockDefinition.TC_AUTOLOCK_NAME, type);
1518: lockDefinition.commit();
1519: addLock(methodPattern, lockDefinition);
1520: }
1521:
1522: public void addReadAutoSynchronize(String methodPattern) {
1523: addAutolock(methodPattern,
1524: ConfigLockLevel.AUTO_SYNCHRONIZED_READ);
1525: }
1526:
1527: public void addWriteAutoSynchronize(String methodPattern) {
1528: addAutolock(methodPattern,
1529: ConfigLockLevel.AUTO_SYNCHRONIZED_WRITE);
1530: }
1531:
1532: public void addLock(String methodPattern,
1533: LockDefinition lockDefinition) {
1534: // keep the list in reverse order of add
1535: synchronized (locks) {
1536: locks.add(0, new Lock(methodPattern, lockDefinition));
1537: }
1538: }
1539:
1540: public boolean shouldBeAdapted(ClassInfo classInfo) {
1541: // now check if class is adaptable
1542: String fullClassName = classInfo.getName();
1543: Boolean cache = readAdaptableCache(fullClassName);
1544: if (cache != null) {
1545: return cache.booleanValue();
1546: }
1547:
1548: // @see isTCPatternMatchingHack() note elsewhere
1549: if (isTCPatternMatchingHack(classInfo)
1550: || permanentExcludesMatcher.match(classInfo)) {
1551: // permanent Excludes
1552: return cacheIsAdaptable(fullClassName, false);
1553: }
1554:
1555: if (fullClassName.indexOf(CGLIB_PATTERN) >= 0) {
1556: if (!allowCGLIBInstrumentation) {
1557: logger
1558: .error("Refusing to instrument CGLIB generated proxy type "
1559: + fullClassName
1560: + " (CGLIB terracotta plugin not installed)");
1561: return cacheIsAdaptable(fullClassName, false);
1562: }
1563: }
1564:
1565: String outerClassname = outerClassnameWithoutInner(fullClassName);
1566: if (isLogical(outerClassname)) {
1567: // We make inner classes of logical classes not instrumented while logical
1568: // bases are instrumented...UNLESS there is a explicit spec for said inner class
1569: boolean adaptable = getSpec(fullClassName) != null
1570: || outerClassname.equals(fullClassName);
1571: return cacheIsAdaptable(fullClassName, adaptable);
1572: }
1573:
1574: // If a root is defined then we automagically instrument
1575: if (classContainsAnyRoots(classInfo)) {
1576: return cacheIsAdaptable(fullClassName, true);
1577: }
1578:
1579: // existing class specs trump config
1580: if (hasSpec(fullClassName)) {
1581: return cacheIsAdaptable(fullClassName, true);
1582: }
1583:
1584: InstrumentationDescriptor desc = getInstrumentationDescriptorFor(classInfo);
1585: return cacheIsAdaptable(fullClassName, desc.isInclude());
1586: }
1587:
1588: private boolean isTCPatternMatchingHack(ClassInfo classInfo) {
1589: String fullClassName = classInfo.getName();
1590: return fullClassName.startsWith("com.tc.")
1591: || fullClassName.startsWith("com.terracottatech.");
1592: }
1593:
1594: public boolean isNeverAdaptable(ClassInfo classInfo) {
1595: return isTCPatternMatchingHack(classInfo)
1596: || permanentExcludesMatcher.match(classInfo)
1597: || nonportablesMatcher.match(classInfo);
1598: }
1599:
1600: private InstrumentationDescriptor getInstrumentationDescriptorFor(
1601: ClassInfo classInfo) {
1602: synchronized (this .instrumentationDescriptors) {
1603: for (Iterator i = this .instrumentationDescriptors
1604: .iterator(); i.hasNext();) {
1605: InstrumentationDescriptor rv = (InstrumentationDescriptor) i
1606: .next();
1607: if (rv.matches(classInfo)) {
1608: return rv;
1609: }
1610: }
1611: }
1612: return DEAFULT_INSTRUMENTATION_DESCRIPTOR;
1613: }
1614:
1615: private String outerClassnameWithoutInner(String fullName) {
1616: int indexOfInner = fullName.indexOf('$');
1617: return indexOfInner < 0 ? fullName : fullName.substring(0,
1618: indexOfInner);
1619: }
1620:
1621: public boolean isTransient(int modifiers, ClassInfo classInfo,
1622: String field) {
1623: if (ByteCodeUtil.isParent(field))
1624: return true;
1625: if (ClassAdapterBase.isDelegateFieldName(field)) {
1626: return false;
1627: }
1628:
1629: String className = classInfo.getName();
1630: if (Modifier.isTransient(modifiers)
1631: && isHonorJavaTransient(classInfo))
1632: return true;
1633:
1634: return transients.contains(className + "." + field);
1635: }
1636:
1637: public boolean isVolatile(int modifiers, ClassInfo classInfo,
1638: String field) {
1639: return Modifier.isVolatile(modifiers)
1640: && isHonorJavaVolatile(classInfo);
1641: }
1642:
1643: private boolean isHonorJavaTransient(ClassInfo classInfo) {
1644: TransparencyClassSpec spec = getSpec(classInfo.getName());
1645: if (spec != null && spec.isHonorTransientSet()) {
1646: return spec.isHonorJavaTransient();
1647: }
1648: return getInstrumentationDescriptorFor(classInfo)
1649: .isHonorTransient();
1650: }
1651:
1652: private boolean isHonorJavaVolatile(ClassInfo classInfo) {
1653: TransparencyClassSpec spec = getSpec(classInfo.getName());
1654: if (spec != null && spec.isHonorVolatileSet()) {
1655: return spec.isHonorVolatile();
1656: }
1657: return getInstrumentationDescriptorFor(classInfo)
1658: .isHonorVolatile();
1659: }
1660:
1661: public boolean isCallConstructorOnLoad(ClassInfo classInfo) {
1662: TransparencyClassSpec spec = getSpec(classInfo.getName());
1663: if (spec != null && spec.isCallConstructorSet()) {
1664: return spec.isCallConstructorOnLoad();
1665: }
1666: return getInstrumentationDescriptorFor(classInfo)
1667: .isCallConstructorOnLoad();
1668: }
1669:
1670: public String getPreCreateMethodIfDefined(String className) {
1671: TransparencyClassSpec spec = getSpec(className);
1672: if (spec != null) {
1673: return spec.getPreCreateMethod();
1674: } else {
1675: return null;
1676: }
1677: }
1678:
1679: public String getPostCreateMethodIfDefined(String className) {
1680: TransparencyClassSpec spec = getSpec(className);
1681: if (spec != null) {
1682: return spec.getPostCreateMethod();
1683: } else {
1684: return null;
1685: }
1686: }
1687:
1688: public String getOnLoadScriptIfDefined(ClassInfo classInfo) {
1689: TransparencyClassSpec spec = getSpec(classInfo.getName());
1690: if (spec != null && spec.isExecuteScriptOnLoadSet()) {
1691: return spec.getOnLoadExecuteScript();
1692: }
1693: return getInstrumentationDescriptorFor(classInfo)
1694: .getOnLoadScriptIfDefined();
1695: }
1696:
1697: public String getOnLoadMethodIfDefined(ClassInfo classInfo) {
1698: TransparencyClassSpec spec = getSpec(classInfo.getName());
1699: if (spec != null && spec.isCallMethodOnLoadSet()) {
1700: return spec.getOnLoadMethod();
1701: }
1702: return getInstrumentationDescriptorFor(classInfo)
1703: .getOnLoadMethodIfDefined();
1704: }
1705:
1706: public Class getTCPeerClass(Class clazz) {
1707: if (moduleSpecs != null) {
1708: for (int i = 0; i < moduleSpecs.length; i++) {
1709: clazz = moduleSpecs[i].getPeerClass(clazz);
1710: }
1711: }
1712: return clazz;
1713: }
1714:
1715: public boolean isDSOSessions(String name) {
1716: for (Iterator it = applicationNames.iterator(); it.hasNext();) {
1717: String appName = (String) it.next();
1718: if (name.matches(appName.replaceAll("\\*", "\\.\\*")))
1719: return true;
1720: }
1721: return false;
1722: }
1723:
1724: public TransparencyClassAdapter createDsoClassAdapterFor(
1725: ClassVisitor writer, ClassInfo classInfo,
1726: InstrumentationLogger lgr, ClassLoader caller,
1727: final boolean forcePortable, boolean honorTransient) {
1728: String className = classInfo.getName();
1729: ManagerHelper mgrHelper = mgrHelperFactory.createHelper();
1730: TransparencyClassSpec spec = getOrCreateSpec(className);
1731: spec.setHonorTransient(honorTransient);
1732:
1733: if (forcePortable) {
1734: if (spec.getInstrumentationAction() == TransparencyClassSpec.NOT_SET) {
1735: spec
1736: .setInstrumentationAction(TransparencyClassSpec.PORTABLE);
1737: } else {
1738: logger.info("Not making " + className
1739: + " forcefully portable");
1740: }
1741: }
1742:
1743: return new TransparencyClassAdapter(classInfo,
1744: basicGetOrCreateSpec(className, null, false), writer,
1745: mgrHelper, lgr, caller, portability);
1746: }
1747:
1748: public ClassAdapter createClassAdapterFor(ClassWriter writer,
1749: ClassInfo classInfo, InstrumentationLogger lgr,
1750: ClassLoader caller) {
1751: return this .createClassAdapterFor(writer, classInfo, lgr,
1752: caller, false);
1753: }
1754:
1755: public ClassAdapter createClassAdapterFor(ClassWriter writer,
1756: ClassInfo classInfo, InstrumentationLogger lgr,
1757: ClassLoader caller, final boolean forcePortable) {
1758: ManagerHelper mgrHelper = mgrHelperFactory.createHelper();
1759: TransparencyClassSpec spec = getOrCreateSpec(classInfo
1760: .getName());
1761:
1762: if (forcePortable) {
1763: if (spec.getInstrumentationAction() == TransparencyClassSpec.NOT_SET) {
1764: spec
1765: .setInstrumentationAction(TransparencyClassSpec.PORTABLE);
1766: } else {
1767: logger.info("Not making " + classInfo.getName()
1768: + " forcefully portable");
1769: }
1770: }
1771:
1772: ClassAdapter dsoAdapter = new TransparencyClassAdapter(
1773: classInfo, spec, writer, mgrHelper, lgr, caller,
1774: portability);
1775: ClassAdapterFactory factory = spec.getCustomClassAdapter();
1776: ClassVisitor cv;
1777: if (factory == null) {
1778: cv = dsoAdapter;
1779: } else {
1780: cv = factory.create(dsoAdapter, caller);
1781: }
1782:
1783: return new SafeSerialVersionUIDAdder(cv);
1784: }
1785:
1786: private TransparencyClassSpec basicGetOrCreateSpec(
1787: String className, String applicator, boolean rememberSpec) {
1788: synchronized (classSpecs) {
1789: TransparencyClassSpec spec = getSpec(className);
1790: if (spec == null) {
1791: if (applicator != null) {
1792: spec = new TransparencyClassSpecImpl(className,
1793: this , applicator);
1794: } else {
1795: spec = new TransparencyClassSpecImpl(className,
1796: this );
1797: }
1798: if (rememberSpec) {
1799: addSpec(spec);
1800: }
1801: }
1802: return spec;
1803: }
1804: }
1805:
1806: public TransparencyClassSpec getOrCreateSpec(String className) {
1807: return basicGetOrCreateSpec(className, null, true);
1808: }
1809:
1810: public TransparencyClassSpec getOrCreateSpec(
1811: final String className, final String applicator) {
1812: if (applicator == null)
1813: throw new AssertionError();
1814: return basicGetOrCreateSpec(className, applicator, true);
1815: }
1816:
1817: private void addSpec(TransparencyClassSpec spec) {
1818: synchronized (classSpecs) {
1819: Assert.eval(!classSpecs.containsKey(spec.getClassName()));
1820: Assert.assertNotNull(spec);
1821: classSpecs.put(spec.getClassName(), spec);
1822: }
1823: }
1824:
1825: public boolean isLogical(String className) {
1826: TransparencyClassSpec spec = getSpec(className);
1827: return spec != null && spec.isLogical();
1828: }
1829:
1830: // TODO: Need to optimize this by identifying the module to query instead of querying all the modules.
1831: public boolean isPortableModuleClass(Class clazz) {
1832: if (moduleSpecs != null) {
1833: for (int i = 0; i < moduleSpecs.length; i++) {
1834: if (moduleSpecs[i].isPortableClass(clazz)) {
1835: return true;
1836: }
1837: }
1838: }
1839: return false;
1840: }
1841:
1842: public Class getChangeApplicator(Class clazz) {
1843: ChangeApplicatorSpec applicatorSpec = null;
1844: TransparencyClassSpec spec = getSpec(clazz.getName());
1845: if (spec != null) {
1846: applicatorSpec = spec.getChangeApplicatorSpec();
1847: }
1848:
1849: if (applicatorSpec == null) {
1850: if (moduleSpecs != null) {
1851: for (int i = 0; i < moduleSpecs.length; i++) {
1852: Class applicatorClass = moduleSpecs[i]
1853: .getChangeApplicatorSpec()
1854: .getChangeApplicator(clazz);
1855: if (applicatorClass != null) {
1856: return applicatorClass;
1857: }
1858: }
1859: }
1860: return null;
1861: }
1862: return applicatorSpec.getChangeApplicator(clazz);
1863: }
1864:
1865: // TODO: Need to optimize this by identifying the module to query instead of querying all the modules.
1866: public boolean isUseNonDefaultConstructor(Class clazz) {
1867: String className = clazz.getName();
1868: if (literalValues.isLiteral(className)) {
1869: return true;
1870: }
1871: TransparencyClassSpec spec = getSpec(className);
1872: if (spec != null) {
1873: return spec.isUseNonDefaultConstructor();
1874: }
1875: if (moduleSpecs != null) {
1876: for (int i = 0; i < moduleSpecs.length; i++) {
1877: if (moduleSpecs[i].isUseNonDefaultConstructor(clazz)) {
1878: return true;
1879: }
1880: }
1881: }
1882: return false;
1883: }
1884:
1885: public void setModuleSpecs(ModuleSpec[] moduleSpecs) {
1886: this .moduleSpecs = moduleSpecs;
1887: }
1888:
1889: /*
1890: * public String getChangeApplicatorClassNameFor(String className) { TransparencyClassSpec spec = getSpec(className);
1891: * if (spec == null) return null; return spec.getChangeApplicatorClassName(); }
1892: */
1893:
1894: public boolean hasSpec(String className) {
1895: return getSpec(className) != null;
1896: }
1897:
1898: private boolean hasSpec(ClassInfo classInfo) {
1899: return getSpec(classInfo.getName()) != null;
1900: }
1901:
1902: /**
1903: * This is used in BootJarTool. In BootJarTool, it changes the package of our implementation of ReentrantLock and
1904: * FutureTask to the java.util.concurrent package. In order to change the different adapter together, we need to
1905: * create a spec with our package and remove the spec after the instrumentation is done.
1906: */
1907: public void removeSpec(String className) {
1908: className = className.replace('/', '.');
1909: classSpecs.remove(className);
1910: }
1911:
1912: public TransparencyClassSpec getSpec(String className) {
1913: // NOTE: This method doesn't create a spec for you. If you want that use getOrCreateSpec()
1914: className = className.replace('/', '.');
1915: TransparencyClassSpec rv = (TransparencyClassSpec) classSpecs
1916: .get(className);
1917:
1918: if (rv == null) {
1919: rv = (TransparencyClassSpec) userDefinedBootSpecs
1920: .get(className);
1921: } else {
1922: // shouldn't have a spec in both of the spec collections
1923: Assert.assertNull(userDefinedBootSpecs.get(className));
1924: }
1925:
1926: return rv;
1927: }
1928:
1929: private void scanForMissingClassesDeclaredInConfig()
1930: throws BootJarException, IOException {
1931: int missingCount = 0;
1932: int preInstrumentedCount = 0;
1933: BootJar bootJar = BootJar.getDefaultBootJarForReading();
1934: Set bjClasses = bootJar.getAllPreInstrumentedClasses();
1935: int bootJarPopulation = bjClasses.size();
1936:
1937: TransparencyClassSpec[] allSpecs = getAllSpecs(true);
1938: for (int i = 0; i < allSpecs.length; i++) {
1939: TransparencyClassSpec classSpec = allSpecs[i];
1940: Assert.assertNotNull(classSpec);
1941:
1942: if (classSpec.isPreInstrumented()) {
1943: preInstrumentedCount++;
1944: if (!(bjClasses.contains(classSpec.getClassName()) || classSpec
1945: .isHonorJDKSubVersionSpecific())) {
1946: String message = "* " + classSpec.getClassName()
1947: + "... missing";
1948: missingCount++;
1949: logger.info(message);
1950: }
1951: }
1952: }
1953:
1954: if (missingCount > 0) {
1955: logger.info("Number of classes in the DSO boot jar:"
1956: + bootJarPopulation);
1957: logger
1958: .info("Number of classes expected to be in the DSO boot jar:"
1959: + preInstrumentedCount);
1960: logger
1961: .info("Number of classes found missing from the DSO boot jar:"
1962: + missingCount);
1963: throw new IncompleteBootJarException(
1964: "Incomplete DSO boot jar; "
1965: + missingCount
1966: + " pre-instrumented class(es) found missing.");
1967: }
1968: }
1969:
1970: /**
1971: * This method will: - check the contents of the boot-jar against tc-config.xml - check that all that all the
1972: * necessary referenced classes are also present in the boot jar
1973: */
1974: public void verifyBootJarContents()
1975: throws UnverifiedBootJarException {
1976: logger.debug("Verifying boot jar contents...");
1977: try {
1978: scanForMissingClassesDeclaredInConfig();
1979: } catch (BootJarException bjex) {
1980: throw new UnverifiedBootJarException(
1981: "BootJarException occurred while attempting to verify the contents of the boot jar.",
1982: bjex);
1983: } catch (IOException ioex) {
1984: throw new UnverifiedBootJarException(
1985: "IOException occurred while attempting to verify the contents of the boot jar.",
1986: ioex);
1987: }
1988: }
1989:
1990: private synchronized TransparencyClassSpec[] getAllSpecs(
1991: boolean includeBootJarSpecs) {
1992: ArrayList rv = new ArrayList(classSpecs.values());
1993:
1994: if (includeBootJarSpecs) {
1995: for (Iterator i = getAllUserDefinedBootSpecs(); i.hasNext();) {
1996: rv.add(i.next());
1997: }
1998: }
1999:
2000: return (TransparencyClassSpec[]) rv
2001: .toArray(new TransparencyClassSpec[rv.size()]);
2002: }
2003:
2004: public TransparencyClassSpec[] getAllSpecs() {
2005: return getAllSpecs(false);
2006: }
2007:
2008: public void addDistributedMethodCall(DistributedMethodSpec dms) {
2009: this .distributedMethods.add(dms);
2010: }
2011:
2012: public DistributedMethodSpec getDmiSpec(MemberInfo memberInfo) {
2013: if (Modifier.isStatic(memberInfo.getModifiers())
2014: || "<init>".equals(memberInfo.getName())
2015: || "<clinit>".equals(memberInfo.getName())) {
2016: return null;
2017: }
2018: for (Iterator i = distributedMethods.iterator(); i.hasNext();) {
2019: DistributedMethodSpec dms = (DistributedMethodSpec) i
2020: .next();
2021: if (matches(dms.getMethodExpression(), memberInfo)) {
2022: return dms;
2023: }
2024: }
2025: return null;
2026: }
2027:
2028: public void addTransient(String className, String fieldName) {
2029: if ((className == null) || (fieldName == null)) {
2030: //
2031: throw new IllegalArgumentException("class " + className
2032: + ", field = " + fieldName);
2033: }
2034: transients.add(className + "." + fieldName);
2035: }
2036:
2037: public String toString() {
2038: return "<StandardDSOClientConfigHelperImpl: "
2039: + configSetupManager + ">";
2040: }
2041:
2042: public void writeTo(DSOApplicationConfigBuilder appConfigBuilder) {
2043: throw new UnsupportedOperationException();
2044: }
2045:
2046: public void addAspectModule(String pattern, String moduleName) {
2047: List modules = (List) this .aspectModules.get(pattern);
2048: if (modules == null) {
2049: modules = new ArrayList();
2050: this .aspectModules.put(pattern, modules);
2051: }
2052: modules.add(moduleName);
2053: }
2054:
2055: public Map getAspectModules() {
2056: return this .aspectModules;
2057: }
2058:
2059: public void addDSOSpringConfig(DSOSpringConfigHelper config) {
2060: this .springConfigs.add(config);
2061:
2062: if (!this .aspectModules.containsKey("org.springframework")) {
2063: addAspectModule("org.springframework",
2064: "com.tc.object.config.SpringAspectModule");
2065: }
2066: }
2067:
2068: public Collection getDSOSpringConfigs() {
2069: return this .springConfigs;
2070: }
2071:
2072: public String getLogicalExtendingClassName(String className) {
2073: TransparencyClassSpec spec = getSpec(className);
2074: if (spec == null || !spec.isLogical()) {
2075: return null;
2076: }
2077: return spec.getLogicalExtendingClassName();
2078: }
2079:
2080: public void addApplicationName(String name) {
2081: applicationNames.add(name);
2082: }
2083:
2084: public void addSynchronousWriteApplication(String name) {
2085: this .synchronousWriteApplications.add(name);
2086: }
2087:
2088: public void addUserDefinedBootSpec(String className,
2089: TransparencyClassSpec spec) {
2090: userDefinedBootSpecs.put(className, spec);
2091: }
2092:
2093: public void addRepository(String location) {
2094: modulesContext.modules.addRepository(location);
2095: }
2096:
2097: public void addModule(String name, String version) {
2098: Module newModule = modulesContext.modules.addNewModule();
2099: newModule.setName(name);
2100: newModule.setVersion(version);
2101: }
2102:
2103: public Modules getModulesForInitialization() {
2104: return modulesContext.getModulesForInitialization();
2105: }
2106:
2107: private static class ModulesContext {
2108:
2109: private boolean alwaysInitializedModules = true; // set to false only when in test
2110: private boolean modulesInitialized = false; // set to true only when in test
2111:
2112: private Modules modules;
2113:
2114: // This is used only in test
2115: // XXX: Remove anything test related from production code
2116: void initializedModulesOnlyOnce() {
2117: this .alwaysInitializedModules = false;
2118: }
2119:
2120: void setModules(Modules modules) {
2121: this .modules = modules;
2122: }
2123:
2124: Modules getModulesForInitialization() {
2125: if (alwaysInitializedModules) {
2126: return this .modules;
2127: } else {
2128: // this could happen only in test
2129: if (modulesInitialized) {
2130: return Modules.Factory.newInstance();
2131: } else {
2132: modulesInitialized = true;
2133: return this .modules;
2134: }
2135: }
2136: }
2137: }
2138:
2139: public int getSessionLockType(String appName) {
2140: for (Iterator iter = synchronousWriteApplications.iterator(); iter
2141: .hasNext();) {
2142: String webApp = (String) iter.next();
2143: if (webApp.equals(appName)) {
2144: return LockLevel.SYNCHRONOUS_WRITE;
2145: }
2146: }
2147: return LockLevel.WRITE;
2148: }
2149:
2150: }
|