Skip to content

Commit f99a1e2

Browse files
authored
Merge pull request #10 from seeker89/jvm
Chapter 8: JVM
2 parents b0a336b + 06536c1 commit f99a1e2

File tree

13 files changed

+225
-1
lines changed

13 files changed

+225
-1
lines changed

Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
all: killer-whiles who-you-gonna-call
1+
all: killer-whiles who-you-gonna-call jvm
22

33
killer-whiles:
44
(cd examples/killer-whiles && make)
@@ -7,6 +7,9 @@ who-you-gonna-call:
77
(cd examples/who-you-gonna-call && make)
88
(cd examples/who-you-gonna-call/src && make gen && make)
99

10+
jvm:
11+
(cd examples/jvm && make)
12+
1013
clean:
1114
rm -rf vm/vm.zip vm/parts.sha256 vm/chaos-engineering-VM*
1215

examples/jvm/Makefile

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
CFLAGS=-O0
2+
3+
all: FizzBuzzEnterpriseEdition/bin/FizzBuzzEnterpriseEdition byteman-download-4.0.11 byte-monkey.jar
4+
5+
src:
6+
git clone https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition.git src
7+
8+
byteman-download-4.0.11:
9+
wget https://downloads.jboss.org/byteman/4.0.11/byteman-download-4.0.11-bin.zip
10+
unzip byteman-download-4.0.11-bin.zip
11+
rm byteman-download-4.0.11-bin.zip
12+
13+
byte-monkey.jar:
14+
wget https://github.com/mrwilson/byte-monkey/releases/download/1.0.0/byte-monkey.jar
15+
16+
FizzBuzzEnterpriseEdition/bin/FizzBuzzEnterpriseEdition: src
17+
(cd src && ./gradlew assemble && ./gradlew build)
18+
unzip src/build/distributions/FizzBuzzEnterpriseEdition.zip
19+
20+
run:
21+
./FizzBuzzEnterpriseEdition/bin/FizzBuzzEnterpriseEdition
22+
23+
run2:
24+
java -classpath "./FizzBuzzEnterpriseEdition/lib/*" com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main
25+
26+
run3:
27+
javap -classpath "./FizzBuzzEnterpriseEdition/lib/*" -c com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main
28+
29+
run4:
30+
java -javaagent:./agent1.jar -classpath "./FizzBuzzEnterpriseEdition/lib/*" com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main
31+
32+
run5:
33+
java -javaagent:./agent2.jar -classpath "./FizzBuzzEnterpriseEdition/lib/*" com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main
34+
35+
run6:
36+
java \
37+
-javaagent:./byteman-download-4.0.11/lib/byteman.jar=script:throw.btm \
38+
-classpath "./FizzBuzzEnterpriseEdition/lib/*" \
39+
com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main
40+
41+
run7:
42+
java \
43+
-javaagent:byte-monkey.jar=mode:fault,rate:0.5,filter:com/seriouscompany/business/java/fizzbuzz/packagenamingpackage/impl/strategies/SystemOutFizzBuzzOutputStrategy/output \
44+
-classpath "./FizzBuzzEnterpriseEdition/lib/*" \
45+
com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.Main
46+
47+
48+
49+
example1-compile:
50+
javac ./org/my/example1.java
51+
example1-run:
52+
java org.my.Example1
53+
example1-bytecode:
54+
javap -c org.my.Example1
55+
example1-agent:
56+
java -javaagent:./agent1.jar org.my.Example1
57+
58+
example2-compile:
59+
javac ./org/my/example2.java
60+
example2-run:
61+
java org.my.Example2
62+
example2-bytecode:
63+
javap -c org.my.Example2
64+
65+
.PHONY: run run2 run3 example1-compile example1-run example1-bytecode example2-compile example2-run example2-bytecode
66+
67+
agent1.jar: org/agent/Agent.java org/agent/ClassPrinter.java org/agent/manifest.mf
68+
javac org/agent/Agent.java
69+
javac org/agent/ClassPrinter.java
70+
jar vcmf org/agent/manifest.mf agent1.jar org/agent
71+
72+
agent2.jar: org/agent2/Agent.java org/agent2/ClassInjector.java org/agent2/manifest.mf
73+
javac -XDignore.symbol.file org/agent2/Agent.java
74+
javac -XDignore.symbol.file org/agent2/ClassInjector.java
75+
jar vcmf org/agent2/manifest.mf agent2.jar org/agent2

examples/jvm/org/agent/Agent.java

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.agent;
2+
3+
import java.lang.instrument.Instrumentation;
4+
5+
class Agent {
6+
public static void premain(String args, Instrumentation instrumentation){
7+
ClassPrinter transformer = new ClassPrinter();
8+
instrumentation.addTransformer(transformer);
9+
}
10+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.agent;
2+
3+
import java.lang.instrument.ClassFileTransformer;
4+
import java.lang.instrument.IllegalClassFormatException;
5+
import java.security.ProtectionDomain;
6+
7+
8+
class ClassPrinter implements ClassFileTransformer {
9+
public byte[] transform(ClassLoader loader,
10+
String className,
11+
Class<?> classBeingRedefined,
12+
ProtectionDomain protectionDomain,
13+
byte[] classfileBuffer) throws IllegalClassFormatException {
14+
System.out.println("Found class: " + className + " (" + classfileBuffer.length + " bytes)");
15+
return classfileBuffer;
16+
}
17+
}

examples/jvm/org/agent/manifest.mf

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Manifest-Version: 1.0
2+
Premain-Class: org.agent.Agent

examples/jvm/org/agent2/Agent.java

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.agent2;
2+
3+
import java.lang.instrument.Instrumentation;
4+
5+
class Agent {
6+
public static void premain(String args, Instrumentation instrumentation){
7+
ClassInjector transformer = new ClassInjector();
8+
instrumentation.addTransformer(transformer);
9+
}
10+
}
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.agent2;
2+
3+
import java.io.IOException;
4+
import java.util.List;
5+
6+
import java.lang.instrument.ClassFileTransformer;
7+
import java.lang.instrument.IllegalClassFormatException;
8+
import java.security.ProtectionDomain;
9+
10+
import jdk.internal.org.objectweb.asm.ClassReader;
11+
import jdk.internal.org.objectweb.asm.ClassWriter;
12+
import jdk.internal.org.objectweb.asm.tree.*;
13+
import jdk.internal.org.objectweb.asm.Opcodes;
14+
15+
16+
public class ClassInjector implements ClassFileTransformer {
17+
18+
public String targetClassName = "com/seriouscompany/business/java/fizzbuzz/packagenamingpackage/impl/strategies/SystemOutFizzBuzzOutputStrategy";
19+
20+
public byte[] transform(ClassLoader loader,
21+
String className,
22+
Class<?> classBeingRedefined,
23+
ProtectionDomain protectionDomain,
24+
byte[] classfileBuffer) throws IllegalClassFormatException {
25+
if (className.equals(this.targetClassName)){
26+
System.err.println("[CHAOS] TARGET ACQUIRED: " + className + " (" + classfileBuffer.length + " bytes)");
27+
28+
ClassNode classNode = new ClassNode();
29+
new ClassReader(classfileBuffer).accept(classNode, 0);
30+
classNode.methods.stream()
31+
.filter(method -> method.name.equals("output"))
32+
.forEach(method -> {
33+
InsnList instructions = new InsnList();
34+
instructions.add(new MethodInsnNode(
35+
Opcodes.INVOKESTATIC,
36+
"org/agent2/ClassInjector",
37+
"throwIOException",
38+
"()V",
39+
false // not a method
40+
));
41+
method.maxStack += 1;
42+
method.instructions.insertBefore(method.instructions.getFirst(), instructions);
43+
System.err.println("[CHAOS] Method " + method.name + " modified");
44+
});
45+
final ClassWriter classWriter = new ClassWriter(0);
46+
classNode.accept(classWriter);
47+
byte[] bytes = classWriter.toByteArray();
48+
System.err.println("[CHAOS] Rewrote: " + className + " (" + bytes.length + " bytes)");
49+
return bytes;
50+
}
51+
return classfileBuffer;
52+
}
53+
54+
public static void throwIOException() throws IOException
55+
{
56+
System.err.println("[CHAOS] BOOM! Throwing");
57+
throw new IOException("CHAOS");
58+
}
59+
}

examples/jvm/org/agent2/manifest.mf

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Manifest-Version: 1.0
2+
Premain-Class: org.agent2.Agent
3+
Can-Redefine-Classes: true
4+
Can-Retransform-Classes: true

examples/jvm/org/my/example1.java

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.my;
2+
3+
class Example1
4+
{
5+
public static void main(String[] args)
6+
{
7+
System.out.println("Hello chaos!");
8+
}
9+
}

examples/jvm/org/my/example2.java

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.my;
2+
import java.io.IOException;
3+
4+
class Example2
5+
{
6+
public static void main(String[] args) throws IOException
7+
{
8+
Example2.throwIOException();
9+
}
10+
11+
public static void throwIOException() throws IOException
12+
{
13+
throw new IOException("Oops");
14+
}
15+
}

examples/jvm/throw.btm

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
RULE throw an exception at output
2+
CLASS SystemOutFizzBuzzOutputStrategy
3+
METHOD output
4+
AT ENTRY
5+
IF true
6+
DO
7+
traceln("entering the method output");
8+
throw new java.io.IOException("BOOM");
9+
ENDRULE

vm/ansible/prerequisites/defaults/main.yml

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ packages_to_install:
4242
- manpages-posix-dev
4343
# seccomp
4444
- libseccomp-dev
45+
# java
46+
- openjdk-8-jdk
4547

4648
packages_to_remove:
4749
- libreoffice-core

vm/ansible/prerequisites/tasks/main.yml

+9
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,12 @@
199199
become: false
200200
shell: |
201201
gsettings set org.gnome.desktop.session idle-delay 0
202+
203+
- name: Add auto-login
204+
become: true
205+
lineinfile:
206+
path: /etc/gdm3/custom.conf
207+
line: "{{ item }}"
208+
loop:
209+
- "AutomaticLoginEnable = true"
210+
- "AutomaticLogin = chaos"

0 commit comments

Comments
 (0)