code generation for alternative languages
TRANSCRIPT
![Page 1: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/1.jpg)
Code generation for alternative languages
and Java runtimes
![Page 2: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/2.jpg)
interface Framework { <T> Class<? extends T> secure(Class<T> type); }
class Service { @Secured(user = "ADMIN") void deleteEverything() { // delete everything... } }
@interface Secured { String user(); }
class UserHolder { static String user = "ANONYMOUS"; }
does not know aboutdepends on
discovers at runtime
![Page 3: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/3.jpg)
class Service { @Secured(user = "ADMIN") void deleteEverything() { if(!"ADMIN".equals(UserHolder.user)) { throw new IllegalStateException("Wrong user"); } // delete everything... } }
redefine class(build time, agent)
create subclass(Liskov substitution)
class SecuredService extends Service { @Override void deleteEverything() { if(!"ADMIN".equals(UserHolder.user)) { throw new IllegalStateException("Wrong user"); } super.deleteEverything(); } }
class Service { @Secured(user = "ADMIN") void deleteEverything() { // delete everything... } }
![Page 4: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/4.jpg)
0xCAFEBABE
source code
byte code
JVM
javac scalac groovyc jrubyc
JIT compilerinterpreter
class loader
creates
reads
runs
![Page 5: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/5.jpg)
![Page 6: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/6.jpg)
class Sample$MockitoMock extends Sample {
@Override String getValue() { return Mockito.mock(this, new Object[0], Sample.class.getMethod("getValue")); } String original$getValue() { return super.getValue(); }
@Override void setValue(String x) { Mockito.mock(this, new Object[] { x }, Sample.class.getMethod("setValue", String.class)); } void original$setValue(String x) { super.setValue(x); } }
class Sample {
String value;
String getValue() { return value; }
void setValue(String x) { this.value = x; } }
![Page 7: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/7.jpg)
class Sample {
var value: String? = null
fun getValue() = value
fun setValue(x: String?) { this.value = x }}
final class Sample {
String value;
final String getValue() { return value; }
final void setValue(String x) { this.value = x; } }
![Page 8: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/8.jpg)
open class Sample {
var value: String? = null
open fun getValue() = value
open fun setValue(x: String?) { this.value = x }}
class Sample {
String value;
String getValue() { return value; }
void setValue(String x) { this.value = x; } }
![Page 9: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/9.jpg)
<plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <configuration> <compilerPlugins> <plugin>all-open</plugin> </compilerPlugins> <pluginOptions> <option>all-open:annotation=pkg.MyOpen</option> </pluginOptions> </configuration>
<dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-allopen</artifactId> <version>${kotlin.version}</version> </dependency> </dependencies> </plugin>
annotation class MyOpen
![Page 10: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/10.jpg)
final class Sample {
String value;
final String getValue() { if (MockitoInfra.isMockMode(this)) { return Mockito.mock( this, new Object[0], Sample.class.getMethod("getValue")); } else { return value; } }
final void setValue(String x) { if (MockitoInfra.isMockMode(this)) { Mockito.mock( this, new Object[] { x }, Sample.class.getMethod("setValue", String.class)); } else { this.value = x; } } }
final class Sample {
String value;
final String getValue() { return value; }
final void setValue(String x) { this.value = x; } }
![Page 11: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/11.jpg)
class MockitoInfra { static final WeakConcurrentMap<Object, MockitoHandler> mocks;
static final ThreadLocal<Boolean> selfCall;
static boolean isMock(Object instance) { return mocks.containsKey(instance); } static void registerMock(Object instance, MockHandler handler) { mocks.put(instance, handler); }
static boolean isMockMode(Object instance) { return isMock(instance) && selfCall.get(); } static void setMockMode(boolean mode) { selfCall.set(mode); } }
https://github.com/raphw/weak-lock-free
![Page 12: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/12.jpg)
package java.lang.instrumentation;
interface Instrumentation {
void addTransformer(ClassFileTransformer transformer, boolean retransform); void retransformClasses(Class<?>... types);
void appendToBootstrapSearch(File file);
// ... }
interface ClassFileTransformer {
byte[] transform(ClassLoader loader, String name, Class<?> type, ProtectionDomain pd, byte[] buffer); }
NOPE!
![Page 13: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/13.jpg)
Java virtual machine
[stack, JIT]
Dalvik virtual machine
[register, JIT]
Android runtime
[register, AOT]
![Page 14: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/14.jpg)
public class SimplePlugin implements Plugin {
@Override public boolean matches(TypeDescription target) { return target.getName().equals("Foo"); }
@Override public DynamicType.Builder<?> apply( DynamicType.Builder<?> builder, TypeDescription typeDescription) { return builder.method(named("bar")) .intercept(value("Hello World!")); } }
https://github.com/raphw/byte-buddy
![Page 15: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/15.jpg)
Build-time instrumentation with Maven.
<plugin> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy-maven-plugin</artifactId> <executions> <execution> <goals> <goal>transform</goal> </goals> </execution> </executions> <configuration> <transformations> <transformation> <plugin>pkg.SimplePlugin</plugin> </transformation> </transformations> </configuration> </plugin>
![Page 16: Code generation for alternative languages](https://reader034.vdocuments.net/reader034/viewer/2022042706/58a952c01a28ab77408b516f/html5/thumbnails/16.jpg)
http://rafael.codes@rafaelcodes
http://documents4j.comhttps://github.com/documents4j/documents4j
http://bytebuddy.nethttps://github.com/raphw/byte-buddy