Will it blend ? Java agents and OSGi Slides revision : 20190923- ea 7 - - PowerPoint PPT Presentation

will it blend java agents and osgi
SMART_READER_LITE
LIVE PREVIEW

Will it blend ? Java agents and OSGi Slides revision : 20190923- ea 7 - - PowerPoint PPT Presentation

Will it blend ? Java agents and OSGi Slides revision : 20190923- ea 7 c 311 1 Welcome 2 About me 3 Outline Quick demo Java agents primer Usage scenarios OSGi integration Integration testing Testing demo 4 Quick demo 5 Java agents


slide-1
SLIDE 1

Will it blend? Java agents and OSGi

Slides revision: 20190923-ea7c311

1

slide-2
SLIDE 2

Welcome

2

slide-3
SLIDE 3

About me

3

slide-4
SLIDE 4

Outline

Quick demo Java agents primer Usage scenarios OSGi integration Integration testing Testing demo

4

slide-5
SLIDE 5

Quick demo

5

slide-6
SLIDE 6

Java agents primer

6

slide-7
SLIDE 7

Java instrumentation APIs

java.lang.instrument Javadoc, Java SE 8 Provides services that allow Java programming language agents to instrument programs running

  • n the JVM.

7

slide-8
SLIDE 8

Static agents

# loaded at application startup $ java -javaagent:agent.jar -jar app.jar Premain-Class: org.example.my.Agent import java.lang.instrument.*; public class Agent { public static void premain(String args,⏎ Instrumentation inst) { inst.addTransformer(new ClassFileTransformer() { /* implementation elided */ }); } }

8

slide-9
SLIDE 9

Dynamic agents

// dynamically attached to a running JVM VirtualMachine vm = VirtualMachine.attach(vmPid); vm.loadAgent(agentFilePath); vm.detach(); Agent-Class: org.example.my.Agent import java.lang.instrument.*; public class Agent { public static void agentmain(String args,⏎ Instrumentation inst) { inst.addTransformer(new ClassFileTransformer() { /* implementation elided */ }); } }

9

slide-10
SLIDE 10

Class transformation

public interface ClassFileTransformer { byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException; }

10

slide-11
SLIDE 11

Java bytecode

public static void main(java.lang.String[]); Code: 0: getstatic #16⏎ // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #22⏎ // String Hello, world 5: invokevirtual #24⏎ // Method java/io/PrintStream.println:(Ljava/lang/String; 8: return

11

slide-12
SLIDE 12

Bytecode generation libraries

Apache Commons BCEL ByteBuddy CGLib Javassist ObjectWeb ASM

12

slide-13
SLIDE 13

Bytecode generation with Javassist

public byte[] transform(...) throws ... { ClassPool classPool = ClassPool.getDefault(); CtMethod method = classPool.getMethod(⏎ Descriptor.toJavaName(className), "main"); method.insertAfter("System.out.println " + ⏎ "(\"... hello yourself!...\");"); byte[] newClass = method.getDeclaringClass()⏎ .toBytecode(); method.getDeclaringClass().detach(); return newClass; }

13

slide-14
SLIDE 14

Usage scenarios

14

slide-15
SLIDE 15

When to use agents

  • 1. Code outside of your control
  • 2. No better platform facilities exist
  • 3. (Usually) Cross-cutting concerns

15

slide-16
SLIDE 16

Agent examples

  • 1. Monitoring (logging, tracing, error reporting ...)
  • 2. Profiling
  • 3. Debugging
  • 4. Mocking libraries
  • 5. Code reload/Hot swap

16

slide-17
SLIDE 17

OSGi integration

17

slide-18
SLIDE 18

Mind the classloader

  • ClassPool defaultPool = ClassPool.getDefault();
  • CtClass cc = defaultPool.get(⏎
  • Descriptor.toJavaName(className));

+ ClassPool classPool = new ClassPool(true); + classPool.appendClassPath(new LoaderClassPath(loader)); + classPool.insertClassPath(new ByteArrayClassPath(⏎ + Descriptor.toJavaName(className), classfileBuffer));

18

slide-19
SLIDE 19

Carefully manage dependencies

New requirements typically fail since they are not defined by the bundle Bundles can be processed at build-time Patching Import-Package DynamicImport-Package: *

19

slide-20
SLIDE 20

OSGi alternatives - Weaving Hooks

 Simplified deployment - OSGi bundle  Simple registration via OSGi whiteboard  Handles updated bundle package imports  OSGi-only solution

20

slide-21
SLIDE 21

Integration testing

21

slide-22
SLIDE 22

Packaging challenges

Java agents... must be packaged as a Jar file, with a specific manifest not trivially attached to the current process usually a one-way deal, no support for rolling back class changes

22

slide-23
SLIDE 23

Custom test launchers

"unit" tests launch Java process with custom agents attached require separate communication channel with java agent no out-of-the-box support for code coverage and

  • ther tools

23

slide-24
SLIDE 24

Bootstrapping the test

// 1. which java? String javaHome = System.getProperty("java.home"); Path javaExe = Paths.get(javaHome, "bin", "java"); // 2. which jar? String ja = findAgentJar(); // 3. which classpath? String classPath = buildClassPath(); // 4. launch ProcessBuilder pb = new ProcessBuilder( javaExe.toString(), "-javaagent:" + ja, "-cp", classPath, TestApplication.class.getName() );

24

slide-25
SLIDE 25

Verifying side effects

Path stdout = Paths.get("target", "stdout.txt"); Path stderr = Paths.get("target", "stderr.txt"); pb.redirectInput(Redirect.INHERIT); pb.redirectOutput(stdout.toFile()); pb.redirectError(stderr.toFile());

25

slide-26
SLIDE 26

Adding code coverage

ProcessBuilder pb = new ProcessBuilder( javaExe.toString(), "-javaagent:" + codeCoverageAgent, "-javaagent:" + ja, "-cp", classPath, TestApplication.class.getName() );

26

slide-27
SLIDE 27

OSGi integration testing

// note - must run in a forked container @RunWith(PaxExam.class) public class OsgiIT { @Configuration public Option[] config() throws IOException { return options( junitBundles(), ⏎ vmOption("-javaagent:" + agentJar) ); } @Test public void callTimesOut() throws IOException { assertTrue(agentReallyWorks()); } }

27

slide-28
SLIDE 28

Testing demo

28

slide-29
SLIDE 29

Resources

https://docs.oracle.com/javase/8/docs/api/java/lang/instrum summary.html https://www.javassist.org/ https://sling.apache.org/documentation/bundles/connectio agent.html

29

slide-30
SLIDE 30

30