Presentation by Micronaut creator Graeme Rocher on how frameworks like Micronaut are evolving Java for the Microservice and Serverless Era through the use of innovative techniques like Ahead of Time Compilation (AoT)
2. About Me
• Graeme Rocher
• Creator of Grails and Micronaut
• Principal Engineer at Object Computing
• 2018 Oracle Groundbreaker Award Winner
• Java Champion
3. Agenda
• Challenges Facing Java
• Introduction to Micronaut
• Micronaut's Approach to Solving The Problems
• Demos!
4. Java and Serverless
• Challenges to using Java in
Serverless / Microservices scenarios
• Existing Tools and Frameworks Not
Optimized for Cold Starts / Low
Memory
• Go, Node etc. better in this regards
• Tim Bray (Amazon/AWS) and others
not recommending Java
https://youtu.be/IPOvrK3S3gQ?t=1109
5. Java's Problems for
Frameworks
• Limited Annotation API
• Type Erasure
• Slow Reflection
• Reflective Data Caches
• Classpath Scanning
• Slow Dynamic Class Loading
6. Java's Problems
• Greatly Exaggerated (Java has been
dead forever)
• Java can be Fast! (see Android and
Micronaut)
• However Most Existing Tools are
based around
• Reflection
• Runtime Proxies
• Runtime Byte Code Generation
(bytebuddy/cglib)
7. Why is Reflection a Problem?
• Today the JDK is OpenJDK!
• Just take a look...
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/
share/classes/java/lang/Class.java#l2471
• All Reflective data initialized on first access and held in soft
references (yes every field, method etc.)
• Won't be GC'ed until your application is low on memory!
8. Avoid Reflection!
• Reflection usages increases memory
usage
• Using reflection relatively slow
• Problem is most modern server-side
frameworks and specifications
are built on reflection
• Some of the Jarkarta specifications
even mandate reflection
9. Just Like The
Android World
• The Android Community already
solved the problem
• Ahead of Time Compilation used
extensively
• Google Dagger 2.x for DI
• Most Android Frameworks avoid
reflection to
avoid paying the memory /
performance cost
10. Micronaut
• A Microservices and Serverless
Focused framework (hence the
branding)
• Also a Complete Application
Framework for any type of
Application
• Dependency Injection, Aspect
Oriented Programming (AOP),
Configuration Management,
Bean Introspection and more..
11. With Micronaut You
Can Build
• Microservices
• Serverless Applications
• Message-Driven Applications with
Kafka/Rabbit
• CLI Applications
• Even Android Applications
• Anything with
static void main(String..args)
12. So What is
Micronaut? Really?
• An Application Framework for the
Future
• Reflection Free, Runtime Proxy Free,
No Dynamic Classloading (in 1.1)
• Ahead of Time (AOT) Compilation
AOT APIs
• ... oh and let's you build
Microservices
13. Micronaut and
GraalVM
• A New Universal Virtual Machine
from Oracle
• Features a native-image Tool
• Converts Java -> native machine
code using AOT
• Works well with Micronaut
• Startup time 20ms and Memory
Consumption 18MB!
http://www.graalvm.org
14. Micronaut's Solutions
Problem Solution
Limited Annotation API Precomputed AnnotationMetadata
Type Erasure Precomputed Argument Interface
Slow Reflection Eliminate Reflection
Reflective Data Caches Zero Data Caches
Classpath Scanning No Classpath Scanning
Slow Dynamic Class Loading No Dynamic Class Loaders
16. @Introspected
@Introspected
class MyBean {
private List<String> names; //getter/setter omitted
}
• AOT Reflection-free replacement for
java.beans.Introspector
• Set/get bean properties, create instances
• Includes AnnotationMetadata
17. AnnotationMetadata
AnnotationMetadata metadata = BeanIntrospection.getIntrospection(MyBean.class)
.getAnnotationMetadata();
if (metadata.hasStereotype(SomeAnnotation.class)) {
// do stuff
}
• AOT Computed / Merged Annotation Replacement for
Reflection based API
• Includes knowledge of meta-
19. Argument
BeanProperty<MyBean, List> property =
introspection.getRequireProperty("names", List.class);
// returns an Argument with an underlying type of String
Optional<Argument> typeVariable = property.asArgument()
.getFirstTypeVariable()
• AOT Computed Generic Type information
• No type erasure / crazly reflection logic to get the type
argument
20. Argument
Why?
• You think resolving generic types in
simple?
https://github.com/spring-projects/
spring-framework/blob/master/spring-
core/src/main/java/org/
springframework/core/
ResolvableType.java
22. BeanDefinition
ApplicationContext ctx = ApplicationContext.run();
BeanDefinition<MyBean> definition
= ctx.getBeanDefinition(MyBean.class);
• Contains precomputed AnnotationMetadata and generic
type info
• Used by ApplicationContext to instantiate beans
23. BeanDefinition
• Bean definitions produced for any @Singleton
• Constructor injection used by default
• Use @Factory for beans you cannot annotate
• Compliant with javax.inject spec and TCK
25. @Requires
Conditional Beans Made Easy
@Requires(property="example.enabled")
@Requires(beans=DataSource.class)
@Requires(missingBeans=Example.class)
@Singleton
class DefaultExampleBean implements Example {
...
}
ApplicationContext context = ApplicationContext.run("example.enabled":"true")
Example example = context.getBean(Example)
26. @Executable
@Scheduled(fixedRate = "5m") // @Scheduled annotated with @Executable
void everyFiveMinutes() {
messageService.sendMessage("Hello World");
}
• Common Stereotype annotation
• Identifies where framework invokes your code
• Produces reflection-free ExectubleMethod instance
27. @ExecutableMethodProcessor
public class ScheduledMethodProcessor
implements ExecutableMethodProcessor<Scheduled> {
public void process(BeanDefinition<?> beanDefinition,
ExecutableMethod<?, ?> method) {
// do stuff with the bean
}
}
• Processes only methods annotated by type argument
• In the above case setting up a scheduled job
29. @Around
@Retryable // @Retryable is annotated with @Around
void invokeMe() {
// do stuff
}
• Intercepts a method with a MethodInterceptor
• No runtime proxies (compile time proxies) or reflection
needed
• No FancyProxyFactoryBean or containers needed!
33. Summary
• Micronaut Provides an Awesome Set of Framework
Primitives
• Sacrifices Compilation Speed to Gain so Much More
• Solves Problems with Spring, Jakarta EE and Java in General
• Opens the Door to GraalVM Native
• Come learn more in my "Micronaut Deep Dive" talk at 6PM!