SlideShare a Scribd company logo
DEV-1550: Why Java 8?
Or, What's a Lambda?
Julian Robichaux, panagenda
Who am I?
• Julian Robichaux
– Programmer and product manager at panagenda
– Developing applications using IBM products since mid-90’s
– Several open-source projects on OpenNTF
– “Learn Java by Example” video course 

on lynda.com (LinkedIn Learning)
– IBM Champion since 2011
– nsftools.com (old stuff)
– @jrobichaux
2
Why are we here?
• To talk about Java 8!
– specifically lambdas and streams
– syntax, gotchas, and “why change?”



• Assuming that everyone in the room is a Java programmer
– you don’t have to be an expert
– any version is fine, we will start with Java 6
– we will also touch on Java 7, just in case



• What to do if you’re still on a Java 6 platform
3
Example Code
• Connect to a web server via HTTPS, and report the key size and expiration
date of the SSL certificate
– check servers for vulnerabilities due to old/weak keys
– tell your admins it’s time to renew the certificate
4
URL url = new URL( "https://my.server" );
checkSSLCertificate(url);
public static void checkSSLCertificate(URL url) {
HttpsURLConnection con = null;
try {
con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory( fakeSocketFactory() );
con.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true; // trust everyone!
}
});
con.connect();
Certificate[] certs = con.getServerCertificates();
for (Certificate cert : certs) {
System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter());
System.out.println( "Server key bit length: " +
((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() );
}
} catch (IOException e) {
e.printStackTrace();
} catch (GeneralSecurityException e) {
e.printStackTrace();
} finally {
con.disconnect();
}
}
Example Code (Java 6)
create an HTTPS connection
tell it that self-signed and
expired certificates are okay
report the expiration date and
RSA key length of each SSL
certificate on the server
Exception handling!
Example Code (Java 6)
/**
* Creates an SSLSocketFactory that doesn't check certificates at all
* DO NOT USE THIS IN REAL LIFE
*/
private static SSLSocketFactory fakeSocketFactory() throws GeneralSecurityException {
TrustManager trustEveryone = new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { trustEveryone }, new SecureRandom());
return sslContext.getSocketFactory();
}
A Few Words About Java 7
because you’ll see this stuff in Java 8
Catch Multiple Exceptions
• Try-catch blocks can catch multiple exceptions in one statement
HttpsURLConnection con = null;
try {
con = (HttpsURLConnection) url.openConnection();
// do stuff..
} catch (IOException e) {
e.printStackTrace();
} catch (GeneralSecurityException e) {
e.printStackTrace();
} finally {
con.disconnect();
}
HttpsURLConnection con = null;
try {
con = (HttpsURLConnection) url.openConnection();
// do stuff..
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
} finally {
con.disconnect();
}
Try-with-resources
• Classes that implement the AutoCloseable interface can be automatically
closed by a try-catch block
HttpsURLConnection con = null;
try {
con = (HttpsURLConnection) url.openConnection();
// do stuff..
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
} finally {
con.disconnect();
}
try (CloseableURLConnection closeableCon = new CloseableURLConnection(url)) {
HttpsURLConnection con = closeableCon.getHttpsConnection();
// do stuff..
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
}
*
*
*
Creating a Closeable Class
static class CloseableURLConnection implements AutoCloseable {
URLConnection con;
public CloseableURLConnection(URL url) throws IOException {
con = url.openConnection();
}
public HttpsURLConnection getHttpsConnection() {
return (HttpsURLConnection)con;
}
@Override
public void close() {
getHttpsConnection().disconnect();
}
}
implement AutoCloseable
create a close() method
Closeable Classes
• Several standard Java classes are now AutoClosable
– InputStream
– OutputStream
– Reader
– Writer
– java.sql.Connection, Statement, and ResultSet

• You no longer have to declare your streams outside the try/catch block, or
remember to close them when you’re done!

• Like a finally clause, try-with-resources objects get closed even if an
Exception is thrown
11
A Few Other Java 7 Goodies
• New and/or improved classes
– java.nio.file, updated XML libraries, new/enhanced cryptography providers

• Binary literals and underscores in numeric literals
– int byteNum = 0b00100001;
– int phoneNum = 555_1212;

• Type inference for generics
– Map<String, List<String>> map = new HashMap<>();

• Switch statements operate on Strings

• http://docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html 

http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html
And Now: Java 8
on to the good stuff
The Code in Java 7…
public static void checkSSLCertificate(URL url) {
try (CloseableURLConnection closeableCon = new CloseableURLConnection(url)) {
HttpsURLConnection con = closeableCon.getHttpsConnection();
con.setSSLSocketFactory( fakeSocketFactory() );
con.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true; // trust everyone!
}
});
con.connect();
Certificate[] certs = con.getServerCertificates();
for (Certificate cert : certs) {
System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter());
System.out.println( "Server key bit length: " +
((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() );
}
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
}
}
anonymous class
loop through an array
The Code in Java 8
public static void checkSSLCertificate(URL url) {
try (CloseableURLConnection closeableCon = new CloseableURLConnection(url)) {
HttpsURLConnection con = closeableCon.getHttpsConnection();
con.setSSLSocketFactory( fakeSocketFactory() );
con.setHostnameVerifier( (hostname, session) -> true );
con.connect();
Certificate[] certs = con.getServerCertificates();
Arrays.asList(certs)
.stream()
.map ( cert -> (X509Certificate)cert )
.peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) )
.map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() )
.forEach( i -> System.out.println("Server key bit length: " + i) );
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
}
}
lambda hostname verifier
read the array as a stream,
not a loop
What’s a Lambda?
• Simplified syntax for writing single-method classes

• You are effectively passing a function as a parameter to a method
16
con.setHostnameVerifier( (hostname, session) -> true );
(parameters)
arrow
expression
How Does that Lambda Work?
con.setHostnameVerifier( new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
con.setHostnameVerifier( (hostname, session) -> true );
?
How Does that Lambda Work?
con.setHostnameVerifier( new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
con.setHostnameVerifier( (hostname, session) -> true );
?
How Does that Lambda Work?
con.setHostnameVerifier( new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
con.setHostnameVerifier( (hostname, session) -> true );
?
How Does that Lambda Work?
con.setHostnameVerifier( new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
con.setHostnameVerifier( (hostname, session) -> true );
?
How Does that Lambda Work?
con.setHostnameVerifier( new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
con.setHostnameVerifier( (hostname, session) -> true );
!
Functional Interfaces
• Lambdas rely on “functional interfaces” to work
– an interface with only one abstract method
– also called a “single abstract method” or SAM interface
– there can be only one! <insert highlander joke here>

• If there’s only one method, the compiler knows which one you will call

• If you know the method, and the compiler knows the method, we don’t
have to talk about the method
– everyone already knows!
– skip the obvious stuff
22
Functional Interfaces
con.setHostnameVerifier( new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
con.setHostnameVerifier( (hostname, session) -> true );
the class MUST be a HostnameVerifier, and the
method MUST be verify(String, SSLSession)
therefore… throw away everything obvious
Lambda Syntax
object.method( (param1, param2) -> result );
object.method( param1 -> doStuff(param1) );
object.method( param1 -> doStuff(param1, object) );
object.method( () -> {
doStuff();
return doMoreStuff();
} );
Method References
• There is an alternative syntax called “Method References”
– for a lambda that only calls a single method of the parameter, or a single
static method that uses the parameter, or creates a single new Object
object.method( s -> s.getLength() );
object.method( String::getLength );
http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Another Example: Sandwiches!
static enum Sandwich {
PB_J ("Peanut butter & jelly", 500),
SUB ("Sub", 500),
HOTDOG ("Hot dog", 900),
TACO ("Taco", 500),
PIZZA ("Pizza", 900);
private String name;
private int calories;
private Sandwich(String name, int calories) {
this.name = name;
this.calories = calories;
}
public String getName() { return name; }
public int getCalories() { return calories; }
public String toString() { return "n" + calories +
" caloriest" + name; }
}
List the Sandwiches in Order of Calories
List<Sandwich> sandwiches = Arrays.asList( Sandwich.values() );
Collections.sort(sandwiches, new Comparator<Sandwich>() {
public int compare(Sandwich s1, Sandwich s2) {
return Integer.compare(s1.getCalories(), s2.getCalories());
}
});
System.out.println(sandwiches);
PB_J ("Peanut butter & jelly", 500),
SUB ("Sub", 500),
HOTDOG ("Hot dog", 900),
TACO ("Taco", 500),
PIZZA ("Pizza", 900);
500 calories Peanut butter & jelly,
500 calories Sub,
500 calories Taco,
900 calories Hot dog,
900 calories Pizza
List the Sandwiches in Order of Calories
List<Sandwich> sandwiches = Arrays.asList( Sandwich.values() );
/*
Collections.sort(sandwiches, new Comparator<Sandwich>() {
public int compare(Sandwich s1, Sandwich s2) {
return Integer.compare(s1.getCalories(), s2.getCalories());
}
});
*/
Collections.sort(sandwiches,
(s1, s2) -> Integer.compare(s1.getCalories(), s2.getCalories()) );
System.out.println(sandwiches);
PB_J ("Peanut butter & jelly", 500),
SUB ("Sub", 500),
HOTDOG ("Hot dog", 900),
TACO ("Taco", 500),
PIZZA ("Pizza", 900);
500 calories Peanut butter & jelly,
500 calories Sub,
500 calories Taco,
900 calories Hot dog,
900 calories Pizza
List the Sandwiches in Order of Calories
List<Sandwich> sandwiches = Arrays.asList( Sandwich.values() );
/*
Collections.sort(sandwiches, new Comparator<Sandwich>() {
public int compare(Sandwich s1, Sandwich s2) {
return Integer.compare(s1.getCalories(), s2.getCalories());
}
});
*/
Collections.sort(sandwiches,
Comparator.comparing( sandwich -> sandwich.getCalories() ) );
System.out.println(sandwiches);
PB_J ("Peanut butter & jelly", 500),
SUB ("Sub", 500),
HOTDOG ("Hot dog", 900),
TACO ("Taco", 500),
PIZZA ("Pizza", 900);
500 calories Peanut butter & jelly,
500 calories Sub,
500 calories Taco,
900 calories Hot dog,
900 calories Pizza
List the Sandwiches in Order of Calories
List<Sandwich> sandwiches = Arrays.asList( Sandwich.values() );
/*
Collections.sort(sandwiches, new Comparator<Sandwich>() {
public int compare(Sandwich s1, Sandwich s2) {
return Integer.compare(s1.getCalories(), s2.getCalories());
}
});
*/
Collections.sort(sandwiches,
Comparator.comparing( Sandwich::getCalories ) );
System.out.println(sandwiches);
PB_J ("Peanut butter & jelly", 500),
SUB ("Sub", 500),
HOTDOG ("Hot dog", 900),
TACO ("Taco", 500),
PIZZA ("Pizza", 900);
500 calories Peanut butter & jelly,
500 calories Sub,
500 calories Taco,
900 calories Hot dog,
900 calories Pizza
All These are the Same Comparator
Collections.sort(sandwiches, new Comparator<Sandwich>() {
public int compare(Sandwich s1, Sandwich s2) {
return Integer.compare(s1.getCalories(), s2.getCalories());
}
});
Collections.sort(sandwiches,
(s1, s2) -> Integer.compare(s1.getCalories(), s2.getCalories()) );
Collections.sort(sandwiches,
Comparator.comparing( sandwich -> sandwich.getCalories() ) );
Collections.sort(sandwiches,
Comparator.comparing( Sandwich::getCalories ) );
Fun with the Comparator
Collections.sort(sandwiches,
Comparator.comparing( Sandwich::getCalories )
.thenComparing( Sandwich::getName )
.reversed() );
900 calories Pizza,
900 calories Hot dog,
500 calories Taco,
500 calories Sub,
500 calories Peanut butter & jelly
PB_J ("Peanut butter & jelly", 500),
SUB ("Sub", 500),
HOTDOG ("Hot dog", 900),
TACO ("Taco", 500),
PIZZA ("Pizza", 900);
But Really, What’s the Point?
• This all seems like needless tomfoolery
– after all, the old code still works!

• Two major advantages:
1. Forces (or strongly encourages) you to write functional code
2. Less visual noise makes code easier to read and understand
33
Collections.sort(sandwiches, new Comparator<Sandwich>() {
public int compare(Sandwich s1, Sandwich s2) {
return Integer.compare(s1.getCalories(), s2.getCalories());
}
});
Collections.sort(sandwiches,
Comparator.comparing( Sandwich::getCalories ) );
Code Should Describe Behavior
Code Should Read Like A Story
Dealing with Exceptions
Collections.sort(sandwiches,
Comparator.comparing( Sandwich::getCalories )
.thenComparing( Sandwich::getName )
.reversed() );
NULLWICH (null, 500),
PB_J ("Peanut butter & jelly", 500),
SUB ("Sub", 500),
HOTDOG ("Hot dog", 900),
TACO ("Taco", 500),
PIZZA ("Pizza", 900);
Exception in thread "main" java.lang.NullPointerException
at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469)
at java.util.Comparator.lambda$thenComparing$36697e65$1(Comparator.java:217)
at java.util.Collections$ReverseComparator2.compare(Collections.java:5178)
at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
at java.util.TimSort.sort(TimSort.java:220)
at java.util.Arrays.sort(Arrays.java:1438)
at java.util.Arrays$ArrayList.sort(Arrays.java:3895)
at java.util.Collections.sort(Collections.java:175)
at com.panagenda.ssltest.MoreJava8Examples.main(MoreJava8Examples.java:52)
Dealing with Exceptions
• It’s not always obvious what caused the Exception

• It’s cumbersome to add a try/catch to a lambda
– same with adding logging

• If an Exception is possible, maybe better to call out to a method instead
36
Collections.sort(sandwiches,
Comparator.comparing( sandwich -> getCalories(sandwich) )
.thenComparing( sandwich -> getName(sandwich) )
.reversed() );
A Few More Examples
// process all the keys and values of a HashMap
Map<String, Integer> myHashMap = new HashMap<>();
myHashMap.forEach( (key, value) -> System.out.println(key + "; " + value) );
// remove all the null elements in a List
List<String> myArrayList = new ArrayList<>();
myArrayList.removeIf( s -> s == null );
// get all the JPG files in a directory
File photoDir = new File("c:/photos");
File[] docFiles = photoDir.listFiles( file -> file.getName().endsWith("jpg") );
// run some code in a thread
new Thread( () -> doSomething() ).start();
Under the Hood
• If you’re really curious about how all this works…
– http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html 

• It’s all Function and Predicate objects
– https://docs.oracle.com/javase/8/docs/api/java/util/function/package-
summary.html
– Closures? By some definitions.
38
Function<Sandwich, Integer> caloryCompare = sandwich -> sandwich.getCalories();
Streams!
of data, not water
From Loop to Stream
Certificate[] certs = con.getServerCertificates();
for (Certificate cert : certs) {
System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter());
System.out.println( "Server key bit length: " +
((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() );
}
Certificate[] certs = con.getServerCertificates();
Arrays.asList(certs)
.stream()
.map ( cert -> (X509Certificate)cert )
.peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) )
.map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() )
.forEach( i -> System.out.println("Server key bit length: " + i) );
?
What Does that Loop Actually Do?
41
Certificate[] certs = con.getServerCertificates();
for (Certificate cert : certs) {
System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter());
System.out.println( "Server key bit length: " +
((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() );
}
print the information
get something from the objectprint the information
get something from the object
How Does the Stream Work?
Certificate[] certs = con.getServerCertificates();
Arrays.asList(certs)
.stream()
.map ( cert -> (X509Certificate)cert )
.peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) )
.map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() )
.forEach( i -> System.out.println("Server key bit length: " + i) );
start with an array,
convert it to a List
convert the List to a stream
TIP: this could also be just
Arrays.stream(certs)
}
change the stream
do something to each item
change the stream
do something to each item
Breaking Down the Example
Certificate[] certs = con.getServerCertificates();
Arrays.asList(certs)
.stream()
.map ( cert -> (X509Certificate)cert )
.peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) )
.map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() )
.forEach( i -> System.out.println("Server key bit length: " + i) );
map() converts each item by
casting it to X509Certificate,
then returns a Stream of
X509Certificate objects
map() gets an int value from
each item, then returns a
Stream of int values
start with an array of
Certificates
Breaking Down the Example
Certificate[] certs = con.getServerCertificates();
Arrays.asList(certs)
.stream()
.map ( cert -> (X509Certificate)cert )
.peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) )
.map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() )
.forEach( i -> System.out.println("Server key bit length: " + i) );
peek() is an intermediate
operation: it does something
with each item and returns
the original Stream
forEach() is a terminal
operation: it does something
with each item and stops
What’s a Stream?
• Allows you to perform operations on a collection of data
– multiple operations can be combined in a pipeline



• Has the following properties
– uses functional arguments (lambdas!) to process data
– does not store data
– pipeline operations are optimized for laziness
– optionally process in parallel (multi-threaded) with no extra code
45
Is a Stream Better than a Loop?
Certificate[] certs = con.getServerCertificates();
for (Certificate cert : certs) {
System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter());
System.out.println( "Server key bit length: " +
((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() );
}
Certificate[] certs = con.getServerCertificates();
Arrays.asList(certs)
.stream()
.map ( cert -> (X509Certificate)cert )
.peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) )
.map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() )
.forEach( i -> System.out.println("Server key bit length: " + i) );
!Stream version is more
descriptive of the behavior
of the code
Stream version can easily be
turned into multi-threaded
code
Multi-threaded You Say?
Arrays.asList(certs)
.stream()
.parallel()
.map ( cert -> (X509Certificate)cert )
.peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) )
.map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() )
.forEach( i -> System.out.println("Server key bit length: " + i) );
DANGER: The forEach() and peek()
output might be out-of-order!
Adding Numbers in a Loop
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9
45
int sum = 0;
for (int i : new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9}) {
sum += i;
}
return sum;
Adding Numbers with Reduce
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9
1 + 2 3 + 4 + 5 6 + 8 7 + 9
3 + 14 12 + 16
45
Adding Numbers with Reduce
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9
1 + 2 3 + 4 + 5 6 + 8 7 + 9
3 + 14 12 + 16
45
By abstracting away the very concept
of looping, you can implement looping
any way you want, including
implementing it in a way that scales
nicely with extra hardware.
Joel Spolsky
https://www.joelonsoftware.com/2006/08/01/
can-your-programming-language-do-this
each computation could be on a separate processor core… or a separate machine!
Other Things to Know About Streams
• Normally get them from Collections or arrays
– List.stream(), Map.entrySet().stream(), Arrays.stream(Object[])
– also other fun places, like BufferedReader.lines() or Files.list()



• Some operations will short circuit instead of processing each item
– built-in optimizations



• Stream operations should be stateless
– for example, don’t update Lists as part of a stream operation
– items could process out of order, and might not be thread-safe
– collect the results at the end instead
51
Other Things to Know About Streams
• Operations on Streams should be associative when possible
– (a + b + c) == (c + b + a) == b + (a + c)
– if order of operations does matter, make sure you:
• start with an ordered set of data, like a List
• use forEachOrdered() instead of forEach()
• don’t use reduce() 



• For reference:
– https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-
summary.html
52
Under the Hood
• If you’re really curious about how all this works…
– http://www.ibm.com/developerworks/java/library/j-java-streams-1-brian-
goetz 

• Read about java.util.function
– https://docs.oracle.com/javase/8/docs/api/java/util/function/package-
summary.html
– Predicate, Consumer, and Supplier interfaces
53
Backwards Compatibility
because not all of us have a choice
Java 8 API Changes (partial list)
• Streams
– in its own package
– throughout Collections, Files, etc.

• Functional classes in java.util.function

• Brand new Date-Time package and classes
– http://docs.oracle.com/javase/tutorial/datetime 

• JavaFX for GUIs

• http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html 

http://docs.oracle.com/javase/8/docs/technotes/guides/language/lambda_api_jdk8.html
55
Function<Sandwich, Integer> caloryCompare =
sandwich -> sandwich.getCalories();
Compiling to Earlier Versions
• Java can compile for previous versions, but…
– you can’t use any of the new APIs (classes or methods)
– you can’t use any of the new language features



• What happens if you use a Java 8 JAR in a Java 6 environment?
– it won’t work
– the JRE checks the JAR file for a version number first
– if the version number is too high, you get errors



• Some tools can convert bytecode to earlier versions
– but new APIs still won’t work
56
Options for Backwards Compatibility
• If you don’t want to use new language features at all
– set “Source compatibility” and “Generated .class files compatibility” to your
desired older Java version
– use a tool to make sure you didn’t use new APIs

Animal Sniffer: http://www.mojohaus.org/animal-sniffer 

57
Options for Backwards Compatibility
• If you only want to use lambdas and try-with-resources
– compile as Java 8, then use RetroLambda to backport your JAR file 

https://github.com/orfjackal/retrolambda
– you still have to make sure you didn’t use new APIs: AnimalSniffer again



• You might be able to backport Streams too (mixed results)
– http://sourceforge.net/projects/streamsupport
58
Is It Worth It?
• Backporting? Maybe, but probably not regularly
– Risky: even if it seems to work, hard to test if it really worked
– make sure you have great unit tests to run against the backported code



• Learning? Absolutely!
– even if you can’t use Java 8 now, you will later
– functional programming can be much “safer”
– teaches you good coding habits
– helps you understand code examples on StackOverflow ;)
59
Required Reading
we only scratched the surface
On the Oracle Website
• Streams
– https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-
summary.html
– http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-
streams-2177646.html 

• Lambdas
– https://docs.oracle.com/javase/tutorial/java/javaOO/
lambdaexpressions.html
– http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
– https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27
61
Articles and Musings
• State of the lambda (Brian Goetz)
– http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html 

• IBM DeveloperWorks articles by Brian Goetz
– http://www.ibm.com/developerworks/java/library/j-java-streams-1-brian-goetz
– http://www.ibm.com/developerworks/java/library/j-java-streams-2-brian-goetz
– http://www.ibm.com/developerworks/java/library/j-java-streams-3-brian-goetz
– http://www.ibm.com/developerworks/java/library/j-java-streams-4-brian-goetz
– http://www.ibm.com/developerworks/java/library/j-java-streams-5-brian-goetz

• Joel Spolsky on MapReduce
– https://www.joelonsoftware.com/2006/08/01/can-your-programming-language-
do-this
62
Books (!)
• Java 8 in Action
– Raoul-Gabriel Urma

Manning Press
• Mastering Lambdas:
Java Programming in
a Multicore World
– Maurice Naftalin

Oracle Press
Notices and
disclaimers
Copyright © 2017 by International Business Machines Corporation (IBM). No part of this document may be reproduced or transmitted in
any form without written permission from IBM.
U.S. Government Users Restricted Rights — Use, duplication or disclosure restricted by GSA ADP Schedule Contract with
IBM.
Information in these presentations (including information relating to products that have not yet been announced by IBM) has been
reviewed for accuracy as of the date of initial publication and could include unintentional technical or typographical errors. IBM shall
have no responsibility to update this information. THIS DOCUMENT IS DISTRIBUTED "AS IS" WITHOUT ANY WARRANTY, EITHER
EXPRESS OR IMPLIED. IN NO EVENT SHALL IBM BE LIABLE FOR ANY DAMAGE ARISING FROM THE USE OF THIS
INFORMATION, INCLUDING BUT NOT LIMITED TO, LOSS OF DATA, BUSINESS INTERRUPTION, LOSS OF PROFIT OR LOSS OF
OPPORTUNITY. IBM products and services are warranted according to the terms and conditions of the agreements under which they
are provided.
IBM products are manufactured from new parts or new and used parts. In some cases, a product may not be new and may have been
previously installed. Regardless, our warranty terms apply.”
Any statements regarding IBM's future direction, intent or product plans are subject to change or withdrawal without notice.
Performance data contained herein was generally obtained in a controlled, isolated environments. Customer examples are presented as
illustrations of how those customers have used IBM products and the results they may have achieved. Actual performance, cost,
savings or other results in other operating environments may vary.
References in this document to IBM products, programs, or services does not imply that IBM intends to make such products, programs
or services available in all countries in which IBM operates or does business.
Workshops, sessions and associated materials may have been prepared by independent session speakers, and do not necessarily
reflect the views of IBM. All materials and discussions are provided for informational purposes only, and are neither intended to, nor
shall constitute legal or other guidance or advice to any individual participant or their specific situation.
It is the customer’s responsibility to insure its own compliance with legal requirements and to obtain advice of competent legal counsel
as to the identification and interpretation of any relevant laws and regulatory requirements that may affect the customer’s business and
any actions the customer may need to take to comply with such laws. IBM does not provide legal advice or represent or warrant that its
services or products will ensure that the customer is in compliance with any law
64
Notices and
disclaimers
continued
Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements or other
publicly available sources. IBM has not tested those products in connection with this publication and cannot confirm the accuracy of
performance, compatibility or any other claims related to non-IBM products. Questions on the capabilities of non-IBM products should
be addressed to the suppliers of those products. IBM does not warrant the quality of any third-party products, or the ability of any such
third-party products to interoperate with IBM’s products. IBM EXPRESSLY DISCLAIMS ALL WARRANTIES, EXPRESSED OR
IMPLIED, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
The provision of the information contained herein is not intended to, and does not, grant any right or license under any IBM patents,
copyrights, trademarks or other intellectual property right.
IBM, the IBM logo, ibm.com, Aspera®, Bluemix, Blueworks Live, CICS, Clearcase, Cognos®, DOORS®, Emptoris®, Enterprise
Document Management System™, FASP®, FileNet®, Global Business Services ®, Global Technology Services ®, IBM
ExperienceOne™, IBM SmartCloud®, IBM Social Business®, Information on Demand, ILOG, Maximo®, MQIntegrator®, MQSeries®,
Netcool®, OMEGAMON, OpenPower, PureAnalytics™, PureApplication®, pureCluster™, PureCoverage®, PureData®,
PureExperience®, PureFlex®, pureQuery®, pureScale®, PureSystems®, QRadar®, Rational®, Rhapsody®, Smarter Commerce®,
SoDA, SPSS, Sterling Commerce®, StoredIQ, Tealeaf®, Tivoli®, Trusteer®, Unica®, urban{code}®, Watson, WebSphere®, Worklight®,
X-Force® and System z® Z/OS, are trademarks of International Business Machines Corporation, registered in many jurisdictions
worldwide. Other product and service names might be trademarks of IBM or other companies. A current list of IBM trademarks is
available on the Web at "Copyright and trademark information" at: www.ibm.com/legal/copytrade.shtml.
65
Thank you!
Julian Robichaux
@jrobichaux
jrobichaux@panagenda.com

More Related Content

PDF
Cracking JWT tokens: a tale of magic, Node.JS and parallel computing
DOCX
Laporan tugas network programming
PPTX
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
PDF
node.js practical guide to serverside javascript
PDF
Enhanced Web Service Testing: A Better Mock Structure
PPTX
Full Stack Unit Testing
PDF
JavaScript Promises
PDF
Unit Testing Express Middleware
Cracking JWT tokens: a tale of magic, Node.JS and parallel computing
Laporan tugas network programming
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
node.js practical guide to serverside javascript
Enhanced Web Service Testing: A Better Mock Structure
Full Stack Unit Testing
JavaScript Promises
Unit Testing Express Middleware

What's hot (20)

PDF
Exploring lambdas and invokedynamic for embedded systems
ODP
Lucio Grenzi - Building serverless applications on the Apache OpenWhisk platf...
PPTX
Building unit tests correctly
PPTX
Unit testing patterns for concurrent code
PDF
DataStax: Making Cassandra Fail (for effective testing)
PDF
Cassandra Summit EU 2014 - Testing Cassandra Applications
PDF
Unit Testing Express and Koa Middleware in ES2015
PDF
PDF
Cassandra is great but how do I test my application?
PDF
What to expect from Java 9
PDF
Code lifecycle in the jvm - TopConf Linz
PDF
Springを用いた社内ライブラリ開発
PPTX
OWASP ZAP Workshop for QA Testers
PPTX
Enhanced Web Service Testing: A Better Mock Structure
PDF
Ajax World Comet Talk
PDF
Advanced Jasmine - Front-End JavaScript Unit Testing
ODP
Introduce about Nodejs - duyetdev.com
ZIP
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
PDF
Fault tolerant microservices - LJC Skills Matter 4thNov2014
PPTX
Real world functional reactive programming
Exploring lambdas and invokedynamic for embedded systems
Lucio Grenzi - Building serverless applications on the Apache OpenWhisk platf...
Building unit tests correctly
Unit testing patterns for concurrent code
DataStax: Making Cassandra Fail (for effective testing)
Cassandra Summit EU 2014 - Testing Cassandra Applications
Unit Testing Express and Koa Middleware in ES2015
Cassandra is great but how do I test my application?
What to expect from Java 9
Code lifecycle in the jvm - TopConf Linz
Springを用いた社内ライブラリ開発
OWASP ZAP Workshop for QA Testers
Enhanced Web Service Testing: A Better Mock Structure
Ajax World Comet Talk
Advanced Jasmine - Front-End JavaScript Unit Testing
Introduce about Nodejs - duyetdev.com
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Fault tolerant microservices - LJC Skills Matter 4thNov2014
Real world functional reactive programming
Ad

Viewers also liked (20)

PDF
DEV-1185: IBM Notes Performance Boost - Reloaded – IBM Connect 2017
PPTX
IBM Connect 2017 - Beyond Domino Designer
PDF
IBM Connect 2017: Refresh and Extend IBM Domino Applications
PPTX
DEV-1268: IBM Connections Adminblast – IBM Connect 2017
PDF
Connect 2017 DEV-1420 - Blue Mix and Domino – Complementing Smartcloud
PPTX
DEV-1223: Socialytics: Accelerating IBM Connections Adoption with Watson Anal...
PPTX
DEV-1467 - Darwino
PPTX
Big Data With Graphs
PDF
Your App Deserves More – The Art of App Modernization
PDF
OpenNTF Domino API (ODA): Super-Charging Domino Development
PDF
Domino, Exchange, O365: Ihre Email Daten sind Gold wert - Kinoforum 2016
PPTX
DEV-1269: Best and Worst Practices for Deploying IBM Connections – IBM Conne...
PDF
Virtual,Faster,Better! How To Virtualize the IBM Notes Client and IBM Client ...
PDF
DEV-1430 IBM Connections Integration
PPTX
One Firm's Wild Ride to The Cloud
PPTX
DEV-1129 How Watson, Bluemix, Cloudant, and XPages Can Work Together In A Rea...
PDF
Socialytics: Accelerating IBM Connections Adoption with Watson Analytics
PDF
GraphQL 101
PDF
Going Cloud - warum und wie? - 42. DNUG
PDF
SI1692: When Lightning Strikes Collaboration - IBM Connect 2016
DEV-1185: IBM Notes Performance Boost - Reloaded – IBM Connect 2017
IBM Connect 2017 - Beyond Domino Designer
IBM Connect 2017: Refresh and Extend IBM Domino Applications
DEV-1268: IBM Connections Adminblast – IBM Connect 2017
Connect 2017 DEV-1420 - Blue Mix and Domino – Complementing Smartcloud
DEV-1223: Socialytics: Accelerating IBM Connections Adoption with Watson Anal...
DEV-1467 - Darwino
Big Data With Graphs
Your App Deserves More – The Art of App Modernization
OpenNTF Domino API (ODA): Super-Charging Domino Development
Domino, Exchange, O365: Ihre Email Daten sind Gold wert - Kinoforum 2016
DEV-1269: Best and Worst Practices for Deploying IBM Connections – IBM Conne...
Virtual,Faster,Better! How To Virtualize the IBM Notes Client and IBM Client ...
DEV-1430 IBM Connections Integration
One Firm's Wild Ride to The Cloud
DEV-1129 How Watson, Bluemix, Cloudant, and XPages Can Work Together In A Rea...
Socialytics: Accelerating IBM Connections Adoption with Watson Analytics
GraphQL 101
Going Cloud - warum und wie? - 42. DNUG
SI1692: When Lightning Strikes Collaboration - IBM Connect 2016
Ad

Similar to DEV-1550: Why Java 8? Or, What's a Lambda? – IBM Connect 2017 (20)

PDF
Java SE 8
PPTX
Software Uni Conf October 2014
PPTX
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
KEY
Back to the future with Java 7 (Geekout June/2011)
PDF
What's new in Java 8
PDF
Java 8
PPTX
Java World, Java Trends, Java 8 and Beyond (iForum - 2014)
PDF
Java 8 Overview
PPTX
Improved Developer Productivity In JDK8
KEY
Java Closures
PDF
JSR 335 / java 8 - update reference
PDF
Java Full Throttle
PDF
Java SE 8 & EE 7 Launch
PDF
Java EE 7 (Lyon JUG & Alpes JUG - March 2014)
PPTX
Getting ready to java 8
PDF
2015 Java update and roadmap, JUG sevilla
PPTX
Java ee 7 New Features
PDF
What's New in IBM Java 8 SE?
PDF
Java: Create The Future Keynote
ODT
Best Of Jdk 7
Java SE 8
Software Uni Conf October 2014
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
Back to the future with Java 7 (Geekout June/2011)
What's new in Java 8
Java 8
Java World, Java Trends, Java 8 and Beyond (iForum - 2014)
Java 8 Overview
Improved Developer Productivity In JDK8
Java Closures
JSR 335 / java 8 - update reference
Java Full Throttle
Java SE 8 & EE 7 Launch
Java EE 7 (Lyon JUG & Alpes JUG - March 2014)
Getting ready to java 8
2015 Java update and roadmap, JUG sevilla
Java ee 7 New Features
What's New in IBM Java 8 SE?
Java: Create The Future Keynote
Best Of Jdk 7

More from panagenda (20)

PDF
Getting the Best of TrueDEM - June News & Updates
PDF
Domino IQ – What to Expect, First Steps and Use Cases
PDF
Domino IQ – Was Sie erwartet, erste Schritte und Anwendungsfälle
PDF
Getting the Best of TrueDEM – May News & Updates
PDF
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
PDF
HCL Nomad Web – Best Practices and Managing Multiuser Environments
PDF
Getting the Best of TrueDEM – April News & Updates
PDF
Teams Call Records: Treasure Trove or Pandora’s Box?
PDF
Teams Call Records: Eine Schatztruhe oder die Büchse der Pandora?
PDF
New Teams Client Architecture Autopsy, a Look Under the Hood
PDF
Architektur des neuen Teams Clients – Ein Blick unter die Haube
PDF
HCL Notes and Domino License Cost Reduction in the World of DLAU
PDF
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
PDF
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
PDF
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
PDF
Why Teams call analytics are critical to your entire business
PDF
De05_panagenda_Prepare-Applications-for-64-bit-Clients.pdf
PDF
Co01_panagenda_NotesDomino-Licensing-Understand-and-Optimize-DLAU-results-wit...
PDF
Ad01_Navigating-HCL-Notes-14-Upgrades_A-Comprehensive-Guide-for-Conquering-Ch...
PDF
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
Getting the Best of TrueDEM - June News & Updates
Domino IQ – What to Expect, First Steps and Use Cases
Domino IQ – Was Sie erwartet, erste Schritte und Anwendungsfälle
Getting the Best of TrueDEM – May News & Updates
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices and Managing Multiuser Environments
Getting the Best of TrueDEM – April News & Updates
Teams Call Records: Treasure Trove or Pandora’s Box?
Teams Call Records: Eine Schatztruhe oder die Büchse der Pandora?
New Teams Client Architecture Autopsy, a Look Under the Hood
Architektur des neuen Teams Clients – Ein Blick unter die Haube
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Why Teams call analytics are critical to your entire business
De05_panagenda_Prepare-Applications-for-64-bit-Clients.pdf
Co01_panagenda_NotesDomino-Licensing-Understand-and-Optimize-DLAU-results-wit...
Ad01_Navigating-HCL-Notes-14-Upgrades_A-Comprehensive-Guide-for-Conquering-Ch...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...

Recently uploaded (20)

PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
history of c programming in notes for students .pptx
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
Computer Software and OS of computer science of grade 11.pptx
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PPTX
CHAPTER 2 - PM Management and IT Context
PPT
Introduction Database Management System for Course Database
PDF
Nekopoi APK 2025 free lastest update
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Designing Intelligence for the Shop Floor.pdf
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
System and Network Administraation Chapter 3
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
wealthsignaloriginal-com-DS-text-... (1).pdf
Understanding Forklifts - TECH EHS Solution
history of c programming in notes for students .pptx
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Computer Software and OS of computer science of grade 11.pptx
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Adobe Illustrator 28.6 Crack My Vision of Vector Design
CHAPTER 2 - PM Management and IT Context
Introduction Database Management System for Course Database
Nekopoi APK 2025 free lastest update
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Designing Intelligence for the Shop Floor.pdf
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Design an Analysis of Algorithms II-SECS-1021-03
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Operating system designcfffgfgggggggvggggggggg
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
System and Network Administraation Chapter 3

DEV-1550: Why Java 8? Or, What's a Lambda? – IBM Connect 2017

  • 1. DEV-1550: Why Java 8? Or, What's a Lambda? Julian Robichaux, panagenda
  • 2. Who am I? • Julian Robichaux – Programmer and product manager at panagenda – Developing applications using IBM products since mid-90’s – Several open-source projects on OpenNTF – “Learn Java by Example” video course 
 on lynda.com (LinkedIn Learning) – IBM Champion since 2011 – nsftools.com (old stuff) – @jrobichaux 2
  • 3. Why are we here? • To talk about Java 8! – specifically lambdas and streams – syntax, gotchas, and “why change?”
 
 • Assuming that everyone in the room is a Java programmer – you don’t have to be an expert – any version is fine, we will start with Java 6 – we will also touch on Java 7, just in case
 
 • What to do if you’re still on a Java 6 platform 3
  • 4. Example Code • Connect to a web server via HTTPS, and report the key size and expiration date of the SSL certificate – check servers for vulnerabilities due to old/weak keys – tell your admins it’s time to renew the certificate 4 URL url = new URL( "https://my.server" ); checkSSLCertificate(url);
  • 5. public static void checkSSLCertificate(URL url) { HttpsURLConnection con = null; try { con = (HttpsURLConnection) url.openConnection(); con.setSSLSocketFactory( fakeSocketFactory() ); con.setHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; // trust everyone! } }); con.connect(); Certificate[] certs = con.getServerCertificates(); for (Certificate cert : certs) { System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter()); System.out.println( "Server key bit length: " + ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ); } } catch (IOException e) { e.printStackTrace(); } catch (GeneralSecurityException e) { e.printStackTrace(); } finally { con.disconnect(); } } Example Code (Java 6) create an HTTPS connection tell it that self-signed and expired certificates are okay report the expiration date and RSA key length of each SSL certificate on the server Exception handling!
  • 6. Example Code (Java 6) /** * Creates an SSLSocketFactory that doesn't check certificates at all * DO NOT USE THIS IN REAL LIFE */ private static SSLSocketFactory fakeSocketFactory() throws GeneralSecurityException { TrustManager trustEveryone = new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {} public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {} }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[] { trustEveryone }, new SecureRandom()); return sslContext.getSocketFactory(); }
  • 7. A Few Words About Java 7 because you’ll see this stuff in Java 8
  • 8. Catch Multiple Exceptions • Try-catch blocks can catch multiple exceptions in one statement HttpsURLConnection con = null; try { con = (HttpsURLConnection) url.openConnection(); // do stuff.. } catch (IOException e) { e.printStackTrace(); } catch (GeneralSecurityException e) { e.printStackTrace(); } finally { con.disconnect(); } HttpsURLConnection con = null; try { con = (HttpsURLConnection) url.openConnection(); // do stuff.. } catch (IOException | GeneralSecurityException e) { e.printStackTrace(); } finally { con.disconnect(); }
  • 9. Try-with-resources • Classes that implement the AutoCloseable interface can be automatically closed by a try-catch block HttpsURLConnection con = null; try { con = (HttpsURLConnection) url.openConnection(); // do stuff.. } catch (IOException | GeneralSecurityException e) { e.printStackTrace(); } finally { con.disconnect(); } try (CloseableURLConnection closeableCon = new CloseableURLConnection(url)) { HttpsURLConnection con = closeableCon.getHttpsConnection(); // do stuff.. } catch (IOException | GeneralSecurityException e) { e.printStackTrace(); } * * *
  • 10. Creating a Closeable Class static class CloseableURLConnection implements AutoCloseable { URLConnection con; public CloseableURLConnection(URL url) throws IOException { con = url.openConnection(); } public HttpsURLConnection getHttpsConnection() { return (HttpsURLConnection)con; } @Override public void close() { getHttpsConnection().disconnect(); } } implement AutoCloseable create a close() method
  • 11. Closeable Classes • Several standard Java classes are now AutoClosable – InputStream – OutputStream – Reader – Writer – java.sql.Connection, Statement, and ResultSet
 • You no longer have to declare your streams outside the try/catch block, or remember to close them when you’re done!
 • Like a finally clause, try-with-resources objects get closed even if an Exception is thrown 11
  • 12. A Few Other Java 7 Goodies • New and/or improved classes – java.nio.file, updated XML libraries, new/enhanced cryptography providers
 • Binary literals and underscores in numeric literals – int byteNum = 0b00100001; – int phoneNum = 555_1212;
 • Type inference for generics – Map<String, List<String>> map = new HashMap<>();
 • Switch statements operate on Strings
 • http://docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html 
 http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html
  • 13. And Now: Java 8 on to the good stuff
  • 14. The Code in Java 7… public static void checkSSLCertificate(URL url) { try (CloseableURLConnection closeableCon = new CloseableURLConnection(url)) { HttpsURLConnection con = closeableCon.getHttpsConnection(); con.setSSLSocketFactory( fakeSocketFactory() ); con.setHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; // trust everyone! } }); con.connect(); Certificate[] certs = con.getServerCertificates(); for (Certificate cert : certs) { System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter()); System.out.println( "Server key bit length: " + ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ); } } catch (IOException | GeneralSecurityException e) { e.printStackTrace(); } } anonymous class loop through an array
  • 15. The Code in Java 8 public static void checkSSLCertificate(URL url) { try (CloseableURLConnection closeableCon = new CloseableURLConnection(url)) { HttpsURLConnection con = closeableCon.getHttpsConnection(); con.setSSLSocketFactory( fakeSocketFactory() ); con.setHostnameVerifier( (hostname, session) -> true ); con.connect(); Certificate[] certs = con.getServerCertificates(); Arrays.asList(certs) .stream() .map ( cert -> (X509Certificate)cert ) .peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) ) .map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ) .forEach( i -> System.out.println("Server key bit length: " + i) ); } catch (IOException | GeneralSecurityException e) { e.printStackTrace(); } } lambda hostname verifier read the array as a stream, not a loop
  • 16. What’s a Lambda? • Simplified syntax for writing single-method classes
 • You are effectively passing a function as a parameter to a method 16 con.setHostnameVerifier( (hostname, session) -> true ); (parameters) arrow expression
  • 17. How Does that Lambda Work? con.setHostnameVerifier( new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); con.setHostnameVerifier( (hostname, session) -> true ); ?
  • 18. How Does that Lambda Work? con.setHostnameVerifier( new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); con.setHostnameVerifier( (hostname, session) -> true ); ?
  • 19. How Does that Lambda Work? con.setHostnameVerifier( new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); con.setHostnameVerifier( (hostname, session) -> true ); ?
  • 20. How Does that Lambda Work? con.setHostnameVerifier( new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); con.setHostnameVerifier( (hostname, session) -> true ); ?
  • 21. How Does that Lambda Work? con.setHostnameVerifier( new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); con.setHostnameVerifier( (hostname, session) -> true ); !
  • 22. Functional Interfaces • Lambdas rely on “functional interfaces” to work – an interface with only one abstract method – also called a “single abstract method” or SAM interface – there can be only one! <insert highlander joke here>
 • If there’s only one method, the compiler knows which one you will call
 • If you know the method, and the compiler knows the method, we don’t have to talk about the method – everyone already knows! – skip the obvious stuff 22
  • 23. Functional Interfaces con.setHostnameVerifier( new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); con.setHostnameVerifier( (hostname, session) -> true ); the class MUST be a HostnameVerifier, and the method MUST be verify(String, SSLSession) therefore… throw away everything obvious
  • 24. Lambda Syntax object.method( (param1, param2) -> result ); object.method( param1 -> doStuff(param1) ); object.method( param1 -> doStuff(param1, object) ); object.method( () -> { doStuff(); return doMoreStuff(); } );
  • 25. Method References • There is an alternative syntax called “Method References” – for a lambda that only calls a single method of the parameter, or a single static method that uses the parameter, or creates a single new Object object.method( s -> s.getLength() ); object.method( String::getLength ); http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
  • 26. Another Example: Sandwiches! static enum Sandwich { PB_J ("Peanut butter & jelly", 500), SUB ("Sub", 500), HOTDOG ("Hot dog", 900), TACO ("Taco", 500), PIZZA ("Pizza", 900); private String name; private int calories; private Sandwich(String name, int calories) { this.name = name; this.calories = calories; } public String getName() { return name; } public int getCalories() { return calories; } public String toString() { return "n" + calories + " caloriest" + name; } }
  • 27. List the Sandwiches in Order of Calories List<Sandwich> sandwiches = Arrays.asList( Sandwich.values() ); Collections.sort(sandwiches, new Comparator<Sandwich>() { public int compare(Sandwich s1, Sandwich s2) { return Integer.compare(s1.getCalories(), s2.getCalories()); } }); System.out.println(sandwiches); PB_J ("Peanut butter & jelly", 500), SUB ("Sub", 500), HOTDOG ("Hot dog", 900), TACO ("Taco", 500), PIZZA ("Pizza", 900); 500 calories Peanut butter & jelly, 500 calories Sub, 500 calories Taco, 900 calories Hot dog, 900 calories Pizza
  • 28. List the Sandwiches in Order of Calories List<Sandwich> sandwiches = Arrays.asList( Sandwich.values() ); /* Collections.sort(sandwiches, new Comparator<Sandwich>() { public int compare(Sandwich s1, Sandwich s2) { return Integer.compare(s1.getCalories(), s2.getCalories()); } }); */ Collections.sort(sandwiches, (s1, s2) -> Integer.compare(s1.getCalories(), s2.getCalories()) ); System.out.println(sandwiches); PB_J ("Peanut butter & jelly", 500), SUB ("Sub", 500), HOTDOG ("Hot dog", 900), TACO ("Taco", 500), PIZZA ("Pizza", 900); 500 calories Peanut butter & jelly, 500 calories Sub, 500 calories Taco, 900 calories Hot dog, 900 calories Pizza
  • 29. List the Sandwiches in Order of Calories List<Sandwich> sandwiches = Arrays.asList( Sandwich.values() ); /* Collections.sort(sandwiches, new Comparator<Sandwich>() { public int compare(Sandwich s1, Sandwich s2) { return Integer.compare(s1.getCalories(), s2.getCalories()); } }); */ Collections.sort(sandwiches, Comparator.comparing( sandwich -> sandwich.getCalories() ) ); System.out.println(sandwiches); PB_J ("Peanut butter & jelly", 500), SUB ("Sub", 500), HOTDOG ("Hot dog", 900), TACO ("Taco", 500), PIZZA ("Pizza", 900); 500 calories Peanut butter & jelly, 500 calories Sub, 500 calories Taco, 900 calories Hot dog, 900 calories Pizza
  • 30. List the Sandwiches in Order of Calories List<Sandwich> sandwiches = Arrays.asList( Sandwich.values() ); /* Collections.sort(sandwiches, new Comparator<Sandwich>() { public int compare(Sandwich s1, Sandwich s2) { return Integer.compare(s1.getCalories(), s2.getCalories()); } }); */ Collections.sort(sandwiches, Comparator.comparing( Sandwich::getCalories ) ); System.out.println(sandwiches); PB_J ("Peanut butter & jelly", 500), SUB ("Sub", 500), HOTDOG ("Hot dog", 900), TACO ("Taco", 500), PIZZA ("Pizza", 900); 500 calories Peanut butter & jelly, 500 calories Sub, 500 calories Taco, 900 calories Hot dog, 900 calories Pizza
  • 31. All These are the Same Comparator Collections.sort(sandwiches, new Comparator<Sandwich>() { public int compare(Sandwich s1, Sandwich s2) { return Integer.compare(s1.getCalories(), s2.getCalories()); } }); Collections.sort(sandwiches, (s1, s2) -> Integer.compare(s1.getCalories(), s2.getCalories()) ); Collections.sort(sandwiches, Comparator.comparing( sandwich -> sandwich.getCalories() ) ); Collections.sort(sandwiches, Comparator.comparing( Sandwich::getCalories ) );
  • 32. Fun with the Comparator Collections.sort(sandwiches, Comparator.comparing( Sandwich::getCalories ) .thenComparing( Sandwich::getName ) .reversed() ); 900 calories Pizza, 900 calories Hot dog, 500 calories Taco, 500 calories Sub, 500 calories Peanut butter & jelly PB_J ("Peanut butter & jelly", 500), SUB ("Sub", 500), HOTDOG ("Hot dog", 900), TACO ("Taco", 500), PIZZA ("Pizza", 900);
  • 33. But Really, What’s the Point? • This all seems like needless tomfoolery – after all, the old code still works!
 • Two major advantages: 1. Forces (or strongly encourages) you to write functional code 2. Less visual noise makes code easier to read and understand 33 Collections.sort(sandwiches, new Comparator<Sandwich>() { public int compare(Sandwich s1, Sandwich s2) { return Integer.compare(s1.getCalories(), s2.getCalories()); } }); Collections.sort(sandwiches, Comparator.comparing( Sandwich::getCalories ) );
  • 34. Code Should Describe Behavior Code Should Read Like A Story
  • 35. Dealing with Exceptions Collections.sort(sandwiches, Comparator.comparing( Sandwich::getCalories ) .thenComparing( Sandwich::getName ) .reversed() ); NULLWICH (null, 500), PB_J ("Peanut butter & jelly", 500), SUB ("Sub", 500), HOTDOG ("Hot dog", 900), TACO ("Taco", 500), PIZZA ("Pizza", 900); Exception in thread "main" java.lang.NullPointerException at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469) at java.util.Comparator.lambda$thenComparing$36697e65$1(Comparator.java:217) at java.util.Collections$ReverseComparator2.compare(Collections.java:5178) at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355) at java.util.TimSort.sort(TimSort.java:220) at java.util.Arrays.sort(Arrays.java:1438) at java.util.Arrays$ArrayList.sort(Arrays.java:3895) at java.util.Collections.sort(Collections.java:175) at com.panagenda.ssltest.MoreJava8Examples.main(MoreJava8Examples.java:52)
  • 36. Dealing with Exceptions • It’s not always obvious what caused the Exception
 • It’s cumbersome to add a try/catch to a lambda – same with adding logging
 • If an Exception is possible, maybe better to call out to a method instead 36 Collections.sort(sandwiches, Comparator.comparing( sandwich -> getCalories(sandwich) ) .thenComparing( sandwich -> getName(sandwich) ) .reversed() );
  • 37. A Few More Examples // process all the keys and values of a HashMap Map<String, Integer> myHashMap = new HashMap<>(); myHashMap.forEach( (key, value) -> System.out.println(key + "; " + value) ); // remove all the null elements in a List List<String> myArrayList = new ArrayList<>(); myArrayList.removeIf( s -> s == null ); // get all the JPG files in a directory File photoDir = new File("c:/photos"); File[] docFiles = photoDir.listFiles( file -> file.getName().endsWith("jpg") ); // run some code in a thread new Thread( () -> doSomething() ).start();
  • 38. Under the Hood • If you’re really curious about how all this works… – http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html 
 • It’s all Function and Predicate objects – https://docs.oracle.com/javase/8/docs/api/java/util/function/package- summary.html – Closures? By some definitions. 38 Function<Sandwich, Integer> caloryCompare = sandwich -> sandwich.getCalories();
  • 40. From Loop to Stream Certificate[] certs = con.getServerCertificates(); for (Certificate cert : certs) { System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter()); System.out.println( "Server key bit length: " + ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ); } Certificate[] certs = con.getServerCertificates(); Arrays.asList(certs) .stream() .map ( cert -> (X509Certificate)cert ) .peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) ) .map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ) .forEach( i -> System.out.println("Server key bit length: " + i) ); ?
  • 41. What Does that Loop Actually Do? 41 Certificate[] certs = con.getServerCertificates(); for (Certificate cert : certs) { System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter()); System.out.println( "Server key bit length: " + ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ); } print the information get something from the objectprint the information get something from the object
  • 42. How Does the Stream Work? Certificate[] certs = con.getServerCertificates(); Arrays.asList(certs) .stream() .map ( cert -> (X509Certificate)cert ) .peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) ) .map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ) .forEach( i -> System.out.println("Server key bit length: " + i) ); start with an array, convert it to a List convert the List to a stream TIP: this could also be just Arrays.stream(certs) } change the stream do something to each item change the stream do something to each item
  • 43. Breaking Down the Example Certificate[] certs = con.getServerCertificates(); Arrays.asList(certs) .stream() .map ( cert -> (X509Certificate)cert ) .peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) ) .map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ) .forEach( i -> System.out.println("Server key bit length: " + i) ); map() converts each item by casting it to X509Certificate, then returns a Stream of X509Certificate objects map() gets an int value from each item, then returns a Stream of int values start with an array of Certificates
  • 44. Breaking Down the Example Certificate[] certs = con.getServerCertificates(); Arrays.asList(certs) .stream() .map ( cert -> (X509Certificate)cert ) .peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) ) .map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ) .forEach( i -> System.out.println("Server key bit length: " + i) ); peek() is an intermediate operation: it does something with each item and returns the original Stream forEach() is a terminal operation: it does something with each item and stops
  • 45. What’s a Stream? • Allows you to perform operations on a collection of data – multiple operations can be combined in a pipeline
 
 • Has the following properties – uses functional arguments (lambdas!) to process data – does not store data – pipeline operations are optimized for laziness – optionally process in parallel (multi-threaded) with no extra code 45
  • 46. Is a Stream Better than a Loop? Certificate[] certs = con.getServerCertificates(); for (Certificate cert : certs) { System.out.println( "Valid until: " + ((X509Certificate)cert).getNotAfter()); System.out.println( "Server key bit length: " + ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ); } Certificate[] certs = con.getServerCertificates(); Arrays.asList(certs) .stream() .map ( cert -> (X509Certificate)cert ) .peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) ) .map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ) .forEach( i -> System.out.println("Server key bit length: " + i) ); !Stream version is more descriptive of the behavior of the code Stream version can easily be turned into multi-threaded code
  • 47. Multi-threaded You Say? Arrays.asList(certs) .stream() .parallel() .map ( cert -> (X509Certificate)cert ) .peek( cert -> System.out.println("Valid until: " + cert.getNotAfter()) ) .map ( cert -> ((RSAPublicKey)cert.getPublicKey()).getModulus().bitLength() ) .forEach( i -> System.out.println("Server key bit length: " + i) ); DANGER: The forEach() and peek() output might be out-of-order!
  • 48. Adding Numbers in a Loop 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 45 int sum = 0; for (int i : new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9}) { sum += i; } return sum;
  • 49. Adding Numbers with Reduce 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 1 + 2 3 + 4 + 5 6 + 8 7 + 9 3 + 14 12 + 16 45
  • 50. Adding Numbers with Reduce 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 1 + 2 3 + 4 + 5 6 + 8 7 + 9 3 + 14 12 + 16 45 By abstracting away the very concept of looping, you can implement looping any way you want, including implementing it in a way that scales nicely with extra hardware. Joel Spolsky https://www.joelonsoftware.com/2006/08/01/ can-your-programming-language-do-this each computation could be on a separate processor core… or a separate machine!
  • 51. Other Things to Know About Streams • Normally get them from Collections or arrays – List.stream(), Map.entrySet().stream(), Arrays.stream(Object[]) – also other fun places, like BufferedReader.lines() or Files.list()
 
 • Some operations will short circuit instead of processing each item – built-in optimizations
 
 • Stream operations should be stateless – for example, don’t update Lists as part of a stream operation – items could process out of order, and might not be thread-safe – collect the results at the end instead 51
  • 52. Other Things to Know About Streams • Operations on Streams should be associative when possible – (a + b + c) == (c + b + a) == b + (a + c) – if order of operations does matter, make sure you: • start with an ordered set of data, like a List • use forEachOrdered() instead of forEach() • don’t use reduce() 
 
 • For reference: – https://docs.oracle.com/javase/8/docs/api/java/util/stream/package- summary.html 52
  • 53. Under the Hood • If you’re really curious about how all this works… – http://www.ibm.com/developerworks/java/library/j-java-streams-1-brian- goetz 
 • Read about java.util.function – https://docs.oracle.com/javase/8/docs/api/java/util/function/package- summary.html – Predicate, Consumer, and Supplier interfaces 53
  • 54. Backwards Compatibility because not all of us have a choice
  • 55. Java 8 API Changes (partial list) • Streams – in its own package – throughout Collections, Files, etc.
 • Functional classes in java.util.function
 • Brand new Date-Time package and classes – http://docs.oracle.com/javase/tutorial/datetime 
 • JavaFX for GUIs
 • http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html 
 http://docs.oracle.com/javase/8/docs/technotes/guides/language/lambda_api_jdk8.html 55 Function<Sandwich, Integer> caloryCompare = sandwich -> sandwich.getCalories();
  • 56. Compiling to Earlier Versions • Java can compile for previous versions, but… – you can’t use any of the new APIs (classes or methods) – you can’t use any of the new language features
 
 • What happens if you use a Java 8 JAR in a Java 6 environment? – it won’t work – the JRE checks the JAR file for a version number first – if the version number is too high, you get errors
 
 • Some tools can convert bytecode to earlier versions – but new APIs still won’t work 56
  • 57. Options for Backwards Compatibility • If you don’t want to use new language features at all – set “Source compatibility” and “Generated .class files compatibility” to your desired older Java version – use a tool to make sure you didn’t use new APIs
 Animal Sniffer: http://www.mojohaus.org/animal-sniffer 
 57
  • 58. Options for Backwards Compatibility • If you only want to use lambdas and try-with-resources – compile as Java 8, then use RetroLambda to backport your JAR file 
 https://github.com/orfjackal/retrolambda – you still have to make sure you didn’t use new APIs: AnimalSniffer again
 
 • You might be able to backport Streams too (mixed results) – http://sourceforge.net/projects/streamsupport 58
  • 59. Is It Worth It? • Backporting? Maybe, but probably not regularly – Risky: even if it seems to work, hard to test if it really worked – make sure you have great unit tests to run against the backported code
 
 • Learning? Absolutely! – even if you can’t use Java 8 now, you will later – functional programming can be much “safer” – teaches you good coding habits – helps you understand code examples on StackOverflow ;) 59
  • 60. Required Reading we only scratched the surface
  • 61. On the Oracle Website • Streams – https://docs.oracle.com/javase/8/docs/api/java/util/stream/package- summary.html – http://www.oracle.com/technetwork/articles/java/ma14-java-se-8- streams-2177646.html 
 • Lambdas – https://docs.oracle.com/javase/tutorial/java/javaOO/ lambdaexpressions.html – http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html – https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27 61
  • 62. Articles and Musings • State of the lambda (Brian Goetz) – http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html 
 • IBM DeveloperWorks articles by Brian Goetz – http://www.ibm.com/developerworks/java/library/j-java-streams-1-brian-goetz – http://www.ibm.com/developerworks/java/library/j-java-streams-2-brian-goetz – http://www.ibm.com/developerworks/java/library/j-java-streams-3-brian-goetz – http://www.ibm.com/developerworks/java/library/j-java-streams-4-brian-goetz – http://www.ibm.com/developerworks/java/library/j-java-streams-5-brian-goetz
 • Joel Spolsky on MapReduce – https://www.joelonsoftware.com/2006/08/01/can-your-programming-language- do-this 62
  • 63. Books (!) • Java 8 in Action – Raoul-Gabriel Urma
 Manning Press • Mastering Lambdas: Java Programming in a Multicore World – Maurice Naftalin
 Oracle Press
  • 64. Notices and disclaimers Copyright © 2017 by International Business Machines Corporation (IBM). No part of this document may be reproduced or transmitted in any form without written permission from IBM. U.S. Government Users Restricted Rights — Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM. Information in these presentations (including information relating to products that have not yet been announced by IBM) has been reviewed for accuracy as of the date of initial publication and could include unintentional technical or typographical errors. IBM shall have no responsibility to update this information. THIS DOCUMENT IS DISTRIBUTED "AS IS" WITHOUT ANY WARRANTY, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL IBM BE LIABLE FOR ANY DAMAGE ARISING FROM THE USE OF THIS INFORMATION, INCLUDING BUT NOT LIMITED TO, LOSS OF DATA, BUSINESS INTERRUPTION, LOSS OF PROFIT OR LOSS OF OPPORTUNITY. IBM products and services are warranted according to the terms and conditions of the agreements under which they are provided. IBM products are manufactured from new parts or new and used parts. In some cases, a product may not be new and may have been previously installed. Regardless, our warranty terms apply.” Any statements regarding IBM's future direction, intent or product plans are subject to change or withdrawal without notice. Performance data contained herein was generally obtained in a controlled, isolated environments. Customer examples are presented as illustrations of how those customers have used IBM products and the results they may have achieved. Actual performance, cost, savings or other results in other operating environments may vary. References in this document to IBM products, programs, or services does not imply that IBM intends to make such products, programs or services available in all countries in which IBM operates or does business. Workshops, sessions and associated materials may have been prepared by independent session speakers, and do not necessarily reflect the views of IBM. All materials and discussions are provided for informational purposes only, and are neither intended to, nor shall constitute legal or other guidance or advice to any individual participant or their specific situation. It is the customer’s responsibility to insure its own compliance with legal requirements and to obtain advice of competent legal counsel as to the identification and interpretation of any relevant laws and regulatory requirements that may affect the customer’s business and any actions the customer may need to take to comply with such laws. IBM does not provide legal advice or represent or warrant that its services or products will ensure that the customer is in compliance with any law 64
  • 65. Notices and disclaimers continued Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements or other publicly available sources. IBM has not tested those products in connection with this publication and cannot confirm the accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of those products. IBM does not warrant the quality of any third-party products, or the ability of any such third-party products to interoperate with IBM’s products. IBM EXPRESSLY DISCLAIMS ALL WARRANTIES, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The provision of the information contained herein is not intended to, and does not, grant any right or license under any IBM patents, copyrights, trademarks or other intellectual property right. IBM, the IBM logo, ibm.com, Aspera®, Bluemix, Blueworks Live, CICS, Clearcase, Cognos®, DOORS®, Emptoris®, Enterprise Document Management System™, FASP®, FileNet®, Global Business Services ®, Global Technology Services ®, IBM ExperienceOne™, IBM SmartCloud®, IBM Social Business®, Information on Demand, ILOG, Maximo®, MQIntegrator®, MQSeries®, Netcool®, OMEGAMON, OpenPower, PureAnalytics™, PureApplication®, pureCluster™, PureCoverage®, PureData®, PureExperience®, PureFlex®, pureQuery®, pureScale®, PureSystems®, QRadar®, Rational®, Rhapsody®, Smarter Commerce®, SoDA, SPSS, Sterling Commerce®, StoredIQ, Tealeaf®, Tivoli®, Trusteer®, Unica®, urban{code}®, Watson, WebSphere®, Worklight®, X-Force® and System z® Z/OS, are trademarks of International Business Machines Corporation, registered in many jurisdictions worldwide. Other product and service names might be trademarks of IBM or other companies. A current list of IBM trademarks is available on the Web at "Copyright and trademark information" at: www.ibm.com/legal/copytrade.shtml. 65