This commit is contained in:
Sander Hautvast 2024-06-20 20:55:42 +02:00
commit 02b15b3e72
4 changed files with 152 additions and 0 deletions

35
.gitignore vendored Normal file
View file

@ -0,0 +1,35 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

1
README.md Normal file
View file

@ -0,0 +1 @@
Experiment with java22 and Rust to monitor exceptions in a JVM

43
pom.xml Normal file
View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Exceptional</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>22</source>
<target>22</target>
<compilerArgs>--enable-preview</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifestEntries>
<Premain-Class>com.github.shautvast.exceptional.Agent</Premain-Class>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,73 @@
package com.github.shautvast.exceptional;
import java.io.InputStream;
import java.lang.classfile.*;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.lang.instrument.ClassDefinition;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
@SuppressWarnings("ALL")
public class Agent {
private static final String MESSAGE = "--- Exceptional agent active";
public static void premain(String agentArgs, Instrumentation instrumentation) throws Exception {
instrumentation.addTransformer(new ClassFileTransformer() {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
return instrumentTheThrowable(className, classfileBuffer);
}
@Override
public byte[] transform(Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
return instrumentTheThrowable(className, classfileBuffer);
}
}, true);
InputStream stream = Agent.class.getResourceAsStream("/java/lang/Throwable.class");
byte[] b = new byte[stream.available()];
stream.read(b);
instrumentation.redefineClasses(new ClassDefinition(Throwable.class, b));
}
private static byte[] instrumentTheThrowable(String className, byte[] classfileBuffer) {
if (className.equals("java/lang/Throwable")) {
ClassFile classFile = ClassFile.of();
ClassModel classModel = classFile.parse(classfileBuffer);
return classFile.build(classModel.thisClass().asSymbol(), classBuilder -> {
for (ClassElement ce : classModel) {
if (ce instanceof MethodModel mm) {
String signature = mm.methodName() + "." + mm.methodType().stringValue();
if (signature.equals("<init>.()V")) {
classBuilder.withMethod(mm.methodName(), mm.methodType(), 1,
methodBuilder -> methodBuilder.withCode(
codebuilder ->
// codebuilder.invokeInstruction(Opcode.LDC, );
codebuilder.invokeInstruction(Opcode.INVOKESTATIC,
ClassDesc.of("com.github.shautvast.exceptional.Agent"), "foo",
MethodTypeDesc.ofDescriptor("()V"),
false)
));
continue;
}
}
classBuilder.with(ce);
}
});
} else {
return classfileBuffer;
}
}
public static void foo() {
System.out.println("foo");
}
}