29 czerwca 2016 blog java
Orginal slides are available on slideshare.net.
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);
}
}
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);
}
}
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.");
}
}
}
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 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 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 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");
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 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
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;
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 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 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();
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 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
}
}
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));
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 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();
}
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
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 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 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"
)
);