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.

Micronaut: Evolving Java for the Microservices and Serverless Era

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)

  • Be the first to comment

Micronaut: Evolving Java for the Microservices and Serverless Era

  1. 1. Evolving Java for the Microservice and Serverless Era
  2. 2. About Me • Graeme Rocher • Creator of Grails and Micronaut • Principal Engineer at Object Computing • 2018 Oracle Groundbreaker Award Winner • Java Champion
  3. 3. Agenda • Challenges Facing Java • Introduction to Micronaut • Micronaut's Approach to Solving The Problems • Demos!
  4. 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. 5. Java's Problems for Frameworks • Limited Annotation API • Type Erasure • Slow Reflection • Reflective Data Caches • Classpath Scanning • Slow Dynamic Class Loading
  6. 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. 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. 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. 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. 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. 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. 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. 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. 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
  15. 15. DEMOMicronaut Bean Introspection
  16. 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. 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-
  18. 18. AnnotationMetadata Why? • All the Nullable annotations!!! • javax.annotation.Nullable (Java) • org.jetbrains.annotations. Nullable (Kotlin) • edu.umd.cs.findbugs. annotations.Nullable (Spotbugs) • org.springframework. lang.Nullable (Spring)
  19. 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. 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
  21. 21. DEMOMicronaut Dependency Injection
  22. 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. 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
  24. 24. @ConfigurationProperties Type Safe Configuration @ConfigurationProperties("example") class ExampleConfiguration { // getters/setters omitted private String name; } ApplicationContext context = ApplicationContext.run("example.name":"Demo"); FooConfiguration config = context.getBean(FooConfiguration); assert config.name == 'Demo'
  25. 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. 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. 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
  28. 28. DEMOMicronaut AOP
  29. 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!
  30. 30. @Around @Around @Type(DefaultRetryInterceptor.class) public @interface Retryable { // annotation attributes } • Use @Type to specify the implementation • At compilation Micronaut applies the AOP advise
  31. 31. DEMOMicronaut
  32. 32. Micronaut Startup and Memory Runtime Memory Startup JDK 11 75MB 1.1s JDK 13 75MB 900ms JDK 13 + CDS 75MB 400ms GraalVM Substrate 15MB 21ms
  33. 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!
  34. 34. Q & A

×