Welcome to Byteman
Simplify Java tracing, monitoring and testing with Byteman
What is Byteman
Byteman is a tool which makes it easy to trace, monitor and test the behaviour of Java application and JDK runtime code. It injects Java code into your application methods or into Java runtime methods without the need for you to recompile, repackage or even redeploy your application. Injection can be performed at JVM startup or after startup while the application is still running. Injected code can access any of your data and call any application methods, including where they are private. You can inject code almost anywhere you want and there is no need to prepare the original source code in advance. You can even remove injected code and reinstall different changes while the application continues to execute.
What would I use Byteman for
The simplest use of Byteman is to inject print statements that trace what your application is doing, identifying control flow through your code and displaying the values of static or instance data. This can be used for monitoring or debugging live deployments as well as for instrumenting code under test so that you can be sure it has operated correctly. By injecting code at very specific locations you avoid the expensive performance overheads which normally arise when you switch on debug or product trace. Also, you get to decide what to trace when you run your application rather than when you write it; so, you don't need 100% hindsight to be able to display the information you need. Finally, you are not just limited to tracing your own code. Byteman will inject into any Java methods, including Java libraries and the JDK runtime. It doesn't need the original source code to be available in order to do so.
Two more complex use cases arise when you use Byteman to test your application. Firstly, Byteman can inject code which checks the flow of control or the state of application and runtime data, failing the test if the program does not operate as expected. Secondly, it can inject faults or other side effects which cause your application to perform unusual or unexpected operations. This allows you to force a test to enter and fully exercise a test scenario reliably and repeatably. The required side-effect might be as simple as forcing a method to throw an exception or to return a synthetic result. Alternatively, you might need to reset (method) local or (static) global state or call out to other parts of the application or runtime. One very useful option, commonly used when testing multi-threaded applications, is to inject delays or synchronization operations which engineer at test time execution timings that are normally only encountered on rare occasions at deployment time.
The Byteman BMUnit package integrates Byteman with JUnit and TestNG making it easy for you to use Byteman to extend the range of your unit and integration tests. BMUnit is easily integrated into maven and ant projects.
How does Byteman work?
Byteman works by modifying the bytecode of your application classes at runtime. However, unlike many other bytecode transformers it operates at the level of Java not bytecode. You give Byteman one or more rules which specify the Java code you want to be executed and the location in methods of application or runtime classes where you want it to be injected. Byteman works out how to rewrite the bytecode so it behaves as if the the original Java code included the source level changes you have requested. Since Byteman only needs access to bytecode this means it can modify library code whose source is either unavailable or unable to be recompiled. This even includes the Java code which forms part of the Java virtual machine, classes such as String, Thread etc. So, with Byteman you can trace and validate what the JVM is doing on behalf of your application code or cause JVM classes like FileInputStream or Map to throw exceptions when your application calls them.
Byteman uses a clear, simple scripting language, based on a formalism called Event Condition Action (ECA) rules to specify where, when and how the original Java code should be transformed. An event specifies a trigger point, a location where you want code to be injected. When execution reaches the trigger point the rule's condition, a Java boolean expression, is evaluated. The Java expression (or sequence of expressions) in the rule action is executed only when the condition evaluates to true. Normally execution continues from the trigger point once the inejcted code has been executed. However, rule actions may include return or throw expressions, forcing a normal or exceptional return, respectively, from the triggering method.
Byteman provides a suite of built-in 'convenience' functions which you can call from rule conditions and actions. They allow you to perform a wide range of useful operations from simple output of messages or stack dumps to propagation of complex error flows where multiple rules introduce coordinated actions in different parts of your application. However, you are not limited to these standard built-in operations. You can inject any Java expression into your application so long as the classes and instances they refer to are in scope at the injection point. You can also replace or extend the available built-in functions by supplying a POJO (plain old java object) as a plugin. Byteman dynamically links rule code into the target method context, auotmatically inferring the type of values and expressions where it can and ensuring that the resulting code is type safe and does not break the type contract defined by the trigger method's signature. Byteman makes it easy to program even the most complex test scenarios.
How do I start using Byteman?
Byteman 4.0.23 is now available for download under the GNU LGPL. It requires a JDK 7 or higher JVM (use the latest 3.X release if you are still on JDK 6). The release includes a programmer's guide, also available online (pdf or html), which provides a complete description of what Byteman does, how it operates and and how it can be used, including all available runtime configuration options.
If you are new to Byteman then the tutorials provide a quick start, showing how Byteman can be employed to perform tracing and monitoring and to support verification of test outcomes and implement fault-injection tests.
-
The introductory tutorial shows you how to get started, using Byteman from the command line to trace and alter execution of a simple program.
-
The follow-up tutorial describes BMUnit, the package which integrates Byteman with JUnit and TestNG, and explains how to drive BMUnit/Byteman tests from maven or ant. It provides simple examples of how Byteman and BMUnit can be used to trace test execution, validate correctness and inject faults to drive tests through error scenarios.
-
The advanced tutorial explains how to use BMUnit to perform sophisticated fault injection testing. It uses a set of related Byteman rule scripts to inject code into a multi-threaded application, revealing the presence of a timing bug.
-
Finally, the rulecheck plugin tutorial explains how to configure the Byteman maven plugin. This plugin automatically checks the validity of your Byteman rule scripts as part of the maven build, ensuring that the target lcoation specificd in your rules match injection points in your application and type checkign the Java code in your rules against the types found in those target locations.
See the documentation page for more information.
The Byteman Community
Byteman is a community project so feedback and contributions are welcome. The project provides a libera.chat IRC channel (look for #byteman) where you can ask for help and a community user forum where you can report any problems you encounter when trying to obtain, build or use Byteman. There is also a developer forum which should only be used by those who wish to contribute to discussions of the design and implementation of Byteman or to suggest enhancements and new features.
Byteman sources are located in the project's git repository. Bug fixes and feature enhancements are managed using the Byteman JIRA issue tracker system. This includes both unresolved issues scheduled for upcoming releases and issues which have been fixed by the current or previous releases. Before reporting an issue in the user forum please search JIRA and the user forum to see if it has already been notified.
JIRA is also used to record scheduled development tasks and new, nice-to-have features to be added to Byteman. If you wish to propose such a feature or vote for its early addition or for resolution of a issue which is important to you then your feedback will be welcome. For new features please post to the developer forum before raising a new JIRA.
Quick Install
- Fedora:
dnf install byteman
- macOS:
brew install byteman
- RHEL:
yum install byteman