A Java library for performing runtime interception of methods

Overview

Snapshot Pipeline Quality Gate Status codecov Maven Central

Interceptify

This library is designed to provide a convenient and simple means of performing runtime interception of Java methods/constructors.

Usage

There is no API in the traditional sense, just a few annotations and a single interface to implement which are used to determine what you want to do - they are as follows:

@InterceptClass("[target]")

This annotation requires you to provide the fully-qualified name of the class you want to intercept. It should be applied to your class that has the methods that will be doing the interception.

@OverwriteMethod("[target]")

This annotation applies to your intercepting method and is used to determine which method of the target class it intends to intercept. Your method can provide a parameter that receives the original method which can be called (or not) as you desire. If the intercepted method is not static, you can also receive a parameter for the instance.

@OverwriteConstructor(before = false, after = true)

This annotation also applies to your method and indicates that you want to overwrite a constructor, the boolean values above are the defaults and determine whether your method should execute before the constructor, after it, or both.

Due to the vagaries of how Java is implemented, you cannot prevent the constructor from executing (although in a future release I might support completely rewriting it) - thus you currently have the options above. If you set both values to false, it will simply fail.

So, for example, say you wanted to intercept the following class:

package foo.bar.baz;
private class InterceptMe {
    public InterceptMe(int a, String b) { ... }
    private Foo doFoo(Bar t, char x) { ... }
    private static Bar doBar(List<String> a, Stream<int>) { ... }
    
    public static void main(String[] args) { ... }
}

You would write a class that looks like so:

@InterceptClass("foo.bar.baz.InterceptMe")
public class Interceptor {
    @OverwriteConstructor
    public static void getConstructor(InterceptMe instance, int a, String b) { ... }
    
    @OverwriteMethod("doFoo")
    public static Foo interceptFoo(InterceptMe instance, Method original, Bar t, char x) { ... }
    
    @OverwriteMethod("doBar")
    public static Bar interceptBar(Method original, List<String> a, Stream<int> b) { ... }
}

There are a few things to note here:

  1. Everything related to the interception should be public.
  2. The name of your method doesn't matter.
  3. The order of arguments matters.

Runtime Execution

Since the classes you want to intercept need to not be loaded into the JVM already, you should define your own main() and have the JVM execute that first instead. You will need to create a class that implements StartupConfig.

Also of important note is that all classes performing interception need to live inside a jar file - since a jar is really just a zip file (and consequently, trivially created) - this decision was made to avoid inevitable confusion caused by working with directory paths and poorly chosen directory names.

So, continuing the example, let's say the original executable was run via java -jar Foo.jar or perhaps java -cp Foo.jar foo.bar.baz.InterceptMe - you would want to change it to java -cp MyInterceptor.jar;Foo.jar MyMainClass.

Note that it is strongly recommended that you provide everything needed on the classpath via the commandline; you don't have to under certain circumstances, but not doing so is requisite upon knowing how ClassLoaders work.

See Also

The Javadoc!

Comments
  • Update ByteBuddy dependency, Add a test for before=true constructor

    Update ByteBuddy dependency, Add a test for before=true constructor

    We are now using the latest ByteBuddy release and consequently, the workaround in ClassExposer has been deleted. Additionally, a test for before=true in constructor interception has been added and behaviour has been corrected to make the test pass.

    This was specifically a problem where, if you are intercepting before the underlying constructor is called, you cannot obtain the "this" parameter because it is uninitialised and the JVM will not allow it.

    As a result, a "before" constructor interception can only access the arguments that will later reach the constructor.

    opened by Olipro 2
  • Unify TypePool usage and fix up class exposure.

    Unify TypePool usage and fix up class exposure.

    There was an issue where nested classes did not have their visibility set due to having extra attributes. This then subsequently led to the discovery of an issue where all types need to be resolveable in order for the visitor to be able to apply the fixes.

    Additionally the JVM passes class names with the foo/bar format, so we convert to dot notation before running transformation.

    All public-facing APIs remain the same.

    opened by Olipro 2
  • Implement StartupConfig method for checking whether to expose a class.

    Implement StartupConfig method for checking whether to expose a class.

    It is now possible to implement a method that is passed the fully-qualified class string and returns true if that class should be modified to have itself, its methods and its fields made public and, where possible, non-final.

    Additionally, documentation has been added for all packages to improve the JavaDoc.

    opened by Olipro 2
  • ClassInjector.java: Fix a bug where the

    ClassInjector.java: Fix a bug where the "final" attribute remained.

    In order for the class to be modified properly, we actually need to first pass PLAIN as a manifestation element. A test has been added that reproduced the error and now passes with this corrected code.

    opened by Olipro 2
  • Support interception of class instance param using Object type.

    Support interception of class instance param using Object type.

    In order to support scenarios where the intercepting code cannot directly declare the type of the class to be intercepted, we now support methods which accept an Object as their first parameter.

    opened by Olipro 1
  • ClassInjector.java: Fix a bug where the

    ClassInjector.java: Fix a bug where the "final" attribute remained.

    In order for the class to be modified properly, we actually need to first pass PLAIN as a manifestation element. A test has been added that reproduced the error and now passes with this corrected code.

    opened by Olipro 0
Owner
Oliver
Oliver
High Performance data structures and utility methods for Java

Agrona Agrona provides a library of data structures and utility methods that are a common need when building high-performance applications in Java. Ma

Real Logic 2.5k Jan 7, 2023
Free and 100% open source Progressive Java Runtime for modern Java™ deployments supported by a leading OpenJDK contributor

BellSoft Liberica JDK is a build of OpenJDK that is tested and verified to be compliant with the Java SE specification using OpenJDK Technology Compat

null 195 Dec 22, 2022
ijrd - internal java runtime debugger (loads through java agents LOL)

ijrd ijrd - internal java runtime debugger (loads through java agents LOL) this actually requires brain to build and then setup little guide to setup

null 6 Jan 28, 2022
JHook - A tool that can dynamically modify Java classes at runtime.

JHook A tool that can dynamically modify Java classes at runtime. Demo Tested on Java 1.8 - Java 17, just support JDK package com.binklac.jhook.test;

VeroFess 11 Dec 23, 2022
Runtime code generation for the Java virtual machine.

Byte Buddy runtime code generation for the Java virtual machine Byte Buddy is a code generation and manipulation library for creating and modifying Ja

Rafael Winterhalter 5.3k Dec 27, 2022
Piranha - a modern cloud runtime

Piranha Project The Piranha Project delivers you with Cloud ready containers and useful add-on / integration modules. Getting Started To get started w

Piranha Cloud 161 Dec 24, 2022
The ByteSkript development kit, including resources for third-party libraries that are not contained within the standard runtime.

ByteSkript Development Kit Todo. The development kit is a set of advanced resources available for library creators. These are not available within the

null 1 Jan 8, 2022
Allows acquiring of vanilla/mod assets at runtime instead of including them in builds potentially violating licenses

AssetMover Allows acquiring of vanilla/mod assets at runtime instead of including them in builds potentially violating licenses. Features: Downloading

Cleanroom 5 Nov 26, 2022
Cloud native multi-runtime microservice framework

Femas: Cloud native multi-runtime microservice framework The repository address has been transferred to PolarisMesh English | 简体中文 Introduction abilit

Tencent 17 Sep 5, 2022
The Distributed Application Runtime (Dapr) provides APIs that simplify microservice connectivity

Quarkus - Dapr Introduction What is Quarkus? Traditional Java stacks were engineered for monolithic applications with long startup times and large mem

Quarkiverse Hub 18 Jan 5, 2023
Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstall apk.

Tinker Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstalling apk. Getting started Add t

Tencent 16.6k Dec 30, 2022
Trust-java - Test Results Verification library for Java

TRUST - Test Results Verification library for Java The TRUST's primary goal is to provide the simple way of different test results verification. Gener

Serhii Shymkiv 2 Nov 19, 2017
Library for converting from one Java class to a dissimilar Java class with similar names based on the Bean convention

Beanmapper Beanmapper is a Java library for mapping dissimilar Java classes with similar names. The use cases for Beanmapper are the following: mappin

null 26 Nov 15, 2022
Create a Music Playlist Library -Core JAVA, JAVA Swing, AWT

Project Specifications Manage Everything about a basic Music Playlist Application in Java A Music Library for Listing, Replaying, Navigating between c

Muhammad Asad 7 Nov 8, 2022
Resconstruct is a java library to infer missing information vectors of java classes.

Reconstruct Resconstruct is a java library to infer missing information vectors of java classes. Features Phantom classes Inheritance solving Dummy fi

Nowilltolife 14 Nov 17, 2022
Z is a Java library providing accessible, consistent function combinators.

Fearless function combination in Java Techniques Unlock your functional programming potential with these combination techniques: Fusion Z.fuse(fn1, fn

J.R. 27 Jun 13, 2022
This is a small library written in Java for minecraft login.

minecraft-auth-library This is a small library written in Java for minecraft login. Usage: Login with microsoft MinecraftAuthenticator minecraftAuthen

Sandro 7 Feb 5, 2022
SpringBoot show case application for reactive-pulsar library (Reactive Streams adapter for Apache Pulsar Java Client)

Reactive Pulsar Client show case application Prerequisites Cloning reactive-pulsar Running this application requires cloning https://github.com/lhotar

Lari Hotari 9 Nov 10, 2022
A bitcoin explorer Java library that utilizes multiple data sources at once.

Bitcoin Explorer A bitcoin explorer library that utilizes multiple data sources at once. Branch Build Unit Tests master development Table of Contents

Scorpius 3 Jan 31, 2022