Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JUDCon 2012 Boston - The dark sides of integrat...
Search
Anton Arhipov
June 12, 2012
Programming
0
62
JUDCon 2012 Boston - The dark sides of integrations
Anton Arhipov
June 12, 2012
Tweet
Share
More Decks by Anton Arhipov
See All by Anton Arhipov
Strengthening Immutability in Kotlin. A Glimpse into Valhalla
antonarhipov
2
36
Kotlin—the New and Noteworthy in 2.2
antonarhipov
1
16
Levels of AI-assisted programming
antonarhipov
0
75
Devoxx France 2024. Kotlin - the new and noteworthy
antonarhipov
2
68
Harnessing the power of AI in IntelliJ IDEA
antonarhipov
1
200
VirtualJUG: Kotlin 2.0 and beyond
antonarhipov
1
130
Kotlin 2.1: Language Updates
antonarhipov
3
170
Devoxx Belgium 2024 - Kotlin 2.0 and beyond
antonarhipov
2
180
Data Analysis with Kotlin Notebook, DataFrame, and Kandy
antonarhipov
1
110
Other Decks in Programming
See All in Programming
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
0
390
Python札幌 LT資料
t3tra
7
1.1k
Kotlin Multiplatform Meetup - Compose Multiplatform 외부 의존성 아키텍처 설계부터 운영까지
wisemuji
0
160
Vibe codingでおすすめの言語と開発手法
uyuki234
0
160
PostgreSQLで手軽にDuckDBを使う!DuckDB&pg_duckdb入門/osc25hi-duckdb
takahashiikki
0
230
公共交通オープンデータ × モバイルUX 複雑な運行情報を 『直感』に変換する技術
tinykitten
PRO
0
180
AtCoder Conference 2025「LLM時代のAHC」
imjk
2
650
AtCoder Conference 2025
shindannin
0
920
ThorVG Viewer In VS Code
nors
0
660
副作用をどこに置くか問題:オブジェクト指向で整理する設計判断ツリー
koxya
1
290
20251212 AI 時代的 Legacy Code 營救術 2025 WebConf
mouson
0
240
[AtCoder Conference 2025] LLMを使った業務AHCの上⼿な解き⽅
terryu16
6
1k
Featured
See All Featured
Scaling GitHub
holman
464
140k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
122
21k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.7k
Rails Girls Zürich Keynote
gr2m
95
14k
Faster Mobile Websites
deanohume
310
31k
Designing for Performance
lara
610
70k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
150
Automating Front-end Workflow
addyosmani
1371
200k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.2k
The SEO Collaboration Effect
kristinabergwall1
0
320
Between Models and Reality
mayunak
1
160
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
120
Transcript
None
The Dark Sides of Integration Anton Arhipov JRebel, ZeroTurnaround @antonarhipov
Make a change Build, deploy, wait Observe results
Where the time goes?
Where the time goes? Build Just don’t Container start Light
containers Deployment ? Navigation Persist sessions
Where the time goes? Build Just don’t Container start Light
containers Deployment JRebel Navigation Persist sessions
@Path(“/”) public String foo() { return “FooBar”; }
@Path(“/”) public String foo() { return “FooBar”; } @Path(“/”) public
FooBar foo() { return new FooBar(); }
@Path(“/”) public String foo() { return “FooBar”; } @Path(“/foobar”) public
FooBar foo() { return new FooBar(); }
None
None
Come To The Dark Side We have cookies
Java App Framework Conf XML HTTP request
Java App Framework Conf XML HTTP request
Java App Framework Conf XML HTTP request 1) Stop request
Java App Framework Conf XML HTTP request 2) Check resources
Java App Framework Conf XML HTTP request 3) Reconfigure
Java App Framework Conf XML HTTP request 4) Resume request
Java App Framework Conf XML HTTP request PROFIT! J
How? • Load time weaving, e.g. binary patching o_O Isn’t
it dangerous?? • Well, you have to be careful J
How? • Add –javaagent to hook into class loading process
• Implement ClassFileTransformer • Use bytecode manipulation libraries (Javassist, cglib, asm) to add any custom logic java.lang.instrument
java.lang.instrument import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.Instrumentation; public class Agent { public
static void premain(String args, Instrumentation inst) throws Exception { inst.addTransformer(new ClassFileTransformer { … }); } } META-INF/MANIFEST.MF Premain-Class: Agent java –javaagent:agent.jar …
java.lang.instrument import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.Instrumentation; public class Agent { public
static void premain(String args, Instrumentation inst) throws Exception { inst.addTransformer(new ClassFileTransformer { … }); } } META-INF/MANIFEST.MF Premain-Class: Agent java –javaagent:agent.jar …
ClassFileTransformer new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className,
Class<?>classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); transformClass(ct, cp); return ct.toBytecode(); } }
ClassFileTransformer new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className,
Class<?>classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); transformClass(ct, cp); return ct.toBytecode(); } }
ClassFileTransformer new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className,
Class<?>classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); transformClass(ct, cp); return ct.toBytecode(); } }
ClassFileTransformer new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className,
Class<?>classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); transformClass(ct, cp); return ct.toBytecode(); } } Enter JRebel SDK
JRebel Spring plugin Weld plugin IntegrationFactory ReloaderFactory #addIntegrationProcesor (Processor) #addClassReloadListener
(Listener)
JRebel SDK class MyPlugin implements Plugin { public void preinit()
{ IntegrationFactory.getInstance(). addIntegrationProcessor( getClass().getClassLoader(), "org.jboss.Registry", new RegistryCBP()); } }
JRebel SDK class MyPlugin implements Plugin { public void preinit()
{ ReloaderFactory.getInstance(). addClassReloadListener( new ClassEventListener() { public void onClassEvent(int type, Class c) { } } }
JRebel SDK public class RegistryCBP extends JavassistClassBytecodeProcessor { public void
process(ClassPool cp, ClassLoader cl, CtClass ctClass) throws Exception { cp.importPackage("org.zeroturnaround.javarebel");
JRebel SDK public class RegistryCBP extends JavassistClassBytecodeProcessor { public void
process(ClassPool cp, ClassLoader cl, CtClass ctClass) throws Exception { cp.importPackage("org.zeroturnaround.javarebel");
JRebel SDK public class RegistryCBP extends JavassistClassBytecodeProcessor { public void
process(ClassPool cp, ClassLoader cl, CtClass ctClass) throws Exception { for (CtConstructor c : ctClass.getConstructors()) { if (c.callsSuper()) c.insertAfter("ReloaderFactory.getInstance(). ” + "addClassReloadListener($0);");
JRebel SDK public class RegistryCBP extends JavassistClassBytecodeProcessor { public void
process(ClassPool cp, ClassLoader cl, CtClass ctClass) throws Exception { ctClass.addInterface(cp.get( ClassEventListener.class.getName())); ctClass.addMethod(CtNewMethod.make( "public void onClassEvent(int type, Class clazz) {"
Javassist • Bytecode manipulation made easy • Source-level and bytecode-level
API • Uses the vocabulary of Java language • On-the-fly compilation of the injected code • http://www.jboss.org/javassist
Insert Before CtClass clazz = ... CtMethod method = clazz.getMethod(“dispatch”,
“(V)V”); m.insertBefore( “{ Reloader reloader = “ + “ReloaderFactory.getInstance();” + “reloader.checkAndReload(SomeClass.class); ” + “Config.init(); }“ );
Adding Interfaces ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.get("org.judcon.Alarm");
ct.addInterface(cp.get(Listener.class.getName())); ct.addMethod(CtNewMethod.make("public void fire() { alert(); }", ct)); public interface Listener { void fire(); } public class Alarm { void alert() {} }
Adding Interfaces ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.get("org.judcon.Alarm");
ct.addInterface(cp.get(Listener.class.getName())); ct.addMethod(CtNewMethod.make("public void fire() { alert(); }", ct)); public interface Listener { void fire(); } public class Alarm { void alert() {} }
Adding Interfaces ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.get("org.judcon.Alarm");
ct.addInterface(cp.get(Listener.class.getName())); ct.addMethod(CtNewMethod.make("public void fire() { alert(); }", ct)); public interface Listener { void fire(); } public class Alarm { void alert() {} }
Intercept Statements ClassPool pool = ClassPool.getDefault(); CtClass ct = pool.get("org.judcon.Config");
ct.getDeclaredMethod("process") .instrument(new ExprEditor() { public void edit(NewExpr e) throws CannotCompileException { e.replace("$_ = $proceed($$);"); } });
Intercept Statements ClassPool pool = ClassPool.getDefault(); CtClass ct = pool.get("org.judcon.Config");
ct.getDeclaredMethod("process") .instrument(new ExprEditor() { public void edit(NewExpr e) throws CannotCompileException { e.replace("$_ = $proceed($$);"); } });
Copy Methods CtClass clazz = ... CtMethod m = clazz.getMethod("configure",
"(V)V"); CtMethod copy = CtNewMethod.copy( m, "__configure", clazz, null); … clazz.addMethod(CtNewMethod.make( "public void onClassEvent(int type, Class clazz) {" + "__configure();" + "} ");
Copy Methods CtClass clazz = ... CtMethod m = clazz.getMethod("configure",
"(V)V"); CtMethod copy = CtNewMethod.copy( m, "__configure", clazz, null); … clazz.addMethod(CtNewMethod.make( "public void onClassEvent(int type, Class clazz) {" + "__configure();" + "} ");
Copy Methods CtClass clazz = ... CtMethod m = clazz.getMethod("configure",
"(V)V"); CtMethod copy = CtNewMethod.copy( m, "__configure", clazz, null); … clazz.addMethod(CtNewMethod.make( "public void onClassEvent(int type, Class clazz) {" + "__configure();" + "} ");
How To Test? • Unit tests are (almost) no use
here • Requires integration testing across all platforms: – Containers / versions – JDK / versions – Framework / versions
Custom Dashboard
Thank You! Questions? @antonarhipov
[email protected]
http://www.jrebel.com