java8.part2

178
New Features in JDK 8 part 2 Ivan St. Ivanov Nayden Gochev Martin Toshev Dmitry Alexandrov

Upload: ivan-ivanov

Post on 10-May-2015

988 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Java8.part2

New Features in JDK 8part 2

Ivan St. IvanovNayden GochevMartin Toshev Dmitry Alexandrov

Page 2: Java8.part2

Agenda• Lambda and Stream API refresh• Annotations on Java types (JSR 308)• Preserving parameter names• API improvements: BigInteger, StringJoiner, Base64• Optional type• Date and Time API (JSR 310)• Concurrency Enhancements• Security Enhancements• Compact Profiles• The Nashorn JavaScript engine

Page 3: Java8.part2

Agenda• Lambda and Stream API refresh• Annotations on Java types (JSR 308)• Preserving parameter names• API improvements: BigInteger, StringJoiner, Base64• Optional type• Date and Time API (JSR 310)• Concurrency Enhancements• Security Enhancements• Compact Profiles• The Nashorn JavaScript engine• BEER !!!!

Page 4: Java8.part2

Lambda and Stream API refresh

Page 5: Java8.part2

Lambdas refresh

• Prior to Java 8, printing the even numbers:

List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6);for (Integer anInt : ints) { if (anInt % 2 == 0) { System.out.println(anInt); }}

Page 6: Java8.part2

Lambdas refresh

• After Java 8:

List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6);ints.stream() .filter(i -> i % 2 == 0) .foreach(i -> System.out.println(i));

Page 7: Java8.part2

Lambdas refresh

• Lambdas bring anonymous function types in Java (JSR 335):

• Example:

(x,y) -> x + y

(parameters) -> {body}

Page 8: Java8.part2

Lambdas refresh

• Lambdas can be used in place of functional interfaces (interfaces with just one method such as Runnable)

• Example:new Thread(new Runnable() {

@Overridepublic void run() {

System.out.println("It runs !"); }}).start();

new Thread(() -> System.out.println("It runs !");).start();

Page 9: Java8.part2

Lambdas refresh

• Examples of such functional interfaces:

java.lang.Runnable -> run() java.util.concurrent.Callable -> call() java.security.PrivilegedAction -> run() java.util.Comparator -> compare(T o1, T o2) java.awt.event.ActionListener ->

actionPerformed (ActionEvent e)

Page 10: Java8.part2

Lambdas refresh

• Examples of such functional interfaces:

java.lang.Runnable -> run() java.util.concurrent.Callable -> call() java.security.PrivilegedAction -> run() java.util.Comparator -> compare(T o1, T o2) java.awt.event.ActionListener ->

actionPerformed (ActionEvent e) java.lang.Iterable ->

forEach(Consumer<? super T> action)

Page 11: Java8.part2

Lambdas refresh

java.lang.Iterable -> forEach(Consumer<? super T> action) ?!?

Isn't this breaking backward compatibility ?!?

Page 12: Java8.part2

Lambdas refresh

java.lang.Iterable -> forEach(Consumer<? super T> action) ?!?

Isn't this breaking compatibility ?!?

No - because forEach is an extension method.

Page 13: Java8.part2

Lambdas refresh

Extension methods provide a mechanism for extending an existing interface without breaking backward compatibility.

public interface Iterable<T> {

default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }}

Page 14: Java8.part2

Lambdas refresh

• Additional functional interfaces are provided by the java.util.function package for use by lambdas such as:o Predicate<T> - one method with param of type T and

boolean return typeo Consumer<T> - one method with param T and no

return typeo Function<T, R> - one method with param T and return

type Ro Supplier<T> - one method with no params and return type T

Page 15: Java8.part2

Stream API

• Databases and other programming languages allow us to specify aggregate operations explicitly

• The streams API provides this mechanism in the Java platform

• The notion of streams is derived from functional programming languages

Page 16: Java8.part2

Stream API

• The stream API makes use of lambdas and extension methods

• Streams can be applied on collections, arrays, IO streams and generator functions

Page 17: Java8.part2

Stream API

• Streams can be finite or infinite

• Streams can apply intermediate functions on the data that produce another stream (e.g. map, reduce)

Page 18: Java8.part2

Stream API

java.util.stream.Stream<T> collection.stream();java.util.stream.Stream<T> collection.parallelStream();

Page 19: Java8.part2

Stream API useful methods

• filter(Predicate), map(Function), reduce(BinaryOperator), collect(Collector)

• min(Comparator), max(Comparator), count()• forEach(Consumer)• findAny(), findFirst()• average(), sum()

Page 20: Java8.part2

Stream internals

• Stream operations are composed into a pipeline

• Streams are lazy: computation is performed when the terminal operation is invoked

int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight()) .sum();

Page 21: Java8.part2

Method references

• Intended to be used in lambda expressions, preventing unnecessary boilerplate

• Example:

• Lambda parameter list and return type must match the signature of the method

books.stream().map(b -> b.getTitle()) books.stream().map(Book::getTitle)

Page 22: Java8.part2

Method references – static methods

public class Printers { public static void print(String s) {...} }

Arrays.asList("a", "b", "c").forEach(Printers::print)

Page 23: Java8.part2

Method references – instance methods (1)

public class Document { public String getPageContent(int pageNumber) { return this.pages.get(pageNumber).getContent(); }}

public static void printPages(Document doc, int[] pageNumbers) { Arrays.stream(pageNumbers) .map(doc::getPageContent) .forEach(Printers::print); }

Page 24: Java8.part2

Method references – instance methods (2)

public class Document { public String getPageContent(int pageNumber) { return this.pages.get(pageNumber).getContent(); }}

public static void printDocuments(List<Page> pages) { pages.stream() .map(Page::getContent) .forEach(Printers::print); }

Page 25: Java8.part2

Method references – constructors

public static Stream<Page> createPagesFrom(Stream<String> contents) { return contents.map(Page::new). }

Page 26: Java8.part2

Static methods on interfaces

• You can declare static methods on interfaces:public interface ContentFormatter { public void format(); static String convertRegex(String regex) { ... }}

Page 27: Java8.part2

Static methods on interfaces

• You can declare static methods on interfaces:public interface ContentFormatter { public void format(); static String convertRegex(String regex) { ... }}

• All the implementing classes will have this method available to them

• No more need for utility classes

Page 28: Java8.part2

Annotations on Java types (JSR 308)

Page 29: Java8.part2

Annotations in Java 5/6/7• Annotations on class declarations @Stateless public class Person

Page 30: Java8.part2

Annotations in Java 5/6/7• Annotations on class declarations @Stateless public class Person

• Annotations on method declarations @Override public String toString() {

Page 31: Java8.part2

Annotations in Java 5/6/7• Annotations on class declarations @Stateless public class Person

• Annotations on method declarations @Override public String toString() {

• Annotations on class fields @PersistenceContext private EntityManager em;

Page 32: Java8.part2

Annotations in Java 5/6/7• Annotations on class declarations @Stateless public class Person

• Annotations on method declarations @Override public String toString() {

• Annotations on class fields @PersistenceContext private EntityManager em;

• Annotations on method parameters public Person getPersonByName(@PathParam("name") String name) {

Page 33: Java8.part2

New in Java 8

You can put annotations anywhere a type is specified:

public void sayHello() { @Encrypted String data; List<@NonNull String> strings; HashMap names = (@Immutable HashMap) map;}

Page 34: Java8.part2

Declaring type annotations

• Use TYPE_PARAMETER or TYPE_USE type parameter (or both):

@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})public @interface Encrypted { }

• Type annotations on local variables can be retained in the class files

• The full generic type is retained and accessible at runtime

Page 35: Java8.part2

Gotchas

• You can’t overload methods based on annotations:

public void sayHello(String message) {} // wrong public void sayHello(@NonNull String message) {}

• Nobody will stop you doing bad things: public void passPassword(@Encrypted String pwd) {} public void hello() { @PlainText String myPass = "foo"; passPassword(myPass); }

• The code above will compile, run… and crash

Page 36: Java8.part2

Type annotations? Really?... OK

• Typical use case is error checking– Hook through the compiler API– The Checker framework

• Not only that:– More fine-grained AOP– Further control of dependency injection

Page 37: Java8.part2

Preserving parameter names

Page 38: Java8.part2

Method parameters

• Before Java 8, only parameter positions and types were preserved after compilation

• In Java 8 you can have those in the .class files• They are not available by default

– Need to enable it with -parameters option to javac

Page 39: Java8.part2

Getting parameter namespublic static List<String> getParameterNames(Method method) { Parameter[] parameters = method.getParameters(); List<String> parameterNames = new ArrayList<>(); for (Parameter parameter : parameters) { if(!parameter.isNamePresent()) { throw new IllegalArgumentException("Parameter names are not present!"); } String parameterName = parameter.getName(); parameterNames.add(parameterName); } return parameterNames;}

Page 40: Java8.part2

API improvements: BigInteger, StringJoiner, Base64

Page 42: Java8.part2

StringJoiner

• StringJoiner is used to construct a sequence of characters separated by a delimiter and optionally starting with a supplied prefix and ending with a supplied suffix.

Page 43: Java8.part2

Example

The String "[George:Sally:Fred]" may be constructed as follows:

StringJoiner sj = new StringJoiner(":", "[", "]");

sj.add("George").add("Sally").add("Fred");

String desiredString = sj.toString();

Page 44: Java8.part2

Used internally in multiple places

List<String> cloudGroups = new ArrayList<>();cloudGroups.add("Cirrus"); cloudGroups.add("Alto"); cloudGroups.add("Stratus"); cloudGroups.add("Vertical Growth"); cloudGroups.add("Special Clouds"); String

cloudGroupsJoined = String.join("," ,cloudGroups);

Page 45: Java8.part2

List<String> cloudGroups = new ArrayList<>(); cloudGroups.add("Cirrus"); cloudGroups.add("Alto"); cloudGroups.add(null); cloudGroups.add("Special Clouds"); cloudGroups.add(null);

String cloudGroupsJoined = cloudGroups.stream() .filter(Objects::nonNull).collect(Collectors.joining(","));

Page 46: Java8.part2

Base64 encode/decode// Encode String asB64 = Base64.getEncoder().encodeToString("some string".getBytes("utf-8"));

System.out.println(asB64); // Output will be: c29tZSBzdHJpbmc=

// Decodebyte[] asBytes = Base64.getDecoder().decode("c29tZSBzdHJpbmc=");

System.out.println(new String(asBytes, "utf-8")); // And the output is: some string

Page 47: Java8.part2

Collections API additions• Iterable.forEach(Consumer)• Iterator.forEachRemaining(Consumer)• Collection.removeIf(Predicate)• Collection.spliterator()• Collection.stream()• Collection.parallelStream()• List.sort(Comparator)• List.replaceAll(UnaryOperator)• Map.forEach(BiConsumer)• Map.replaceAll(BiFunction)• Map.putIfAbsent(K, V)

• Map.remove(Object, Object)• Map.replace(K, V, V)• Map.replace(K, V)• Map.computeIfAbsent(K, Function)• Map.computeIfPresent(K, BiFunction)• Map.compute(K, BiFunction)• Map.merge(K, V, BiFunction)• Map.getOrDefault(Object, V)

Page 48: Java8.part2

Optional type

Page 49: Java8.part2

Optional

The main point behind Optional is to wrap an Object and to provide convenience API to handle nullability in a fluent manner.

Optional<String> stringOrNot = Optional.of("123"); //This String reference will never be null String alwaysAString = stringOrNot.orElse("");

Page 50: Java8.part2

But lets first see a nice example by Venkat Subramaniam

• Task is : Double the first even number greater than 3

Having List<Integer> values = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

Page 51: Java8.part2

Old way

int result = 0;for(int e : values){

if(e > 3 && e% 2 == 0) { result = e * 2; break; }}System.out.println(result);

Is it correct ? Is it ok ? .. Lets start eclipse

Page 52: Java8.part2

Ecilpse demo

So the new way :

System.out.println( values.stream()

.filter(value -> value >3) .filter(value -> value % 2 == 0) .map(value -> value * 2) .findFirst()Its easier to understand right ? But lets start it in eclipse.

Page 53: Java8.part2

So in summary Optional is heavily used in streaming API …!

// This Integer reference will be wrapped againOptional<Integer> integerOrNot = stringOrNot.map(Integer::parseInt);

// This int reference will never be nullint alwaysAnInt = stringOrNot .map(s -> Integer.parseInt(s)) .orElse(0);

Arrays.asList(1, 2, 3) .stream() .findAny() .ifPresent(System.out::println);

More at : http://java.dzone.com/articles/optional-will-remain-option

Page 54: Java8.part2

Date and Time API (JSR 310)

Page 55: Java8.part2

Date and Time API• The Date-Time API was developed using several

design principles.– Clear: The methods in the API are well defined and

their behavior is clear and expected. For example, invoking a method with a null parameter value typically triggers a NullPointerException.

– Fluent. Because most methods do not allow parameters with a null value and do not return a null value, method calls can be chained together and the resulting code can be quickly understood.

– Immutable

Page 56: Java8.part2

• The Date-Time API consists of the primary package, java.time, and four subpackages:

• java.time• java.time.chrono• java.time.format• java.time.temporal• java.time.zone

Page 57: Java8.part2

OverviewClass or Enum Year Month Day Hours Minutes Seconds* Zone Offset Zone ID toString Output

Instant X 2013-08-20T15:16:26.355Z

LocalDate X X X 2013-08-20

LocalDateTime X X X X X X 2013-08-20T08:16:26.937

ZonedDateTime X X X X X X X X2013-08-21T00:16:26.941+09:00[Asia/Tokyo]

LocalTime X X X 08:16:26.943

MonthDay X X --08-20Year X 2013YearMonth X X 2013-08

Month X AUGUST

OffsetDateTime X X X X X X X 2013-08-20T08:16:26.954-07:00

OffsetTime X X X X 08:16:26.957-07:00

Duration ** ** ** X PT20H (20 hours)

Period X X X *** *** P10D (10 days)

Page 58: Java8.part2

Method Naming ConventionsPrefix Method Type Use

of static factory Creates an instance where the factory is primarily validating the input parameters, not converting them.

from static factory Converts the input parameters to an instance of the target class, which may involve losing information from the input.

parse static factory Parses the input string to produce an instance of the target class.

format instance Uses the specified formatter to format the values in the temporal object to produce a string.

get instance Returns a part of the state of the target object.is instance Queries the state of the target object.

with instanceReturns a copy of the target object with one element changed; this is the immutable equivalent to a set method on a JavaBean.

plus instance Returns a copy of the target object with an amount of time added.

minus instance Returns a copy of the target object with an amount of time subtracted.

to instance Converts this object to another type.at instance Combines this object with another.

Page 59: Java8.part2

DayOfWeek and Month EnumsThe Date-Time API provides enums for specifying days of the week and months of the

year.

DayOfWeek

System.out.printf("%s%n", DayOfWeek.MONDAY.plus(3));

DayOfWeek dow = DayOfWeek.MONDAY;Locale locale = Locale.getDefault();System.out.println(dow.getDisplayName(TextStyle.FULL, locale));System.out.println(dow.getDisplayName(TextStyle.NARROW, locale));System.out.println(dow.getDisplayName(TextStyle.SHORT, locale));//Monday//M//Mon

Page 60: Java8.part2

MonthSystem.out.printf("%d%n", Month.FEBRUARY.maxLength());

Month month = Month.AUGUST;

Locale locale = Locale.getDefault();

System.out.println(month.getDisplayName(TextStyle.FULL, locale));System.out.println(month.getDisplayName(TextStyle.NARROW, locale));System.out.println(month.getDisplayName(TextStyle.SHORT, locale));

//August/A//Aug

Page 61: Java8.part2

LocalDateLocalDate date = LocalDate.of(2000, Month.NOVEMBER, 20);

DayOfWeek dotw = LocalDate.of(2012, Month.JULY, 9).getDayOfWeek();

LocalDate date = LocalDate.of(2000, Month.NOVEMBER, 20);TemporalAdjuster adj = TemporalAdjusters.next(DayOfWeek.WEDNESDAY);LocalDate nextWed = date.with(adj);System.out.printf("For the date of %s, the next Wednesday is %s.%n",date, nextWed);

//For the date of 2000-11-20, the next Wednesday is 2000-11-22.

Page 62: Java8.part2

YearMonth

YearMonth date = YearMonth.now();System.out.printf("%s: %d%n", date, date.lengthOfMonth());

YearMonth date2 = YearMonth.of(2010, Month.FEBRUARY);System.out.printf("%s: %d%n", date2, date2.lengthOfMonth());

YearMonth date3 = YearMonth.of(2012, Month.FEBRUARY);System.out.printf("%s: %d%n", date3, date3.lengthOfMonth());

//2013-06: 30//2010-02: 28//2012-02: 29

Page 63: Java8.part2

MonthDay & YearMonthDay date = MonthDay.of(Month.FEBRUARY, 29);boolean validLeapYear = date.isValidYear(2010);

boolean validLeapYear = Year.of(2012).isLeap();

Page 64: Java8.part2

LocalTime

LocalTime thisSec = LocalTime.now();

someMethod(thisSec.getHour(),thisSec.getMinute(),thisSec.getSecond());

Page 65: Java8.part2

LocalDateTimeSystem.out.printf("now: %s%n", LocalDateTime.now());

System.out.printf("Apr 15, 1994 @ 11:30am: %s%n", LocalDateTime.of(1994, Month.APRIL, 15, 11, 30));

System.out.printf("now (from Instant): %s%n", LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault()));

System.out.printf("6 months from now: %s%n", LocalDateTime.now().plusMonths(6));

System.out.printf("6 months ago: %s%n", LocalDateTime.now().minusMonths(6));now: 2013-07-24T17:13:59.985Apr 15, 1994 @ 11:30am: 1994-04-15T11:30now (from Instant): 2013-07-24T17:14:00.4796 months from now: 2014-01-24T17:14:00.4806 months ago: 2013-01-24T17:14:00.481

Page 66: Java8.part2

Time Zone and Offset Classes

• ZoneId specifies a time zone identifier and provides rules for converting between an Instant and a LocalDateTime.

• ZoneOffset specifies a time zone offset from Greenwich/UTC time.

Page 67: Java8.part2

The Date-Time API provides three temporal-based classes that work with time zones:

• ZonedDateTime handles a date and time with a corresponding time zone with a time zone offset from Greenwich/UTC.

• OffsetDateTime handles a date and time with a corresponding time zone offset from Greenwich/UTC, without a time zone ID.

• OffsetTime handles time with a corresponding time zone offset from Greenwich/UTC, without a time zone ID.

Page 68: Java8.part2

ZonedDateTime

The ZonedDateTime class, in effect, combines the LocalDateTime class with the ZoneId class. It is used to represent a full date (year, month, day) and time (hour, minute, second, nanosecond) with a time zone (region/city, such as Europe/Paris).

Page 69: Java8.part2

OffsiteDateTime// Find the last Thursday in July 2013.LocalDateTime date = LocalDateTime.of(2013, Month.JULY, 20, 19, 30);

ZoneOffset offset = ZoneOffset.of("-08:00");

OffsetDateTime date = OffsetDateTime.of(date, offset);

OffsetDateTime lastThursday = date.with(TemporalAdjuster.lastInMonth(DayOfWeek.THURSDAY));

System.out.printf("The last Thursday in July 2013 is the %sth.%n", lastThursday.getDayOfMonth());

//The last Thursday in July 2013 is the 25th..

Page 70: Java8.part2

Instant Class

• One of the core classes of the Date-Time API

import java.time.Instant;Instant timestamp = Instant.now();//2013-05-30T23:38:23.085ZInstant oneHourLater = Instant.now().plusHours(1);

Page 71: Java8.part2

Instant Class (2)

• There are methods for comparing instants, such as isAfter and isBefore. The until method returns how much time exists between two Instant objects.

long secondsFromEpoch = Instant.ofEpochSecond(0L).until(Instant.now(), ChronoUnit.SECONDS);

Page 72: Java8.part2

ParsingString in = ...;LocalDate date = LocalDate.parse(in, DateTimeFormatter.BASIC_ISO_DATE);

Page 73: Java8.part2

String input = ...;try { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM d yyyy"); LocalDate date = LocalDate.parse(input, formatter); System.out.printf("%s%n", date);}catch (DateTimeParseException exc) { System.out.printf("%s is not parsable!%n", input); throw exc; // Rethrow the exception.}// 'date' has been successfully parsed

Page 74: Java8.part2

FormattingZoneId leavingZone = ...;ZonedDateTime departure = ...;

try { DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm a"); String out = departure.format(format); System.out.printf("LEAVING: %s (%s)%n", out, leavingZone);}catch (DateTimeException exc) { System.out.printf("%s can't be formatted!%n", departure); throw exc;}

LEAVING: Jul 20 2013 07:30 PM (America/Los_Angeles)ARRIVING: Jul 21 2013 10:20 PM (Asia/Tokyo)

Page 75: Java8.part2

The Temporal PackageThe Temporal interface provides a framework for accessing temporal-based objects, and is implemented by the temporal-based classes, such as Instant, LocalDateTime, and ZonedDateTime. This interface provides methods to add or subtract units of time, making time-based arithmetic easy and consistent across the various date and time classes. The TemporalAccessor interface provides a read-only version of the Temporal interface.

Page 76: Java8.part2

Both Temporal and TemporalAccessor objects are defined in terms of fields, as specified in the TemporalField interface. The ChronoField enum is a concrete implementation of the TemporalField interface and provides a rich set of defined constants, such as DAY_OF_WEEK, MINUTE_OF_HOUR, and MONTH_OF_YEAR.

Page 77: Java8.part2

The units for these fields are specified by the TemporalUnit interface. The ChronoUnit enum implements the TemporalUnit interface. The field ChronoField.DAY_OF_WEEK is a combination of ChronoUnit.DAYS andChronoUnit.WEEKS. The ChronoField and ChronoUnit enums are discussed in the following sections.

Page 78: Java8.part2

• ChronoField and IsoFields• The ChronoField enum, which implements

the TemporalField interface, provides a rich set of constants for accessing date and time values. A few examples are CLOCK_HOUR_OF_DAY,

boolean isSupported = LocalDate.now().isSupported(ChronoField.CLOCK_HOUR_OF_DAY);

Page 79: Java8.part2

• The ChronoUnit enum implements the TemporalUnit interface, and provides a set of standard units based on date and time, from milliseconds to millennia. Note that not all ChronoUnit objects are supported by all classes.

• For example, the Instant class does not support ChronoUnit.MONTHS or ChronoUnit.YEARS. The TemporalAccessor.isSupported(TemporalUnit) method can be used to verify whether a class supports a particular time unit

boolean isSupported = instant.isSupported(ChronoUnit.DAYS); //false

Page 80: Java8.part2

• Temporal Adjuster• The TemporalAdjuster interface, in

the java.time.temporal package, provides methods that take a Temporal value and return an adjusted value.

• Example on next slide

Page 81: Java8.part2

LocalDate date = LocalDate.of(2000, Month.OCTOBER, 15);DayOfWeek dotw = date.getDayOfWeek();System.out.printf("%s is on a %s%n", date, dotw);System.out.printf("first day of Month: %s%n", date.with(TemporalAdjusters.firstDayOfMonth()));System.out.printf("first Monday of Month: %s%n", date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)));System.out.printf("last day of Month: %s%n", date.with(TemporalAdjusters.lastDayOfMonth()));System.out.printf("first day of next Month: %s%n", date.with(TemporalAdjusters.firstDayOfNextMonth()));System.out.printf("first day of next Year: %s%n", date.with(TemporalAdjusters.firstDayOfNextYear()));System.out.printf("first day of Year: %s%n", date.with(TemporalAdjusters.firstDayOfYear()));2000-10-15 is on a SUNDAYfirst day of Month: 2000-10-01first Monday of Month: 2000-10-02last day of Month: 2000-10-31first day of next Month: 2000-11-01first day of next Year: 2001-01-01first day of Year: 2000-01-01

Page 82: Java8.part2

Custom Adjusters/** * The adjustInto method accepts a Temporal instance * and returns an adjusted LocalDate. If the passed in * parameter is not a LocalDate, then a DateTimeException is thrown. */public Temporal adjustInto(Temporal input) { LocalDate date = LocalDate.from(input); int day; if (date.getDayOfMonth() < 15) { day = 15; } else { day = date.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth(); } date = date.withDayOfMonth(day); if (date.getDayOfWeek() == DayOfWeek.SATURDAY || date.getDayOfWeek() == DayOfWeek.SUNDAY) { date = date.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)); }

return input.with(date);}

Page 83: Java8.part2

Custom Adjuster usage

LocalDate nextPayday = date.with(new PaydayAdjuster());

Given the date: 2013 Jun 3the next payday: 2013 Jun 14

Given the date: 2013 Jun 18the next payday: 2013 Jun 28

Page 84: Java8.part2

Temporal QueryA TemporalQuery can be used to retrieve information from a temporal-based object.

• We will look at :– Predefined Queries– Custom Queries

Page 85: Java8.part2

TemporalQueries query = TemporalQueries.precision();System.out.printf("LocalDate precision is %s%n", LocalDate.now().query(query));System.out.printf("LocalDateTime precision is %s%n", LocalDateTime.now().query(query));System.out.printf("Year precision is %s%n", Year.now().query(query));System.out.printf("YearMonth precision is %s%n", YearMonth.now().query(query));System.out.printf("Instant precision is %s%n", Instant.now().query(query));

LocalDate precision is DaysLocalDateTime precision is NanosYear precision is YearsYearMonth precision is MonthsInstant precision is Nanos

Page 86: Java8.part2

FamillyBirthday class// Returns true if the passed-in date is the same as one of the// family birthdays. Because the query compares the month and day only,// the check succeeds even if the Temporal types are not the same.public static Boolean isFamilyBirthday(TemporalAccessor date) { int month = date.get(ChronoField.MONTH_OF_YEAR); int day = date.get(ChronoField.DAY_OF_MONTH);

// Krisi’s birthday is on May 28. if ((month == Month.MAY.getValue()) && (day == 28)) return Boolean.TRUE;

// mom and dad birthday is on Febuary 16. if ((month == Month.FEBRUARY.getValue()) && (day == 16)) return Boolean.TRUE;

return Boolean.FALSE;}

Page 87: Java8.part2

The FamilyBirthday class does not implement the TemporalQuery interface and can be used as part of a

lambda expression.

// Invoking the query without using a lambda expression.//if we were implementing TemporalQuery and defining the //queryFrom methodBoolean isFamilyVacation = date.query(new FamilyVacations());

// Invoking the query using a lambda expression.Boolean isFamilyBirthday = date.query(FamilyBirthdays::isFamilyBirthday);

Page 88: Java8.part2

DurationInstant t1, t2;...long ns = Duration.between(t1, t2).toNanos();

Instant start;...Duration gap = Duration.ofSeconds(10);Instant later = start.plus(gap);

A Duration is not connected to the timeline, in that it does not track time zones or daylight saving time. Adding a Duration equivalent to 1 day to a ZonedDateTime results in exactly 24 hours being added

Page 89: Java8.part2

ChronoUnit

import java.time.Instant;import java.time.temporal.Temporal;import java.time.temporal.ChronoUnit;

Instant previous, current, gap;...current = Instant.now();if (previous != null) { gap = ChronoUnit.MILLIS.between(previous,current);}

Page 90: Java8.part2

Period• To define an amount of time with date-based values

(years, months, days), use the Period classLocalDate today = LocalDate.now();LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);

Period p = Period.between(birthday, today);long p2 = ChronoUnit.DAYS.between(birthday, today);System.out.println("You are " + p.getYears() + " years, " + p.getMonths() + " months, and " + p.getDays() + " days old. (" + p2 + " days total)");

//You are 53 years, 4 months, and 29 days old. (19508 days total)

Page 91: Java8.part2

calculate how long it is until your next birthday

LocalDate birthday = LocalDate.of(1983, Month.OCTOBER, 28);

LocalDate nextBDay = birthday.withYear(today.getYear());

//If your birthday has occurred this year already, add 1 to the year.if (nextBDay.isBefore(today) || nextBDay.isEqual(today)) { nextBDay = nextBDay.plusYears(1);}Period p = Period.between(today, nextBDay);long p2 = ChronoUnit.DAYS.between(today, nextBDay);System.out.println("There are " + p.getMonths() + " months, and " + p.getDays() + " days until your next birthday. (" + p2 + " total)");

Page 92: Java8.part2

ClockMost temporal-based objects provide a no-argument now() method that provides the current date and time using the system clock and the default time zone. These temporal-based objects also provide a one-argumentnow(Clock) method that allows you to pass in an alternative Clock.• Clock.offset(Clock, Duration) returns a clock that is offset by

the specified Duration.• Clock.systemUTC() returns a clock representing the

Greenwich/UTC time zone.• Clock.fixed(Instant, ZoneId) always returns the same Instant.

For this clock, time stands still

Page 93: Java8.part2

Converting to/from a Non-ISO-Based Date

LocalDateTime date = LocalDateTime.of(2013, Month.JULY, 20, 19, 30);JapaneseDate jdate = JapaneseDate.from(date);HijrahDate hdate = HijrahDate.from(date);MinguoDate mdate = MinguoDate.from(date);ThaiBuddhistDate tdate = ThaiBuddhistDate.from(date);

LocalDate date = LocalDate.from(JapaneseDate.now());

Page 95: Java8.part2

• The following example converts a Calendar instance to a ZonedDateTime instance. Note that a time zone must be supplied to convert from an Instant to a ZonedDateTime:

Calendar now = Calendar.getInstance();

ZonedDateTime zdt = ZonedDateTime.ofInstant(now.toInstant(),

ZoneId.systemDefault()));

Page 96: Java8.part2

Instant inst = date.toInstant();

Date newDate = Date.from(inst);

Note : There is no one-to-one mapping correspondence between the two APIs, but the table on the next slide gives you a general idea of which functionality in the java.util date and time classes maps to the java.time APIs.

Page 97: Java8.part2

java.util Functionality java.time Functionality Comments

java.util.Date java.time.Instant

The Instant and Date classes are similar. Each class:- Represents an instantaneous point of time on the timeline (UTC)- Holds a time independent of a time zone- Is represented as epoch-seconds (since 1970-01-01T00:00:00Z) plus nanosecondsThe Date.from(Instant) and Date.toInstant() methods allow conversion between these classes.

java.util.GregorianCalendar java.time.ZonedDateTime

The ZonedDateTime class is the replacement for GregorianCalendar. It provides the following similar functionality.Human time representation is as follows: LocalDate: year, month, day LocalTime: hours, minutes, seconds, nanoseconds ZoneId: time zone ZoneOffset: current offset from GMTThe GregorianCalendar.from(ZonedDateTime) and GregorianCalendar.to(ZonedDateTime) methods faciliate conversions between these classes.

java.util.TimeZone java.time.ZoneId orjava.time.ZoneOffset

The ZoneId class specifies a time zone identifier and has access to the rules used each time zone. The ZoneOffset class specifies only an offset from Greenwich/UTC. For more information, see Time Zone and Offset Classes.

GregorianCalendar with the date set to 1970-01-01

java.time.LocalTimeCode that sets the date to 1970-01-01 in a GregorianCalendar instance in order to use the time components can be replaced with an instance of LocalTime.

Page 98: Java8.part2

Concurrency Enhancements

Page 99: Java8.part2

Scalable Updatable Variables

• Maintaining a single variable that is updatable from many threads is a common scalability issue

• Atomic variables already present in the JDK serve as a means to implement updatable variables in a multithreaded environment

• New classes are introduced in order to reduce atomicity guarantees in favor of high throughput - DoubleAccumulator, DoubleAdder, LongAccumulator, LongAdder

Page 100: Java8.part2

Scalable Updatable Variables

• Example:

DoubleAccumulator accumulator = new DoubleAccumulator((x, y) -> x + y, 0.0);// code being executed from some threadsaccumulator.accumulate(10);accumulator.accumulate(20);System.out.println(accumulator.doubleValue());

Page 101: Java8.part2

Parallel tasks

• ForkJoinPool.commonPool() - introduced in order to retrieve the common pool that is basically a fork-join pool for all ForkJoinTasks that are not submitted to a pool

• The common pool is used to implement parallel streams

• The common pool is as easy way to retrieve a ForkJoinPool for parrallel operations that also improves resource utilization

Page 102: Java8.part2

Parallel tasks

• Example:public class NumberFormatAction extends RecursiveAction {

… @Overrideprotected void compute() {

if (end - start <= 2) {System.out.println(Thread.currentThread().getName() + " " +

start + " " + end);} else {

int mid = start + (end - start) / 2;NumberFormatAction left = new NumberFormatAction(start,

mid);NumberFormatAction right = new NumberFormatAction(mid + 1,

end);invokeAll(left, right);

}public static void main(String[] args) {

NumberFormatAction action = new NumberFormatAction(1, 50);ForkJoinPool.commonPool().invoke(action);

}}}

Page 103: Java8.part2

ConcurrentHashMap

• ConcurrentHashMap<V, K> class completely rewritten in order to improve its usage as a cache and several new methods have been added as part of the new stream and lambda expressions:o forEacho forEachKeyo forEachValueo forEachEntry

Page 104: Java8.part2

StampedLock

• A very specialized type of explicit lock

• Similar to ReentrantReadWriteLock but provides additionally conversion between the lock modes (writing, reading and optimistic reading)

• Optimistic read lock is a "cheap" version of a read lock that can be invalidated by a read lock

• Lock state is determined by version and lock mode

Page 105: Java8.part2

StampedLock

• ExampleStampedLock sl = new StampedLock();

long stamp = sl.writeLock();try {

// do something that needs exclusive locking} finally {

sl.unlockWrite(stamp);}

Page 106: Java8.part2

StampedLock

• Examplepublic long getValue() {

long stamp = sl.tryOptimisticRead();long value = this.value;if (!sl.validate(stamp)) {

stamp = sl.readLock();try {

value = this.value;} finally {

sl.unlockRead(stamp);}

}return value;

}

Page 107: Java8.part2

CompletableFuture

• Provides a facility to create a chain of dependent non-blocking tasks - an asynchronous task can be triggered as the result of a completion of another task

• A CompletableFuture may be completed/cancelled by a thread prematurely

• Such a facility is already provided by Google's Guava library

Task 1 Task 2 Task 3 Task 4triggers triggers triggers

Page 108: Java8.part2

CompletableFuture

• Provides a very flexible API that allows additionally to:

o combine the result of multiple tasks in a CompletableFuture

o provide synchronous/asynchronous callbacks upon completion of a task

o provide a CompletableFuture that executes when first task in group completes

o provide a CompletableFuture that executes when all tasks in a group complete

Page 109: Java8.part2

CompletableFuture

• Example

CompletableFuture<Integer> task1 = new CompletableFuture<Integer>();

// forcing completing of future by specifying resulttask1.complete(10);

Page 110: Java8.part2

CompletableFuture

• ExampleCompletableFuture<Integer> task1 = CompletableFuture.supplyAsync(() -> { … return 10;});

// executed on completion of the futuretask1.thenApply((x) -> {…});

// executed in case of exception or completion of the futuretask1.handle((x, y) -> {…});

// can be completed prematurely with a result// task1.complete(20);System.err.println(task1.get());

Page 111: Java8.part2

CompletableFuture

• ExampleCompletableFuture<Object> prev = null;Supplier<Object> supplier = () -> { … };

for (int i = 0; i < count; i++) {CompletableFuture<Object> task;if (prev != null) {

task = prev.thenCompose((x) -> {return

CompletableFuture.supplyAsync(supplier);});} else {

task = CompletableFuture.supplyAsync(supplier);}prev = task;}

prev.get();

Page 112: Java8.part2

Other changes

• A few more interfaces and classes added to java.util.concurrent … (the most significant of which being CompletableFuture)

Page 113: Java8.part2

Security Enhancements

Page 114: Java8.part2

AccessController

• A new overloaded AccessController.doPrivileged() method that allows for checking against a subset of privileges from the current protection domain

• When the call stack is traversed only the subset of privileges are checked and not all privileges of the calling protection domainwar file application

server

Protection Domain 1

Protection Domain 2 AccessController.

doPrivileged(…)

Page 115: Java8.part2

AccessController

• ExampleAccessController.doPrivileged((PrivilegedAction<Void>) () -> {

List<String> files = Arrays.asList(new File("C:\\

windows").list());System.out.println(files);return null;

}, null, new FilePermission("C:\\windows",

"read, execute"));

Page 116: Java8.part2

Certificate revocation

• Typical use case for certificate revocations are stolen certificates and impersonation

• The java.security.cert.PKIXRevocationChecker class is introduced to support programmatic checking of certificate revocation status for X.509 certificates based on the PKIX algorithm

• Supports both OCSP (Online Certificate Status Protocol and Certificate Revocation Lists (CRL)

Page 117: Java8.part2

Certificate revocation

certificate authorityrevocation

checking OCSP

CRLcertificate

certificate

Page 118: Java8.part2

Certificate revocation

• Example (part 1)// retrieve certificateString keystoreFilename = "cert.keystore";char[] password = "password".toCharArray();String alias = "alias";FileInputStream fIn = new FileInputStream(keystoreFilename);KeyStore keystore = KeyStore.getInstance("JKS");keystore.load(fIn, password);Certificate cert = keystore.getCertificate(alias);

// generate cert pathList<Certificate> certs = new LinkedList<Certificate>();certs.add(cert);CertPath path = CertificateFactory.getInstance("X.509").generateCertPath(certs);

Page 119: Java8.part2

Certificate revocation

• Example (part 2)// check certificate path for revocationCertPathValidator cpv = CertPathValidator.getInstance("PKIX");PKIXRevocationChecker rc = (PKIXRevocationChecker) cpv.getRevocationChecker();String truststoreFileName = "trust.keystore";char[] trustStorePassword = "password".toCharArray();FileInputStream tIn = new FileInputStream(truststoreFileName);KeyStore truststore = KeyStore.getInstance("JKS");truststore.load(tIn, trustStorePassword);

PKIXParameters params = new PKIXParameters(truststore);rc.setOptions(EnumSet.of(Option.SOFT_FAIL));params.addCertPathChecker(rc);params.setRevocationEnabled(false);CertPathValidatorResult res = cpv.validate(path, params);

Page 120: Java8.part2

Stronger Algorithms for Password-Based Encryption (JEP 121)

• Several AES-based Password-Based Encryption (PBE) algorithms are added to the SunJCE (Sun Java Cryptography Extensions) provider

• Provide stronger cipher and message digest algorithms based on the PKCS12 standard

PBEWithHmacSHA256AndAES_128 

PBEWithHmacSHA512AndAES_256PBEwithSHA1AndRC4_128PBEwithSHA1AndRC4_40PBEwithSHA1AndDESede

PBEwithSHA1AndRC2_128

Page 121: Java8.part2

SSL/TLS Server Name Indication (SNI) Extension support (JEP 114)

• SNI is the conceptual equivalent to HTTP/1.1 virtual hosting for HTTPS

• SNI allows a server to present multiple certificates on the same IP address and port number and hence allows multiple secure (HTTPS) websites (or any other Service over TLS) to be served off the same IP address without requiring all those sites to use the same certificate

Page 122: Java8.part2

SSL/TLS Server Name Indication (SNI) Extension support (JEP 114)

• The SNI extension is a feature that extends the SSL/TLS protocols to indicate what server name the client is attempting to connect to during handshaking

• Servers can use server name indication information to decide if specific SSLSocket or SSLEngine instances should accept a connection

• SNI extension for server applications is provided by JDK8 (support for client applications is enabled be default by JSSE)

Page 123: Java8.part2

SSL/TLS Server Name Indication (SNI) Extension support (JEP 114)

• ExampleSSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket sslServerSocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(9999); SNIMatcher matcher = SNIHostName.createSNIMatcher("(.*\\.)*example\\.com");Collection<SNIMatcher> matchers = new ArrayList<>(1); matchers.add(matcher); SSLParameters params = sslServerSocket.getSSLParameters();params.setSNIMatchers(matchers); sslServerSocket.setSSLParameters(params); SSLSocket sslsocket = (SSLSocket) sslServerSocket.accept();

Page 124: Java8.part2

Other changes

• Client-side TLS (Transport Layer Security) 1.2 enabled by default in SunJSSE (the default provider for the Java Secure Socket Extension)

• Support the AEAD/GCM crypto algorithms in JCA/JCE providers (JEP 115) (AEAD is a class of block cipher modes which encrypt (parts of) the message and authenticate the message simultaneously)

Page 125: Java8.part2

Other changes

• Overhaul JKS-JCEKS-PKCS12 Keystores (JEP 166) - provide better support for PKCS12 keystores in terms of the JKS/JCEKS keystore format

• SHA-224 Message Digests (JEP 130)• Enhanced Support for NSA Suite B Cryptography• Better Support for High Entropy Random Number

Generation (JEP 123)

SecureRandom 

SecureRandom.getInstanceStrong()

Page 126: Java8.part2

Other changes

• A number of other enhancements provided as Java 7 updates:– easy way to disable Java in browser– Java upgrade enforcement– adjustable plugin security levels– whitelisting of Java assets– enforcement of signing of sandboxed applications– certificate revocation services enabled by default– uninstaller for old versions of Java)

Page 127: Java8.part2

Yet other changes …

• PKCS#11 Crypto Provider for 64-bit Windows (JEP 131)

• Kerberos 5 support enhancements

• other more specific enhancements …

Page 128: Java8.part2

Compact Profiles

Page 129: Java8.part2

The Monolithic JDK (high level overview)

Page 130: Java8.part2

The Monolithic JDK (low level overview)

Page 131: Java8.part2

Why?• A smaller runtime environment could be better

optimized for performance and start up time.

• Elimination of unused code is always a good idea from a security perspective.

• If the environment could be pared down significantly, there may be tremendous benefit to bundling runtimes with each individual Java application.

• These bundled applications could be downloaded more quickly.

Page 132: Java8.part2

About…

• Full implementation of the modular Java platform has been delayed until Java 9.

• JEP 161

• At the current time three compact profiles have been defined: – compact1,– compact2,– compact3– …and Full JRE

Page 133: Java8.part2

Expected to look like this…

Page 134: Java8.part2

Compact 1

Page 135: Java8.part2

Compact 2

Page 136: Java8.part2

Compact 3

Page 137: Java8.part2

Compact 1• java.io• java.lang• java.lang.annotation• java.lang.invoke• java.lang.ref• java.lang.reflect• java.math• java.net• java.nio• java.nio.channels• java.nio.channels.spi• java.nio.charset• java.nio.charset.spi• java.nio.file• java.nio.file.attribute

• java.nio.file.spi• java.security• java.security.cert• java.security.interfaces• java.security.spec• java.text• java.text.spi• java.util• java.util.concurrent• java.util.concurrent.atomi

c• java.util.concurrent.locks• java.util.jar• java.util.logging• java.util.regex

• java.util.spi• java.util.zip• javax.crypto• javax.crypto.interfaces• javax.crypto.spec• javax.net• javax.net.ssl• javax.security.auth• javax.security.auth.callbac

k• javax.security.auth.login• javax.security.auth.spi• javax.security.auth.x500• javax.security.cert

Page 138: Java8.part2

Compact 2

• javax.transaction• javax.transaction.xa• javax.xml• javax.xml.datatype• javax.xml.namespace• javax.xml.parsers• javax.xml.stream• javax.xml.stream.events• javax.xml.stream.util• javax.xml.transform• javax.xml.transform.dom• javax.xml.transform.sax

• javax.xml.transform.stax• javax.xml.transform.stream• javax.xml.validation• javax.xml.xpath• org.w3c.dom• org.w3c.dom.bootstrap• org.w3c.dom.events• org.w3c.dom.ls• org.xml.sax• org.xml.sax.ext• org.xml.sax.helpers

Page 139: Java8.part2

Compact 3

• javax.management.relation• javax.management.remote• javax.management.remote.rmi• javax.management.timer• javax.naming• javax.naming.directory• javax.naming.event• javax.naming.ldap• javax.naming.spi• javax.script• javax.security.auth.kerberos• javax.security.sasl

• javax.sql.rowset• javax.sql.rowset.serial• javax.sql.rowset.spi• javax.tools• javax.xml.crypto• javax.xml.crypto.dom• javax.xml.crypto.dsig• javax.xml.crypto.dsig.dom• javax.xml.crypto.dsig.keyinfo• javax.xml.crypto.dsig.spec• org.ieft.jgss

Page 140: Java8.part2

Full JRE

• corba• awt• swing

Page 141: Java8.part2

IDE support

• Eclipse – NO

• Intellij IDEA – NO

• Netbeans 8.0 - YES

Page 142: Java8.part2

IDE support

• Eclipse – NO

• Intellij IDEA – NO

• Netbeans 8.0 - YES

Page 143: Java8.part2

IDE Support

Page 144: Java8.part2

Example• … as Swing is not part of any of the compact

profiles

Page 145: Java8.part2

Building profiles

• In OpenJDK profiles are not generated by default!

• To build profiles:> make profiles

Page 146: Java8.part2

The result

Page 147: Java8.part2

The Nashorn JavaScript engine

Page 148: Java8.part2

Was ist das?

• Oracles runtime for ECMAScript 5.1

• GPL licensed

• Part of OpenJDK

• Released this march!

• Just type jjs in the shell… and you are in!

Page 149: Java8.part2

Why?

• Atwoods law: any application that can be written in JavaScript, will eventually be written in JavaScript

• Oracle proving ground for support of dynamic languages

• Designed for secure execution. Shipped as part of JRE, privileged execution (Unlike Rhino).

• Currently supports ECMAScript 5.1 (but 100%). No backwards compatibility.

Page 150: Java8.part2

Why not Rhino

• All code compiled to bytecode. No interpretation.

• No Rhino-style continuations

• JSR-223 javax.script.* is the only public API.

Page 151: Java8.part2

Part eins:

Java -> JavaScript

Page 152: Java8.part2

Simple:import javax.script.ScriptEngine;import javax.script.ScriptEngineManager;import javax.script.ScriptException;

public class EvalScript { public static void main(String[] args) throws Exception { // create a script engine manager ScriptEngineManager factory = new ScriptEngineManager(); // create a Nashorn script engine ScriptEngine engine = factory.getEngineByName("nashorn"); // evaluate JavaScript statement try { engine.eval("print('Hello, World!');"); } catch (final ScriptException se) { se.printStackTrace(); } }}

Page 153: Java8.part2

Multiple invokeimport javax.script.Invocable;import javax.script.ScriptEngine;import javax.script.ScriptEngineManager;

public class Eval_Invocable { public static void main(String[] args) throws Exception { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("nashorn");

engine.eval("function f(x){return x < 2 ? 1 : f(x-1)*x} "); engine.eval("function sum(x,y){return x+y}");

Invocable i = (Invocable) engine;

System.out.println(i.invokeFunction("f",5)); System.out.println(i.invokeFunction("f",10)); System.out.println(i.invokeFunction("sum",5,10)); System.out.println(i.invokeFunction("sum",10,15)); }}

Page 154: Java8.part2

Implement interface

public class Eval_InvocableInterface { public static void main(String... args) throws Exception{ ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");

engine.eval("function f(x){return x<2?1:f(x-1)*x};\n" + "var i = 5;\n" + "function run(){print('f('+i+')='+f(i++))}");

engine.eval("function sum(x,y){return x+y}");

Invocable i = (Invocable) engine; Runnable r = i.getInterface(Runnable.class); r.run();

Adder adder= i.getInterface(Adder.class); System.out.println(adder.sum(1,3)); }}

public interface Adder { int sum(int a,int b);}

Page 155: Java8.part2

Passing variablespublic class Eval_Bind { public static void main(String... args) throws Exception {

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");

Bindings b = engine.createBindings(); b.put("file", new File("/")); engine.eval("list = file.listFiles()", b);

System.out.println(Arrays.toString((File[]) b.get("list"))); }}

Page 156: Java8.part2

Part deux:

JavaScript -> Java

Page 157: Java8.part2

Simplevar timer = new java.util.Timer();

timer.schedule( new java.util.TimerTask({ run: function(){ print("Tick") } }) ,0,1000)java.lang.Thread.sleep(5000)timer.cancel();

Page 158: Java8.part2

Even more simple

var timer2= new java.util.Timer();

timer2.schedule(function(){print("Tack")},0,1000)

java.lang.Thread.sleep(5000)timer2.cancel();

Page 159: Java8.part2

Construct Java(Script) object

• var linkedList = new java.util.LinkedList()

• var LinkedList = java.util.LinkedList var list = new LinkedList()

• var LinkedList = Java.type(“java.util.LinkedList”) var list = new LinkedList()

Page 160: Java8.part2

Typesvar ints = new (Java.type(“int[]”))(6)ints[0]=1ints[1]=1.6ints[2]=nullints[3]=“45”ints[4]=“str”Ints[5]=undefinedprint(ints)print(java.util.Arrays.toString(ints))

Output will be:[I@43re2sd[1, 1, 0, 45, 0, 0]

Page 161: Java8.part2

Types 2Var dbls = new (Java.type(“double[]”))(6)dbls [0]=1dbls [1]=1.6dbls [2]=nulldbls [3]=“45”dbls [4]=“str”dbls [5]=undefinedprint(dbls )print(java.util.Arrays.toString(dbls ))

Output will be:[D@43re2sd[1.0, 1.6, 0.0, 45.0, NaN, Nan]

Page 162: Java8.part2

Type conversion

• Passing JavaScript values to Java methods will use all allowed Java method invocation conversions… + all allowed JavaScript conversions

• All native JS objects implement java.util.Map

• And they do not implement java.util.List

Page 163: Java8.part2

Type conversion 2

Consider:

static void about(Object object) { System.out.println(object.getClass());}

Page 164: Java8.part2

Type conversion 2MyJavaClass.about(123);// class java.lang.Integer

MyJavaClass.about(49.99);// class java.lang.Double

MyJavaClass.about(true);// class java.lang.Boolean

MyJavaClass.about("hi there")// class java.lang.String

MyJavaClass.about(new Number(23));// class jdk.nashorn.internal.objects.NativeNumber

MyJavaClass.about(new Date());// class jdk.nashorn.internal.objects.NativeDate

MyJavaClass.about(new RegExp());// class jdk.nashorn.internal.objects.NativeRegExp

MyJavaClass.about({foo: 'bar'});// class jdk.nashorn.internal.scripts.JO4

Page 165: Java8.part2

Arrays conversions

• Not converted automatically!

• Explicit APIs provided:– var javaArray = Java.toJavaArray(jsArray,type)– var jsArray = Java.toJavaScriptArray(javaArray)

Page 166: Java8.part2

Static accesses

Output::/[JavaClass java.util.AbstractMap$SimpleEntry]1=b

var ps = java.io.File.pathSeparatorprint(ps)var File = Java.type("java.io.File")var p = File.separatorprint(p)var MapEntry = java.util.AbstractMap.SimpleEntryprint(MapEntry)var m = new MapEntry(1,"b");print(m)

Page 167: Java8.part2

By the way.. Its Java 8

Page 168: Java8.part2

By the way.. Its Java 8

lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas lambdas … and default methods

Page 169: Java8.part2

By the way.. Its Java 8

Output:

[Ljava.lang.Object;@6591f517[2, 4, 4, 8, 32, 42, 54]

var stack = new java.util.LinkedList();[1, 2, 3, 4,54,87,42,32,65,4,5,8,43].forEach(function(item) { stack.push(item);});

print(stack.getClass());

var sorted = stack .stream() .filter(function(i){return i%2==0}) .sorted() .toArray();print(java.util.Arrays.toString(sorted));

Page 170: Java8.part2

Java 8…default methodsJava:public interface DefTest { default void sayHello(String name){ System.out.println("Hello "+name); }}

public class DefTestImpl implements DefTest {//nothing here

}

JavaScript:>jjs -cp .jjs> var DT = Java.type("DefTestImpl")jjs> DT[JavaClass DefTestImpl]jjs> var dt = new DT()jjs> dt.sayHello("World")Hello World

Page 171: Java8.part2

Part …last:

JavaScript(ing)

Page 172: Java8.part2

Scripting extensions

• Additional classpath elements can be specified for the Java Virtual Machine (JVM).

• JavaScript strict mode can be activated.

• An intriguing scripting mode can be enabled.

Page 173: Java8.part2

Shell invocations

Output:buzz:Nashorn mitia$ jjs -scripting scripting.js |> total 112|> 0 drwxr-xr-x 16 mitia staff 544 21 апр 21:39 .|> 0 drwxr-xr-x 3 mitia staff 102 19 апр 14:26 ..|> 8 -rw-r--r-- 1 mitia staff 113 21 апр 21:32 Adder.class|> 8 -rw-r--r-- 1 mitia staff 603 21 апр 21:32 DefTest.class|> 8 -rw-r--r-- 1 mitia staff 273 21 апр 21:39 DefTestImpl.class|> 8 -rw-r--r-- 1 mitia staff 1001 21 апр 21:32 EvalScript.class|> 8 -rw-r--r-- 1 mitia staff 1379 21 апр 21:32 Eval_Bind.class|> 8 -rw-r--r-- 1 mitia staff 1402 21 апр 21:32 Eval_Invocable.class

var lines = 'ls -lsa'.split("\n");for each (var line in lines) { print("|> " + line);}

Page 174: Java8.part2

Heredocs

$ jjs -scripting heredocs.jsSo... foo = barand the current time is Thu Aug 01 2013 16:21:16 GMT+0200 (CEST)

var data = { foo: “bar”, time: new Date()};

print(<So... foo = ${data.foo} and the current time is ${data.time} EOF);

Page 175: Java8.part2

Shell invocations

$ chmod +x executable.js$ ./executable.jsArguments (0)$ ./executable.js -- hello world !Arguments (3)- hello- world- !

#!/usr/bin/env jjs -scriptingprint("Arguments (${$ARG.length})");for each (arg in $ARG) { print("- ${arg}")}

Page 176: Java8.part2

Benchmark

Page 177: Java8.part2

TBD

• Optimize Optimize Optimize Optimize …

• WebGL over JSR-231 (wow!)

• Not-ECMA JS features not implemented– Generators, destructing assignment, etc

Page 178: Java8.part2

Next..?

• Node.js port POC. C stuff replaced with Java stuff.

• Async I/O by Grizzy.

• Runs on Raspberry PI!!!!