Code generation for alternative languages
-
Upload
rafael-winterhalter -
Category
Software
-
view
49 -
download
5
Transcript of Code generation for alternative languages
Code generation for alternative languages
and Java runtimes
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
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... } }
0xCAFEBABE
source code
byte code
JVM
javac scalac groovyc jrubyc
JIT compilerinterpreter
class loader
creates
reads
runs
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; } }
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; } }
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; } }
<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
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; } }
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
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!
Java virtual machine
[stack, JIT]
Dalvik virtual machine
[register, JIT]
Android runtime
[register, AOT]
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
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>
http://rafael.codes@rafaelcodes
http://documents4j.comhttps://github.com/documents4j/documents4j
http://bytebuddy.nethttps://github.com/raphw/byte-buddy