Top Banner
@ Delabassee @ JosePaumard #SE84EE Java EE devs Java SE 8 for
84

Java SE 8 for Java EE developers

Apr 16, 2017

Download

Education

José Paumard
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#SE84EE

Java EE devs

Java SE 8 for

Page 2: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Agenda

Java SE 8 has been released ~1.5 year ago

Java EE 7 Application Servers

- GlassFish, WildFly, Liberty Profile, WebLogic, etc.

Page 3: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Agenda

Java SE 8 has been released ~1.5 year ago

Java EE 7 Application Servers

- GlassFish, WildFly, Liberty Profile, WebLogic, etc.

Check some important Java SE 8 new features

for Java EE developers... with patterns!

Page 4: Java SE 8 for Java EE developers

@Delabassee

Page 5: Java SE 8 for Java EE developers

@JosePaumard

Page 6: Java SE 8 for Java EE developers

@JosePaumard

Page 7: Java SE 8 for Java EE developers

start

Page 8: Java SE 8 for Java EE developers

The following is intended to outline our general product direction.

It is intended for information purposes only, and may not be

incorporated into any contract. It is not a commitment to deliver

any material, code, or functionality, and should not be relied upon

in making purchasing decisions. The development, release, and

timing of any features or functionality described for Oracle’s

products remains at the sole discretion of Oracle.

Page 9: Java SE 8 for Java EE developers
Page 10: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Questions?

#SE84EE

http://slido.com

Page 11: Java SE 8 for Java EE developers

Date

Page 12: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

New Date & Time API

Date & Time API is a new introduction in Java 8

Initiated by Stephen Colebourne, based on Joda Time

Complete replacement of Date & Calendar

Page 13: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Date: ZonedTime

Useful for localized times

Set<String> allZonesIds = ZoneId.getAvailableZoneIds() ;

String ukTZ = ZoneId.of("Europe/Paris") ;

Page 14: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Date: ZonedTime

Useful for localized times

System.out.println(ZonedDateTime.of(

1998, Month.JULY.getValue(), 12, // year / month / day22, 0, 0, 0, // h / mn / s / nanosZoneId.of("Europe/Paris"))

); // prints 1998-07-22T22:00-00:01:15[Europe/London]

Page 15: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Date: ZonedTime

Useful for localized times

System.out.println(ZonedDateTime.of(

1998, Month.JULY.getValue(), 12, // year / month / day22, 0, 0, 0, // h / mn / s / nanosZoneId.of("Europe/Paris"))

);

ZonedDateTime nextWorldCup = currentWorldCup.plus(Period.ofYear(4));

Page 16: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Date: ZonedTime

Useful for localized times

System.out.println(ZonedDateTime.of(

1998, Month.JULY.getValue(), 12, // year / month / day22, 0, 0, 0, // h / mn / s / nanosZoneId.of("Europe/Paris"))

);

ZonedDateTime nextWorldCup = currentWorldCup.plus(Period.ofYear(4));

ZonedDateTime nexWorldCupJapan= nextWorldCup.withZoneSameInstant(ZoneId.of("Asia/Tokyo")) ;

Page 17: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Date: bridges with java.util.Date

Conversions between j.u.Date and Date & Time

Time time = Time.from(localTime); // API -> legacyLocalTime localTime = time.toLocalTime(); // legacy -> new API

Date date = Date.from(localDate); // API -> legacyLocalDate localDate = date.toLocalDate(); // legacy -> new API

TimeStamp time = TimeStamp.from(instant); // API -> legacyInstant instant = time.toInstant(); // legacy -> new API

Date date = Date.from(instant); // API -> legacyInstant instant = date.toInstant(); // legacy -> new API

Page 18: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Usable in JPA

JPA does not support this Date & Time API (yet)

But with converters, we can still use it

@Entitypublic abstract class AbstractPersistent {

@Convert(converter=DateConverter.class)private Instant instant;

}

Page 19: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Usable in JPA

The converter is a classical object

public class DateConverterimplements AttributeConverter<Instant, Date> {

public Date convertToDatabaseColumn(Instant instant) {return Date.from(instant);

}

public Instant convertToEntityAttribute(Date date) {return date.toInstant();

}}

Page 20: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Usable in JPA

The converter is a classical object

public class DateFormatConverterimplements AttributeConverter<ZonedDateTime, String> {

public String convertToDatabaseColumn(ZonedDateTime time) {return DateTimeFormatter.ISO_DATE_TIME.format(time);

}

public ZonedDateTime convertToEntityAttribute(String formated) {return DateTimeFormatter.ISO_DATE_TIME

.parse(formated, ZonedDateTime::from);}

}

Page 21: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Usable in JPA

With JPA converters we can use the types

from Date & Time API and map in j.u.l.Date or String

Page 22: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Usable in JSF

With a Custom JSF Converter

@FacesConverter("instantConverter")public class TimeConverter implements javax.faces.convert.Converter {

@Overridepublic Object getAsObject(FacesContext ctx, … , String value) {

return Instant.parse(value);}

}

Page 23: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Usable in JSF

With a Custom JSF Converter...@Overridepublic String getAsString(FacesContext ctx, … , Object value) {

DateTimeFormatter formatter =DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)

.withLocale(Locale.US)

.withZone(ZoneId.systemDefault());

return formatter.format((TemporalAccessor) value);}

}

Page 24: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Usable in JSF

With a Custom JSF Converter<h:form><h:inputText id = "date”

value = "#{order.timestamp}" size = "20" required="true”label = "start"

converter = "instantConverter" />...

@ManagedBean(name="order") @SessionScopedpublic class myBean implements Serializable{

Instant timestamp;…

Page 25: Java SE 8 for Java EE developers

Annotations

Page 26: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Annotations in Java 7

Wrapping annotations

An annotation cannot be applied more than once

@NamedQueries({@NamedQuery(name=SELECT_ALL, query="..."), @NamedQuery(name=COUNT_ALL, query="...")

})public class Customer {

}

Page 27: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Annotations in Java 8

Java 8 makes it possible!

@NamedQuery(name=SELECT_ALL, query="..."), @NamedQuery(name=COUNT_ALL, query="...")public class Customer {

}

Page 28: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Bean Validation

Suppose we want to validate a parameter

public orderdCar order( @CheckCar("VW") Car aCar ) { ...

}

Page 29: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Bean Validation

Here is the Bean Validation code for @CheckCar

@Target({PARAMETER})@Retention(RUNTIME)@Constraint(validatedBy = CarValidator.class)public @interface CheckCar {

Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};String value();

}

Page 30: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Bean Validation

And for the validator

public class CarValidatorimplements ConstraintValidator<CheckCar, Car> {

private String carBrand;

public void initialize(CheckCar constraintAnnotation) {this.carBrand = constraintAnnotation.value();

}

public boolean isValid(Car obj, ConstraintValidatorContext ctrCtx) {if (object == null) return true;return (!obj.getBrand().toUpperCase().contains(carBrand));

}

}

Page 31: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Bean Validation

And the Java 8 trick to make it repeatable

@Target({PARAMETER})@Retention(RUNTIME)@Repeatable(CheckCars.class)@Constraint(validatedBy = CarValidator.class)public @interface CheckCar {

Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};String value();

}

Page 32: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Bean Validation

And the Java 8 trick to make it repeatable

@Target({PARAMETER})@Retention(RUNTIME)public @interface CheckCars {

CheckCar[] value() default{};}

Page 33: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Bean Validation

Suppose we want to validate a parameter

public orderdCar order( @CheckCar("VW") @ChechCar("Audi") Car aCar ) { ...

}

Page 34: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Type annotations

Annotations can be now put on types

Example 1: tell that a variable should not be null

private @NonNull List<Person> persons = ... ;

Page 35: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Type annotations

Annotations can be now put on types

Example 1: tell that a variable should not be null

Example 2: the content should not be null neither

private @NonNull List<Person> persons = ... ;

private @NonNull List<@NonNull Person> persons = ... ;

Page 36: Java SE 8 for Java EE developers

String

Page 37: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Joining strings

New String joiners are coming to the JDK!

Page 38: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Joining strings

StringJoiner class

And it prints:

StringJoiner sj = new StringJoiner(", ") ;

sj.add("one").add("two").add("three") ;String s = sj.toString() ;System.out.println(s) ;

> one, two, three

Page 39: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Joining strings

StringJoiner with prefix / postfix

And it prints:

StringJoiner sj = new StringJoiner(", ", "{", "}") ;

sj.add("one").add("two").add("three") ;String s = sj.toString() ;System.out.println(s) ;

> {one, two, three}

Page 40: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Joining strings

Also accessible from the String class

And it prints:

// From the String class, with a varargString s = String.join(", ", "one", "two", "three");System.out.println(s);

> one, two, three

Page 41: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Joining strings

And directly from a List

// From a list to a String using the Stream & Collectors APIString s =

listOfStrings.stream().collect(Collectors.joining(", "));

System.out.println(s);

> one, two, three

Page 42: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Joining strings

And directly from a List

The result is

// From the String class, with a varargString s =

listOfStrings.stream().collect(Collectors.joining(", ", "{", "}"));

System.out.println(s);

> {one, two, three}

Page 43: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Support for Base64 decoding

After a few years…

import java.util.Base64;

String txt = "Modern Times!";

String encoded = Base64.getEncoder().encodeToString(txt.getBytes(StandardCharsets.UTF_8));

String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);

Page 44: Java SE 8 for Java EE developers

Streams

Page 45: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

What is a Stream?

A new API

A typed interface

A new concept

Page 46: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

What is a Stream?

A new API

A typed interface

A new concept

Let’s see some code!

Page 47: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Readable and efficient patterns

Extract histograms from data

List<Person> people = Arrays.asList();

Map<City, Double> agesByCity = people.stream()

.filter(p -> p.getAge() > 20)

.collect(Collectors.groupingBy(

Person::getCity, Collectors.averagingDouble(Person::getAge)

));

Page 48: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Readable and efficient patterns

Extract histograms from data

List<Person> people = Arrays.asList();

Map<City, Double> agesByCity = people.stream()

.filter(p -> p.getAge() > 20)

.collect(Collectors.groupingBy(

Person::getCity, Collectors.averagingDouble(Person::getAge)

));

Page 49: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Readable and efficient patterns

Extract histograms from data

List<Person> people = Arrays.asList();

Map<City, Double> agesByCity = people.stream()

.filter(p -> p.getAge() > 20)

.collect(Collectors.groupingBy(

Person::getCity, Collectors.averagingDouble(Person::getAge)

));

Page 50: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Readable and efficient patterns

Extract histograms from data

List<Person> people = Arrays.asList();

Map<City, Double> agesByCity = people.stream()

.filter(p -> p.getAge() > 20)

.collect(Collectors.groupingBy(

Person::getCity, Collectors.averagingDouble(Person::getAge)

));

Page 51: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Readable and efficient patterns

Extract histograms from data

List<Person> people = Arrays.asList();

Map<City, Double> agesByCity = people.stream()

.filter(p -> p.getAge() > 20)

.collect(Collectors.groupingBy(

Person::getCity, Collectors.averagingDouble(Person::getAge)

));

Page 52: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Readable and efficient patterns

Extract histograms from data

List<Person> people = Arrays.asList();

Map<City, Double> agesByCity = people.stream()

.filter(p -> p.getAge() > 20)

.collect(Collectors.groupingBy(

Person::getCity, Collectors.averagingDouble(Person::getAge)

));

Page 53: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Building a Stream on a String

Building a Stream on the letters of a String:

String s = "hello";IntStream stream = s.chars(); // stream on the letters of s

Page 54: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Building a Stream on a String

Building a Stream on the letters of a String:

String s = "hello";IntStream stream = s.chars(); // stream on the letters of s

s.chars() // IntStream.mapToObj(letter -> (char)letter) // Stream<Character>.map(Character::toUpperCase).forEach(System.out::println); // Prints a Character

> HELLO

Page 55: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Build a Stream from a text file

Find the first error line from a log file

// Java 7 : try with resources and use of PathsPath path = Paths.get("d:", "tmp", "debug.log");try (Stream<String> stream = Files.lines(path)) {

stream.filter(line -> line.contains("ERROR")).findFirst().ifPresent(System.out::println);

} catch (IOException ioe) {// handle the exception

}

Page 56: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Build a Stream from a regex

Building a Stream from a regexp

// book is a looooooooong StringStream<String> words =

Pattern.compile(" ").splitAsStream(book) ;

Page 57: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Build a Stream from a regex

Building a Stream from a regexp

More efficient than:

// book is a looooooooong StringStream<String> words =

Pattern.compile(" ").splitAsStream(book) ;

// book is a looooooooong StringStream<String> words =

Stream.of(book.split(" "));

Page 58: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Flatmap: Files.lines + regex

Splitting a text files into words

Stream<String> streamOfLines = Files.lines(path);

Function<String, Stream<String>> splitter = line -> Pattern.compile(" ").splitAsStream(line);

long numberOfWords = streamOfLines.flatMap(splitter)

.map(String::toLowerCase)

.distinct()

.count();

Page 59: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Why is it important for Java EE?

Given this JSON file

[

{

"name":"Duke",

"gender":"m",

"phones":[

"home":"650‐123‐4567","mobile":"650‐111‐2222"

]

},

{

"name":"Jane", …

]

JsonArray contacts = Json.createArrayBuilder()

.add(…

Page 60: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Why is it important for Java EE?

And some JSON-P magic

Map<String, Long> names = contacts.getValuesAs(JsonObject.class).stream()

.filter(x -> "f".equals(x.getString("gender")))

.map(x -> (x.getString("name")))

.collect(Collectors.groupingBy(

Function.identity(),Collectors.counting()

));

Page 61: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Why is it important for Java EE?

// TodayJsonArray names =

contacts.getValuesAs(JsonObject.class).stream().filter(x -> "f".equals(x.getString("gender"))).map(x -> (x.getString("name"))).collect(

Collector.of(() -> Json.createArrayBuilder(), (builder, value) -> builder.add(value),(builder1, builder2) -> builder1.add(builder2), builder -> builder.build()

));

Page 62: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Why is it important for Java EE?

// TodayJsonArray names =

contacts.getValuesAs(JsonObject.class).stream().filter(x -> "f".equals(x.getString("gender"))).map(x -> (x.getString("name"))).collect(

Collector.of(Json::createArrayBuilder, JsonArrayBuilder::add,JsonArrayBuilder::add, JsonArrayBuilder::build

));

Page 63: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Why is it important for Java EE?

// TodayJsonArray names =

contacts.getValuesAs(JsonObject.class).stream().filter(x -> "f".equals(x.getString("gender"))).map(x -> (x.getString("name"))).collect(

Collectors.collectingAndThen(Collector.of(

Json::createArrayBuilder, JsonArrayBuilder::add,JsonArrayBuilder::add

), JsonArrayBuilder::build

));

Page 64: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Why is it important for Java EE?

Collect into JSON

Avaiblable through the JsonCollectors factory

// Tomorrow, with JSON-P 1.1JsonArray names =

contacts.getValuesAs(JsonObject.class).stream().filter(x -> "f".equals(x.getString("gender"))).map(x -> (x.getString("name"))).collect(

JsonCollectors.toJsonArray());

Page 65: Java SE 8 for Java EE developers

Parallelism

Page 66: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

A warning on parallelism

All parallel operations (Streams, ConcurrentHashMap)

take place in the common ForkJoinPool

The common ForkJoinPool takes all the

available cores / CPUs

Page 67: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

A warning on parallelism

All parallel operations (Streams, ConcurrentHashMap)

take place in the common ForkJoinPool

The common ForkJoinPool takes all the

available cores / CPUs

To preserve your Application Server:

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "1") ;

Page 68: Java SE 8 for Java EE developers

CompletableFuture

Page 69: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

CompletableFuture

New addition to j.u.concurrent

Allow to chain asynchronous tasks

Use case: test the asynchronous calls in the Servlet API,

EJB, JAX-RS, …

Page 70: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Creation of an asynchronous task

The Jersey way to create an asynchronous call

@Path("/resource")public class AsyncResource {

@GETpublic void asyncGet(@Suspended final AsyncResponse asyncResponse) {

new Thread(new Runnable() {public void run() {

String result = longOperation();asyncResponse.resume(result);

}}).start();

}}

Page 71: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Creation of an asynchronous task

(let us fix this code with Java 8)

@Path("/resource")public class AsyncResource {

@GETpublic void asyncGet(@Suspended final AsyncResponse asyncResponse) {

executor.submit(() -> {String result = longOperation();asyncResponse.resume(result);

});}

}

Page 72: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

We want to check if the result object

is passed to the resume() method of the asyncResponse

It is a very basic test, but tricky to write since we are in an

asynchronous world

We have mocks for that!

Page 73: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

We can inject a mock AsyncResponse, even mock the result

Then verify the correct interaction:

But we need to verify this once the run() method has been

called…

Mockito.verify(mockAsyncResponse).resume(result);

Page 74: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

This is where CompletionStage come to the rescue!

@Path("/resource")public class AsyncResource {

@Inject ExecutorService executor;

@GETpublic void asyncGet(@Suspended final AsyncResponse asyncResponse) {

executor.submit(() -> {String result = longOperation();asyncResponse.resume(result);

});}

}

Page 75: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

@Path("/resource")public class AsyncResource {

@Inject ExecutorService executor;

@GETpublic void asyncGet(@Suspended final AsyncResponse asyncResponse) {

executeAsync(asyncResponse);}

public CompletableFuture<Void> executeAsync(final AsyncResponse asyncResponse) {return CompletableFuture.runAsync(() -> {

asyncResponse.resume(longOperation());}, executor);

}}

Page 76: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

AsyncResource asyncResource = new AsyncResource();

asyncResource.executeAsync(mockAsyncResponse); // returns the CompletableFuture.thenRun(() -> { // then execute this Runnable

Mockito.verify(mockAsyncResponse).resume(result);}

);

Page 77: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

Be careful of visibility issues

1) It’s better to run this in the same thread

2) Since the mocks are used and checked in this thread,

create them in this thread too

Page 78: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

So the complete pattern becomes this one

1) First we create our mocks

String result = Mockito.mock(String.class);AsyncResponse response = Mockito.mock(AsyncResponse.class);

Runnable train = () -> Mockito.doReturn(result).when(response.longOperation());Runnable verify = () -> Mockito.verify(response).resume(result);

Page 79: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

So the complete pattern becomes this one

2) Then we create the call & verify

Runnable callAndVerify = () -> {asyncResource.executeAsync(response).thenRun(verify);

}

Page 80: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

So the complete pattern becomes this one

3) Then we create the task

ExecutorService executor = Executors.newSingleThreadExecutor();

AsynResource asyncResource = new AsyncResource();asyncResource.setExecutorService(executor);

CompletableFuture.runAsync(train, executor) // this trains our mocks.thenRun(callAndVerify); // this verifies our mocks

Page 81: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

How to test it?

Since a CompletableFuture is also a Future, we can fail

with a timeout if the test does not complete fast enough

ExecutorService executor = Executors.newSingleThreadExecutor();

AsynResource asyncResource = new AsyncResource();asyncResource.setExecutorService(executor);

CompletableFuture.runAsync(train, executor) // this trains our mocks.thenRun(callAndVerify) // this verifies our mocks.get(10, TimeUnit.SECONDS);

Page 82: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#Devoxx #SE84EE

Conclusion

Java 8 is not just about lambdas

There are also many new and very useful patterns

Ready to be used before becoming a lambda ninja!

Not covered:

- Collection framework

- Concurrency, Concurrent hashmap

- JavaScript on the JVM with Nashorn

- Security

Page 83: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#SE84EE

Thank you!

Page 84: Java SE 8 for Java EE developers

@Delabassee @JosePaumard#SE84EE