@aalmiray #DevoxxPL
JAVA LIBRARIES
YOU CAN’T
AFFORD TO MISS
ANDRES ALMIRAY
@AALMIRAY
@aalmiray #DevoxxPL
@aalmiray #DevoxxPL
DEPENDENCY
INJECTION
@aalmiray #DevoxxPL
Guice - https://github.com/google/guice
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(Engine.class).annotatedWith(named("efficient"))
.to(FusionPoweredEngine.class)
bind(Engine.class).annotatedWith(named("poor"))
.to(CoalPoweredEngine.class)
}
});
Key key = Key.of(Engine.class, named("poor"));
Engine engine = injector.getInstance(key);
// do something with engine	
  
@aalmiray #DevoxxPL
Spring - http://projects.spring.io/spring-framework/
•  More than just dependency injection
•  Assertions
•  MessageSource + MessageFormat
•  Serialization
•  JDBC, JPA
•  JMX
•  Validation
•  Scheduling
•  Testing
@aalmiray #DevoxxPL
BEHAVIOR
@aalmiray #DevoxxPL
SLF4J - http://www.slf4j.org/
•  Wraps all other logging frameworks:
•  java.util.logging
•  Apache commons logging
•  Log4j
•  Provides varargs methods
@aalmiray #DevoxxPL
Guava - https://github.com/google/guava
•  New Collections:
•  MultiSet
•  BiMap
•  MultiMap
•  Table
•  Utility classes for Collections
•  Utility classes for String
•  Caches
•  Reflection
•  I/O
•  Functional programming support (JDK6+)
@aalmiray #DevoxxPL
OkHttp - http://square.github.io/okhttp/
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
@aalmiray #DevoxxPL
RxJava - http://reactivex.io/
Observable<Repository> observable = github.repositories(model.getOrganization());
if (model.getLimit() > 0) {
observable = observable.take(model.getLimit());
}
Subscription subscription = observable
.timeout(10, TimeUnit.SECONDS)
.doOnSubscribe(() -> model.setState(RUNNING))
.doOnTerminate(() -> model.setState(READY))
.subscribeOn(Schedulers.io())
.subscribe(
model.getRepositories()::add,
Throwable::printStackTrace);
model.setSubscription(subscription);
@aalmiray #DevoxxPL
Retrofit - http://square.github.io/retrofit/
public interface GithubAPI {
@GET("/orgs/{name}/repos")
Call<List<Repository>> repositories(@Path("name") String name);
@GET
Call<List<Repository>>> repositoriesPaginate(@Url String url);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(JacksonConverterFactory.create(objectMapper))
.build();
return retrofit.create(GithubAPI.class);
@aalmiray #DevoxxPL
Retrofit + RxJava
public interface GithubAPI {
@GET("/orgs/{name}/repos")
Observable<Response<List<Repository>>> repositories(@Path("name") String
name);
@GET
Observable<Response<List<Repository>>> repositoriesPaginate(@Url String url);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(JacksonConverterFactory.create(objectMapper))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit.create(GithubAPI.class);
@aalmiray #DevoxxPL
JDeferred - http://jdeferred.org/
model.setState(RUNNING);
int limit = model.getLimit();
limit = limit > 0 ? limit : Integer.MAX_VALUE;
Promise<Collection<Repository>, Throwable, Repository> promise =
github.repositories(model.getOrganization(), limit);
promise.progress(model.getRepositories()::add)
.fail(Throwable::printStackTrace)
.always((state, resolved, rejected) -> model.setState(READY));
@aalmiray #DevoxxPL
MBassador - https://github.com/bennidi/mbassador
public class EventHandler {
private static final Logger LOG = LoggerFactory.getLogger(EventHandler.class);
@Inject
private net.engio.mbassy.bus.MBassador<ApplicationEvent> eventBus;
@net.engio.mbassy.listener.Handler
public void handleNewInstance(NewInstanceEvent event) {
LOG.trace("New instance created {}", event.getInstance());
}
public void createInstance() {
eventBus.publish(new NewInstanceEvent(Person.builder()
.name("Andres")
.lastname("Almiray")
.build()));
}
}
@aalmiray #DevoxxPL
BYTECODE/
AST
@aalmiray #DevoxxPL
Lombok - https://projectlombok.org/
import javax.annotation.Nonnull;
@lombok.Data
public class Person {
private final String name;
private final String lastname;
@Nonnull
@lombok.Builder
public static Person create(@Nonnull String name, @Nonnull String lastname) {
return new Person(name, lastname);
}
}
@lombok.Data
@lombok.EqualsAndHashCode(callSuper = true)
@lombok.ToString(callSuper = true)
public class NewInstanceEvent extends ApplicationEvent {
@javax.annotation.Nonnull
private final Object instance;
}
@aalmiray #DevoxxPL
ByteBuddy - http://bytebuddy.net
public class Foo {
public String bar() { return null; }
public String foo() { return null; }
public String foo(Object o) { return null; }
}
Foo dynamicFoo = new ByteBuddy()
.subclass(Foo.class)
.method(isDeclaredBy(Foo.class)).intercept(FixedValue.value("One!"))
.method(named("foo")).intercept(FixedValue.value("Two!"))
.method(named("foo").and(takesArguments(1)))
.intercept(FixedValue.value("Three!"))
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded()
.newInstance();
@aalmiray #DevoxxPL
TESTING
@aalmiray #DevoxxPL
JUnitParams - https://github.com/Pragmatists/JUnitParams
@RunWith(JUnitParamsRunner.class)
@TestFor(SampleService.class)
public class SampleServiceTest {
private SampleService service;
@Rule
public final GriffonUnitRule griffon = new GriffonUnitRule();
@Test
@Parameters({",Howdy stranger!",
"Test, Hello Test"})
public void sayHello(String input, String output) {
assertThat(service.sayHello(input), equalTo(output));
}
}	
  
@aalmiray #DevoxxPL
Mockito - http://mockito.org/
@Test @Parameters({",Howdy stranger!", "Test, Hello Test"})
public void sayHelloAction(String input, String output) {
// given:
SampleController controller = new SampleController();
controller.setModel(new SampleModel());
controller.setService(mock(SampleService.class));
// expectations
when(controller.getService().sayHello(input)).thenReturn(output);
// when:
controller.getModel().setInput(input);
controller.sayHello();
// then:
assertThat(controller.getModel().getOutput(), equalTo(output));
verify(controller.getService(), only()).sayHello(input);
}	
  
@aalmiray #DevoxxPL
Jukito - https://github.com/ArcBees/Jukito
@RunWith(JukitoRunner.class)
public class SampleControllerJukitoTest {
@Inject private SampleController controller;
@Before
public void setupMocks(SampleService sampleService) {
when(sampleService.sayHello("Test")).thenReturn("Hello Test");
}
@Test
public void sayHelloAction() {
controller.setModel(new SampleModel());
controller.getModel().setInput("Test");
controller.sayHello();
assertThat(controller.getModel().getOutput(),
equalTo("Hello Test"));
verify(controller.getService(), only()).sayHello("Test");
}
}	
  
@aalmiray #DevoxxPL
Spock- http://spockframework.org/
@spock.lang.Unroll
class SampleControllerSpec extends spock.lang.Specification {
def "Invoke say hello with #input results in #output"() {
given:
SampleController controller = new SampleController()
controller.model = new SampleModel()
controller.service = Mock(SampleService) {
sayHello(input) >> output
}
when:
controller.model.input = input
controller.sayHello()
then:
controller.model.output == output
where:
input << ['', 'Test']
output << ['Howdy, stranger!', 'Hello Test']
}
}	
  
@aalmiray #DevoxxPL
Awaitility - https://github.com/awaitility/awaitility
@Test @Parameters({",Howdy stranger!”, "Test, Hello Test"})
public void sayHelloAction(String input, String output) {
// given:
SampleModel model = mvcGroupManager.findModel("sample", SampleModel.class);
SampleController controller = mvcGroupManager.findController("sample",
SampleController.class);
// expect:
assertThat(model.getOutput(), nullValue());
// when:
model.setInput(input);
controller.invokeAction("sayHello");
// then:
await().until(() -> model.getOutput(), notNullValue());
assertThat(model.getOutput(), equalTo(output));
}	
  
@aalmiray #DevoxxPL
Rest-assured - https://github.com/rest-assured/rest-assured
get("/lotto").then().assertThat().body("lotto.lottoId",	
  equalTo(5));	
  
	
  
given().	
  
	
  	
  	
  	
  param("key1",	
  "value1").	
  
	
  	
  	
  	
  param("key2",	
  "value2").	
  
when().	
  
	
  	
  	
  	
  post("/somewhere").	
  
then().	
  
	
  	
  	
  	
  body(containsString("OK"));	
  
	
  
	
  
* Includes JsonPath and XmlPath support
@aalmiray #DevoxxPL
HONORARY
MENTIONS
@aalmiray #DevoxxPL
Okio - https://github.com/square/okio
HikariCP - https://github.com/brettwooldridge/HikariCP
gRPC - http://www.grpc.io/
Kryo - https://github.com/EsotericSoftware/kryo
MockServer - http://www.mock-server.com/
@aalmiray #DevoxxPL
THANK YOU!
ANDRES ALMIRAY
@AALMIRAY

Java libraries you can't afford to miss

  • 1.
    @aalmiray #DevoxxPL JAVA LIBRARIES YOUCAN’T AFFORD TO MISS ANDRES ALMIRAY @AALMIRAY
  • 2.
  • 3.
  • 4.
    @aalmiray #DevoxxPL Guice -https://github.com/google/guice Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { bind(Engine.class).annotatedWith(named("efficient")) .to(FusionPoweredEngine.class) bind(Engine.class).annotatedWith(named("poor")) .to(CoalPoweredEngine.class) } }); Key key = Key.of(Engine.class, named("poor")); Engine engine = injector.getInstance(key); // do something with engine  
  • 5.
    @aalmiray #DevoxxPL Spring -http://projects.spring.io/spring-framework/ •  More than just dependency injection •  Assertions •  MessageSource + MessageFormat •  Serialization •  JDBC, JPA •  JMX •  Validation •  Scheduling •  Testing
  • 6.
  • 7.
    @aalmiray #DevoxxPL SLF4J -http://www.slf4j.org/ •  Wraps all other logging frameworks: •  java.util.logging •  Apache commons logging •  Log4j •  Provides varargs methods
  • 8.
    @aalmiray #DevoxxPL Guava -https://github.com/google/guava •  New Collections: •  MultiSet •  BiMap •  MultiMap •  Table •  Utility classes for Collections •  Utility classes for String •  Caches •  Reflection •  I/O •  Functional programming support (JDK6+)
  • 9.
    @aalmiray #DevoxxPL OkHttp -http://square.github.io/okhttp/ public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); OkHttpClient client = new OkHttpClient(); String post(String url, String json) throws IOException { RequestBody body = RequestBody.create(JSON, json); Request request = new Request.Builder() .url(url) .post(body) .build(); Response response = client.newCall(request).execute(); return response.body().string(); }
  • 10.
    @aalmiray #DevoxxPL RxJava -http://reactivex.io/ Observable<Repository> observable = github.repositories(model.getOrganization()); if (model.getLimit() > 0) { observable = observable.take(model.getLimit()); } Subscription subscription = observable .timeout(10, TimeUnit.SECONDS) .doOnSubscribe(() -> model.setState(RUNNING)) .doOnTerminate(() -> model.setState(READY)) .subscribeOn(Schedulers.io()) .subscribe( model.getRepositories()::add, Throwable::printStackTrace); model.setSubscription(subscription);
  • 11.
    @aalmiray #DevoxxPL Retrofit -http://square.github.io/retrofit/ public interface GithubAPI { @GET("/orgs/{name}/repos") Call<List<Repository>> repositories(@Path("name") String name); @GET Call<List<Repository>>> repositoriesPaginate(@Url String url); } Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com") .addConverterFactory(JacksonConverterFactory.create(objectMapper)) .build(); return retrofit.create(GithubAPI.class);
  • 12.
    @aalmiray #DevoxxPL Retrofit +RxJava public interface GithubAPI { @GET("/orgs/{name}/repos") Observable<Response<List<Repository>>> repositories(@Path("name") String name); @GET Observable<Response<List<Repository>>> repositoriesPaginate(@Url String url); } Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com") .addConverterFactory(JacksonConverterFactory.create(objectMapper)) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); return retrofit.create(GithubAPI.class);
  • 13.
    @aalmiray #DevoxxPL JDeferred -http://jdeferred.org/ model.setState(RUNNING); int limit = model.getLimit(); limit = limit > 0 ? limit : Integer.MAX_VALUE; Promise<Collection<Repository>, Throwable, Repository> promise = github.repositories(model.getOrganization(), limit); promise.progress(model.getRepositories()::add) .fail(Throwable::printStackTrace) .always((state, resolved, rejected) -> model.setState(READY));
  • 14.
    @aalmiray #DevoxxPL MBassador -https://github.com/bennidi/mbassador public class EventHandler { private static final Logger LOG = LoggerFactory.getLogger(EventHandler.class); @Inject private net.engio.mbassy.bus.MBassador<ApplicationEvent> eventBus; @net.engio.mbassy.listener.Handler public void handleNewInstance(NewInstanceEvent event) { LOG.trace("New instance created {}", event.getInstance()); } public void createInstance() { eventBus.publish(new NewInstanceEvent(Person.builder() .name("Andres") .lastname("Almiray") .build())); } }
  • 15.
  • 16.
    @aalmiray #DevoxxPL Lombok -https://projectlombok.org/ import javax.annotation.Nonnull; @lombok.Data public class Person { private final String name; private final String lastname; @Nonnull @lombok.Builder public static Person create(@Nonnull String name, @Nonnull String lastname) { return new Person(name, lastname); } } @lombok.Data @lombok.EqualsAndHashCode(callSuper = true) @lombok.ToString(callSuper = true) public class NewInstanceEvent extends ApplicationEvent { @javax.annotation.Nonnull private final Object instance; }
  • 17.
    @aalmiray #DevoxxPL ByteBuddy -http://bytebuddy.net public class Foo { public String bar() { return null; } public String foo() { return null; } public String foo(Object o) { return null; } } Foo dynamicFoo = new ByteBuddy() .subclass(Foo.class) .method(isDeclaredBy(Foo.class)).intercept(FixedValue.value("One!")) .method(named("foo")).intercept(FixedValue.value("Two!")) .method(named("foo").and(takesArguments(1))) .intercept(FixedValue.value("Three!")) .make() .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .newInstance();
  • 18.
  • 19.
    @aalmiray #DevoxxPL JUnitParams -https://github.com/Pragmatists/JUnitParams @RunWith(JUnitParamsRunner.class) @TestFor(SampleService.class) public class SampleServiceTest { private SampleService service; @Rule public final GriffonUnitRule griffon = new GriffonUnitRule(); @Test @Parameters({",Howdy stranger!", "Test, Hello Test"}) public void sayHello(String input, String output) { assertThat(service.sayHello(input), equalTo(output)); } }  
  • 20.
    @aalmiray #DevoxxPL Mockito -http://mockito.org/ @Test @Parameters({",Howdy stranger!", "Test, Hello Test"}) public void sayHelloAction(String input, String output) { // given: SampleController controller = new SampleController(); controller.setModel(new SampleModel()); controller.setService(mock(SampleService.class)); // expectations when(controller.getService().sayHello(input)).thenReturn(output); // when: controller.getModel().setInput(input); controller.sayHello(); // then: assertThat(controller.getModel().getOutput(), equalTo(output)); verify(controller.getService(), only()).sayHello(input); }  
  • 21.
    @aalmiray #DevoxxPL Jukito -https://github.com/ArcBees/Jukito @RunWith(JukitoRunner.class) public class SampleControllerJukitoTest { @Inject private SampleController controller; @Before public void setupMocks(SampleService sampleService) { when(sampleService.sayHello("Test")).thenReturn("Hello Test"); } @Test public void sayHelloAction() { controller.setModel(new SampleModel()); controller.getModel().setInput("Test"); controller.sayHello(); assertThat(controller.getModel().getOutput(), equalTo("Hello Test")); verify(controller.getService(), only()).sayHello("Test"); } }  
  • 22.
    @aalmiray #DevoxxPL Spock- http://spockframework.org/ @spock.lang.Unroll classSampleControllerSpec extends spock.lang.Specification { def "Invoke say hello with #input results in #output"() { given: SampleController controller = new SampleController() controller.model = new SampleModel() controller.service = Mock(SampleService) { sayHello(input) >> output } when: controller.model.input = input controller.sayHello() then: controller.model.output == output where: input << ['', 'Test'] output << ['Howdy, stranger!', 'Hello Test'] } }  
  • 23.
    @aalmiray #DevoxxPL Awaitility -https://github.com/awaitility/awaitility @Test @Parameters({",Howdy stranger!”, "Test, Hello Test"}) public void sayHelloAction(String input, String output) { // given: SampleModel model = mvcGroupManager.findModel("sample", SampleModel.class); SampleController controller = mvcGroupManager.findController("sample", SampleController.class); // expect: assertThat(model.getOutput(), nullValue()); // when: model.setInput(input); controller.invokeAction("sayHello"); // then: await().until(() -> model.getOutput(), notNullValue()); assertThat(model.getOutput(), equalTo(output)); }  
  • 24.
    @aalmiray #DevoxxPL Rest-assured -https://github.com/rest-assured/rest-assured get("/lotto").then().assertThat().body("lotto.lottoId",  equalTo(5));     given().          param("key1",  "value1").          param("key2",  "value2").   when().          post("/somewhere").   then().          body(containsString("OK"));       * Includes JsonPath and XmlPath support
  • 25.
  • 26.
    @aalmiray #DevoxxPL Okio -https://github.com/square/okio HikariCP - https://github.com/brettwooldridge/HikariCP gRPC - http://www.grpc.io/ Kryo - https://github.com/EsotericSoftware/kryo MockServer - http://www.mock-server.com/
  • 27.