SlideShare a Scribd company logo
1 of 87
Download to read offline
Marvel of Annotation
by Alexey Buzdin
Preprocessing
@AlexeyBuzdin
GDGRiga.lv RigaDevDay.lv
๏ What?
๏ Why?
๏ How?
๏ Dagger
๏ Lombok
๏ MapStruct
๏ Retrofit
๏ What?
๏ Why?
๏ How?
๏ Dagger
๏ MapStruct
๏ Retrofit
๏ Lombok
“Developer loves
to write code”
“Developer loves
to write code”
- noone ever
“Developer loves
complex tasks”
“Developer loves
complex tasks”
- probably you
CRUD
CRUD
- api
- type: XML, JSON
- resources
- /clients
- access: R
- entity
🔑 clientId
- full name
- email
- /payments
- entity
🔑 paymentId
🔑 clientId | link
- amount
- db: jdbc:mysql://localhost:3306/crudapp
CRUD
- api
- type: XML, JSON
- resources
- /clients
- access: R
- entity
🔑 clientId
- full name
- email
- /payments
- entity
🔑 paymentId
🔑 clientId | link
- amount
- db: jdbc:mysql://localhost:3306/crudapp
Authentication?
CRUD
- api
- type: XML, JSON
- resources
- /clients
- access: R
- entity
🔑 clientId
- full name
- email
- /payments
- entity
🔑 paymentId
🔑 clientId | link
- amount
- db: jdbc:mysql://localhost:3306/crudapp
- ldap: ldap://ldap.example.com/dc=example,dc=com
never let go of your
D R E A M S
In Practice
In Practice
Routing
XML, JSON
Building Response
public class SimpleServlet extends GenericServlet {



public void service(ServletRequest req, ServletResponse res)

throws ServletException, IOException {

// do something in here

}

}
Generic Servlet
In Practice
Routing
XML, JSON
Building Response
In Practice
Map
Validate
Routing
XML, JSON
Building Response
In Practice
Construct Query
Map
Validate
Routing
XML, JSON
Building Response
Reflection and
Runtime Code Generation
Everywhere!
Spring, Hibernate, GSON, Jersy, Dozer,
Guice, Weld, etc…
Reflection - Slow?
Reflection - Slow?
http://docs.oracle.com/javase/tutorial/reflect/index.html
Performance Overhead
Because reflection involves types that are dynamically resolved, certain
Java virtual machine optimizations can not be performed. Consequently,
reflective operations have slower performance than their non-reflective
counterparts, and should be avoided in sections of code which are
called frequently in performance-sensitive applications.
Reflection - Slow?
http://docs.oracle.com/javase/tutorial/reflect/index.html
Performance Overhead
Because reflection involves types that are dynamically resolved, certain
Java virtual machine optimizations can not be performed. Consequently,
reflective operations have slower performance than their non-reflective
counterparts, and should be avoided in sections of code which are
called frequently in performance-sensitive applications.
Reflection - Slow?
http://docs.oracle.com/javase/tutorial/reflect/index.html
Performance Overhead
Because reflection involves types that are dynamically resolved, certain
Java virtual machine optimizations can not be performed. Consequently,
reflective operations have slower performance than their non-reflective
counterparts, and should be avoided in sections of code which are
called frequently in performance-sensitive applications.
Code Generation?
https://zeroturnaround.com/rebellabs/how-to-make-java-more-dynamic-with-runtime-code-generation/
Code Generation?
https://zeroturnaround.com/rebellabs/how-to-make-java-more-dynamic-with-runtime-code-generation/
Generates Java Bytecode at Runtime
Code Generation?
https://zeroturnaround.com/rebellabs/how-to-make-java-more-dynamic-with-runtime-code-generation/
Generates Java Bytecode at Runtime
Not always ok
Code Generation?
https://zeroturnaround.com/rebellabs/how-to-make-java-more-dynamic-with-runtime-code-generation/
GWT, Android, j2objc,
RoboVM, code transpilers
Doesn’t work
Annotation Processing
Annotation Processing
A tool build in javac for scanning and
processing annotations at compile time
How?
public class MyProcessor extends AbstractProcessor {
@Override public synchronized void init(ProcessingEnvironment env){ }
@Override public boolean process(
Set<? extends TypeElement> annotations, RoundEnvironment env) { }
@Override public Set<String> getSupportedAnnotationTypes() { }
@Override public SourceVersion getSupportedSourceVersion() { }
}
http://hannesdorfmann.com/annotation-processing/annotationprocessing101/
How?
public class MyProcessor extends AbstractProcessor {
@Override public synchronized void init(ProcessingEnvironment env){ }
@Override public boolean process(
Set<? extends TypeElement> annotations, RoundEnvironment env) { }
@Override public Set<String> getSupportedAnnotationTypes() { }
@Override public SourceVersion getSupportedSourceVersion() { }
}
http://hannesdorfmann.com/annotation-processing/annotationprocessing101/
How?
public class MyProcessor extends AbstractProcessor {
@Override public synchronized void init(ProcessingEnvironment env){ }
@Override public boolean process(
Set<? extends TypeElement> annotations, RoundEnvironment env) { }
@Override public Set<String> getSupportedAnnotationTypes() { }
@Override public SourceVersion getSupportedSourceVersion() { }
}
http://hannesdorfmann.com/annotation-processing/annotationprocessing101/
How?
public class MyProcessor extends AbstractProcessor {
@Override public synchronized void init(ProcessingEnvironment env){ }
@Override public boolean process(
Set<? extends TypeElement> annotations, RoundEnvironment env) { }
@Override public Set<String> getSupportedAnnotationTypes() { }
@Override public SourceVersion getSupportedSourceVersion() { }
}
http://hannesdorfmann.com/annotation-processing/annotationprocessing101/
How?
public class MyProcessor extends AbstractProcessor {
@Override public synchronized void init(ProcessingEnvironment env){ }
@Override public boolean process(
Set<? extends TypeElement> annotations, RoundEnvironment env) { }
@Override public Set<String> getSupportedAnnotationTypes() { }
@Override public SourceVersion getSupportedSourceVersion() { }
}
http://hannesdorfmann.com/annotation-processing/annotationprocessing101/
How?
MyProcessor.jar
- com
- example
- MyProcessor.class
- META-INF
- services
- javax.annotation.processing.Processor
com.example.MyProcessor
com.foo.OtherProcessor
net.blabla.SpecialProcessor
javax.annotation.processing.Processor
javac will run the process in separate JVM
Example
public class PizzaStore {
public Meal order(String mealName) {
if ("Margherita".equals(mealName)) return new MargheritaPizza();
if ("Calzone".equals(mealName)) return new CalzonePizza();
if ("Tiramisu".equals(mealName)) return new Tiramisu();
throw new IllegalArgumentException("Unknown meal '" + mealName + "'");
}
}
Example
public class PizzaStore {
private MealFactory factory = new MealFactory();
public Meal order(String mealName) {
return factory.create(mealName);
}
}
@Target(ElementType.TYPE) @Retention(RetentionPolicy.CLASS)
public @interface Factory {
Class type();
String id();
}
@Factory(
id = "Margherita",
type = Meal.class
)
public class MargheritaPizza implements Meal {
@Override public float getPrice() {
return 6f;
}
}
How?
public class MyProcessor extends AbstractProcessor {
@Override public synchronized void init(ProcessingEnvironment env){ }
@Override public boolean process(
Set<? extends TypeElement> annotations, RoundEnvironment env) { }
@Override public Set<String> getSupportedAnnotationTypes() { }
@Override public SourceVersion getSupportedSourceVersion() { }
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> annotataions = new LinkedHashSet<String>();
annotataions.add(Factory.class.getCanonicalName());
return annotataions;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
typeUtils = processingEnv.getTypeUtils();
elementUtils = processingEnv.getElementUtils();
filer = processingEnv.getFiler();
messager = processingEnv.getMessager();
}
package com.example; // PackageElement
public class Foo { // TypeElement
private int a; // VariableElement
private Foo other; // VariableElement
public Foo () {} // ExecuteableElement
public void setA ( // ExecuteableElement
int newA // TypeElement
) {}
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
// Itearate over all @Factory annotated elements
for (Element annotatedElement : env.getElementsAnnotatedWith(Factory.class)){
...
}
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
// Itearate over all @Factory annotated elements
for (Element annotatedElement : env.getElementsAnnotatedWith(Factory.class)){
if (annotatedElement.getKind() != ElementKind.CLASS) {
messager.printMessage(Diagnostic.Kind.ERROR, “Ooops!”, annotatedElement);
return true;
}
...
}
}
public class FactoryAnnotatedClass {
private TypeElement annotatedClassElement;;
private String simpleTypeName; // Class name
private String id; // “Margherita”
public FactoryAnnotatedClass(TypeElement classElement) throws Exception {
Factory annotation = classElement.getAnnotation(Factory.class);
…
}
}
try {
Class<?> clazz = annotation.type();
qualifiedGroupClassName = clazz.getCanonicalName();
simpleFactoryGroupName = clazz.getSimpleName();
} catch (MirroredTypeException mte) {
DeclaredType classTypeMirror = (DeclaredType) mte.getTypeMirror();
TypeElement classTypeElement = (TypeElement) classTypeMirror.asElement();
qualifiedGroupClassName = classTypeElement.getQualifiedName().toString();
simpleFactoryGroupName = classTypeElement.getSimpleName().toString();
}
public void generateCode(Elements elementUtils, Filer filer) throws IOException {
MethodSpec.Builder method = MethodSpec.methodBuilder("create")
.addModifiers(Modifier.PUBLIC)
.addParameter(String.class, "id")
.returns(TypeName.get(superClassName.asType()));
// Foreach
method.beginControlFlow("if ($S.equals(id))", item.getId())
.addStatement("return new $L()”, item.getTypeElement().getQualifiedName().toString())
.endControlFlow();
TypeSpec typeSpec = TypeSpec.classBuilder(factoryClassName)
.addMethod(method.build()).build();
JavaFile.builder(packageName, typeSpec).build().writeTo(filer);
}
https://github.com/square/javapoet
Processing Rounds
Annotation Processing
A tool build in javac for scanning and
processing annotations at compile time
Dependency Injection
Dagger 2
The fastest Java DI Framework!
https://google.github.io/dagger/
import javax.inject.Inject;
class CoffeeMaker {
@Inject Heater heater;
@Inject Pump pump;
...
}
Dagger 2
@Component(modules = DripCoffeeModule.class)
interface CoffeeShop {
CoffeeMaker maker();
}
@Module
class DripCoffeeModule {
@Provides static Heater provideHeater() {
return new ElectricHeater();
}
@Provides static Pump providePump(Thermosiphon pump) {
return pump;
}
}
import javax.inject.Inject;
class CoffeeMaker {
@Inject Heater heater;
@Inject Pump pump;
...
}
Dagger 2
CoffeeShop coffeeShop = DaggerCoffeeShop.create();
Dagger 2
๏ Singletons and Scoped Bindings
๏ Lazy injections
๏ Provider injections
๏ Qualifiers
Dagger 2
The fastest Java DI Framework!
https://google.github.io/dagger/
MapStruct
Bean Mapping at Compile Time
http://mapstruct.org/
public class Car {
private String make;
private int numberOfSeats;
private CarType type;
//constructor, getters, setters etc.
}
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
@Mappings({
@Mapping(source = "make", target = "manufacturer"),
@Mapping(source = "numberOfSeats", target = "seatCount")
})
CarDto carToCarDto(Car car);
}
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
@Mappings({
@Mapping(source = "make", target = "manufacturer"),
@Mapping(source = "numberOfSeats", target = "seatCount")
})
CarDto carToCarDto(Car car);
}
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
@Mappings({
@Mapping(source = "make", target = "manufacturer"),
@Mapping(source = "numberOfSeats", target = "seatCount")
})
CarDto carToCarDto(Car car);
}
MapStruct
http://mapstruct.org/
๏ Nested mappings
๏ Updating existing bean instances
Retrofit
A type-safe HTTP client for Java
https://square.github.io/retrofit/
Retrofit
public interface WeatherData {
@GET(“weather?”)
Observable<WeatherData> getWeatherData(@Query(“q”) String city);
}
Retrofit retrofit = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://api.openweathermap.org/data/2.5/")
.build();
WeatherService weatherService = retrofit.create(WeatherService.class);
Observable<WeatherData> london = weatherService.getWeatherData("Riga");
Retrofit
๏ Header Manipulation
๏ Sync and Asyn calls
๏ Custom Converters
Lombok
Spice up your Java
https://projectlombok.org/
@ToString
@ToString(exclude="id")
public class ToStringExample {
private static final int STATIC_VAR = 10;
private String name;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id;
}
@EqualsAndHashCode
@EqualsAndHashCode(exclude={"id", "shape"})
public class EqualsAndHashCodeExample {
private transient int transientVar = 10;
private String name;
private double score;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id;
}
@RequiredArgsConstructor
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
private int x, y;
@NonNull private T description;
@NoArgsConstructor
public static class NoArgsExample {
@NonNull private String field;
}
}
@Data & @Value
@Data
public class PoJo {
private String name;
private double score;
private String[] tags;
private int id;
}
@Value
public class PoJo {
private String name;
private double score;
private String[] tags;
private int id;
}
public String example() {
val example = new ArrayList<String>();
example.add("Hello, World!");
val foo = example.get(0);
return foo.toLowerCase();
}
public String example() {
val example = new ArrayList<String>();
example.add("Hello, World!");
val foo = example.get(0);
return foo.toLowerCase();
}
val !!11one
@ExtensionMethod
class Extensions {
public static String toTitleCase(String in) {
if (in.isEmpty()) return in;
return "" + Character.toTitleCase(in.charAt(0)) +
in.substring(1).toLowerCase();
}
}
@ExtensionMethod({java.util.Arrays.class, Extensions.class})
public class ExtensionMethodExample {
public String test() { return "hELlO, WORlD!”.toTitleCase(); }
}
lombok.fieldDefaults.defaultPrivate = true
Lombok.config
Lombok
Spice up your Java
https://projectlombok.org/
๏@Builder
๏@Log
๏@Delegate
• https://github.com/bluelinelabs/LoganSquare
• https://github.com/greenrobot/EventBus
• … and more
Conclusion
Annotation Processing
Conclusion
Powerful
Fast
Sometimes Brittle
Annotation Processing
Conclusion
Powerful
Fast
Sometimes Brittle
Annotation Processing
Conclusion
Powerful
Fast
Sometimes Brittle
Annotation Processing
Powerful
Fast
Sometimes a Life Saver
Conclusion
Powerful
Fast
Sometimes Brittle
Annotation Processing
“Use it wisely we must!”
Q&A
Thank You!
@AlexeyBuzdinFollow me at

More Related Content

What's hot

Fullstack End-to-end test automation with Node.js, one year later
Fullstack End-to-end test automation with Node.js, one year laterFullstack End-to-end test automation with Node.js, one year later
Fullstack End-to-end test automation with Node.js, one year laterMek Srunyu Stittri
 
The Gist of React Native
The Gist of React NativeThe Gist of React Native
The Gist of React NativeDarren Cruse
 
Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012Hazem Saleh
 
Asynchronous Module Definition (AMD)
Asynchronous Module Definition (AMD)Asynchronous Module Definition (AMD)
Asynchronous Module Definition (AMD)xMartin12
 
Refactoring JavaScript Applications
Refactoring JavaScript ApplicationsRefactoring JavaScript Applications
Refactoring JavaScript ApplicationsJovan Vidić
 
EWD 3 Training Course Part 14: Using Ajax for QEWD Messages
EWD 3 Training Course Part 14: Using Ajax for QEWD MessagesEWD 3 Training Course Part 14: Using Ajax for QEWD Messages
EWD 3 Training Course Part 14: Using Ajax for QEWD MessagesRob Tweed
 
vJUG - The JavaFX Ecosystem
vJUG - The JavaFX EcosystemvJUG - The JavaFX Ecosystem
vJUG - The JavaFX EcosystemAndres Almiray
 
Javascript training sample
Javascript training sampleJavascript training sample
Javascript training sampleprahalad_das_in
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Ran Mizrahi
 
Seven Versions of One Web Application
Seven Versions of One Web ApplicationSeven Versions of One Web Application
Seven Versions of One Web ApplicationYakov Fain
 
Behat Workshop at WeLovePHP
Behat Workshop at WeLovePHPBehat Workshop at WeLovePHP
Behat Workshop at WeLovePHPMarcos Quesada
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFXHendrik Ebbers
 
JavaOne - The JavaFX Community and Ecosystem
JavaOne - The JavaFX Community and EcosystemJavaOne - The JavaFX Community and Ecosystem
JavaOne - The JavaFX Community and EcosystemAlexander Casall
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with JestMichał Pierzchała
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF SummitOrtus Solutions, Corp
 
JavaFX JumpStart @JavaOne 2016
JavaFX JumpStart @JavaOne 2016JavaFX JumpStart @JavaOne 2016
JavaFX JumpStart @JavaOne 2016Hendrik Ebbers
 
JavaFX in Action (devoxx'16)
JavaFX in Action (devoxx'16)JavaFX in Action (devoxx'16)
JavaFX in Action (devoxx'16)Alexander Casall
 

What's hot (19)

Fullstack End-to-end test automation with Node.js, one year later
Fullstack End-to-end test automation with Node.js, one year laterFullstack End-to-end test automation with Node.js, one year later
Fullstack End-to-end test automation with Node.js, one year later
 
The Gist of React Native
The Gist of React NativeThe Gist of React Native
The Gist of React Native
 
Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012
 
Asynchronous Module Definition (AMD)
Asynchronous Module Definition (AMD)Asynchronous Module Definition (AMD)
Asynchronous Module Definition (AMD)
 
Refactoring JavaScript Applications
Refactoring JavaScript ApplicationsRefactoring JavaScript Applications
Refactoring JavaScript Applications
 
EWD 3 Training Course Part 14: Using Ajax for QEWD Messages
EWD 3 Training Course Part 14: Using Ajax for QEWD MessagesEWD 3 Training Course Part 14: Using Ajax for QEWD Messages
EWD 3 Training Course Part 14: Using Ajax for QEWD Messages
 
vJUG - The JavaFX Ecosystem
vJUG - The JavaFX EcosystemvJUG - The JavaFX Ecosystem
vJUG - The JavaFX Ecosystem
 
Javascript training sample
Javascript training sampleJavascript training sample
Javascript training sample
 
React Native
React NativeReact Native
React Native
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
 
Seven Versions of One Web Application
Seven Versions of One Web ApplicationSeven Versions of One Web Application
Seven Versions of One Web Application
 
The JavaFX Ecosystem
The JavaFX EcosystemThe JavaFX Ecosystem
The JavaFX Ecosystem
 
Behat Workshop at WeLovePHP
Behat Workshop at WeLovePHPBehat Workshop at WeLovePHP
Behat Workshop at WeLovePHP
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
 
JavaOne - The JavaFX Community and Ecosystem
JavaOne - The JavaFX Community and EcosystemJavaOne - The JavaFX Community and Ecosystem
JavaOne - The JavaFX Community and Ecosystem
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with Jest
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
 
JavaFX JumpStart @JavaOne 2016
JavaFX JumpStart @JavaOne 2016JavaFX JumpStart @JavaOne 2016
JavaFX JumpStart @JavaOne 2016
 
JavaFX in Action (devoxx'16)
JavaFX in Action (devoxx'16)JavaFX in Action (devoxx'16)
JavaFX in Action (devoxx'16)
 

Similar to Marvel of Annotation Preprocessing in Java by Alexey Buzdin

Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationAndrew Rota
 
Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010Chris Ramsdale
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpmsom_nangia
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpmwilburlo
 
Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Luciano Mammino
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsMike Subelsky
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 
Google io bootcamp_2010
Google io bootcamp_2010Google io bootcamp_2010
Google io bootcamp_2010Chris Ramsdale
 
Google Developer Fest 2010
Google Developer Fest 2010Google Developer Fest 2010
Google Developer Fest 2010Chris Ramsdale
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversTatsuhiko Miyagawa
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gearsdion
 
Workshop: Building Vaadin add-ons
Workshop: Building Vaadin add-onsWorkshop: Building Vaadin add-ons
Workshop: Building Vaadin add-onsSami Ekblad
 
Phone gap 12 things you should know
Phone gap 12 things you should knowPhone gap 12 things you should know
Phone gap 12 things you should knowISOCHK
 
Real World Dependency Injection - phpday
Real World Dependency Injection - phpdayReal World Dependency Injection - phpday
Real World Dependency Injection - phpdayStephan Hochdörfer
 

Similar to Marvel of Annotation Preprocessing in Java by Alexey Buzdin (20)

Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​
 
JBoss World 2010
JBoss World 2010JBoss World 2010
JBoss World 2010
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
Google io bootcamp_2010
Google io bootcamp_2010Google io bootcamp_2010
Google io bootcamp_2010
 
Google Developer Fest 2010
Google Developer Fest 2010Google Developer Fest 2010
Google Developer Fest 2010
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
 
Plack at YAPC::NA 2010
Plack at YAPC::NA 2010Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
PSGI/Plack OSDC.TW
PSGI/Plack OSDC.TWPSGI/Plack OSDC.TW
PSGI/Plack OSDC.TW
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
 
RxSwift to Combine
RxSwift to CombineRxSwift to Combine
RxSwift to Combine
 
Workshop: Building Vaadin add-ons
Workshop: Building Vaadin add-onsWorkshop: Building Vaadin add-ons
Workshop: Building Vaadin add-ons
 
Phone gap 12 things you should know
Phone gap 12 things you should knowPhone gap 12 things you should know
Phone gap 12 things you should know
 
Real World Dependency Injection - phpday
Real World Dependency Injection - phpdayReal World Dependency Injection - phpday
Real World Dependency Injection - phpday
 

Recently uploaded

Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 

Recently uploaded (20)

Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 

Marvel of Annotation Preprocessing in Java by Alexey Buzdin