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
73
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JUDCon 2012 Boston - The dark sides of integrations
Anton Arhipov
June 12, 2012
More Decks by Anton Arhipov
See All by Anton Arhipov
Spec-Driven Development with AI-Agents: From High-Level Requirements to Working Software
antonarhipov
2
590
Spec-Driven Development with AI Agents (Workshop, May 2026)
antonarhipov
4
520
Spec-Driven Development with AI Agents. Java Day Istanbul 2026
antonarhipov
3
140
Spec-Driven Development with AI Agents: From High-Level Requirements to Working Software
antonarhipov
3
150
Strengthening Immutability in Kotlin. A Glimpse into Valhalla
antonarhipov
3
110
Kotlin—the New and Noteworthy in 2.2
antonarhipov
1
50
Levels of AI-assisted programming
antonarhipov
0
160
Devoxx France 2024. Kotlin - the new and noteworthy
antonarhipov
2
110
Harnessing the power of AI in IntelliJ IDEA
antonarhipov
1
260
Other Decks in Programming
See All in Programming
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.2k
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
170
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
1
350
「正の参照」と 「負の導出」で組む ハーネスエンジニアリング
cottpan
1
150
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
120
Android CLI
fornewid
0
170
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
180
The Bowling Game- From Imperative to Functional Programming - Part 1
philipschwarz
PRO
0
340
AIが無かった頃の素敵な出会いの話
codmoninc
1
220
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
1k
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
240
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
KATA
mclloyd
PRO
35
15k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
620
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
310
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
770
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
460
Technical Leadership for Architectural Decision Making
baasie
3
440
A Tale of Four Properties
chriscoyier
163
24k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
BBQ
matthewcrist
89
10k
Navigating Weather and Climate Data
rabernat
0
400
Art, The Web, and Tiny UX
lynnandtonic
304
22k
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