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
63
0
Share
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
52
Strengthening Immutability in Kotlin. A Glimpse into Valhalla
antonarhipov
2
78
Kotlin—the New and Noteworthy in 2.2
antonarhipov
1
33
Levels of AI-assisted programming
antonarhipov
0
110
Devoxx France 2024. Kotlin - the new and noteworthy
antonarhipov
2
94
Harnessing the power of AI in IntelliJ IDEA
antonarhipov
1
230
VirtualJUG: Kotlin 2.0 and beyond
antonarhipov
1
160
Kotlin 2.1: Language Updates
antonarhipov
3
200
Devoxx Belgium 2024 - Kotlin 2.0 and beyond
antonarhipov
2
200
Other Decks in Programming
See All in Programming
今からFlash開発できるわけないじゃん、ムリムリ! (※ムリじゃなかった!?)
arkw
0
180
ネイティブアプリとWebフロントエンドのAPI通信ラッパーにおける共通化の勘所
suguruooki
0
250
Xdebug と IDE による デバッグ実行の仕組みを見る / Exploring-How-Debugging-Works-with-Xdebug-and-an-IDE
shin1x1
0
340
脱 雰囲気実装!AgentCoreを良い感じにWEBアプリケーションに組み込むために
takuyay0ne
3
440
VueエンジニアがReactを触って感じた_設計の違い
koukimiura
0
160
おれのAgentic Coding 2026/03
tsukasagr
1
130
Redox OS でのネームスペース管理と chroot の実現
isanethen
0
550
ローカルで稼働するAI エージェントを超えて / beyond-local-ai-agents
gawa
2
250
感情を設計する
ichimichi
5
1.2k
飯MCP
yusukebe
0
480
我々はなぜ「層」を分けるのか〜「関心の分離」と「抽象化」で手に入れる変更に強いシンプルな設計〜 #phperkaigi / PHPerKaigi 2026
shogogg
2
810
RSAが破られる前に知っておきたい 耐量子計算機暗号(PQC)入門 / Intro to PQC: Preparing for the Post-RSA Era
mackey0225
3
120
Featured
See All Featured
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
1k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
500
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.8k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
130
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.7k
Why Our Code Smells
bkeepers
PRO
340
58k
The Pragmatic Product Professional
lauravandoore
37
7.2k
Skip the Path - Find Your Career Trail
mkilby
1
100
Marketing to machines
jonoalderson
1
5.1k
The agentic SEO stack - context over prompts
schlessera
0
730
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