SlideShare une entreprise Scribd logo
1  sur  34
Byte code field report
or
Why we still heavily rely on
Unsafe as of Java 13
What background do I base this talk/opinion based on?
behaviour changing behavior enhancing
dynamic subclass
mocking
e.g. Mockito
persistence proxy
e.g. Hibernate
retransformation
security
e.g. Sqreen
APM/tracing
e.g. Instana
In what areas are instrumentation and dynamic subclassing mainly used?
interface Instrumentation { // since Java 5
void addClassFileTransformer(ClassFileTransformer cft);
}
How to define and change byte code at runtime?
class Unsafe {
Class<?> defineClass(String name, byte[] bytes, ...) { ... }
}
class MethodHandle { // since Java 9
Class<?> defineClass(byte[] bytes) { ... }
}
// since Java 11
package jdk.internal;
class Unsafe { // since Java 9
Class<?> defineClass(String name, byte[] bytes, ...) { ... }
}
Defining classes from Java agents
Transforming classes from Java agents
Defining classes from libraries
Transforming classes from libraries
Miscellaneous
class Sample {
void method() {
Api.invoke(new Callback() {
@Override
void callback() {
System.out.println("called back");
}
}
}
}
Java agents also need to define classes.
class Sample {
void method() {
// do something
}
}
abstract class Callback {
abstract void callback();
}
class Api {
static void invoke(Callback c) { ... }
}
API enhancement proposal: JDK-8200559
interface ClassFileTransformer {
interface ClassDefiner {
Class<?> defineClass(byte[] bytes);
}
byte[] transform(
ClassDefiner classDefiner,
Module module,
ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer
) throws IllegalClassFormatException;
}
// restricted to package of transformed class
class Sender {
void send(Receiver receiver) {
Framework.sendAsync(receiver, new TaggedEvent());
}
}
Injected classes with multiple use sites.
class Sender {
void send(Receiver receiver) {
Framework.sendAsync(receiver, new Event());
}
}
class Receiver {
void receive(Event event) {
if (event instanceof TaggedEvent) {
TrackingAgent.record(((TaggedEvent) event).timestamp);
}
System.out.println(event);
}
}
class Receiver {
void receive(Event event) {
System.out.println(event);
}
}
class TaggedEvent extends Event {
long time = currentTimeMillis();
}
Why JDK-8200559 does not cover all use cases.
• A Java agent cannot rely on a given class loading order.
• The TaggedEvent class must be defined in the package of the first class being loaded.
class sender.Sender
class sender.TaggedEvent
class receiver.Receiver
class receiver.Receiver
class receiver.TaggedEvent
class sender.Sender
package event;
class Event {
/* package-private */ void overridable() {
// default behavior
}
}
• The mediator class might need to be defined in a different package to begin with.
Emulating Unsafe.defineClass via JDK-8200559.
static void defineClass(Instrumentation inst, Class<?> pgkWitness, byte[] bytes) {
ClassFileTransformer t =
(definer, module, loader, name, c, pd, buffer) -> {
if (c == pgkWitness) {
definer.defineClass(bytes);
}
return null;
};
instrumentation.addClassFileTransformer(t, true);
try {
instrumentation.retransformClasses(pgkWitness);
} finally {
instrumentation.removeClassFileTransformer(t);
}
}
0
100
200
300
400
500
600
700
800
milliseconds
sun.misc.Unsafe java.lang.invoke.MethodHandle using package witness
inst.retransformClasses(MethodHandles.class);
class MethodHandles {
public static Lookup publicLookup() {
if (Thread.currentThread().getId() == MY_PRIVILEGED_THREAD) {
return Lookup.IMPL_LOOKUP;
} else {
return Lookup.PUBLIC_LOOKUP;
}
}
}
Bonus: Hijacking the internal method handle to define classes in foreign packages.
class Lookup {
static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC | UNCOND);
}
Defining classes from Java agents
Transforming classes from Java agents
Defining classes from libraries
Transforming classes from libraries
Miscellaneous
Using unsafe class definition in testing context.
UserClass userClass = Mockito.mock(UserClass.class);
user.jar mockito.jar
(unnamed) module
byte[] userClassMock = ...
methodHandle.defineClass(userClassMock);
user module
No standardized support for "test dependencies". It is impossible to open modules to Mockito which only exists in tests.
How to use Unsafe with the jdk.unsupported module being unrolled?
Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe u = (Unsafe) f.get(null);
u.defineClass( ... );
Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true); // only possible from agent (redefineModules) or cmd
Unsafe u = (Unsafe) f.get(null);
f.defineClass( ... );
static void makeAccessible(Unsafe unsafe, Field target) {
Field f = AccessibleObject.class.getDeclaredField("override");
long offset = unsafe.getObjectFieldOffset(f);
u.putBoolean(target, offset, true);
}
// since Java 12
static void makeAccessible(Unsafe unsafe, Field target) {
Field f = classFileCopy(AccessibleObject.class).getDeclaredField("override");
long offset = unsafe.getObjectFieldOffset(f);
u.putBoolean(target, offset, true);
}
0
5
10
15
20
25
30
35
40
45
milliseconds
direct class file copy
user.jar mockito.jar
(unnamed) moduleuser module
class UserClass$MockitoMock
extends UserClass
implements MockitoMock
export/read
class UserClass interface MockitoMock
Handling proxies in a modularized application
UnsafeHelper.defineClass(...);
class ModuleProbe {
static { UserClass.class.getModule()
.addReads(MockitoMock.class
.getModule()); }
}
UnsafeHelper.defineClass(...);
Class.forName(
ModuleProbe.class.getName(),
true, cl);
user.jar mockito.jar
(unnamed) moduleuser module
class UserClass interface MockitoMock
Handling proxies in a modularized application
mock class loader
class MockitoBridge {
static Module module;
}
class ModuleProbe {
static { UserClass.class.getModule()
.addReads(MockitoBridge.class
.getModule());
UserClass.class.getModule()
.addExports(MockitoBridge.module);
}
}
class loader Bclass loader A
UnsafeHelper.defineClass(...);
UnsafeHelper.defineClass(...);
Class.forName(
ModuleProbe.class.getName(),
true, cl);
MockitoBridge.module = mcl
.getUnnamedModule();
0
20
40
60
80
100
120
140
milliseconds
regular direct probe bridged probe
Defining classes from Java agents
Transforming classes from Java agents
Defining classes from libraries
Transforming classes from libraries
Miscellaneous
static Instrumentation inst() {
long processId = ProcessHandle.current().pid();
String location = InstrumentationHolder.class.getProtectionDomain()
.getCodeSource()
.getURL()
.toString();
AttachUtil.startVmAndRun(() -> {
VirtualMachine vm = VirtualMachine.attach(String.valueOf(processId));
vm.loadAgent(location, "");
}
return InstrumentationHolder.inst;
}
class InstrumentationHolder {
static Instrumentation inst;
public static void agentmain(String arg, Instrumentation inst) {
InstrumentationHolder.inst = inst;
}
}
static Instrumentation inst() {
long processId = ProcessHandle.current().pid();
VirtualMachine vm = VirtualMachine.attach(String.valueOf(processId));
vm.loadAgent(InstrumentationHolder.class.getProtectionDomain(),
.getCodeSource()
.getURL()
.toString(), "");
return InstrumentationHolder.inst;
}
Instrumenting code without attaching a Java agent.
FinalUserClass finalUserClass = Mockito.mock(FinalUserClass.class);
Controlled by the jdk.attach.allowAttachSelf option which is false by default.
0
500
1000
1500
2000
2500
3000
milliseconds
command line self-attachment indirect self-attachment
Using self-attach for emulating Unsafe.allocateInstance in Mockito.
UserClass userClass = Mockito.mock(UserClass.class);
class UserClass {
UserClass() { // some side effect }
}
class UserClass {
UserClass() {
if (!MockitoThreadLocalControl.isMockInstantiation()) {
// some side effect
}
}
}
Dealing with the security manager in unit tests and agents.
class AccessControlContext {
void checkPermission(Permission perm) throws AccessControlException {
// check access against security manager
}
}
Not all security managers respect a policy file what makes instrumentation even more attractive.
class AccessControlContext {
void checkPermission(Permission perm) throws AccessControlException {
SecurityManagerInterceptor.check(this, perm);
}
}
interface Instrumentation {
Class<?> defineClass(byte[] bytes, ClassLoader cl);
// ...
}
class TestSupport { // module jdk.test
static Instrumentation getInstrumentation() { ... }
static <T> T allocateInstance(Class<T> type) { ... }
static void setSecurityManagerUnsafe(SecurityManager sm) { ... }
}
What is missing for a full migration away from Unsafe?
The jdk.test module would:
• not be bundled with a non-JDK VM distribution
• it would print a console warning when being loaded
• allow to mark test-scope libraries not to load in production environments
• be resolved automatically by test runners like Maven Surefire
Defining classes from Java agents
Transforming classes from Java agents
Defining classes from libraries
Transforming classes from libraries
Miscellaneous
Callback callback = ...;
ClassFileTransformer t = (definer, module, loader, name, c, pd, buffer) -> {
// how to make the callback instance accessible to an instrumented method?
}
class Dispatcher { // inject into a well-known class loader
ConcurrentMap<String, Object> vals = new ConcurrentHashMap<>();
}
How do agents inject state into classes without changing their shape?
void foo() {
Callback c = (Callback) Dispatcher.vals.get("unique-name");
c.invoked("foo");
}
void foo() {
}
Callback callback = ...;
Dispatcher.vals.put("unique-name", callback);
State state = ...;
ClassFileTransformer t = (definer, module, loader, name, c, pd, buffer) -> {
// how to inject non-serializable state into an instrumented class?
}
How do agents inject state into classes without changing their shape?
class Init { // inject into a well-know class loader
static ConcurrentMap<String, Object> vals = new ConcurrentHashMap<>();
}
Init.vals.put("unique-name", state);
class UserClass {
static final State state;
static {
state = (State) Init.vals.get("unique-name");
}
}
class UserClass {
static final State state;
}
Working with "well-known" class loaders.
Well-known (across all Java versions): system class loader, boot loader
interface Instrumentation {
void appendToBootstrapClassLoaderSearch(JarFile jar);
void appendToSystemClassLoaderSearch(JarFile jar);
}
Change in behavior:
• Java 8 and before: URLClassLoader checks appended search path for any package.
• Java 9 and later: BuiltInClassLoader checks appended search path for unknown packages.
Working with "well-known" modules.
interface Instrumentation {
void redefineModule(
Module module,
Set<Module> extraReads,
Map<String,Set<Module>> extraExports,
Map<String,Set<Module>> extraOpens,
Set<Class<?>> extraUses,
Map<Class<?>,List<Class<?>>> extraProvides
);
}
Not respected by other module systems (OSGi/JBoss modules) which are harder to adjust.
Solutions:
• Adjust module graph via instrumentation + instrument all class loaders to whitelist agent dispatcher package.
• Put dispatcher code into a known package that all class loaders and the VM accept: java.lang@java.base.
The latter is only possible via Unsafe API since Java 9 and later.
Most dynamic code generation is not really dynamic.
Dynamic code generation is
• mainly used because types are not known at library-compile-time despite being known at application compile-time.
• should be avoided for production apllications (reduce start-up time) but is very useful for testing.
@SupportedSourceVersion(SourceVersion.latestSupported())
@SupportedAnnotationTypes("my.SampleAnnotation")
public class MyProcessor extends AbstractProcessor {
void init(ProcessingEnvironment env) { }
boolean process(Set<? extends TypeElement> annoations, RoundEnvironment env) { }
}
Downside of using annotation processors:
• Bound to the Java programming language.
• Cannot change bytecode. (Only via internal API as for example in Lombock.)
• No general code-interception mechanism as for Java agents.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-maven-plugin</artifactId>
<version>LATEST</version>
</dependency>
How to write a "hybrid agent" using build tools.
interface Transformer {
DynamicType.Builder<?> transform(
DynamicType.Builder<?> builder,
TypeDescription typeDescription,
ClassLoader classLoader,
JavaModule module);
}
interface Plugin {
DynamicType.Builder<?> apply(
DynamicType.Builder<?> builder,
TypeDescription typeDescription,
ClassFileLocator classFileLocator);
}
Unified concept in Byte Buddy: agents, plugins and subclass proxies:
Remaining downside of build plugins:
Difficult to instrument code in the JVM and third-party jar files.
An agent-like compile-time transformation API would be a great edition to AOT-based Java, e.g. Graal.
Memory-leaks caused by hybrid agents: lack of ephomerons
public class BootDispatcher {
public static WeakMap<Object, Dispatcher>
dispatchers;
}
class UserClass {
void m() {
BootDispatcher.dispatchers
.get(this)
.handle("m", this);
}
}
class UserClass {
void m() { /* do something */ }
}
class UserClass {
AgentDispatcher dispatcher;
void m() {
dispatcher.handle("m", this);
}
}
static dynamic
hard reference
http://rafael.codes
@rafaelcodes
http://documents4j.com
https://github.com/documents4j/documents4j
http://bytebuddy.net
https://github.com/raphw/byte-buddy

Contenu connexe

Tendances

An introduction to JVM performance
An introduction to JVM performanceAn introduction to JVM performance
An introduction to JVM performanceRafael Winterhalter
 
Bytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASMBytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASMashleypuls
 
Synapseindia reviews.odp.
Synapseindia reviews.odp.Synapseindia reviews.odp.
Synapseindia reviews.odp.Tarunsingh198
 
Java tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo CahersiveenJava tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo CahersiveenGraham Royce
 
Monitoring distributed (micro-)services
Monitoring distributed (micro-)servicesMonitoring distributed (micro-)services
Monitoring distributed (micro-)servicesRafael Winterhalter
 
Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrencyfeng lee
 
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningCarol McDonald
 
Getting started with Java 9 modules
Getting started with Java 9 modulesGetting started with Java 9 modules
Getting started with Java 9 modulesRafael Winterhalter
 
Николай Папирный Тема: "Java memory model для простых смертных"
Николай Папирный Тема: "Java memory model для простых смертных"Николай Папирный Тема: "Java memory model для простых смертных"
Николай Папирный Тема: "Java memory model для простых смертных"Ciklum Minsk
 

Tendances (19)

Java Concurrency by Example
Java Concurrency by ExampleJava Concurrency by Example
Java Concurrency by Example
 
An introduction to JVM performance
An introduction to JVM performanceAn introduction to JVM performance
An introduction to JVM performance
 
Java Programming - 03 java control flow
Java Programming - 03 java control flowJava Programming - 03 java control flow
Java Programming - 03 java control flow
 
Bytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASMBytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASM
 
Javatut1
Javatut1 Javatut1
Javatut1
 
Synapseindia reviews.odp.
Synapseindia reviews.odp.Synapseindia reviews.odp.
Synapseindia reviews.odp.
 
Java tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo CahersiveenJava tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo Cahersiveen
 
Project Coin
Project CoinProject Coin
Project Coin
 
Java tut1
Java tut1Java tut1
Java tut1
 
Tutorial java
Tutorial javaTutorial java
Tutorial java
 
Monitoring distributed (micro-)services
Monitoring distributed (micro-)servicesMonitoring distributed (micro-)services
Monitoring distributed (micro-)services
 
Java Tut1
Java Tut1Java Tut1
Java Tut1
 
Java memory model
Java memory modelJava memory model
Java memory model
 
Java Concurrency
Java ConcurrencyJava Concurrency
Java Concurrency
 
Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrency
 
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
 
Getting started with Java 9 modules
Getting started with Java 9 modulesGetting started with Java 9 modules
Getting started with Java 9 modules
 
Николай Папирный Тема: "Java memory model для простых смертных"
Николай Папирный Тема: "Java memory model для простых смертных"Николай Папирный Тема: "Java memory model для простых смертных"
Николай Папирный Тема: "Java memory model для простых смертных"
 
JVM
JVMJVM
JVM
 

Similaire à Byte code field report

Class loader basic
Class loader basicClass loader basic
Class loader basic명철 강
 
Introduction of Object Oriented Programming Language using Java. .pptx
Introduction of Object Oriented Programming Language using Java. .pptxIntroduction of Object Oriented Programming Language using Java. .pptx
Introduction of Object Oriented Programming Language using Java. .pptxPoonam60376
 
object oriented programming using java, second sem BCA,UoM
object oriented programming using java, second sem BCA,UoMobject oriented programming using java, second sem BCA,UoM
object oriented programming using java, second sem BCA,UoMambikavenkatesh2
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languagesRafael Winterhalter
 
Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)aragozin
 
U3 JAVA.pptx
U3 JAVA.pptxU3 JAVA.pptx
U3 JAVA.pptxmadan r
 
Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Anton Arhipov
 
Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance TuningMinh Hoang
 
Exercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera CymbronExercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera Cymbroncymbron
 
Dependency injection in scala
Dependency injection in scalaDependency injection in scala
Dependency injection in scalaMichal Bigos
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingVisual Engineering
 
Java Programs
Java ProgramsJava Programs
Java Programsvvpadhu
 
java_bba_21_vision academy_final.pdf
java_bba_21_vision academy_final.pdfjava_bba_21_vision academy_final.pdf
java_bba_21_vision academy_final.pdfakankshasorate1
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 

Similaire à Byte code field report (20)

Class loader basic
Class loader basicClass loader basic
Class loader basic
 
Introduction of Object Oriented Programming Language using Java. .pptx
Introduction of Object Oriented Programming Language using Java. .pptxIntroduction of Object Oriented Programming Language using Java. .pptx
Introduction of Object Oriented Programming Language using Java. .pptx
 
SWING.pptx
SWING.pptxSWING.pptx
SWING.pptx
 
object oriented programming using java, second sem BCA,UoM
object oriented programming using java, second sem BCA,UoMobject oriented programming using java, second sem BCA,UoM
object oriented programming using java, second sem BCA,UoM
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
 
Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)
 
U3 JAVA.pptx
U3 JAVA.pptxU3 JAVA.pptx
U3 JAVA.pptx
 
Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012
 
Java Tutorial 1
Java Tutorial 1Java Tutorial 1
Java Tutorial 1
 
Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance Tuning
 
Lecture 6.pptx
Lecture 6.pptxLecture 6.pptx
Lecture 6.pptx
 
Exercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera CymbronExercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera Cymbron
 
Dependency injection in scala
Dependency injection in scalaDependency injection in scala
Dependency injection in scala
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
Fault tolerance made easy
Fault tolerance made easyFault tolerance made easy
Fault tolerance made easy
 
Java bcs 21_vision academy_final
Java bcs 21_vision academy_finalJava bcs 21_vision academy_final
Java bcs 21_vision academy_final
 
Java Programs
Java ProgramsJava Programs
Java Programs
 
java_bba_21_vision academy_final.pdf
java_bba_21_vision academy_final.pdfjava_bba_21_vision academy_final.pdf
java_bba_21_vision academy_final.pdf
 
Static keyword.pptx
Static keyword.pptxStatic keyword.pptx
Static keyword.pptx
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 

Dernier

Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durbanmasabamasaba
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...masabamasaba
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
SHRMPro HRMS Software Solutions Presentation
SHRMPro HRMS Software Solutions PresentationSHRMPro HRMS Software Solutions Presentation
SHRMPro HRMS Software Solutions PresentationShrmpro
 

Dernier (20)

Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
SHRMPro HRMS Software Solutions Presentation
SHRMPro HRMS Software Solutions PresentationSHRMPro HRMS Software Solutions Presentation
SHRMPro HRMS Software Solutions Presentation
 

Byte code field report

  • 1. Byte code field report or Why we still heavily rely on Unsafe as of Java 13
  • 2. What background do I base this talk/opinion based on?
  • 3. behaviour changing behavior enhancing dynamic subclass mocking e.g. Mockito persistence proxy e.g. Hibernate retransformation security e.g. Sqreen APM/tracing e.g. Instana In what areas are instrumentation and dynamic subclassing mainly used?
  • 4. interface Instrumentation { // since Java 5 void addClassFileTransformer(ClassFileTransformer cft); } How to define and change byte code at runtime? class Unsafe { Class<?> defineClass(String name, byte[] bytes, ...) { ... } } class MethodHandle { // since Java 9 Class<?> defineClass(byte[] bytes) { ... } } // since Java 11 package jdk.internal; class Unsafe { // since Java 9 Class<?> defineClass(String name, byte[] bytes, ...) { ... } }
  • 5. Defining classes from Java agents Transforming classes from Java agents Defining classes from libraries Transforming classes from libraries Miscellaneous
  • 6. class Sample { void method() { Api.invoke(new Callback() { @Override void callback() { System.out.println("called back"); } } } } Java agents also need to define classes. class Sample { void method() { // do something } } abstract class Callback { abstract void callback(); } class Api { static void invoke(Callback c) { ... } }
  • 7. API enhancement proposal: JDK-8200559 interface ClassFileTransformer { interface ClassDefiner { Class<?> defineClass(byte[] bytes); } byte[] transform( ClassDefiner classDefiner, Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer ) throws IllegalClassFormatException; } // restricted to package of transformed class
  • 8. class Sender { void send(Receiver receiver) { Framework.sendAsync(receiver, new TaggedEvent()); } } Injected classes with multiple use sites. class Sender { void send(Receiver receiver) { Framework.sendAsync(receiver, new Event()); } } class Receiver { void receive(Event event) { if (event instanceof TaggedEvent) { TrackingAgent.record(((TaggedEvent) event).timestamp); } System.out.println(event); } } class Receiver { void receive(Event event) { System.out.println(event); } } class TaggedEvent extends Event { long time = currentTimeMillis(); }
  • 9. Why JDK-8200559 does not cover all use cases. • A Java agent cannot rely on a given class loading order. • The TaggedEvent class must be defined in the package of the first class being loaded. class sender.Sender class sender.TaggedEvent class receiver.Receiver class receiver.Receiver class receiver.TaggedEvent class sender.Sender package event; class Event { /* package-private */ void overridable() { // default behavior } } • The mediator class might need to be defined in a different package to begin with.
  • 10. Emulating Unsafe.defineClass via JDK-8200559. static void defineClass(Instrumentation inst, Class<?> pgkWitness, byte[] bytes) { ClassFileTransformer t = (definer, module, loader, name, c, pd, buffer) -> { if (c == pgkWitness) { definer.defineClass(bytes); } return null; }; instrumentation.addClassFileTransformer(t, true); try { instrumentation.retransformClasses(pgkWitness); } finally { instrumentation.removeClassFileTransformer(t); } }
  • 12. inst.retransformClasses(MethodHandles.class); class MethodHandles { public static Lookup publicLookup() { if (Thread.currentThread().getId() == MY_PRIVILEGED_THREAD) { return Lookup.IMPL_LOOKUP; } else { return Lookup.PUBLIC_LOOKUP; } } } Bonus: Hijacking the internal method handle to define classes in foreign packages. class Lookup { static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED); static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC | UNCOND); }
  • 13. Defining classes from Java agents Transforming classes from Java agents Defining classes from libraries Transforming classes from libraries Miscellaneous
  • 14. Using unsafe class definition in testing context. UserClass userClass = Mockito.mock(UserClass.class); user.jar mockito.jar (unnamed) module byte[] userClassMock = ... methodHandle.defineClass(userClassMock); user module No standardized support for "test dependencies". It is impossible to open modules to Mockito which only exists in tests.
  • 15. How to use Unsafe with the jdk.unsupported module being unrolled? Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); Unsafe u = (Unsafe) f.get(null); u.defineClass( ... ); Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); // only possible from agent (redefineModules) or cmd Unsafe u = (Unsafe) f.get(null); f.defineClass( ... ); static void makeAccessible(Unsafe unsafe, Field target) { Field f = AccessibleObject.class.getDeclaredField("override"); long offset = unsafe.getObjectFieldOffset(f); u.putBoolean(target, offset, true); } // since Java 12 static void makeAccessible(Unsafe unsafe, Field target) { Field f = classFileCopy(AccessibleObject.class).getDeclaredField("override"); long offset = unsafe.getObjectFieldOffset(f); u.putBoolean(target, offset, true); }
  • 17. user.jar mockito.jar (unnamed) moduleuser module class UserClass$MockitoMock extends UserClass implements MockitoMock export/read class UserClass interface MockitoMock Handling proxies in a modularized application UnsafeHelper.defineClass(...); class ModuleProbe { static { UserClass.class.getModule() .addReads(MockitoMock.class .getModule()); } } UnsafeHelper.defineClass(...); Class.forName( ModuleProbe.class.getName(), true, cl);
  • 18. user.jar mockito.jar (unnamed) moduleuser module class UserClass interface MockitoMock Handling proxies in a modularized application mock class loader class MockitoBridge { static Module module; } class ModuleProbe { static { UserClass.class.getModule() .addReads(MockitoBridge.class .getModule()); UserClass.class.getModule() .addExports(MockitoBridge.module); } } class loader Bclass loader A UnsafeHelper.defineClass(...); UnsafeHelper.defineClass(...); Class.forName( ModuleProbe.class.getName(), true, cl); MockitoBridge.module = mcl .getUnnamedModule();
  • 20. Defining classes from Java agents Transforming classes from Java agents Defining classes from libraries Transforming classes from libraries Miscellaneous
  • 21. static Instrumentation inst() { long processId = ProcessHandle.current().pid(); String location = InstrumentationHolder.class.getProtectionDomain() .getCodeSource() .getURL() .toString(); AttachUtil.startVmAndRun(() -> { VirtualMachine vm = VirtualMachine.attach(String.valueOf(processId)); vm.loadAgent(location, ""); } return InstrumentationHolder.inst; } class InstrumentationHolder { static Instrumentation inst; public static void agentmain(String arg, Instrumentation inst) { InstrumentationHolder.inst = inst; } } static Instrumentation inst() { long processId = ProcessHandle.current().pid(); VirtualMachine vm = VirtualMachine.attach(String.valueOf(processId)); vm.loadAgent(InstrumentationHolder.class.getProtectionDomain(), .getCodeSource() .getURL() .toString(), ""); return InstrumentationHolder.inst; } Instrumenting code without attaching a Java agent. FinalUserClass finalUserClass = Mockito.mock(FinalUserClass.class); Controlled by the jdk.attach.allowAttachSelf option which is false by default.
  • 23. Using self-attach for emulating Unsafe.allocateInstance in Mockito. UserClass userClass = Mockito.mock(UserClass.class); class UserClass { UserClass() { // some side effect } } class UserClass { UserClass() { if (!MockitoThreadLocalControl.isMockInstantiation()) { // some side effect } } }
  • 24. Dealing with the security manager in unit tests and agents. class AccessControlContext { void checkPermission(Permission perm) throws AccessControlException { // check access against security manager } } Not all security managers respect a policy file what makes instrumentation even more attractive. class AccessControlContext { void checkPermission(Permission perm) throws AccessControlException { SecurityManagerInterceptor.check(this, perm); } }
  • 25. interface Instrumentation { Class<?> defineClass(byte[] bytes, ClassLoader cl); // ... } class TestSupport { // module jdk.test static Instrumentation getInstrumentation() { ... } static <T> T allocateInstance(Class<T> type) { ... } static void setSecurityManagerUnsafe(SecurityManager sm) { ... } } What is missing for a full migration away from Unsafe? The jdk.test module would: • not be bundled with a non-JDK VM distribution • it would print a console warning when being loaded • allow to mark test-scope libraries not to load in production environments • be resolved automatically by test runners like Maven Surefire
  • 26. Defining classes from Java agents Transforming classes from Java agents Defining classes from libraries Transforming classes from libraries Miscellaneous
  • 27. Callback callback = ...; ClassFileTransformer t = (definer, module, loader, name, c, pd, buffer) -> { // how to make the callback instance accessible to an instrumented method? } class Dispatcher { // inject into a well-known class loader ConcurrentMap<String, Object> vals = new ConcurrentHashMap<>(); } How do agents inject state into classes without changing their shape? void foo() { Callback c = (Callback) Dispatcher.vals.get("unique-name"); c.invoked("foo"); } void foo() { } Callback callback = ...; Dispatcher.vals.put("unique-name", callback);
  • 28. State state = ...; ClassFileTransformer t = (definer, module, loader, name, c, pd, buffer) -> { // how to inject non-serializable state into an instrumented class? } How do agents inject state into classes without changing their shape? class Init { // inject into a well-know class loader static ConcurrentMap<String, Object> vals = new ConcurrentHashMap<>(); } Init.vals.put("unique-name", state); class UserClass { static final State state; static { state = (State) Init.vals.get("unique-name"); } } class UserClass { static final State state; }
  • 29. Working with "well-known" class loaders. Well-known (across all Java versions): system class loader, boot loader interface Instrumentation { void appendToBootstrapClassLoaderSearch(JarFile jar); void appendToSystemClassLoaderSearch(JarFile jar); } Change in behavior: • Java 8 and before: URLClassLoader checks appended search path for any package. • Java 9 and later: BuiltInClassLoader checks appended search path for unknown packages.
  • 30. Working with "well-known" modules. interface Instrumentation { void redefineModule( Module module, Set<Module> extraReads, Map<String,Set<Module>> extraExports, Map<String,Set<Module>> extraOpens, Set<Class<?>> extraUses, Map<Class<?>,List<Class<?>>> extraProvides ); } Not respected by other module systems (OSGi/JBoss modules) which are harder to adjust. Solutions: • Adjust module graph via instrumentation + instrument all class loaders to whitelist agent dispatcher package. • Put dispatcher code into a known package that all class loaders and the VM accept: java.lang@java.base. The latter is only possible via Unsafe API since Java 9 and later.
  • 31. Most dynamic code generation is not really dynamic. Dynamic code generation is • mainly used because types are not known at library-compile-time despite being known at application compile-time. • should be avoided for production apllications (reduce start-up time) but is very useful for testing. @SupportedSourceVersion(SourceVersion.latestSupported()) @SupportedAnnotationTypes("my.SampleAnnotation") public class MyProcessor extends AbstractProcessor { void init(ProcessingEnvironment env) { } boolean process(Set<? extends TypeElement> annoations, RoundEnvironment env) { } } Downside of using annotation processors: • Bound to the Java programming language. • Cannot change bytecode. (Only via internal API as for example in Lombock.) • No general code-interception mechanism as for Java agents.
  • 32. <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-maven-plugin</artifactId> <version>LATEST</version> </dependency> How to write a "hybrid agent" using build tools. interface Transformer { DynamicType.Builder<?> transform( DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module); } interface Plugin { DynamicType.Builder<?> apply( DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassFileLocator classFileLocator); } Unified concept in Byte Buddy: agents, plugins and subclass proxies: Remaining downside of build plugins: Difficult to instrument code in the JVM and third-party jar files. An agent-like compile-time transformation API would be a great edition to AOT-based Java, e.g. Graal.
  • 33. Memory-leaks caused by hybrid agents: lack of ephomerons public class BootDispatcher { public static WeakMap<Object, Dispatcher> dispatchers; } class UserClass { void m() { BootDispatcher.dispatchers .get(this) .handle("m", this); } } class UserClass { void m() { /* do something */ } } class UserClass { AgentDispatcher dispatcher; void m() { dispatcher.handle("m", this); } } static dynamic hard reference