Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Code generation for alternative languages

An overview how to realize code generation of languages on the JVM that implement other class layouts than the Java programming languages. As an example, the inline-mock-maker for Mockito is discussed which supports languages like Kotlin that make any property final by default.

  • Be the first to comment

  • Be the first to like this

Code generation for alternative languages

  1. 1. Code generation for alternative languages and Java runtimes
  2. 2. 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 discoversatruntime
  3. 3. 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... } }
  4. 4. 0xCAFEBABE source code byte code JVM javac scalac groovyc jrubyc JIT compilerinterpreter class loader creates reads runs
  5. 5. 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; } }
  6. 6. 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; } }
  7. 7. 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; } }
  8. 8. <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
  9. 9. 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; } }
  10. 10. 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
  11. 11. 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!
  12. 12. Java virtual machine [stack, JIT] Dalvik virtual machine [register, JIT] Android runtime [register, AOT]
  13. 13. 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
  14. 14. 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>
  15. 15. http://rafael.codes @rafaelcodes http://documents4j.com https://github.com/documents4j/documents4j http://bytebuddy.net https://github.com/raphw/byte-buddy

    Be the first to comment

    Login to see the comments

An overview how to realize code generation of languages on the JVM that implement other class layouts than the Java programming languages. As an example, the inline-mock-maker for Mockito is discussed which supports languages like Kotlin that make any property final by default.

Views

Total views

370

On Slideshare

0

From embeds

0

Number of embeds

0

Actions

Downloads

4

Shares

0

Comments

0

Likes

0

×