Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
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
61
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
33
Kotlin—the New and Noteworthy in 2.2
antonarhipov
1
11
Levels of AI-assisted programming
antonarhipov
0
67
Devoxx France 2024. Kotlin - the new and noteworthy
antonarhipov
2
62
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
実は歴史的なアップデートだと思う AWS Interconnect - multicloud
maroon1st
0
200
Context is King? 〜Verifiability時代とコンテキスト設計 / Beyond "Context is King"
rkaga
10
1.3k
Microservices rules: What good looks like
cer
PRO
0
1.4k
DevFest Android in Korea 2025 - 개발자 커뮤니티를 통해 얻는 가치
wisemuji
0
150
Flutter On-device AI로 완성하는 오프라인 앱, 박제창 @DevFest INCHEON 2025
itsmedreamwalker
1
110
「コードは上から下へ読むのが一番」と思った時に、思い出してほしい話
panda728
PRO
38
26k
手が足りない!兼業データエンジニアに必要だったアーキテクチャと立ち回り
zinkosuke
0
730
UIデザインに役立つ 2025年の最新CSS / The Latest CSS for UI Design 2025
clockmaker
18
7.5k
20 years of Symfony, what's next?
fabpot
2
360
tparseでgo testの出力を見やすくする
utgwkk
2
230
【CA.ai #3】Google ADKを活用したAI Agent開発と運用知見
harappa80
0
320
バックエンドエンジニアによる Amebaブログ K8s 基盤への CronJobの導入・運用経験
sunabig
0
160
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
9
710
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.8k
What's in a price? How to price your products and services
michaelherold
246
13k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.3k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.6k
Designing for Performance
lara
610
69k
Java REST API Framework Comparison - PWX 2021
mraible
34
9k
GraphQLとの向き合い方2022年版
quramy
50
14k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.8k
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