{"id":20171395,"url":"https://github.com/brutusin/instrumentation","last_synced_at":"2025-04-10T02:42:27.967Z","repository":{"id":26222805,"uuid":"29669380","full_name":"brutusin/instrumentation","owner":"brutusin","description":"An extensible java agent framework that instruments (modifies the bytecode at class loading time) programs running on the JVM, with the purpose of capturing method invocation events (start, finish, errors ...) and notifying custom listeners.","archived":false,"fork":false,"pushed_at":"2020-03-12T23:21:29.000Z","size":536,"stargazers_count":47,"open_issues_count":7,"forks_count":10,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-24T04:12:26.192Z","etag":null,"topics":["aop","bytecode","bytecode-manipulation","instrumentation"],"latest_commit_sha":null,"homepage":"http://brutusin.org/instrumentation","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brutusin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-22T08:43:02.000Z","updated_at":"2024-01-06T15:49:58.000Z","dependencies_parsed_at":"2022-07-27T06:32:02.531Z","dependency_job_id":null,"html_url":"https://github.com/brutusin/instrumentation","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brutusin%2Finstrumentation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brutusin%2Finstrumentation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brutusin%2Finstrumentation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brutusin%2Finstrumentation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brutusin","download_url":"https://codeload.github.com/brutusin/instrumentation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248145019,"owners_count":21055030,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aop","bytecode","bytecode-manipulation","instrumentation"],"created_at":"2024-11-14T01:24:36.837Z","updated_at":"2025-04-10T02:42:27.940Z","avatar_url":"https://github.com/brutusin.png","language":"Java","readme":"\u003e Check out https://github.com/ShiftLeftSecurity/bctrace instead. A more mature and stable version of this project\n\n# org.brutusin:instrumentation [![Build Status](https://api.travis-ci.org/brutusin/instrumentation.svg?branch=master)](https://travis-ci.org/brutusin/instrumentation) [![Maven Central Latest Version](https://maven-badges.herokuapp.com/maven-central/org.brutusin/instrumentation/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.brutusin/instrumentation/)\nAn extensible java agent framework that instruments programs running on the JVM (modifying the bytecode at class loading time), with the purpose of capturing method invocation events (start, finish, errors ...) and notifying custom listeners.\n\n**Table of Contents**\n- [org.brutusin:instrumentation](#orgbrutusininstrumentation)\n  - [How it works](#how-it-works)\n  - [Maven dependency](#maven-dependency)\n  - [Example](#example)\n    - [Implementation](#implementation)\n    - [Packaging](#packaging)\n    - [JRE launching](#jre-launching)\n    - [Main stack](#main-stack)\n    - [Brutusin dependent modules](#brutusin-dependent-modules)\n    - [Support, bugs and requests](#support-bugs-and-requests)\n    - [Authors](#authors)\n    - [License](#license)\n\t\n## How it works\nThe [java instrumentation package](http://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html) introduced in JDK1.5, provides a simple way to transform java-class definition at loading time, consisting basically in a `byte[]` to `byte[]` transformation, by the so called \"java agents\".\n\nThis module provides an agent ([org.brutusin.instrumentation.Agent](src/main/java/org/brutusin/instrumentation/Agent.java)) that creates an execution listener instance (from the name of a concrete class extending [org.brutusin.instrumentation.Interceptor](src/main/java/org/brutusin/instrumentation/Interceptor.java) passed from the JVM agent arguments) and, making use of the [ASM library](http://asm.ow2.org/), introduces a series of instructions in the method definitions of the classes to be loaded (classes and methods can be skipped) to notify these execution events to the listener.\n\nFrom a simplified point of view, the dynamic transformation turns a method like this: \n```java\npublic Object foo(Object bar){\n    return new Object();\n}\n```\n\ninto that:\n```java\npublic Object foo(Object bar){\n    onStart(bar);\n    try{\n        Object ret = new Object();\n        onFinished(ret);\n        return ret;\n    } catch(Throwable th){\n        onThrowable(th);\n        throw th; // at bytecode level this is legal\n    }\n}\n```\n\nallowing your custom listener to be notified.\n\n## Maven dependency \n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.brutusin\u003c/groupId\u003e\n    \u003cartifactId\u003einstrumentation\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\nClick [here](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.brutusin%22%20a%3A%22instrumentation%22) to see the latest available version released to the Maven Central Repository.\n\nIf you are not using maven and need help you can ask [here](https://github.com/brutusin/instrumentation/issues).\n\n## Example\n*See [logging-instrumentation](https://github.com/brutusin/logging-instrumentation) for a complete working example.*\n### Implementation\nCreate the following listener implementation:\n\n```java\npackage mypackage;\n\npublic class MyInterceptor extends Interceptor {\n\n    @Override\n    public void init(String arg) {\n        System.out.println(\"Interceptor args: \" + arg);\n    }\n\n    @Override\n    public boolean interceptClass(String className, byte[] byteCode) {\n        return true; // all classes can be intrumented\n    }\n\n    @Override\n    public boolean interceptMethod(ClassNode cn, MethodNode mn) {\n        return true; // all methods are instrumented\n    }\n\n    @Override\n    protected void doOnStart(Method m, Object[] arg, String executionId) {\n        System.out.println(\"doOnStart \" + m + \" \" + executionId);\n    }\n\n    @Override\n    protected void doOnThrowableThrown(Method m, Throwable throwable, String executionId) {\n        System.out.println(\"doOnThrowableThrown \" + m + \" \" + executionId);\n    }\n\n    @Override\n    protected void doOnThrowableUncatched(Method m, Throwable throwable, String executionId) {\n        System.out.println(\"doOnThrowableUncatched \" + m + \" \" + executionId);\n    }\n\n    @Override\n    protected void doOnFinish(Method m, Object result, String executionId) {\n        System.out.println(\"doOnFinish \" + m + \" \" + executionId);\n    }\n}\n```\n### Packaging\nCreate a [fat-jar](http://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html#jar-with-dependencies) with the previous class and its dependencies. Add the following attribute to  the manifest of the agent JAR:\n```\nPremain-Class: org.brutusin.instrumentation.Agent\n```\nSuppose this jar to be named `myagent.jar`\n### JRE launching\nRun (at least JRE 1.5) the desired java application with the following JVM options: (suppossing myagent.jar located in the working directory)\n```\n-javaagent:myagent.jar=mypackage.MyInterceptor;an_interceptor_optional_parameter\n```\n\n## Main stack\nThis module could not be possible without:\n* [org.ow2.asm:asm-all](http://asm.ow2.org/)\n\n## Brutusin dependent modules\n* [org.brutusin:logging-instrumentation](https://github.com/brutusin/logging-instrumentation)\n\n## Support, bugs and requests\nhttps://github.com/brutusin/instrumentation/issues\n\n## Authors\n\n- Ignacio del Valle Alles (\u003chttps://github.com/idelvall/\u003e)\n\nContributions are always welcome and greatly appreciated!\n\n## License\nApache License, Version 2.0\nhttp://www.apache.org/licenses/LICENSE-2.0\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrutusin%2Finstrumentation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrutusin%2Finstrumentation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrutusin%2Finstrumentation/lists"}