ASM Sample Project (#2664)
* ASM Sample Project * Update Premain.java * Update pom.xml
This commit is contained in:
parent
6655ca0ba1
commit
815c66c9dd
|
@ -0,0 +1,51 @@
|
||||||
|
<?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>com.baeldung.examples</groupId>
|
||||||
|
<artifactId>asm</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.ow2.asm</groupId>
|
||||||
|
<artifactId>asm</artifactId>
|
||||||
|
<version>5.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.ow2.asm</groupId>
|
||||||
|
<artifactId>asm-util</artifactId>
|
||||||
|
<version>5.2</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Premain-Class>
|
||||||
|
com.baeldung.examples.asm.instrumentation.Premain
|
||||||
|
</Premain-Class>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.9</version>
|
||||||
|
<configuration>
|
||||||
|
<argLine>-javaagent:"C:\asm-1.0.jar"</argLine>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,160 @@
|
||||||
|
package com.baeldung.examples.asm;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
import org.objectweb.asm.ClassVisitor;
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
import org.objectweb.asm.FieldVisitor;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||||
|
import static org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||||
|
import static org.objectweb.asm.Opcodes.ASM4;
|
||||||
|
import static org.objectweb.asm.Opcodes.V1_5;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.util.TraceClassVisitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author baeldung
|
||||||
|
* @param <String>
|
||||||
|
*/
|
||||||
|
public class CustomClassWriter {
|
||||||
|
|
||||||
|
ClassReader reader;
|
||||||
|
ClassWriter writer;
|
||||||
|
AddFieldAdapter addFieldAdapter;
|
||||||
|
AddInterfaceAdapter addInterfaceAdapter;
|
||||||
|
PublicizeMethodAdapter pubMethAdapter;
|
||||||
|
final static String CLASSNAME = "java.lang.Integer";
|
||||||
|
final static String CLONEABLE = "java/lang/Cloneable";
|
||||||
|
|
||||||
|
public CustomClassWriter() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
reader = new ClassReader(CLASSNAME);
|
||||||
|
writer = new ClassWriter(reader, 0);
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(CustomClassWriter.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomClassWriter(byte[] contents) {
|
||||||
|
reader = new ClassReader(contents);
|
||||||
|
writer = new ClassWriter(reader, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
CustomClassWriter ccw = new CustomClassWriter();
|
||||||
|
ccw.publicizeMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] addField() {
|
||||||
|
addFieldAdapter = new AddFieldAdapter("aNewBooleanField", org.objectweb.asm.Opcodes.ACC_PUBLIC, writer);
|
||||||
|
reader.accept(addFieldAdapter, 0);
|
||||||
|
return writer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] publicizeMethod() {
|
||||||
|
pubMethAdapter = new PublicizeMethodAdapter(writer);
|
||||||
|
reader.accept(pubMethAdapter, 0);
|
||||||
|
return writer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] addInterface() {
|
||||||
|
addInterfaceAdapter = new AddInterfaceAdapter(writer);
|
||||||
|
reader.accept(addInterfaceAdapter, 0);
|
||||||
|
return writer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddInterfaceAdapter extends ClassVisitor {
|
||||||
|
|
||||||
|
public AddInterfaceAdapter(ClassVisitor cv) {
|
||||||
|
super(ASM4, cv);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name,
|
||||||
|
String signature, String superName, String[] interfaces) {
|
||||||
|
String[] holding = new String[interfaces.length + 1];
|
||||||
|
holding[holding.length - 1] = CLONEABLE;
|
||||||
|
System.arraycopy(interfaces, 0, holding, 0, interfaces.length);
|
||||||
|
|
||||||
|
cv.visit(V1_5, access, name, signature, superName, holding);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PublicizeMethodAdapter extends ClassVisitor {
|
||||||
|
|
||||||
|
final Logger logger = Logger.getLogger("PublicizeMethodAdapter");
|
||||||
|
TraceClassVisitor tracer;
|
||||||
|
PrintWriter pw = new PrintWriter(System.out);
|
||||||
|
|
||||||
|
public PublicizeMethodAdapter(ClassVisitor cv) {
|
||||||
|
super(ASM4, cv);
|
||||||
|
this.cv = cv;
|
||||||
|
tracer = new TraceClassVisitor(cv, pw);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(int access,
|
||||||
|
String name,
|
||||||
|
String desc,
|
||||||
|
String signature,
|
||||||
|
String[] exceptions) {
|
||||||
|
|
||||||
|
if (name.equals("toUnsignedString0")) {
|
||||||
|
logger.info("Visiting unsigned method");
|
||||||
|
return tracer.visitMethod(ACC_PUBLIC + ACC_STATIC, name, desc, signature, exceptions);
|
||||||
|
}
|
||||||
|
return tracer.visitMethod(access, name, desc, signature, exceptions);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void visitEnd() {
|
||||||
|
tracer.visitEnd();
|
||||||
|
System.out.println(tracer.p.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddFieldAdapter extends ClassVisitor {
|
||||||
|
|
||||||
|
String fieldName;
|
||||||
|
int access;
|
||||||
|
boolean isFieldPresent;
|
||||||
|
|
||||||
|
public AddFieldAdapter(String fieldName, int access, ClassVisitor cv) {
|
||||||
|
super(ASM4, cv);
|
||||||
|
this.cv = cv;
|
||||||
|
this.access = access;
|
||||||
|
this.fieldName = fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldVisitor visitField(int access, String name, String desc,
|
||||||
|
String signature, Object value) {
|
||||||
|
if (name.equals(fieldName)) {
|
||||||
|
isFieldPresent = true;
|
||||||
|
}
|
||||||
|
return cv.visitField(access, name, desc, signature, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnd() {
|
||||||
|
if (!isFieldPresent) {
|
||||||
|
FieldVisitor fv = cv.visitField(access, fieldName, Type.BOOLEAN_TYPE.toString(), null, null);
|
||||||
|
if (fv != null) {
|
||||||
|
fv.visitEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cv.visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.examples.asm.instrumentation;
|
||||||
|
|
||||||
|
import com.baeldung.examples.asm.CustomClassWriter;
|
||||||
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
|
import java.lang.instrument.IllegalClassFormatException;
|
||||||
|
import java.lang.instrument.Instrumentation;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author baeldung
|
||||||
|
*/
|
||||||
|
public class Premain {
|
||||||
|
|
||||||
|
public static void premain(String agentArgs, Instrumentation inst) {
|
||||||
|
inst.addTransformer(new ClassFileTransformer() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] transform(ClassLoader l, String name, Class c,
|
||||||
|
ProtectionDomain d, byte[] b)
|
||||||
|
throws IllegalClassFormatException {
|
||||||
|
|
||||||
|
if (name.equals("java/lang/Integer")) {
|
||||||
|
CustomClassWriter cr = new CustomClassWriter(b);
|
||||||
|
return cr.addField();
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue