Skip to content

Commit 815c66c

Browse files
k0l0ssusKevinGilmore
authored andcommitted
ASM Sample Project (eugenp#2664)
* ASM Sample Project * Update Premain.java * Update pom.xml
1 parent 6655ca0 commit 815c66c

4 files changed

Lines changed: 244 additions & 0 deletions

File tree

asm/pom.xml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<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">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>com.baeldung.examples</groupId>
5+
<artifactId>asm</artifactId>
6+
<version>1.0</version>
7+
<packaging>jar</packaging>
8+
<dependencies>
9+
<dependency>
10+
<groupId>org.ow2.asm</groupId>
11+
<artifactId>asm</artifactId>
12+
<version>5.2</version>
13+
</dependency>
14+
<dependency>
15+
<groupId>org.ow2.asm</groupId>
16+
<artifactId>asm-util</artifactId>
17+
<version>5.2</version>
18+
</dependency>
19+
</dependencies>
20+
<properties>
21+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
22+
<maven.compiler.source>1.8</maven.compiler.source>
23+
<maven.compiler.target>1.8</maven.compiler.target>
24+
</properties>
25+
<build>
26+
<plugins>
27+
<plugin>
28+
<groupId>org.apache.maven.plugins</groupId>
29+
<artifactId>maven-jar-plugin</artifactId>
30+
<version>2.4</version>
31+
<configuration>
32+
<archive>
33+
<manifestEntries>
34+
<Premain-Class>
35+
com.baeldung.examples.asm.instrumentation.Premain
36+
</Premain-Class>
37+
</manifestEntries>
38+
</archive>
39+
</configuration>
40+
</plugin>
41+
<plugin>
42+
<groupId>org.apache.maven.plugins</groupId>
43+
<artifactId>maven-surefire-plugin</artifactId>
44+
<version>2.9</version>
45+
<configuration>
46+
<argLine>-javaagent:"C:\asm-1.0.jar"</argLine>
47+
</configuration>
48+
</plugin>
49+
</plugins>
50+
</build>
51+
</project>
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package com.baeldung.examples.asm;
2+
3+
import java.io.IOException;
4+
import java.io.PrintWriter;
5+
import java.util.logging.Level;
6+
import java.util.logging.Logger;
7+
import org.objectweb.asm.ClassReader;
8+
import org.objectweb.asm.ClassVisitor;
9+
import org.objectweb.asm.ClassWriter;
10+
import org.objectweb.asm.FieldVisitor;
11+
import org.objectweb.asm.MethodVisitor;
12+
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
13+
import static org.objectweb.asm.Opcodes.ACC_STATIC;
14+
import static org.objectweb.asm.Opcodes.ASM4;
15+
import static org.objectweb.asm.Opcodes.V1_5;
16+
import org.objectweb.asm.Type;
17+
import org.objectweb.asm.util.TraceClassVisitor;
18+
19+
/**
20+
*
21+
* @author baeldung
22+
* @param <String>
23+
*/
24+
public class CustomClassWriter {
25+
26+
ClassReader reader;
27+
ClassWriter writer;
28+
AddFieldAdapter addFieldAdapter;
29+
AddInterfaceAdapter addInterfaceAdapter;
30+
PublicizeMethodAdapter pubMethAdapter;
31+
final static String CLASSNAME = "java.lang.Integer";
32+
final static String CLONEABLE = "java/lang/Cloneable";
33+
34+
public CustomClassWriter() {
35+
36+
try {
37+
reader = new ClassReader(CLASSNAME);
38+
writer = new ClassWriter(reader, 0);
39+
40+
} catch (IOException ex) {
41+
Logger.getLogger(CustomClassWriter.class.getName()).log(Level.SEVERE, null, ex);
42+
}
43+
}
44+
45+
public CustomClassWriter(byte[] contents) {
46+
reader = new ClassReader(contents);
47+
writer = new ClassWriter(reader, 0);
48+
}
49+
50+
public static void main(String[] args) {
51+
CustomClassWriter ccw = new CustomClassWriter();
52+
ccw.publicizeMethod();
53+
}
54+
55+
public byte[] addField() {
56+
addFieldAdapter = new AddFieldAdapter("aNewBooleanField", org.objectweb.asm.Opcodes.ACC_PUBLIC, writer);
57+
reader.accept(addFieldAdapter, 0);
58+
return writer.toByteArray();
59+
}
60+
61+
public byte[] publicizeMethod() {
62+
pubMethAdapter = new PublicizeMethodAdapter(writer);
63+
reader.accept(pubMethAdapter, 0);
64+
return writer.toByteArray();
65+
}
66+
67+
public byte[] addInterface() {
68+
addInterfaceAdapter = new AddInterfaceAdapter(writer);
69+
reader.accept(addInterfaceAdapter, 0);
70+
return writer.toByteArray();
71+
}
72+
73+
public class AddInterfaceAdapter extends ClassVisitor {
74+
75+
public AddInterfaceAdapter(ClassVisitor cv) {
76+
super(ASM4, cv);
77+
}
78+
79+
@Override
80+
public void visit(int version, int access, String name,
81+
String signature, String superName, String[] interfaces) {
82+
String[] holding = new String[interfaces.length + 1];
83+
holding[holding.length - 1] = CLONEABLE;
84+
System.arraycopy(interfaces, 0, holding, 0, interfaces.length);
85+
86+
cv.visit(V1_5, access, name, signature, superName, holding);
87+
}
88+
89+
}
90+
91+
public class PublicizeMethodAdapter extends ClassVisitor {
92+
93+
final Logger logger = Logger.getLogger("PublicizeMethodAdapter");
94+
TraceClassVisitor tracer;
95+
PrintWriter pw = new PrintWriter(System.out);
96+
97+
public PublicizeMethodAdapter(ClassVisitor cv) {
98+
super(ASM4, cv);
99+
this.cv = cv;
100+
tracer = new TraceClassVisitor(cv, pw);
101+
}
102+
103+
@Override
104+
public MethodVisitor visitMethod(int access,
105+
String name,
106+
String desc,
107+
String signature,
108+
String[] exceptions) {
109+
110+
if (name.equals("toUnsignedString0")) {
111+
logger.info("Visiting unsigned method");
112+
return tracer.visitMethod(ACC_PUBLIC + ACC_STATIC, name, desc, signature, exceptions);
113+
}
114+
return tracer.visitMethod(access, name, desc, signature, exceptions);
115+
116+
}
117+
118+
public void visitEnd() {
119+
tracer.visitEnd();
120+
System.out.println(tracer.p.getText());
121+
}
122+
123+
}
124+
125+
public class AddFieldAdapter extends ClassVisitor {
126+
127+
String fieldName;
128+
int access;
129+
boolean isFieldPresent;
130+
131+
public AddFieldAdapter(String fieldName, int access, ClassVisitor cv) {
132+
super(ASM4, cv);
133+
this.cv = cv;
134+
this.access = access;
135+
this.fieldName = fieldName;
136+
}
137+
138+
@Override
139+
public FieldVisitor visitField(int access, String name, String desc,
140+
String signature, Object value) {
141+
if (name.equals(fieldName)) {
142+
isFieldPresent = true;
143+
}
144+
return cv.visitField(access, name, desc, signature, value);
145+
}
146+
147+
@Override
148+
public void visitEnd() {
149+
if (!isFieldPresent) {
150+
FieldVisitor fv = cv.visitField(access, fieldName, Type.BOOLEAN_TYPE.toString(), null, null);
151+
if (fv != null) {
152+
fv.visitEnd();
153+
}
154+
}
155+
cv.visitEnd();
156+
}
157+
158+
}
159+
160+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.baeldung.examples.asm.instrumentation;
2+
3+
import com.baeldung.examples.asm.CustomClassWriter;
4+
import java.lang.instrument.ClassFileTransformer;
5+
import java.lang.instrument.IllegalClassFormatException;
6+
import java.lang.instrument.Instrumentation;
7+
import java.security.ProtectionDomain;
8+
9+
/**
10+
*
11+
* @author baeldung
12+
*/
13+
public class Premain {
14+
15+
public static void premain(String agentArgs, Instrumentation inst) {
16+
inst.addTransformer(new ClassFileTransformer() {
17+
18+
@Override
19+
public byte[] transform(ClassLoader l, String name, Class c,
20+
ProtectionDomain d, byte[] b)
21+
throws IllegalClassFormatException {
22+
23+
if (name.equals("java/lang/Integer")) {
24+
CustomClassWriter cr = new CustomClassWriter(b);
25+
return cr.addField();
26+
}
27+
return b;
28+
}
29+
});
30+
}
31+
32+
}

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
</properties>
2929

3030
<modules>
31+
<module>asm</module>
3132
<module>atomix</module>
3233
<module>apache-cayenne</module>
3334
<module>aws</module>

0 commit comments

Comments
 (0)