I am trying to manipulate a static method. For this, Byte Buddy or any other framework can be used.
There is one library that is called Pi4J that is used for controlling
This is perfectly possible when using a Java agent in combination with Byte Buddy. For example, you can modify the GpioFactory::getInstance
method as demonstrated by the following Java agent:
public class MyAgent {
public static void premain(String arg, Instrumentation inst) {
new AgentBuilder.Default()
.type(ElementMatchers.named("com.pi4j.io.gpio.GpioFactory")
.transform((builder, type) -> // Or anonymous class for pre Java 8
builder.method(ElementMatchers.named("getInstance"))
.intercept(MethodDelegation.to(MyFactory.class));
).installOn(inst)
}
}
public class MyFactory {
public static GpioController intercept(@SuperCall Callable<GpioController> s)
throws Exception {
return s.call(); // Wrap controller here.
}
}
Using this agent, Any controller instance that is returned from the original getInstance
method would be passed through the MyFactory::intercept
method.
Alternatively, you can equally instrument all implementations of GpioController
to directly do the logging. This would then affect all instances of the interface.
If you do not have the possibility to add a Java agent at startup, on JDKs (not standard JVMs), you can use ByteBuddyAgent.install()
(from the byte-buddy-agent
dependency) to manually install an agent at runtime. In this case, you need to make sure however that the agent is installed before the GpioFactory
is loaded. You can find more information in the documentation of the library.
Finally, note that AspectJ and Byte Buddy both use a Java agent to achieve their instrumentation. AspectJ does however use its own syntax where Byte Buddy models its API in Java what is the main core difference.
The code for Pi4J is open source on github under LGPL license. You can simply clone the repository, modify to your needs and use own version. If you feel your changes can help others as well think about contributing tp pi4j.