stil WIP
This commit is contained in:
commit
02b15b3e72
4 changed files with 152 additions and 0 deletions
35
.gitignore
vendored
Normal file
35
.gitignore
vendored
Normal 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
1
README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Experiment with java22 and Rust to monitor exceptions in a JVM
|
||||
43
pom.xml
Normal file
43
pom.xml
Normal 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>
|
||||
73
src/main/java/com/github/shautvast/exceptional/Agent.java
Normal file
73
src/main/java/com/github/shautvast/exceptional/Agent.java
Normal 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");
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue