[jboss-svn-commits] JBL Code SVN: r29689 - in labs/jbosstm/workspace/adinn/byteman/trunk: dd/scripts and 8 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Oct 20 08:48:04 EDT 2009


Author: adinn
Date: 2009-10-20 08:48:04 -0400 (Tue, 20 Oct 2009)
New Revision: 29689

Added:
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/build.xml
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/ClassLoadMonitor.txt
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/FileMonitor.txt
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/FinalizeMonitor.txt
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/SocketMonitor.txt
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/ThreadMonitor.txt
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/helper/
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/helper/StackTraceHelper.java
   labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/helper/ThreadMonitorHelper.java
Removed:
   labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/HeuristicSaveAndRecover.txt
   labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/HeuristicSaveAndRecover10.txt
   labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/ParticipantCrashAndRecover.txt
   labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/ParticipantCrashAndRecover10.txt
Modified:
   labs/jbosstm/workspace/adinn/byteman/trunk/build-release-pkgs.xml
   labs/jbosstm/workspace/adinn/byteman/trunk/build.xml
Log:
added some sample scripts to do system tracing and modified the build script to install them and all other products in a single install directory -- partially fixes BYTEMAN-52 and BYTEMAN-53

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/build-release-pkgs.xml
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/build-release-pkgs.xml	2009-10-20 12:36:47 UTC (rev 29688)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/build-release-pkgs.xml	2009-10-20 12:48:04 UTC (rev 29689)
@@ -72,7 +72,7 @@
             http://www.jboss.org/community/docs/DOC-11381 -->
 
 <!--
-    <property name="svnbase" value="https://svn.jboss.org/repos/labs/labs/jbosstm/workspace/adinn/byteman/tags"/>
+    <property name="svnbase" value="https://svn.jboss.org/repos/labs/labs/jbosstm/workspace/adinn/byteman"/>
     <property name="tag" value="trunk"/>
     <property name="filename" value="1.1.1.SNAPSHOT"/>
     <property name="mvn.repositoryId" value="snapshots.jboss.org"/>
@@ -103,6 +103,7 @@
 
     <target name="init">
         <tstamp/>
+        <delete dir="${workdir}"/>
         <mkdir dir="${workdir}"/>
     </target>
 
@@ -116,20 +117,13 @@
 
         <!-- package the byteman source release (all src tree) -->
         <delete file="${workdir}/byteman-${filename}-src.zip"/>
+
         <zip basedir="${workdir}" destfile="${workdir}/byteman-${filename}-src.zip"
              includes="${tag}/**"/>
-
-        <!-- build the binary release -->
-        <delete dir="${workdir}/build"/>
-        <mkdir dir="${workdir}/build"/>
-        <unzip src="${workdir}/byteman-${filename}-src.zip" dest="${workdir}/build"/>
-        <ant dir="${workdir}/build/${tag}" antfile="build.xml" target="install">
+        <!-- build the src and binary release zips -->
+        <ant dir="${workdir}/${tag}" antfile="build.xml" target="zip.both">
             <property name="tag" value="${tag}"/>
         </ant>
-
-        <!-- package the binary release -->
-	<delete file="${workdir}/build/${tag}/build/byteman-${filename}.zip"/>
-        <copy toFile="${workdir}/byteman-${filename}.zip" file="${workdir}/build/${tag}/build/byteman.zip"/>
     </target>
 
     <!-- copy the release into the cms svn tree (http://www.jboss.org/jbosstm web site content) -->

Modified: labs/jbosstm/workspace/adinn/byteman/trunk/build.xml
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/build.xml	2009-10-20 12:36:47 UTC (rev 29688)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/build.xml	2009-10-20 12:48:04 UTC (rev 29689)
@@ -26,20 +26,39 @@
 
     <property name="ext.asm.jars" value="asm-all-3.0.jar"/>
 
+    <!-- locations for inputs ot build process-->
     <property name="src.dir"           value="src"/>
-    <property name="src.dir.jdk6"           value="srcjdk6"/>
+    <property name="bin.src.dir"       value="bin"/>
+    <property name="docs.src.dir"      value="docs"/>
     <property name="dd.dir"            value="dd"/>
-    <property name="dd.dir.jdk6"            value="ddjdk6"/>
     <property name="dd.grammar.dir"    value="${dd.dir}/grammar"/>
-    <property name="ext.lib.dir" value="ext"/>
+    <property name="ext.lib.dir"       value="ext"/>
+    <property name="tests.dir"         value="tests"/>
+    <property name="tests.src.dir"     value="${tests.dir}/src"/>
+    <property name="tests.dd.dir"      value="${tests.dir}/dd"/>
+
+    <!-- locations of intermediate build products -->
+
     <property name="build.dir"         value="build"/>
     <property name="build.classes.dir" value="${build.dir}/classes"/>
     <property name="build.lib.dir"     value="${build.dir}/lib"/>
-    <property name="htdocs.dir"     value="htdocs"/>
+    <property name="htdocs.dir"        value="htdocs"/>
 
+    <!-- location of installed build products -->
+    <property name="install.dir" value="install"/>
+    <property name="install.lib.dir" value="${install.dir}/lib"/>
+    <property name="install.bin.dir" value="${install.dir}/bin"/>
+    <property name="install.docs.dir" value="${install.dir}/docs"/>
+
+    <!-- names of specific input and output products -->
+
     <property name="ext.jflex.jars" value="JFlex.jar"/>
     <property name="ext.javacup.jars" value="javacup.jar"/>
     <property name="ext.javacup.rt.jars" value="javacuprt.jar"/>
+    <property name="byteman.jar" value="byteman.jar"/>
+    <property name="byteman.bin.scripts" value="bytemancheck.sh submit.sh bmjava.sh"/>
+    <property name="byteman.doc.files" value="ProgrammersGuide.pdf"/>
+    <property name="manifest.file" value="${dd.dir}/META-INF/MANIFEST.MF"/>
 
     <property name="javac.debug" value="on"/>
 
@@ -116,54 +135,79 @@
          -->
          <unjar src="${ext.lib.dir}/javacuprt.jar" dest="${build.classes.dir}"/>
          <unjar src="${ext.lib.dir}/asm-all-3.0.jar" dest="${build.classes.dir}"/>
-         <jar jarfile="${build.lib.dir}/byteman.jar" manifest="${dd.dir}/META-INF/MANIFEST.MF">
+         <jar jarfile="${build.lib.dir}/${byteman.jar}" manifest="${manifest.file}">
              <fileset dir="${build.classes.dir}" includes="**/*"/>
          </jar>
     </target>
 
-    <target name="install" depends="jar">
-        <zip  destfile="${build.dir}/byteman.zip">
-            <fileset dir="${build.dir}" includes="lib/byteman.jar"/>
-            <fileset dir="." includes="README"/>
-            <fileset dir="." includes="docs/ProgrammersGuide.pdf"/>
-            <fileset dir="." includes="bin/bytemancheck.sh bin/submit.sh"/>
-            <fileset dir="." includes="ext/asm-all-3.0.jar"/>
-            <fileset dir="." includes="ext/third_party_licenses.txt"/>
-        </zip>
+    <!-- installation targets -->
+    <target  name="init-install">
+        <delete dir="${install.dir}"/>
+        <mkdir dir="${install.dir}"/>
+        <mkdir dir="${install.lib.dir}"/>
+        <mkdir dir="${install.bin.dir}"/>
+        <mkdir dir="${install.docs.dir}"/>
     </target>
 
-    <target name="install-src" depends="htdocs">
-        <zip  destfile="${build.dir}/byteman-src.zip">
-            <fileset dir="." includes="README build.xml"/>
-            <fileset dir="${build.dir}" includes="lib/byteman.jar"/>
-            <fileset dir="." includes="src/**/*" excludes="src/**/.svn/**/*"/>
-            <fileset dir="." includes="docs/**" excludes="docs/**/.svn/**/*"/>
-            <fileset dir="." includes="htdocs/**" excludes="docs/**/.svn/**/*"/>
-            <fileset dir="." includes="bin/**" excludes="bin/**/.svn/**/*"/>
-            <fileset dir="." includes="ext/**" excludes="ext/**/.svn/**/*"/>
-            <fileset dir="." includes="dd/**" excludes="dd/**/.svn/**/*"/>
-            <fileset dir="." includes="tests/build.xml"/>
-            <fileset dir="." includes="tests/src/**/*" excludes="tests/src/**/.svn/**/*"/>
-            <fileset dir="." includes="tests/dd/**/*" excludes="tests/sdd/**/.svn/**/*"/>
+    <target name="local-install">
+        <copy todir="${install.lib.dir}">
+            <fileset dir="${build.lib.dir}" includes="${byteman.jar}"/>
+        </copy>
+        <copy todir="${install.bin.dir}">
+            <fileset dir="${bin.src.dir}" includes="${byteman.bin.scripts}"/>
+        </copy>
+        <copy todir="${install.docs.dir}">
+            <fileset dir="${docs.src.dir}" includes="${byteman.doc.files}"/>
+        </copy>
+    </target>
+
+    <!-- target to make and install samples in samples directory -->
+    <target name="sample-install">
+        <ant dir="sample" target="install"/>
+    </target>
+
+    <target name="install" depends="jar, init-install, local-install, sample-install">
+    </target>
+
+    <!-- target for use by build-release-pkgs script n.b. this assumes it is being run in a clean
+         source tree under tags obtained using svn export. -->
+    <target name="zip" depends="install">
+        <zip destfile="${build.dir}/byteman.zip">
+            <fileset  dir="${install.dir}" includes="**/*"/>
         </zip>
+        <zip destfile="${build.dir}/byteman-src.zip">
+            <fileset  dir="${install.dir}" includes="**/*"/>
+            <fileset  dir="." includes="${src.dir}/**/*"/>
+            <fileset  dir="." includes="${dd.dir}/**/*"/>
+            <fileset  dir="." includes="${docs.src.dir}/**/*"/>
+            <fileset  dir="." includes="${htdocs.dir}/**/*"/>
+            <fileset  dir="." includes="${bin.src.dir}/**/*"/>
+            <fileset  dir="." includes="${ext.lib.dir}/**/*"/>
+            <fileset  dir="." includes="${tests.src.dir}/**/*"/>
+            <fileset  dir="." includes="${tests.dd.dir}/**/*"/>
+        </zip>
     </target>
 
+    <!-- target to make htdocs for byteman code -->
    <target name="htdocs">
        <delete dir="${htdocs.dir}"/>
        <mkdir dir="${htdocs.dir}"/>
-       <javadoc packagenames="org.jboss.byteman" destdir="${htdocs.dir}" linksource="true" private="true">
+       <javadoc packagenames="org.jboss.byteman" destdir="${htdocs.dir}" private="true">
            <classpath>
                <fileset dir="${ext.lib.dir}" includes="${ext.asm.jars}"/>
                <fileset dir="${ext.lib.dir}" includes="${ext.javacup.jars}"/>
                <fileset dir="${ext.lib.dir}" includes="${ext.javacup.rt.jars}"/>
            </classpath>
            <fileset dir="${src.dir}" includes="**/*.java"/>
-           <fileset dir="${src.dir.jdk6}" includes="**/*.java"/>
        </javadoc>
    </target>
 
-   <target name="clean">
-       <delete dir="${build.dir}"/>
-       <delete dir="${dd.grammar.dir}" includes="*.java *.tokens"/>
-    </target>
+    <target name="clean">
+        <delete dir="${build.dir}"/>
+        <delete dir="${dd.grammar.dir}" includes="*.java *.tokens"/>
+     </target>
+
+    <target name="spotless" depends="clean">
+        <delete dir="${install.dir}"/>
+     </target>
 </project>

Deleted: labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/HeuristicSaveAndRecover.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/HeuristicSaveAndRecover.txt	2009-10-20 12:36:47 UTC (rev 29688)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/HeuristicSaveAndRecover.txt	2009-10-20 12:48:04 UTC (rev 29689)
@@ -1,235 +0,0 @@
-##############################################################################
-# JBoss, Home of Professional Open Source
-# Copyright 2008, Red Hat Middleware LLC, and individual contributors
-# by the @authors tag. See the copyright.txt in the distribution for a
-# full listing of individual contributors.
-#
-# This is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# This software is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this software; if not, write to the Free
-# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-#
-# @authors Andrew Dinn
-#
-# Heuristic Recovery After Delayed Commit in Single JVM
-#
-# This script automates testing of a specific recovery scenario for the
-# JBossTS XTS implementation of the WS-AT 1.1 protocol using byteman
-# rules. The scenario is as follows:
-#
-# AS boots
-# Client starts a WS-AT transaction
-# Client invokes web service 1
-# Web service 1 registers as participant P1
-# Client invokes web service 2
-# Web service 2 registers as participant P2
-# Client commits WS-AT transaction
-# Coordinator initiates commit of participant P1
-# ** Rule system intercepts commit and crahses JVM
-#
-# AS reboots
-# Recovery system starts after 2 minutes
-# Recovery system recreates PREPARED WS-AT transaction coordinator
-# Recovery system recreates participant stub for P1
-# ** Rule system adds countdown(2) for P1
-# Recovery system recreates participant stub for P2
-# ** Rule system adds countdown for P2
-# Recovery system calls replay of PREPARED transaction
-# ** Rule system traces PREPARED replay invocation
-# Coordinator sends commit to P1
-# ** Rule system decrements P1's countdown to 1
-#
-# P1 replies with committed
-# ** Rule system intercepts committed message handler and aborts thread
-#
-# Coordinator sends commit to P2
-# ** Rule system decrements P2's countdown to 1
-# (last 2 steps repeated while countdown is active)
-#
-# P2 replies with committed
-# ** Rule system intercepts committed message handler and aborts thread
-# (last 2 steps repeated while countdown is active)
-#
-# Coordinator times out commit and writes heuristic transaction to log
-# Recovery system sleeps
-
-# Recovery system restarts after 2 minutes
-# Recovery system recreates HEURISTIC WS-AT transaction coordinator
-# Recovery system detects existing participant stub for P1
-# Recovery system detects existing participant stub for P2
-#
-# Coordinator sends commit to P1
-# ** Rule system decrements P1's countdown to 0 and removes countdown
-# P1 replies with committed
-# Coordinator sends commit to P2
-# ** Rule system decrements P2's countdown to 0 and removes countdown
-# P2 replies with committed
-# Coordinator clears heuristic log record and copletes commit
-# ** Rule system detects completed commit and kills JVM
-#
-# The number of participants must be at least 2 but can actually be
-# more. One way of exercising the test is to start the AS and run the
-# XTS demo. It should crash at the point of commit. At reboot the
-# rest of the test shoudl run automatically and the server should be
-# killed after a the heuristic transaction is successfuly killed. The
-# console (or server) log should contain messages indicating replays of
-# the prepared and then the heuristic transactions and then a message
-# indicating that the heuristic transacton has committed.
-
-#######################################################################
-# This rule is triggered when a participant stub (CoordinatorEngine) is
-# created from details located in the log record. It adds a countdown
-# which is tripped each time a commit is tried on the participant.
-# While the countdown is active committed messages will be blocked.
-# Note that it calls isRecovered() to detect that the stub has been
-# recreated from the log.
-# The line number is the trigger point is after assignment of all
-# the instance's fields ensuring the rule can safely test them.
-
-RULE add coordinator engine countdown
-CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
-METHOD <init>(String, boolean, W3CEndpointReference, boolean, State)
-AFTER WRITE recovered
-BIND engine:CoordinatorEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF recovered
-DO debug("adding countdown for " + identifier),
-   addCountDown(identifier, 1)
-ENDRULE
-
-#######################################################################
-# This rule is triggered when a non-recovered participant stub
-# (CoordinatorEngine) is sent a commit message i.e. immediately
-# after a successful prepare. It exits the JVM, simulating a crash.
-# The trigger point is at the start of the method
-
-RULE kill JVM
-CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
-METHOD commit
-AT ENTRY
-BIND engine:CoordinatorEngine = $0,
-     recovered:boolean = engine.isRecovered(), 
-     identifier:String = engine.getId()
-IF (NOT recovered)
-   AND
-   debug("commit on non-recovered engine " + identifier)
-DO debug("!!!killing JVM!!!"),
-   killJVM()
-ENDRULE
-
-#######################################################################
-# This rule is triggered when a recovered participant stub
-# (CoordinatorEngine) is sent a commit message i.e. immediately
-# after a successful prepare. It decrements the countdown. First
-# time round this takes it from 1 to 0 but leaves it in place. Second
-# time round it removes it allowing committed messages to flow.
-# The trigger point is at the start of the method.
-
-RULE countdown at commit
-CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
-METHOD commit
-AT ENTRY
-BIND engine:CoordinatorEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF recovered
-   AND
-   debug("commit on recovered engine " + identifier)
-   AND
-   debug("counting down")
-   AND
-   countDown(identifier)
-DO debug("countdown completed for " + identifier)
-ENDRULE
-
-#######################################################################
-# This rule is triggered when a recovered participant stub
-# (CoordinatorEngine) is sent a committed message i.e. in the handler
-# thread which responds to a COMMITTED message from a participant.
-# If it detects a countdown registered using the participant id it
-# throws a runtime exception causing the thread to abort and stopping
-# delivery of the COMMITTED message. The trigger point is at the start
-# of the method.
-
-RULE kill committed thread
-CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
-METHOD committed(Notification, AddressingProperties, ArjunaContext)
-AT ENTRY
-BIND engine:CoordinatorEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF recovered
-   AND
-   debug("committed on recovered engine " + identifier)
-   AND
-   getCountDown(identifier)
-DO debug("!!!killing committed thread for " + identifier + "!!!"),
-   return
-ENDRULE
-
-#######################################################################
-# This rule is triggered when the recovery system finds the PREPARED
-# transaction in the log and reruns the phase 2 commit operation.
-# It prints a message which can be used to verify that the test has
-# worked correctly. The trigger point is at the call to phase2Commit.
-
-RULE trace prepared replay
-CLASS org.jboss.jbossts.xts.recovery.RecoverACCoordinator
-METHOD replayPhase2
-AT INVOKE phase2Commit
-BIND coordinator = $0,
-     uid : Uid = coordinator.identifier(),
-     status : int = coordinator.status()
-IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
-     OR
-     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
-DO debug("replaying commit for prepared transaction " + uid)
-ENDRULE
-
-#######################################################################
-# This rule is triggered when the recovery system finds the COMMITTED
-# transaction in the log and reruns the phase 2 commit operation.
-# It prints a message which can be used to verify that the test has
-# worked correctly. The trigger point is at the call to phase2Commit.
-
-RULE trace heuristic committed replay
-CLASS org.jboss.jbossts.xts.recovery.RecoverACCoordinator
-METHOD replayPhase2
-AT INVOKE phase2Commit
-BIND coordinator = $0,
-     uid : Uid = coordinator.identifier(),
-     status : int = coordinator.status()
-IF status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTED
-DO debug("replaying commit for heuristic committed transaction " + uid)
-ENDRULE
-
-#######################################################################
-# This rule is triggered when the recovery system deletes the COMMITTED
-# transaction from the log. It prints a message which can be used to
-# verify that the test has worked correctly. It also kills the JVM to
-# halt the test. The trigger point is on return from the call to
-# remove_committed, ensuring that the log is cleaned up before the exit
-# takes place
-
-RULE trace remove committed state
-CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
-METHOD updateState
-AFTER INVOKE remove_committed
-BIND action : BasicAction = $0,
-     uid  = action.get_uid()
-IF TRUE
-DO debug("removed committed transaction " + uid),
-   debug("!!!killing JVM!!!"),
-   killJVM()
-ENDRULE

Deleted: labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/HeuristicSaveAndRecover10.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/HeuristicSaveAndRecover10.txt	2009-10-20 12:36:47 UTC (rev 29688)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/HeuristicSaveAndRecover10.txt	2009-10-20 12:48:04 UTC (rev 29689)
@@ -1,234 +0,0 @@
-##############################################################################
-# JBoss, Home of Professional Open Source
-# Copyright 2008, Red Hat Middleware LLC, and individual contributors
-# by the @authors tag. See the copyright.txt in the distribution for a
-# full listing of individual contributors.
-#
-# This is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# This software is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this software; if not, write to the Free
-# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-#
-# @authors Andrew Dinn
-#
-# Heuristic Recovery After Delayed Commit in Single JVM
-#
-# This script automates testing of a specific recovery scenario for the
-# JBossTS XTS implementation of the WS-AT 1.0 protocol using byteman
-# rules. The scenario is as follows:
-#
-# AS boots
-# Client starts a WS-AT transaction
-# Client invokes web service 1
-# Web service 1 registers as participant P1
-# Client invokes web service 2
-# Web service 2 registers as participant P2
-# Client commits WS-AT transaction
-# Coordinator initiates commit of participant P1
-# ** Rule system intercepts commit and crahses JVM
-#
-# AS reboots
-# Recovery system starts after 2 minutes
-# Recovery system recreates PREPARED WS-AT transaction coordinator
-# Recovery system recreates participant stub for P1
-# ** Rule system adds countdown(2) for P1
-# Recovery system recreates participant stub for P2
-# ** Rule system adds countdown for P2
-# Recovery system calls replay of PREPARED transaction
-# ** Rule system traces PREPARED replay invocation
-# Coordinator sends commit to P1
-# ** Rule system decrements P1's countdown to 1
-#
-# P1 replies with committed
-# ** Rule system intercepts committed message handler and aborts thread
-#
-# Coordinator sends commit to P2
-# ** Rule system decrements P2's countdown to 1
-# (last 2 steps repeated while countdown is active)
-#
-# P2 replies with committed
-# ** Rule system intercepts committed message handler and aborts thread
-# (last 2 steps repeated while countdown is active)
-#
-# Coordinator times out commit and writes heuristic transaction to log
-# Recovery system sleeps
-
-# Recovery system restarts after 2 minutes
-# Recovery system recreates HEURISTIC WS-AT transaction coordinator
-# Recovery system detects existing participant stub for P1
-# Recovery system detects existing participant stub for P2
-#
-# Coordinator sends commit to P1
-# ** Rule system decrements P1's countdown to 0 and removes countdown
-# P1 replies with committed
-# Coordinator sends commit to P2
-# ** Rule system decrements P2's countdown to 0 and removes countdown
-# P2 replies with committed
-# Coordinator clears heuristic log record and copletes commit
-# ** Rule system detects completed commit and kills JVM
-#
-# The number of participants must be at least 2 but can actually be
-# more. One way of exercising the test is to start the AS and run the
-# XTS demo. It should crash at the point of commit. At reboot the
-# rest of the test shoudl run automatically and the server should be
-# killed after a the heuristic transaction is successfuly killed. The
-# console (or server) log should contain messages indicating replays of
-# the prepared and then the heuristic transactions and then a message
-# indicating that the heuristic transacton has committed.
-
-#######################################################################
-# This rule is triggered when a participant stub (CoordinatorEngine) is
-# created from details located in the log record. It adds a countdown
-# which is tripped each time a commit is tried on the participant.
-# While the countdown is active committed messages will be blocked.
-# Note that it calls isRecovered() to detect that the stub has been
-# recreated from the log.
-# The trigger point follows all the field assignments, ensuring that they
-# can be read by the rule.
-
-RULE add coordinator engine countdown
-CLASS com.arjuna.wst.messaging.engines.CoordinatorEngine
-METHOD <init>(String, boolean, EndpointReferenceType, boolean, State)
-AFTER WRITE recovered
-BIND engine:CoordinatorEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF recovered
-DO debug("adding countdown for " + identifier),
-   addCountDown(identifier, 1)
-ENDRULE
-
-#######################################################################
-# This rule is triggered when a non-recovered participant stub
-# (CoordinatorEngine) is sent a commit message i.e. immediately
-# after a successful prepare. It exits the JVM, simulating a crash.
-# The trigger point is the first line.
-
-RULE kill JVM
-CLASS com.arjuna.wst.messaging.engines.CoordinatorEngine
-METHOD commit
-AT ENTRY
-BIND engine:CoordinatorEngine = $0,
-     recovered:boolean = engine.isRecovered(), 
-     identifier:String = engine.getId()
-IF (NOT recovered)
-   AND
-   debug("commit on non-recovered engine " + identifier)
-DO debug("!!!killing JVM!!!"),
-   killJVM()
-ENDRULE
-
-#######################################################################
-# This rule is triggered when a recovered participant stub
-# (CoordinatorEngine) is sent a commit message i.e. immediately
-# after a successful prepare. It decrements the countdown. First
-# time round this takes it from 1 to 0 but leaves it in place. Second
-# time round it removes it allowing committed messages to flow.
-# The trigger point is the first line.
-
-RULE countdown at commit
-CLASS com.arjuna.wst.messaging.engines.CoordinatorEngine
-METHOD commit
-AT ENTRY
-BIND engine:CoordinatorEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF recovered
-   AND
-   debug("commit on recovered engine " + identifier)
-   AND
-   debug("counting down")
-   AND
-   countDown(identifier)
-DO debug("countdown completed for " + identifier)
-ENDRULE
-
-#######################################################################
-# This rule is triggered when a recovered participant stub
-# (CoordinatorEngine) is sent a committed message i.e. in the handler
-# thread which responds to a COMMITTED message from a participant.
-# If it detects a countdown registered using the participant id it
-# throws a runtime exception causing the thread to abort and stopping
-# delivery of the COMMITTED message. The trigger point is the first
-# line.
-
-RULE kill committed thread
-CLASS com.arjuna.wst.messaging.engines.CoordinatorEngine
-METHOD committed(NotificationType, AddressingContext, ArjunaContext)
-AT ENTRY
-BIND engine:CoordinatorEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF recovered
-   AND
-   debug("committed on recovered engine " + identifier)
-   AND
-   getCountDown(identifier)
-DO debug("!!!killing committed thread for " + identifier + "!!!"),
-   return
-ENDRULE
-
-#######################################################################
-# This rule is triggered when the recovery system finds the PREPARED
-# transaction in the log and reruns the phase 2 commit operation.
-# It prints a message which can be used to verify that the test has
-# worked correctly. The trigger point is the call to phase2Commit.
-
-RULE trace prepared replay
-CLASS org.jboss.jbossts.xts.recovery.RecoverACCoordinator
-METHOD replayPhase2
-AT INVOKE phase2Commit
-BIND coordinator = $0,
-     uid : Uid = coordinator.identifier(),
-     status : int = coordinator.status()
-IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
-     OR
-     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
-DO debug("replaying commit for prepared transaction " + uid)
-ENDRULE
-
-#######################################################################
-# This rule is triggered when the recovery system finds the COMMITTED
-# transaction in the log and reruns the phase 2 commit operation.
-# It prints a message which can be used to verify that the test has
-# worked correctly. The trigger point is the call to phase2Commit.
-
-RULE trace heuristic committed replay
-CLASS org.jboss.jbossts.xts.recovery.RecoverACCoordinator
-METHOD replayPhase2
-AT INVOKE phase2Commit
-BIND coordinator = $0,
-     uid : Uid = coordinator.identifier(),
-     status : int = coordinator.status()
-IF status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTED
-DO debug("replaying commit for heuristic committed transaction " + uid)
-ENDRULE
-
-#######################################################################
-# This rule is triggered when the recovery system deletes the COMMITTED
-# transaction from the log. It prints a message which can be used to
-# verify that the test has worked correctly. It also kills the JVM to
-# halt the test. The trigger point is after return from the call to
-# remove_committed, ensuring that the lgo is cleaned up before exit.
-
-RULE trace remove committed state
-CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
-METHOD updateState
-AFTER INVOKE remove_committed
-BIND action : BasicAction = $0,
-     uid  = action.get_uid()
-IF TRUE
-DO debug("removed committed transaction " + uid),
-   debug("!!!killing JVM!!!"),
-   killJVM()
-ENDRULE

Deleted: labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/ParticipantCrashAndRecover.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/ParticipantCrashAndRecover.txt	2009-10-20 12:36:47 UTC (rev 29688)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/ParticipantCrashAndRecover.txt	2009-10-20 12:48:04 UTC (rev 29689)
@@ -1,176 +0,0 @@
-##############################################################################
-# JBoss, Home of Professional Open Source
-# Copyright 2008, Red Hat Middleware LLC, and individual contributors
-# by the @authors tag. See the copyright.txt in the distribution for a
-# full listing of individual contributors.
-#
-# This is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# This software is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this software; if not, write to the Free
-# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-#
-# @authors Andrew Dinn
-#
-# Participant Recovery with Remote Coordinator
-#
-# This script automates testing of a specific recovery scenario for the
-# JBossTS XTS implementation of the WS-AT 1.1 protocol using byteman
-# rules. The scenario is as follows:
-#
-# AS1 boots
-# AS2 boots
-# AS1 Client starts a WS-AT transaction talking to coordinator in AS2
-# AS1 Client invokes web service 1
-# AS1 Web service 1 registers as participant P1
-# AS1 Client invokes web service 2
-# AS1 Web service 2 registers as participant P2
-# AS1 Client commits WS-AT transaction
-#
-# AS2 Coordinator initiates commit of participant P1
-# AS2 Coordinator sends commit to P1
-#
-# AS1 P1 receives commit
-# ** AS1 Rule system intercepts commit and crashes JVM
-#
-# AS2 Coordinator attempts to resend message
-# ** AS2 Rule system suspends coordinator waiting on incoming prepared
-#    message from P1
-#    (commit messages continue to be resent in the meantime)
-#
-# AS1 reboots
-# AS1 Recovery system starts after 2 minutes
-# AS1 Recovery system recreates PREPARED WS-AT participant P1
-# ** AS1 Rule system traces recreate
-# AS1 Participant P1 resends prepared
-# AS1 Participant P1 receives commit for P1
-# AS1 Participant P1 sends committed
-#
-# AS2 Participant stub receives committed message for P1
-# ** AS2 Rule system signals coordinator clearing wait
-# ** AS2 rule system traces receipt of committed message for P1
-#
-# AS2 Coordinator detects committed from P1
-# AS2 Coordinator sends commit for P2
-# AS2 Coordinator receives committed from P2
-# AS2 Coordinator completes transaction
-# ** AS2 Rule system traces successful completion
-#
-# One way of exercising the test is to start the ASes and run the XTS
-# demo in one AS using a remote coordinator in the othher AS. It should
-# crash at the point of commit. At reboot the rest of the test should
-# run automatically and the server should be killed after a the
-# transaction is successfuly terminated. The console (or server)
-# log should contain messages indicating replays of the prepared and
-# then the heuristic transactions and then a message indicating that the
-# heuristic transacton has committed.that the participant server (AS1)
-# has crashed and then restarted.
-
-#
-# !!! N.B. this test currently fails because JBossWS Native fails to cope
-# !!! with requests for services while they are bootstrapping
-#
-
-######################################################################
-# AS1 Rule set
-#######################################################################
-# This rule is triggered in the AS1 when a non-recovered WS-AT
-# participant receives a commit message. It causes the JVM to crash.
-# The trigger point is the start of the method.
-
-RULE crash unrecovered participant at commit
-CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
-METHOD commit
-AT ENTRY
-BIND engine:ParticipantEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF (NOT recovered)
-   AND
-   debug("commit on non-recovered participant engine " + identifier)
-DO debug("!!!killing JVM!!!"),
-   killJVM()
-ENDRULE
-
-#######################################################################
-# This rule is triggered in the AS1 when a recovered WS-AT participant
-# is recreated from the log. It traces the call to allow success of the
-# test to be detected.
-# The trigger point is the end of the constructor so that the rule can
-# safely read all the fields.
-
-RULE trace recovered participant recreate
-CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
-METHOD <init>(Participant, id, State, W3CEndpointReference, boolean)
-AFTER WRITE persisted
-BIND engine:ParticipantEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF recovered
-DO debug("recreated recovered participant engine " + identifier)
-ENDRULE
-
-
-######################################################################
-# AS2 Rule set
-######################################################################
-# This rule is triggered in AS2 when a participant stub
-# (CoordinatorEngine) first posts a commit message to the participant.
-# The coordinator thread suspends until a committed message is received
-# from the participant. This ensures that it waits until AS1
-# has restarted allowing the transaction to then complete. The
-# condition tests whether a flag with key "firstCommit" has been set.
-# By default this is clear so the condition is true first time the
-# rule is called. The action sets te flag causing the condition to
-# evaluate to false on subsequent commit calls.
-# The trigger point is just before calling waitForState.
-
-RULE suspend coordinator after sending first commit
-CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
-METHOD commit
-LINE 330
-BIND engine:CoordinatorEngine = $0,
-     identifier:String = engine.getId()
-IF (NOT flagged("firstCommit"))
-DO debug("coordinator waiting for participant to resend prepare" + identifier),
-   flag("firstCommit"),
-   waitFor(identifier)
-ENDRULE
-
-#######################################################################
-
-# This rule is triggered when a committed message is received from P1.
-# This indicates that the participant has been recreated and
-# successfully responded to a commit message after reboot of AS1. The
-# rule uses a call to signal to wake up the coordinator which was
-# suspended when the first commit was sent. This call only returns true
-# if the identifier is for P1 and the coordinator has not already been
-# signalled. Note that the call to signal is made in the condition to
-# avoid a race between threads handling successive committed messages.
-# If instead the condition called waiting() and the action called
-# signal() then, depending upon scheduling, both threads might find the
-# condition to be true before one of them could execute signal().
-# Although this would be harmless in this case it could be significant
-# when using other rules.
-# The triogger point is at the sttart of the method.
-
-RULE signal waiting coordinator
-CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
-METHOD committed
-AT ENTRY
-BIND engine : CoordinatorEngine = $0,
-     identifier:String = engine.getId()
-IF debug("received committed for participant " + identifier)
-   AND
-   signal(identifier)
-DO debug("signalled coordinator waiting on " + identifier)
-ENDRULE

Deleted: labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/ParticipantCrashAndRecover10.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/ParticipantCrashAndRecover10.txt	2009-10-20 12:36:47 UTC (rev 29688)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/dd/scripts/ParticipantCrashAndRecover10.txt	2009-10-20 12:48:04 UTC (rev 29689)
@@ -1,174 +0,0 @@
-##############################################################################
-# JBoss, Home of Professional Open Source
-# Copyright 2008, Red Hat Middleware LLC, and individual contributors
-# by the @authors tag. See the copyright.txt in the distribution for a
-# full listing of individual contributors.
-#
-# This is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# This software is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this software; if not, write to the Free
-# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-#
-# @authors Andrew Dinn
-#
-# Participant Recovery with Remote Coordinator
-#
-# This script automates testing of a specific recovery scenario for the
-# JBossTS XTS implementation of the WS-AT 1.0 protocol using byteman
-# rules. The scenario is as follows:
-#
-# AS1 boots
-# AS2 boots
-# AS1 Client starts a WS-AT transaction talking to coordinator in AS2
-# AS1 Client invokes web service 1
-# AS1 Web service 1 registers as participant P1
-# AS1 Client invokes web service 2
-# AS1 Web service 2 registers as participant P2
-# AS1 Client commits WS-AT transaction
-#
-# AS2 Coordinator initiates commit of participant P1
-# AS2 Coordinator sends commit to P1
-#
-# AS1 P1 receives commit
-# ** AS1 Rule system intercepts commit and crashes JVM
-#
-# AS2 Coordinator attempts to resend message
-# ** AS2 Rule system suspends coordinator waiting on incoming prepared
-#    message from P1
-#    (commit messages continue to be resent in the meantime)
-#
-# AS1 reboots
-# AS1 Recovery system starts after 2 minutes
-# AS1 Recovery system recreates PREPARED WS-AT participant P1
-# ** AS1 Rule system traces recreate
-# AS1 Participant P1 resends prepared
-# AS1 Participant P1 receives commit for P1
-# AS1 Participant P1 sends committed
-#
-# AS2 Participant stub receives committed message for P1
-# ** AS2 Rule system signals coordinator clearing wait
-# ** AS2 rule system traces receipt of committed message for P1
-#
-# AS2 Coordinator detects committed from P1
-# AS2 Coordinator sends commit for P2
-# AS2 Coordinator receives committed from P2
-# AS2 Coordinator completes transaction
-# ** AS2 Rule system traces successful completion
-#
-# One way of exercising the test is to start the ASes and run the XTS
-# demo in one AS using a remote coordinator in the othher AS. It should
-# crash at the point of commit. At reboot the rest of the test should
-# run automatically and the server should be killed after a the
-# transaction is successfuly terminated. The console (or server)
-# log should contain messages indicating replays of the prepared and
-# then the heuristic transactions and then a message indicating that the
-# heuristic transacton has committed.that the participant server (AS1)
-# has crashed and then restarted.
-
-######################################################################
-# AS1 Rule set
-#######################################################################
-# This rule is triggered in the AS1 when a non-recovered WS-AT
-# participant receives a commit message. It causes the JVM to crash.
-# The trigger point is at the start of the call.
-
-RULE crash unrecovered participant at commit
-CLASS com.arjuna.wst.messaging.engines.ParticipantEngine
-METHOD commit
-AT ENTRY
-BIND engine:ParticipantEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF (NOT recovered)
-   AND
-   debug("commit on non-recovered participant engine " + identifier)
-DO debug("!!!killing JVM!!!"),
-   killJVM()
-ENDRULE
-
-#######################################################################
-# This rule is triggered in the AS1 when a recovered WS-AT participant
-# is recreated from the log. It traces the call to allow success of the
-# test to be detected.
-# The trigger point is at teh end of the field writes so that the rule
-# can safely read them.
-
-RULE trace recovered participant recreate
-CLASS com.arjuna.wst.messaging.engines.ParticipantEngine
-METHOD <init>(Participant, String, State, EndpointReferenceType, boolean)
-AFETR WRITE persisted
-BIND engine:ParticipantEngine = $0,
-     recovered:boolean = engine.isRecovered(),
-     identifier:String = engine.getId()
-IF recovered
-DO debug("recreated recovered participant engine " + identifier)
-ENDRULE
-
-
-######################################################################
-# AS2 Rule set
-######################################################################
-# This rule is triggered in AS2 when a participant stub
-# (CoordinatorEngine) first posts a commit message to the participant.
-# The coordinator thread suspends until a committed message is received
-# from the participant. This ensures that it waits until AS1
-# has restarted allowing the transaction to then complete. The
-# condition tests whether a flag with key "firstCommit" has been set.
-# By default this is clear so the condition is true first time the
-# rule is called. The action sets te flag causing the condition to
-# evaluate to false on subsequent commit calls.
-# The triggger point is immediately before the call to waitForState.
-
-RULE suspend coordinator after sending first commit
-CLASS com.arjuna.wst.messaging.engines.CoordinatorEngine
-METHOD commit
-AT INVOKE waitForState
-BIND engine:CoordinatorEngine = $0,
-     identifier:String = engine.getId()
-IF (NOT flagged("firstCommit"))
-DO debug("coordinator waiting for participant to resend prepare" + identifier),
-   flag("firstCommit"),
-   waitFor(identifier),
-   debug("coordinator finished waiting for participant to resend prepare" + identifier)
-ENDRULE
-
-#######################################################################
-# This rule is triggered when a committed message is received from P1.
-# This indicates that the participant has been recreated and
-# successfully responded to a commit message after reboot of AS1. The
-# rule uses a call to signal to wake up the coordinator which was
-# suspended when the first commit was sent. This call only returns true
-# if the identifier is for P1 and the coordinator has not already been
-# signalled. Note that the call to signal is made in the condition to
-# avoid a race between threads handling successive committed messages.
-# If instead the condition called waiting() and the action called
-# signal() then, depending upon scheduling, both threads might find the
-# condition to be true before one of them could execute signal().
-# Although this would be harmless in this case it could be significant
-# when using other rules.
-# The trigger point is the start of th method.
-
-RULE signal waiting coordinator
-CLASS com.arjuna.wst.messaging.engines.CoordinatorEngine
-METHOD committed
-AT ENTRY
-BIND engine : CoordinatorEngine = $0,
-     identifier:String = engine.getId()
-IF debug("received committed for participant " + identifier)
-   AND
-   (waiting(identifier)
-    AND
-    signalWake(identifier))
-DO debug("signalled coordinator waiting on " + identifier)
-ENDRULE
-

Added: labs/jbosstm/workspace/adinn/byteman/trunk/sample/build.xml
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/sample/build.xml	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/sample/build.xml	2009-10-20 12:48:04 UTC (rev 29689)
@@ -0,0 +1,86 @@
+<!--
+  JBoss, Home of Professional Open Source
+  Copyright 2009, Red Hat Middleware LLC, and individual contributors
+  as indicated by the @author tags.
+  See the copyright.txt in the distribution for a full listing
+  of individual contributors.
+  This copyrighted material is made available to anyone wishing to use,
+  modify, copy, or redistribute it subject to the terms and conditions
+  of the GNU General Public License, v. 2.0.
+  This program is distributed in the hope that it will be useful, but WITHOUT A
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+  You should have received a copy of the GNU General Public License,
+  v. 2.0 along with this distribution; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+  MA  02110-1301, USA.
+
+  (C) 2009
+  @author JBoss Inc.
+-->
+
+<project name="byteman-sample" default="install" basedir=".">
+
+    <!-- n.b. we assume the byteman jar has been installed in the parent tree -->
+    <property name="byteman.jar" value="byteman.jar"/>
+    <property name="byteman.sample.jar" value="byteman-sample.jar"/>
+
+    <!-- paths for local build -->
+    <property name="src.dir"           value="src"/>
+    <property name="scripts.dir"       value="scripts"/>
+    <property name="build.dir"         value="build"/>
+    <property name="build.classes.dir" value="${build.dir}/classes"/>
+    <property name="build.lib.dir"     value="${build.dir}/lib"/>
+
+    <!-- paths for installation into parent install tree -->
+    <property name="parent.install.dir" value="../install"/>
+    <property name="install.sample.dir" value="${parent.install.dir}/sample"/>
+    <property name="install.sample.lib.dir" value="${install.sample.dir}/lib"/>
+    <property name="install.sample.scripts.dir" value="${install.sample.dir}/scripts"/>
+
+    <!-- enable debugging of compiled code including refs to local vars -->
+    <property name="javac.debug" value="on"/>
+
+    <target name="init">
+        <delete dir="${build.dir}"/>
+        <mkdir dir="${build.dir}"/>
+        <mkdir dir="${build.classes.dir}"/>
+        <mkdir dir="${build.lib.dir}"/>
+    </target>
+
+    <target name="compile" depends="init">
+        <javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="${javac.debug}">
+            <classpath>
+                <pathelement location="${parent.install.dir}/lib/${byteman.jar}"/>
+            </classpath>
+        </javac>
+    </target>
+
+    <target name="jar" depends="compile">
+        <jar jarfile="${build.lib.dir}/${byteman.sample.jar}">
+            <fileset dir="${build.classes.dir}" includes="**/*"/>
+        </jar>
+   </target>
+
+    <target name="init-install">
+        <delete dir="${install.sample.dir}" />
+        <mkdir dir="${install.sample.dir}" />
+        <mkdir dir="${install.sample.lib.dir}" />
+        <mkdir dir="${install.sample.scripts.dir}" />
+   </target>
+
+    <target name="install" depends="jar, init-install">
+        <copy todir="${install.sample.lib.dir}" file="${build.lib.dir}/${byteman.sample.jar}"/>
+        <copy todir="${install.sample.scripts.dir}">
+            <fileset dir="${scripts.dir}" includes="*.txt *.bms"/>
+        </copy>
+   </target>
+
+    <target name="clean">
+        <delete dir="${build.dir}"/>
+     </target>
+
+    <target name="spotless">
+        <delete dir="${install.sample.dir}"/>
+     </target>
+</project>

Added: labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/ClassLoadMonitor.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/ClassLoadMonitor.txt	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/ClassLoadMonitor.txt	2009-10-20 12:48:04 UTC (rev 29689)
@@ -0,0 +1,68 @@
+########################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# by the @authors tag. See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this software; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+#
+# @authors Andrew Dinn
+#
+# ClassLoadMonitor
+#
+# A byteman script which prints a stacktrace whenever ClassLoader.defineClass
+# is called.
+#
+# In order for this to run successfully the byteman jar and the byteman
+# samples jar need to be added to the bootstrap classpath using the
+# boot option to the -javaagent JVM command line argument. The script may
+# be loaded either at JVM startup, as shown below, or submitted dynamically
+# via the byteman listener (this requires use of the listener:true option)
+#
+# to use ths script with java program org.my.App execute the following commands
+#
+#  -- set the directory in which byteman has been installed
+#  BYTEMAN_HOME= ...
+#
+#   -- we need to add byteman jar and samples jar to the boot path
+#   BYTEMAN_JAR=${BYTEMAN_HOME}/lib/byteman.jar
+#   SAMPLE_JAR=${BYTEMAN_HOME}/sample/lib/byteman-samples.jar
+#
+#   -- identify this script
+#   SCRIPT={BYTEMAN_HOME}/sample/scripts/ClassLoadMonitor.txt
+#
+#   -- setting this property enables transformation of java.lang classes!
+#   ALLOW_JAVA_LANG=-Dorg.jboss.byteman.quodlibet
+#
+#   -- compose the javaagent options and pass to the java command
+#   BYTEMAN_OPTS=-javaagent:${BYTEMAN_JAR}=script:${SCRIPT},boot:${BYTEMAN_JAR},boot:${SAMPLE_JAR}
+#   java ${ALLOW_JAVA_LANG} ${BYTEMAN_OPTS} org.my.App
+#
+#
+
+########################################################################
+#
+# Rule to trace class load
+#
+
+RULE ClassLoadMonitor trace create
+CLASS java.lang.ClassLoader
+METHOD defineClass(String, byte[], int, int, ProtectionDomain)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT EXIT
+IF TRUE
+DO traceStack("*** Called defineClass(" + $1 + ") in thread " + Thread.currentThread().getName() + "\n")
+ENDRULE

Added: labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/FileMonitor.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/FileMonitor.txt	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/FileMonitor.txt	2009-10-20 12:48:04 UTC (rev 29689)
@@ -0,0 +1,82 @@
+########################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# by the @authors tag. See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this software; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+#
+# @authors Andrew Dinn
+#
+# FileMonitor
+#
+# A byteman script which prints a stack trace whenever a file input or
+# output stream is created from a File instance or subsequently closed.
+#
+# In order for this to run successfully the byteman jar and the byteman
+# samples jar need to be added to the bootstrap classpath using the
+# boot option to the -javaagent JVM command line argument. The script may
+# be loaded either at JVM startup, as shown below, or submitted dynamically
+# via the byteman listener (this requires use of the listener:true option)
+#
+# to use ths script with java program org.my.App execute the following commands
+#
+#  -- set the directory in which byteman has been installed
+#  BYTEMAN_HOME= ...
+#
+#   -- we need to add byteman jar and samples jar to the boot path
+#   BYTEMAN_JAR=${BYTEMAN_HOME}/lib/byteman.jar
+#   SAMPLE_JAR=${BYTEMAN_HOME}/sample/lib/byteman-samples.jar
+#
+#   -- identify this script
+#   SCRIPT={BYTEMAN_HOME}/sample/scripts/FileMonitor.txt
+#
+#   -- setting this property enables transformation of java.lang classes!
+#   ALLOW_JAVA_LANG=-Dorg.jboss.byteman.quodlibet
+#
+#   -- compose the javaagent options and pass to the java command
+#   BYTEMAN_OPTS=-javaagent:${BYTEMAN_JAR}=script:${SCRIPT},boot:${BYTEMAN_JAR},boot:${SAMPLE_JAR}
+#   java ${ALLOW_JAVA_LANG} ${BYTEMAN_OPTS} org.my.App
+#
+#
+
+########################################################################
+#
+# Rule to trace create of file input stream
+#
+
+RULE FileMonitor trace FileInputStream create
+CLASS java.io.FileInputStream
+METHOD <init>(java.io.File)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT RETURN
+IF TRUE
+DO traceStack("*** Opened " + $1.getPath() + " for read in thread " + Thread.currentThread().getName() + "\n")
+ENDRULE
+
+########################################################################
+#
+# Rule to trace create of file output stream
+#
+
+RULE FileMonitor trace FileOutputStream create
+CLASS java.io.FileOutputStream
+METHOD <init>(java.io.File)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT RETURN
+IF TRUE
+DO traceStack("*** Opened " + $1.getPath() + " for write in thread " + Thread.currentThread().getName() + "\n")
+ENDRULE

Added: labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/FinalizeMonitor.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/FinalizeMonitor.txt	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/FinalizeMonitor.txt	2009-10-20 12:48:04 UTC (rev 29689)
@@ -0,0 +1,66 @@
+########################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# by the @authors tag. See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this software; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+#
+# @authors Andrew Dinn
+#
+# FinalizeMonitor
+#
+# A byteman script which tarecs calls to Object.finalize().
+#
+# In order for this to run successfully the byteman jar and the byteman
+# samples jar need to be added to the bootstrap classpath using the
+# boot option to the -javaagent JVM command line argument. The script may
+# be loaded either at JVM startup, as shown below, or submitted dynamically
+# via the byteman listener (this requires use of the listener:true option)
+#
+# to use ths script with java program org.my.App execute the following commands
+#
+#  -- set the directory in which byteman has been installed
+#  BYTEMAN_HOME= ...
+#
+#   -- we need to add byteman jar and samples jar to the boot path
+#   BYTEMAN_JAR=${BYTEMAN_HOME}/lib/byteman.jar
+#   SAMPLE_JAR=${BYTEMAN_HOME}/sample/lib/byteman-samples.jar
+#
+#   -- identify this script
+#   SCRIPT={BYTEMAN_HOME}/sample/scripts/FinalizeMonitor.txt
+#
+#   -- setting this property enables transformation of java.lang classes!
+#   ALLOW_JAVA_LANG=-Dorg.jboss.byteman.quodlibet
+#
+#   -- compose the javaagent options and pass to the java command
+#   BYTEMAN_OPTS=-javaagent:${BYTEMAN_JAR}=script:${SCRIPT},boot:${BYTEMAN_JAR},boot:${SAMPLE_JAR}
+#   java ${ALLOW_JAVA_LANG} ${BYTEMAN_OPTS} org.my.App
+#
+#
+
+########################################################################
+#
+# Rule to trace calls to Object.finalize()
+#
+
+RULE FinalizeMonitor trace finalize
+CLASS java.lang.Object
+METHOD finalize
+AT RETURN
+IF TRUE
+DO traceln("finalizing " + $0)
+ENDRULE

Added: labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/SocketMonitor.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/SocketMonitor.txt	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/SocketMonitor.txt	2009-10-20 12:48:04 UTC (rev 29689)
@@ -0,0 +1,289 @@
+########################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# by the @authors tag. See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this software; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+#
+# @authors Andrew Dinn
+#
+# SocketMonitor
+#
+# A byteman script which traces thread creation, start, run and exit
+#
+# In order for this to run successfully the byteman jar and the byteman
+# samples jar need to be added to the bootstrap classpath using the
+# boot option to the -javaagent JVM command line argument. The script may
+# be loaded either at JVM startup, as shown below, or submitted dynamically
+# via the byteman listener (this requires use of the listener:true option)
+#
+# to use ths script with java program org.my.App execute the following commands
+#
+#  -- set the directory in which byteman has been installed
+#  BYTEMAN_HOME= ...
+#
+#   -- we need to add byteman jar and samples jar to the boot path
+#   BYTEMAN_JAR=${BYTEMAN_HOME}/lib/byteman.jar
+#   SAMPLE_JAR=${BYTEMAN_HOME}/sample/lib/byteman-samples.jar
+#
+#   -- identify this script
+#   SCRIPT={BYTEMAN_HOME}/sample/scripts/SocketMonitor.txt
+#
+#   -- setting this property enables transformation of java.lang classes!
+#   ALLOW_JAVA_LANG=-Dorg.jboss.byteman.quodlibet
+#
+#   -- compose the javaagent options and pass to the java command
+#   BYTEMAN_OPTS=-javaagent:${BYTEMAN_JAR}=script:${SCRIPT},boot:${BYTEMAN_JAR},boot:${SAMPLE_JAR}
+#   java ${ALLOW_JAVA_LANG} ${BYTEMAN_OPTS} org.my.App
+#
+#
+
+########################################################################
+#
+# Rule to trace ServerSocket creation
+#
+
+RULE ServerSocket trace create
+CLASS java.net.ServerSocket
+METHOD <init>(int, int, InetAddress)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT EXIT
+IF TRUE
+DO traceStack("*** server create " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace ServerSocket creation failed with invalid port
+#
+
+RULE ServerSocket trace create failed with invalid port
+CLASS java.net.ServerSocket
+METHOD <init>(int, int, InetAddress)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT THROW 1
+IF TRUE
+DO traceStack("*** server create failed with invalid port " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace ServerSocket creation failed with security exception
+#
+
+RULE ServerSocket trace create failed with security exception
+CLASS java.net.ServerSocket
+METHOD <init>(int, int, InetAddress)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT THROW 2
+IF TRUE
+DO traceStack("*** server create failed with security exception " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace ServerSocket creation failed with IOException
+#
+
+RULE ServerSocket trace create failed with IOException
+CLASS java.net.ServerSocket
+METHOD <init>(int, int, InetAddress)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT THROW 3
+IF TRUE
+DO traceStack("*** server create failed with IOException " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace ServerSocket bind
+#
+
+RULE ServerSocket trace bind
+CLASS java.net.ServerSocket
+METHOD bind(SocketAddress, int)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT EXIT
+IF TRUE
+DO traceStack("*** server bind " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace ServerSocket accept
+#
+
+RULE ServerSocket trace accept
+CLASS java.net.ServerSocket
+METHOD accept()
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT EXIT
+IF TRUE
+DO traceStack("*** server accept " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace ServerSocket close
+#
+# the AT CALL close location means we do not trace calls to already closed sockets
+#
+
+RULE ServerSocket trace close
+CLASS java.net.ServerSocket
+METHOD close
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT CALL close
+IF TRUE
+DO traceStack("*** server close " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace socket create
+#
+
+RULE Socket trace create
+CLASS java.net.Socket
+METHOD <init>(SocketAddress, SocketAddress, boolean)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT EXIT
+IF TRUE
+DO traceStack("*** create " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace socket create failed with invalid address
+#
+
+RULE Socket trace create failed with invalid address
+CLASS java.net.Socket
+METHOD <init>(SocketAddress, SocketAddress, boolean)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT THROW 1
+IF TRUE
+DO traceStack("*** create failed with invalid address exception " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace socket create failed with IOException
+#
+
+RULE Socket trace create failed with IOException
+CLASS java.net.Socket
+METHOD <init>(SocketAddress, SocketAddress, boolean)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT THROW 2
+IF TRUE
+DO traceStack("*** create failed with IOException " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace socket bind
+#
+
+RULE Socket trace bind
+CLASS java.net.Socket
+METHOD bind(SocketAddress)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT EXIT
+IF TRUE
+DO traceStack("*** bind " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace socket connect
+#
+
+RULE Socket trace connect
+CLASS java.net.Socket
+METHOD connect(SocketAddress, int)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT EXIT
+IF TRUE
+DO traceStack("*** connect " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace socket close
+#
+# the AT CALL close location means we do not trace calls to already closed sockets
+#
+
+RULE Socket trace close
+CLASS java.net.Socket
+METHOD close()
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT CALL close
+IF TRUE
+DO traceStack("*** close " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# The Sun code overrides the standard socket methdos without calling
+# super() so we need to add special case rules for the overriding
+# methods.
+
+########################################################################
+#
+# Rule to trace socket bind for Sun's socket impl
+#
+
+RULE Socket trace bind  for Sun's socket impl
+CLASS sun.nio.ch.ServerSocketChannelImpl
+METHOD bind(SocketAddress)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT EXIT
+IF TRUE
+DO traceStack("*** bind for Sun's socket impl " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace socket connect for Sun's socket impl
+#
+
+RULE Socket trace connect for Sun's socket impl
+CLASS sun.nio.ch.ServerSocketChannelImpl
+METHOD connect(SocketAddress, int)
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT EXIT
+IF TRUE
+DO traceStack("*** connect for Sun's socket impl " + $0, 15)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace socket close for Sun's socket impl
+#
+# the AT CALL close location means we do not trace calls to already closed sockets
+#
+
+RULE Socket trace close for Sun's socket impl
+CLASS sun.nio.ch.ServerSocketChannelImpl
+METHOD close()
+HELPER org.jboss.byteman.sample.helper.StackTraceHelper
+AT CALL close
+IF TRUE
+DO traceStack("*** close for Sun's socket impl " + $0, 15)
+ENDRULE

Added: labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/ThreadMonitor.txt
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/ThreadMonitor.txt	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/sample/scripts/ThreadMonitor.txt	2009-10-20 12:48:04 UTC (rev 29689)
@@ -0,0 +1,95 @@
+########################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# by the @authors tag. See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this software; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+#
+# @authors Andrew Dinn
+#
+# ThreadMonitor
+#
+# A byteman script which traces thread creation, start, run and exit
+#
+# In order for this to run successfully the byteman jar and the byteman
+# samples jar need to be added to the bootstrap classpath using the
+# boot option to the -javaagent JVM command line argument. The script may
+# be loaded either at JVM startup, as shown below, or submitted dynamically
+# via the byteman listener (this requires use of the listener:true option)
+#
+# to use ths script with java program org.my.App execute the following commands
+#
+#  -- set the directory in which byteman has been installed
+#  BYTEMAN_HOME= ...
+#
+#   -- we need to add byteman jar and samples jar to the boot path
+#   BYTEMAN_JAR=${BYTEMAN_HOME}/lib/byteman.jar
+#   SAMPLE_JAR=${BYTEMAN_HOME}/sample/lib/byteman-samples.jar
+#
+#   -- identify this script
+#   SCRIPT={BYTEMAN_HOME}/sample/scripts/ThreadMonitor.txt
+#
+#   -- setting this property enables transformation of java.lang classes!
+#   ALLOW_JAVA_LANG=-Dorg.jboss.byteman.quodlibet
+#
+#   -- compose the javaagent options and pass to the java command
+#   BYTEMAN_OPTS=-javaagent:${BYTEMAN_JAR}=script:${SCRIPT},boot:${BYTEMAN_JAR},boot:${SAMPLE_JAR}
+#   java ${ALLOW_JAVA_LANG} ${BYTEMAN_OPTS} org.my.App
+#
+#
+
+########################################################################
+#
+# Rule to trace thread creation
+#
+
+RULE ThreadMonitor trace create
+CLASS java.lang.Thread
+METHOD <init>
+HELPER org.jboss.byteman.sample.helper.ThreadMonitorHelper
+AT EXIT
+IF TRUE
+DO traceCreate($0)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace thread start
+#
+
+RULE ThreadMonitor trace start
+CLASS java.lang.Thread
+METHOD start
+HELPER org.jboss.byteman.sample.helper.ThreadMonitorHelper
+AT EXIT
+IF TRUE
+DO traceStart($0)
+ENDRULE
+
+########################################################################
+#
+# Rule to trace thread exit
+#
+
+RULE ThreadMonitor trace exit
+CLASS java.lang.Thread
+METHOD exit
+HELPER org.jboss.byteman.sample.helper.ThreadMonitorHelper
+AT ENTRY
+IF TRUE
+DO traceExit($0)
+ENDRULE

Added: labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/helper/StackTraceHelper.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/helper/StackTraceHelper.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/helper/StackTraceHelper.java	2009-10-20 12:48:04 UTC (rev 29689)
@@ -0,0 +1,416 @@
+package org.jboss.byteman.sample.helper;
+
+import org.jboss.byteman.rule.helper.Helper;
+import org.jboss.byteman.rule.Rule;
+import org.jboss.byteman.rule.exception.ExecuteException;
+
+import java.util.Map;
+import java.lang.management.ThreadMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * Helper class providing support for stack scanning and tracing
+ */
+public class StackTraceHelper extends Helper
+{
+    private static String RULE_CLASS_NAME = Rule.class.getCanonicalName();
+    private static String RULE_EXECUTE_METHOD_NAME = "execute";
+
+    protected StackTraceElement[] stack;
+
+    protected StackTraceHelper(Rule rule) {
+        super(rule);
+        stack = Thread.currentThread().getStackTrace();
+    }
+
+    /**
+     * return the index of the frame for the trigger method below which the rule system created
+     * this helper or -1 if it cannot be found
+     * @return the index of the frame for the trigger method or -1 if it cannot be found
+     */
+    protected int triggerIndex()
+    {
+        return triggerIndex(stack);
+    }
+
+    /**
+     * return the index of the frame in stack for the trigger method below which the rule system
+     * was entered or -1 if it cannot be found
+     * @return the index of the frame for the trigger method or -1 if it cannot be found
+     */
+    protected int triggerIndex(StackTraceElement[] stack)
+    {
+        int l= stack.length;
+        int i;
+        // find the trigger method frame above the rule engine entry point
+        // we should see two calls to rule.execute()
+        for (i = 0; i < l; i++) {
+            if (RULE_CLASS_NAME.equals(stack[i].getClassName()) &&
+                    RULE_EXECUTE_METHOD_NAME.equals(stack[i].getMethodName())) {
+                break;
+            }
+        }
+
+        if (i >= l - 1 ||
+                !RULE_CLASS_NAME.equals(stack[i].getClassName()) ||
+                !RULE_EXECUTE_METHOD_NAME.equals(stack[i].getMethodName())) {
+            // illegal usage
+            new ExecuteException("StacktraceHelper.traceStack : can only be called below Rule.execute()").printStackTrace();
+            return -1;
+        }
+
+        return  i + 2;
+    }
+
+    /**
+     * return the index of the first frame at or below index start which matches pattern
+     * @param pattern a pattern to be matched against the concatenated stack classname and methodname using
+     * String.matches()
+     * @param start the index of the first frame which should be tested for a match. this must be greater than
+     * or equal to the trigger index.
+     * @param limit the index of the first frame which should not be tested for a match. this must be less than
+     * or equal to the stack length
+     * @return the index of the matching frame between start and limit - 1 or -1 if it no match found
+     */
+    protected int matchIndex(String pattern, int start, int limit)
+    {
+        int l= stack.length;
+        int i = start;
+        // find the trigger method frame above the rule engine entry point
+        // we should see two calls to rule.execute()
+        for (i = 0; i < limit; i++) {
+            String fullName = stack[i].getClassName() + "." + stack[i].getMethodName();
+            if (fullName.matches(pattern)) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * print the details of the current stack frame at index idx followed by a newline to buffer by calling
+     * printlnFrame(buffer, stack[idx])
+     * @param buffer
+     * @param idx
+     */
+    protected void printlnFrame(StringBuffer buffer, int idx)
+    {
+        printlnFrame(buffer, stack[idx]);
+    }
+
+    /**
+     * print the details of stack frame at index idx to buffer
+     * print the details of stack frame to buffer
+     * @param buffer
+     * @param idx
+     */
+    protected void printFrame(StringBuffer buffer, int idx)
+    {
+        printFrame(buffer, stack[idx]);
+    }
+
+    /**
+     * print the details of stack frame followed by a newline to buffer by calling
+     * printlnFrame(buffer, frame) then buffer.append('\n')
+     * @param buffer
+     * @param frame
+     */
+    protected void printlnFrame(StringBuffer buffer, StackTraceElement frame)
+    {
+        printFrame(buffer, frame);
+        buffer.append('\n');
+    }
+
+    /**
+     * print the details of stack frame to buffer
+     * @param buffer
+     * @param frame
+     */
+    protected void printFrame(StringBuffer buffer, StackTraceElement frame)
+    {
+        buffer.append(frame.getClassName());
+        buffer.append(".");
+        buffer.append(frame.getMethodName());
+        buffer.append(" at ");
+        buffer.append(frame.getFileName());
+        buffer.append(":");
+        buffer.append(frame.getLineNumber());
+    }
+
+    /**
+     * print a stack trace to System.out by calling traceStack(null)
+     */
+    public void traceStack()
+    {
+        traceStack(null);
+    }
+
+    /**
+     * print a stack trace to System.out by calling traceStack(prefix, "out")
+     */
+    public void traceStack(String prefix)
+    {
+        traceStack(prefix, "out");
+    }
+
+    /**
+     * print a stack trace to System.out by calling traceStack(prefix, key, 0)
+     */
+    public void traceStack(String prefix, Object key)
+    {
+        traceStack(prefix, key, 0);
+    }
+
+    /**
+     * print a stack trace to System.out by calling traceStack(null, maxFrames)
+     */
+    public void traceStack(int maxFrames)
+    {
+        traceStack(null, maxFrames);
+    }
+
+    /**
+     * print a stack trace to System.out by calling traceStack(prefix, "out", maxFrames)
+     */
+    public void traceStack(String prefix, int maxFrames)
+    {
+        traceStack(prefix, "out", maxFrames);
+    }
+
+    /**
+     * print a stack trace to the trace stream identified by key
+     *
+     * @param prefix a String to be printed once before printing each line of stack trace. if supplied as null
+     * then the prefix "Stack trace for thread " + Thread.currentThread().getName() + "\n" is used
+     * @param key an object identifying the trace stream to which output should be generated
+     * @param maxFrames the maximum number of frames to print or 0 if no limit should apply
+     */
+    public void traceStack(String prefix, Object key, int maxFrames)
+    {
+        StringBuffer buffer = new StringBuffer();
+        int l = stack.length;
+        int i = triggerIndex();
+
+        if (i < 0) {
+            return;
+        }
+
+        if (prefix != null) {
+            buffer.append(prefix);
+        } else {
+            buffer.append("Stack trace for thread ");
+            buffer.append(Thread.currentThread().getName());
+            buffer.append('\n');
+        }
+        boolean dotdotdot = false;
+
+        if (maxFrames > 0 && (i + maxFrames) < l) {
+            l = i + maxFrames;
+            dotdotdot = true;
+        }
+        
+        for (; i < l; i++) {
+            printlnFrame(buffer, i);
+        }
+        if (dotdotdot) {
+            buffer.append("  . . .\n");
+        }
+
+        trace(key, buffer.toString());
+    }
+
+    /**
+     * print all stack frames which match pattern to System.out by calling traceStackMatching(pattern, null)
+     */
+
+    public void traceStackMatching(String pattern)
+    {
+        traceStackMatching(pattern, null);
+    }
+
+    /**
+     * print all stack frames which match pattern to System.out preceded by prefix by calling
+     * traceStackMatching(pattern, null, "out")
+     */
+
+    public void traceStackMatching(String pattern, String prefix)
+    {
+        traceStackMatching(pattern, null, "out");
+    }
+
+    /**
+     * print all stack frames which match pattern to the trace stream identified by key preceded by prefix.
+     *
+     * @param pattern a pattern which will be matched against the concatenated classname and
+     * method name of the stack frame by calling String.matches()
+     * @param prefix a String to be printed once before printing each line of stack trace. if supplied as null
+     * then the prefix "Stack trace for thread " + Thread.currentThread().getName() + " matching " + pattern + "\n" is used
+     * @param key an object identifying the trace stream to which output should be generated
+     */
+
+    public void traceStackMatching(String pattern, String prefix, Object key)
+    {
+        StringBuffer buffer = new StringBuffer();
+        int l = stack.length;
+        int i = triggerIndex();
+
+        if (i < 0) {
+            return;
+        }
+
+        if (prefix != null) {
+            buffer.append(prefix);
+        } else {
+            buffer.append("Stack trace for thread ");
+            buffer.append(Thread.currentThread().getName());
+            buffer.append(" matching ");
+            buffer.append(pattern);
+            buffer.append('\n');
+        }
+        for (; i < l; i++) {
+            String fullName = stack[i].getClassName() + "." +  stack[i].getMethodName();
+            if (fullName.matches(pattern)) {
+                printlnFrame(buffer, i);
+            }
+        }
+
+        trace(key, buffer.toString());
+    }
+
+    /**
+     * print all stack frames between the frames which match start and end to System.out by calling
+     * traceStackMatching(from, to, null)
+     */
+
+    public void traceStackBetween(String from, String to)
+    {
+        traceStackBetween(from, to, null);
+    }
+
+    /**
+     * print all stack frames between the frames which match start and end to System.out preceded by prefix
+     * by calling traceStackMatching(from, to, null, "out")
+     */
+
+    public void traceStackBetween(String from, String to, String prefix)
+    {
+        traceStackBetween(from, to, null, "out");
+    }
+
+    /**
+     * print all stack frames between the frames which match start and end to the trace stream identified by key
+     * preceded by prefix.
+     *
+     * @param from a pattern which identifies the first frame which should be printed. from will be matched against
+     * the concatenated classname and method name of each successive stack frame by calling String.matches().
+     * If null is supplied then the trigger frame will be used as the first frame to print. If a non-null value
+     * is supplied and no match is foudn then no farmes will be printed.
+     * @param to a pattern which identifies the last frame which should be printed. to will be matched against
+     * the concatenated classname and method name of each successive stack frame by calling String.matches().
+     * If null is supplied or no match is found then the bottom frame will be used as the last frame to print.
+     * @param prefix a String to be printed once before printing each line of stack trace. if supplied as null
+     * then the prefix "Stack trace (restricted) for " + Thread.currentThread().getName() + "\n" is used
+     * @param key an object identifying the trace stream to which output should be generated
+     */
+
+    public void traceStackBetween(String from, String to, String prefix, Object key)
+    {
+        StringBuffer buffer = new StringBuffer();
+        int l = stack.length;
+        int i = triggerIndex();
+        if (i < 0) {
+            return;
+        }
+
+        int first;
+        if (from != null) {
+            first = matchIndex(from, i, l);
+            if (first < 0) {
+                return;
+            }
+        } else {
+            first = i;
+        }
+
+        int last;
+        if (to != null) {
+            last = matchIndex(to, first + 1, l);
+            if (last < 0) {
+                last = l - 1;
+            }
+        } else {
+            last = l - 1;
+        }
+
+        if (prefix != null) {
+            buffer.append(prefix);
+        } else {
+            buffer.append("Stack trace (restricted) for ");
+            buffer.append(Thread.currentThread().getName());
+            buffer.append('\n');
+        }
+        for (i = first; i < last; i++) {
+            printlnFrame(buffer, i);
+        }
+
+        trace(key, buffer.toString());
+    }
+
+    /**
+     * print a stack trace of all threads in the system to System.out by calling traceStacks("out")
+     */
+    public void traceAllStacks()
+    {
+        traceAllStacks("out");
+    }
+
+    /**
+     * print a stack trace of all threads in the system to the trace stream keyed by key
+     */
+    public void traceAllStacks(String key)
+    {
+        StringBuffer buffer = new StringBuffer();
+        if (threadMXBean != null) {
+            ThreadInfo[] threadInfo = threadMXBean.dumpAllThreads(threadMXBean.isObjectMonitorUsageSupported(), threadMXBean.isSynchronizerUsageSupported());
+            for (int i = 0; i < threadInfo.length; i++) {
+                buffer.append(threadInfo[i].toString());
+            }
+        } else {
+            Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
+            for (Map.Entry<Thread, StackTraceElement[]> entry : map.entrySet()) {
+                Thread thread = entry.getKey();
+                StackTraceElement[] stack = entry.getValue();
+                int l = stack.length;
+                int i = 0;
+                buffer.append("Stack trace for thread ");
+                buffer.append(Thread.currentThread().getName());
+                buffer.append('\n');
+                for (; i < l; i++) {
+                    printlnFrame(buffer, i);
+                }
+                buffer.append('\n');
+            }
+        }
+        trace(key, buffer.toString());
+    }
+
+    private static ThreadMXBean threadMXBean = initThreadMXBean();
+
+    private static ThreadMXBean initThreadMXBean() {
+        try {
+            return AccessController.doPrivileged(
+                new PrivilegedExceptionAction<ThreadMXBean>() {
+                    public ThreadMXBean run() throws Exception {
+                        return ManagementFactory.getThreadMXBean();
+                    }
+                });
+        } catch (Exception exp) {
+            throw new UnsupportedOperationException(exp);
+        }
+    }
+
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/helper/ThreadMonitorHelper.java
===================================================================
--- labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/helper/ThreadMonitorHelper.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/byteman/trunk/sample/src/org/jboss/byteman/sample/helper/ThreadMonitorHelper.java	2009-10-20 12:48:04 UTC (rev 29689)
@@ -0,0 +1,164 @@
+package org.jboss.byteman.sample.helper;
+
+import org.jboss.byteman.rule.Rule;
+
+/**
+ * Helper class used by ThreadMonitorHelper script to trace thread operations
+ */
+public class ThreadMonitorHelper extends StackTraceHelper
+{
+    protected ThreadMonitorHelper(Rule rule) {
+        super(rule);
+    }
+
+    /**
+     * trace creation of the supplied thread to System.out
+     *
+     * this should only be triggered from the constructor for class java.lang.Thread"
+     *
+     * @param thread the newly created thread
+     */
+    public void traceCreate(Thread thread)
+    {
+        traceCreate(thread, "out");
+    }
+    /**
+     * trace creation of the supplied thread to the trace stream identified by key
+     *
+     * @param thread the newly created thread
+     * @param key an object identifying the trace stream to which output should be generated
+     */
+    public void traceCreate(Thread thread, Object key)
+    {
+        StringBuffer buffer = new StringBuffer();
+        int l = stack.length;
+        int t = triggerIndex();
+        if (t < 0) {
+            return;
+        }
+
+        int i = matchIndex("java.lang.Thread.<init>", t, l);
+        if (i < 0) {
+            // illegal usage
+            traceStack("ThreadMonitorHelper.traceCreate : should only be triggered below Thread.<init>\n", key);
+            return;
+        }
+        buffer.append("*** Thread create ");
+        buffer.append(thread.getName());
+        buffer.append(" ");
+        buffer.append(thread.getClass().getCanonicalName());
+        buffer.append('\n');
+
+        // find bottommost constructor invocation
+        i++;
+        while (i < l && matchIndex(".*<init>", i, i) >= 0) {
+            i++;
+        }
+        if (i == l) {
+            // happens when a system thread is created by the runtime
+            buffer.append("    from VM runtime\n");
+        } else {
+            buffer.append("    from ");
+            printlnFrame(buffer, i);
+        }
+        trace(key, buffer.toString());
+    }
+
+    /**
+     * trace start of the supplied thread to System.out
+     *
+     * this should only be triggered from the call to java.lang.Thread.start"
+     *
+     * @param thread the newly starting thread
+     */
+    public void traceStart(Thread thread)
+    {
+        traceStart(thread, "out");
+    }
+
+    /**
+     * trace start of the supplied thread to the trace stream identified by key
+     *
+     * this should only be triggered from the call to java.lang.Thread.start"
+     *
+     * @param thread the newly starting thread
+     * @param key an object identifying the trace stream to which output should be generated
+     */
+    public void traceStart(Thread thread, Object key)
+    {
+        StringBuffer buffer = new StringBuffer();
+        int l = stack.length;
+        int t = triggerIndex();
+        if (t < 0) {
+            return;
+        }
+
+        int i = matchIndex("java.lang.Thread.start", t, l);
+        if (i < 0) {
+            // illegal usage
+            traceStack("ThreadMonitorHelper.traceStart : should only be triggered below Thread.start\n", key);
+            return;
+        }
+
+        buffer.append("*** Thread start ");
+        buffer.append(thread.getName());
+        buffer.append(" ");
+        buffer.append(thread.getClass().getCanonicalName());
+        buffer.append('\n');
+        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
+
+        if (++i == l) {
+            // should not happen
+            traceStack("ThreadMonitorHelper.traceStart : failed to find frame for caller of start\n", key);
+            return;
+        }
+
+        buffer.append("    from ");
+        printlnFrame(buffer, i);
+        trace(key, buffer.toString());
+    }
+
+    /**
+     * trace exit of the supplied thread to System.out
+     *
+     * this should only be triggered from the call to java.lang.Thread.exit"
+     *
+     * @param thread the exiting thread
+     */
+    public void traceExit(Thread thread)
+    {
+        traceExit(thread, "out");
+    }
+
+    /**
+     * trace exit of the supplied thread to the trace stream identified by key
+     *
+     * this should only be triggered from the call to java.lang.Thread.exit"
+     *
+     * @param thread the exiting thread
+     * @param key an object identifying the trace stream to which output should be generated
+     */
+    public void traceExit(Thread thread, Object key)
+    {
+        StringBuffer buffer = new StringBuffer();
+        int l = stack.length;
+        int t = triggerIndex();
+        if (triggerIndex() < 0) {
+            return;
+        }
+        int i = matchIndex("java.lang.Thread.exit", t, l);
+        if (i < 0) {
+            // illegal usage
+            traceStack("ThreadMonitorHelper.traceExit : should only be triggered below Thread.exit\n", key);
+            return;
+        }
+
+        buffer.append("*** Thread exit ");
+        buffer.append(thread.getName());
+        buffer.append(" ");
+        buffer.append(thread.getClass().getCanonicalName());
+        buffer.append('\n');
+
+        trace(key, buffer.toString());
+    }
+}



More information about the jboss-svn-commits mailing list