29 czerwca 2016 blog java

This is the list of libraries that was presented by Andres Almiray during Devoxx 2016 in Kraków. I added links to projects' home urls and short description together with example code copied from documentation.

Orginal slides are available on slideshare.net.

Guice

Guice alleviates the need for factories and the use of new in your Java code. Think of Guice's @Inject as the new new. You will still need to write factories in some cases, but your code will not depend directly on them. Your code will be easier to change, unit test and reuse in other contexts.

Homepage: github.com/google/guice

Getting started: github.com/google/guice/wiki/GettingStarted

Example code:

public class BillingModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);
    bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
  }
}

Spring Framework

The Spring Framework is an application framework and inversion of control container for the Java platform.

Homepage: spring.io/docs

Quick start: projects.spring.io/spring-boot/#quick-start

Example code:

@Controller
@EnableAutoConfiguration
public class SampleController {

  @RequestMapping("/")
  @ResponseBody
  String home() {
    return "Hello World!";
  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(SampleController.class, args);
  }
}

SLF4J

The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time.

Homepage: www.slf4j.org/index.html

How to use it: www.slf4j.org/manual.html

Example code:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Wombat {

  final Logger logger = LoggerFactory.getLogger(Wombat.class);
  Integer t;
  Integer oldT;

  public void setTemperature(Integer temperature) {

    oldT = t;
    t = temperature;
    logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
    if (temperature.intValue() > 50) {
      logger.info("Temperature has risen above 50 degrees.");
    }
  }
}

Guava

The Guava project contains several of Google's core libraries that we rely on in our Java-based projects: collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth.

Homepage: github.com/google/guava

User guide: github.com/google/guava/wiki

Bonus link - do you know how to eat guava?

Example code:

Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
Map<String, Integer> right = ImmutableMap.of("b", 2, "c", 4, "d", 5);
MapDifference<String, Integer> diff = Maps.difference(left, right);

diff.entriesInCommon(); // {"b" => 2}
diff.entriesDiffering(); // {"c" => (3, 4)}
diff.entriesOnlyOnLeft(); // {"a" => 1}
diff.entriesOnlyOnRight(); // {"d" => 5}

OkHttp

OkHttp is an HTTP client that’s efficient by default:

Homepage: square.github.io/okhttp/

Wiki: github.com/square/okhttp/wiki

Example code:

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();
}

RxJava

RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.

It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.

Homepage: github.com/ReactiveX/RxJava

How to use it: github.com/ReactiveX/RxJava/wiki/How-To-Use-RxJava

Example code:

public static void hello(String... names) {
  Observable.from(names).subscribe(new Action1<String>() {

    @Override
    public void call(String s) {
      System.out.println("Hello " + s + "!");
    }

  });
}

// ...
hello("Ben", "George");
Hello Ben!
Hello George!

Retrofit

Retrofit turns your HTTP API into a Java interface. Uses OkHttp and RxJava.

Homepage: square.github.io/retrofit/

Example code:

public interface GitHubService {  
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

// ...
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);
Call<List<Repo>> repos = service.listRepos("octocat");

JDeffered

JDeferred is a Java Deferred/Promise library similar to JQuery's Deferred Object. Inspired by JQuery and Android Deferred Object.

Homepage: jdeferred.org

Quick examples: github.com/jdeferred/jdeferred#quick-examples

Example code:

dm.when(() -> {
  return "Hey!";
}).done(r -> System.out.println(r));

dm.when(() -> {
      return "Hello";
    },
    () -> {
      return "World";
    }
).done(rs
    -> rs.forEach(r -> System.out.println(r.getResult()))
);

MBassador

MBassador is a light-weight, high-performance message (event) bus implementation based on the publish subscribe pattern. It is designed for ease of use and aims to be feature rich and extensible while preserving resource efficiency and performance.

Homepage: github.com/bennidi/mbassador

Usage: github.com/bennidi/mbassador#usage

Example code:

// Listeners are subscribed by passing them to the #subscribe() method
bus.subscribe(new ListenerDefinition.SyncAsyncListener());

// #subscribe() is idem-potent => Multiple calls to subscribe do NOT add the listener more than once (set semantics)
Object listener = new ListenerDefinition.SyncAsyncListener();
bus.subscribe(listener);
bus.subscribe(listener);

// Classes without handlers will be silently ignored
bus.subscribe(new Object());
bus.subscribe(new String());

bus.publishAsync(new File("/tmp/random.csv")); //returns immediately, publication will continue asynchronously
bus.post(new File("/tmp/random.csv")).asynchronously(); // same as above

bus.publish("some message"); // will return after each handler has been invoked
bus.post("some message").now(); // same as above

Lombok

One of the most frequently voiced criticisms of the Java language is the volume of this type of code that is found in most projects. This problem is frequently a result of design decisions in various libraries, but is exacerbated by limitations in the language itself. Project Lombok aims to reduce the prevalence of some of the worst offenders by replacing them with a simple set of annotations.

Homepage: projectlombok.org

Installation and guide: jnb.ociweb.com/jnb/jnbJan2010.html

Example code:

@Getter @Setter private boolean employed = true;
@Setter(AccessLevel.PROTECTED) private String name;

ByteBuddy

Byte Buddy is a code generation library for creating Java classes during the runtime of a Java application and without the help of a compiler. Other than the code generation utilities that ship with the Java Class Library, Byte Buddy allows the creation of arbitrary classes and is not limited to implementing interfaces for the creation of runtime proxies.

Homepage: bytebuddy.net

Tutorial: bytebuddy.net/#/tutorial

Example code:

Class<?> dynamicType = new ByteBuddy()
    .subclass(Object.class)
    .method(ElementMatchers.named("toString"))
    .intercept(FixedValue.value("Hello World!"))
    .make()
    .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
    .getLoaded();

assertThat(dynamicType.newInstance().toString(), is("Hello World!"));

JUnitParams

JUnitParams project adds a new runner to JUnit and provides much easier and readable parametrised tests for JUnit >=4.6. Main differences to standard JUnit Parametrised runner:

Homepage: github.com/Pragmatists/JUnitParams

Quickstart: github.com/Pragmatists/junitparams/wiki/Quickstart

Example code:

@RunWith(JUnitParamsRunner.class)
public class PersonTest {

  @Test
  @Parameters({"17, false",
    "22, true"})
  public void personIsAdult(int age, boolean valid) throws Exception {
    assertThat(new Person(age).isAdult(), is(valid));
  }

}

Mockito

Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with a clean & simple API. Mockito doesn’t give you hangover because the tests are very readable and they produce clean verification errors.

Homepage: mockito.org

Latest documentation: site.mockito.org/mockito/docs/current/org/mockito/Mockito.html

Example code:

import static org.mockito.Mockito.*;

// mock creation
List mockedList = mock(List.class);

// using mock object - it does not throw any "unexpected interaction" exception
mockedList.add("one");
mockedList.clear();

// selective, explicit, highly readable verification
verify(mockedList).add("one");
verify(mockedList).clear();

Jukito

The combined power of JUnit, Guice and Mockito. Plus it sounds like a cool martial art. So you started using dependency injection because somebody told you it would make your tests simpler? But as you gaze at your deep hierarchy of test classes, "simple" is not exactly the word you think of. Plus, creating a new mock whenever you add a parameter to an injected constructor gets old very quickly. You are not alone! And Jukito was created specifically for people like you.

Homepage: github.com/ArcBees/Jukito

Example code:

@RunWith(JukitoRunner.class)
public class CalculatorTest {

  public static class Module extends JukitoModule {

    protected void configureTest() {
      bindMany(Calculator.class,
          ScientificCalculator.class,
          BusinessCalculator.class);

      bindManyInstances(AdditionExample.class,
          new AdditionExample(1, 1, 2),
          new AdditionExample(10, 10, 20),
          new AdditionExample(18, 24, 42));
    }
  }

  @Test
  public void testAdd(@All Calculator calculator, @All AdditionExample example) {
    // WHEN
    int result = calculator.add(example.a, example.b);

    // THEN
    assertEquals(example.expected, result);
  }
}

Spock

Spock is a testing and specification framework for Java and Groovy applications. What makes it stand out from the crowd is its beautiful and highly expressive specification language.

Homepage: github.com/spockframework/spock

Spock web console: meetspock.appspot.com/edit/5163196142845952

Tutorial: thejavatar.com/testing-with-spock

Example code:

class HelloSpock extends Specification {
  def "length of Spock's and his friends' names"() {
    expect:
    name.size() == length

    where:
    name     | length
    "Spock"  | 5
    "Kirk"   | 4
    "Scotty" | 6
  }
}

Awaitility

Testing asynchronous systems is hard. Not only does it require handling threads, timeouts and concurrency issues, but the intent of the test code can be obscured by all these details. Awaitility is a DSL that allows you to express expectations of an asynchronous system in a concise and easy to read manner.

Homepage: github.com/awaitility/awaitility

Usage: github.com/awaitility/awaitility/wiki/Usage

Example code:

await().atMost(5, SECONDS).until(userRepository::size, is(1));

Rest-assured

Testing and validating REST services in Java is harder than in dynamic languages such as Ruby and Groovy. REST Assured brings the simplicity of using these languages into the Java domain.

Homepage: rest-assured.io

Usage: github.com/rest-assured/rest-assured/wiki/Usage

Example code:

given().
         parameters("firstName", "John", "lastName", "Doe").
when().
         post("/greetXML").
then().
         body("greeting.firstName", equalTo("John")).
         body("greeting.lastName", equalTo("Doe"));

Okio

Okio is a new library that complements java.io and java.nio to make it much easier to access, store, and process your data.

Homepage: github.com/square/okio

Example code:

public void decodePng(InputStream in) throws IOException {
  BufferedSource pngSource = Okio.buffer(Okio.source(in));

  ByteString header = pngSource.readByteString(PNG_HEADER.size());
  if (!header.equals(PNG_HEADER)) {
    throw new IOException("Not a PNG.");
  }

  while (true) {
    Buffer chunk = new Buffer();

    // Each chunk is a length, type, data, and CRC offset.
    int length = pngSource.readInt();
    String type = pngSource.readUtf8(4);
    pngSource.readFully(chunk, length);
    int crc = pngSource.readInt();

    decodeChunk(type, chunk);
    if (type.equals("IEND")) {
      break;
    }
  }

  pngSource.close();
}

HikariCP

Fast, simple, reliable. HikariCP is a "zero-overhead" production ready JDBC connection pool. At roughly 90Kb, the library is very light.

Homepage: brettwooldridge.github.io/HikariCP

Explanation: github.com/brettwooldridge/HikariCP/wiki/Down-the-Rabbit-Hole

Configuration: github.com/brettwooldridge/HikariCP#initialization

gRPC

In gRPC a client application can directly call methods on a server application on a different machine as if it was a local object, making it easier for you to create distributed applications and services. As in many RPC systems, gRPC is based around the idea of defining a service, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a stub (referred to as just client in some languages) that provides the same methods as the server.

Homepage: www.grpc.io

Tutorial: www.grpc.io/docs/tutorials/basic/java.html

Example code:

public void greet(String name) {
  logger.info("Will try to greet " + name + " ...");
  HelloRequest request = HelloRequest.newBuilder().setName(name).build();
  HelloReply response;
  try {
    response = blockingStub.sayHello(request);
  } catch (StatusRuntimeException e) {
    logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
    return;
  }
  logger.info("Greeting: " + response.getMessage());
}

Kryo

Kryo is a fast and efficient object graph serialization framework for Java. The goals of the project are speed, efficiency, and an easy to use API. The project is useful any time objects need to be persisted, whether to a file, database, or over the network. Kryo can also perform automatic deep and shallow copying/cloning. This is direct copying from object to object, not object->bytes->object.

Homepage: github.com/EsotericSoftware/kryo

Quick start: github.com/EsotericSoftware/kryo#quickstart

Example code:

Kryo kryo = new Kryo();
// ...
Output output = new Output(new FileOutputStream("file.bin"));
SomeClass someObject = ...
kryo.writeObject(output, someObject);
output.close();
// ...
Input input = new Input(new FileInputStream("file.bin"));
SomeClass someObject = kryo.readObject(input, SomeClass.class);
input.close();

MockServer

MockServer can be used for mocking any system you integrate with via HTTP or HTTPS (i.e. services, web sites, etc).

Homepage: mock-server.com

Getting started: mock-server.com/mock_server/getting_started.html

Example code:

new MockServerClient("localhost", 1080)
    .when(
        request()
        .withMethod("POST")
        .withPath("/login")
        .withBody("{username: 'foo', password: 'bar'}")
    )
    .respond(
        response()
        .withStatusCode(302)
        .withCookie(
            "sessionId", "2By8LOhBmaW5nZXJwcmludCIlMDAzMW"
        )
        .withHeader(
            "Location", "https://www.mock-server.com"
        )
    );