java8.part2
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
BigInteger
4 new methods added to BigInteger classlongValueExact(), intValueExact(),shortValueExact(), and byteValueExact().
All four of the newly introduced “xxxxxExact()” methods throw an ArithmeticException if the number contained in the BigInteger instance cannot be provided in the specified form without loss of information
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());
Legacy Date-Time Code• Calendar.toInstant() converts the Calendar object to
an Instant.• GregorianCalendar.toZonedDateTime() converts
a GregorianCalendar instance to a ZonedDateTime.• GregorianCalendar.from(ZonedDateTime) creates
a GregorianCalendar object using the default locale from a ZonedDateTime instance.
• Date.from(Instant) creates a Date object from an Instant.• Date.toInstant() converts a Date object to an Instant.• TimeZone.toZoneId() converts a TimeZone object to
a ZoneId
• 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!!!!