Transcript

New Features in JDK 8part 2

Ivan St. IvanovNayden GochevMartin Toshev Dmitry Alexandrov

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

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 !!!!

Lambda and Stream API refresh

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

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

Lambdas refresh

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

• Example:

(x,y) -> x + y

(parameters) -> {body}

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

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)

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)

Lambdas refresh

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

Isn't this breaking backward compatibility ?!?

Lambdas refresh

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

Isn't this breaking compatibility ?!?

No - because forEach is an extension method.

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

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

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

Stream API

• The stream API makes use of lambdas and extension methods

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

Stream API

• Streams can be finite or infinite

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

Stream API

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

Stream API useful methods

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

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

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

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)

Method references – static methods

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

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

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

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

Method references – constructors

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

Static methods on interfaces

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

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

Annotations on Java types (JSR 308)

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

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

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

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 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) {

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

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

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

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

Preserving parameter names

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

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

API improvements: BigInteger, StringJoiner, Base64

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.

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

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

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(","));

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

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)

Optional type

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

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

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

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.

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

Date and Time API (JSR 310)

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

• 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

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)

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.

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

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

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.

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

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

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

LocalTime

LocalTime thisSec = LocalTime.now();

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

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

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.

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.

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).

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..

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

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

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

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

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)

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.

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.

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.

• 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);

• 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

• 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

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

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

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

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

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

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

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

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

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

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

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)

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)");

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

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

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

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.

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.

Concurrency Enhancements

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

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

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

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

}}}

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

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

StampedLock

• ExampleStampedLock sl = new StampedLock();

long stamp = sl.writeLock();try {

// do something that needs exclusive locking} finally {

sl.unlockWrite(stamp);}

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;

}

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

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

CompletableFuture

• Example

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

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

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

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

Other changes

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

Security Enhancements

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(…)

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"));

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)

Certificate revocation

certificate authorityrevocation

checking OCSP

CRLcertificate

certificate

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

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

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

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

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)

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

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)

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

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)

Yet other changes …

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

• Kerberos 5 support enhancements

• other more specific enhancements …

Compact Profiles

The Monolithic JDK (high level overview)

The Monolithic JDK (low level overview)

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.

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

Expected to look like this…

Compact 1

Compact 2

Compact 3

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

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

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

Full JRE

• corba• awt• swing

IDE support

• Eclipse – NO

• Intellij IDEA – NO

• Netbeans 8.0 - YES

IDE support

• Eclipse – NO

• Intellij IDEA – NO

• Netbeans 8.0 - YES

IDE Support

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

profiles

Building profiles

• In OpenJDK profiles are not generated by default!

• To build profiles:> make profiles

The result

The Nashorn JavaScript engine

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!

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.

Why not Rhino

• All code compiled to bytecode. No interpretation.

• No Rhino-style continuations

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

Part eins:

Java -> JavaScript

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

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

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

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

Part deux:

JavaScript -> Java

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

Even more simple

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

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

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

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

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]

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]

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

Type conversion 2

Consider:

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

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

Arrays conversions

• Not converted automatically!

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

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)

By the way.. Its Java 8

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

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

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

Part …last:

JavaScript(ing)

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.

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

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

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}")}

Benchmark

TBD

• Optimize Optimize Optimize Optimize …

• WebGL over JSR-231 (wow!)

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

Next..?

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

• Async I/O by Grizzy.

• Runs on Raspberry PI!!!!

top related