Organizer Conference Gold partner General partner

Runtime class generation

let the machine work for you

autumn 2016

Jan @Novoj Novotný

Follow presentation with me at
http://novoj.github.io/reveal.js/runtime-class-generation.html

Code with me
git@github.com:novoj/RuntimeClassGeneration.git

About me

Wouldn't it be nice if this code

public interface PersonDao {

    void create(String firstName, String lastName, LocalDate birthDate);

    void store(Person person);

    Person getById();

    boolean removeById();

}

was automatically implemented by machine?

It's already out there

Just to name a few:

But how they do it?

Using automatic class (code) generation in:

Both approaches have their pros and cons.

Project Lombok

Lombok Person Example / POM Example

Let's prototype!

Branch: tutorial01

Look at:

Pros

  • type safe code around hashmap
  • supports refactoring
  • supports searching

Cons

  • string parsing - method.getName()
  • ugly code
  • most likely pretty slow

Refactor!

Proxy class caching

Branch: tutorial02

  • java.lang.reflect.Proxy already caches classes
  • but we can do this more effectively
  • this is valid even for other class generators - I recommend disabling generator caching and implement your own

Refactor!

Method logic caching

Branch: tutorial03

Let's make it even better:

  1. convert IF to lambda functions
  2. cache pair Proxy.method + service lambda
  3. cache information about method name decomposition, so that parsing is done only once

Custom method body

Branch: tutorial04

What if we need custom logic on a proxy?

What if we want to mix and match custom logic with automatic one?

Default / abstract methods to the rescue.

Look at:

DAO implementation

all building blocks in place

Branch: tutorial05

Nothing much new here

Look at:

DAO implementation

nicer create & add method

Branch: tutorial06

Let's get advantage of parameters!

Look at:

DAO implementation

finder / removal implementation

DAO implementation

finder implementation

Branch: tutorial07

Look at:

Bonus

proxy serialization

Branch: master

We can't simply serialize proxy - class might not be known at the moment of deserialization.

We need to serialize "recipe" how to reconstruct the class.

Look at:

Bonus

always repackage


    org.sonatype.plugins
    jarjar-maven-plugin
    1.9
    
        
	        package
	        
		        jarjar
	        
	        
		        true
		        
			        org.javassist:javassist
		        
		        
			        
				        javassist.**
				        cz.novoj.generation.internal.javassist.@1
			        
		        
	        
        
    

Bonus

additional topics

  • annotations on methods are not inherited in Java and some class generations utils doesn't copy them on overriden methods on subclass, look what Spring guys worked around this
  • generics resolution - is tricky, again see Spring implementation
  • performance of proxies is not so bad, but dynamic nature makes them much slower than static class implementation

Thank your for your attention

Contact me at @Novoj or novotnaci@gmail.com