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
55
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
Kotlin 2.1: Language Updates
antonarhipov
3
60
Devoxx Belgium 2024 - Kotlin 2.0 and beyond
antonarhipov
2
120
Data Analysis with Kotlin Notebook, DataFrame, and Kandy
antonarhipov
1
25
Kotlin 2.0 and Beyond
antonarhipov
2
190
Kotlin Standard Library Gems
antonarhipov
2
460
Ktor Workshop
antonarhipov
1
93
Everybody is a Marketer
antonarhipov
0
120
Idiomatic Kotlin, v2023.05
antonarhipov
2
140
Kotlin DSL in under an hour, DevoxxUK 2023
antonarhipov
2
130
Other Decks in Programming
See All in Programming
プロダクトの品質に コミットする / Commit to Product Quality
pekepek
2
760
Fibonacci Function Gallery - Part 1
philipschwarz
PRO
0
160
数十万行のプロジェクトを Scala 2から3に完全移行した
xuwei_k
0
220
42 best practices for Symfony, a decade later
tucksaun
1
170
N.E.X.T LEVEL
pluu
2
290
103 Early Hints
sugi_0000
1
200
Testing Assembly: Code or Low Code - Navigating the Test Automation Options
maaretp
0
110
RWC 2024 DICOM & ISO/IEC 2022
m_seki
0
190
Semantic Kernelのネイティブプラグインで知識拡張をしてみる
tomokusaba
0
180
AWS認定資格を勉強した先に何があったか
satoshi256kbyte
2
210
Keeping it Ruby: Why Your Product Needs a Ruby SDK - RubyWorld 2024
envek
0
170
Zoneless Testing
rainerhahnekamp
0
120
Featured
See All Featured
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
1
160
Product Roadmaps are Hard
iamctodd
PRO
49
11k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
A Tale of Four Properties
chriscoyier
157
23k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
Become a Pro
speakerdeck
PRO
26
5k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
17
2.2k
Side Projects
sachag
452
42k
How STYLIGHT went responsive
nonsquared
95
5.2k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
Designing for humans not robots
tammielis
250
25k
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