#(int x, int y)(x * y)
Versions and Features |
The New World |
Projects To Look Out For |
Slides at slides.codefx.org.
If you’re shy, tweet questions
with #JavaNext
Versions and Features |
The New World |
Projects To Look Out For |
From Java 8 to Java 11.
released 03/2014
free support ends 01/2019
n -> lambdas()
Method::references
features.stream()
default method() { … }
led by Brian Goetz
ran from 12/2009 to 02/2014
mailing list (thousands of messages)
launched with a straw-man (12/2009):
#(int x, int y)(x * y)
1st early draft review (11/2011):
Callable<String> c = () -> "done";
2nd review (06/2012) and 3rd review (01/2013)
public review (12/2013) and final ballot (02/2014)
start with an idea
that is then evolved
can take a long time
are fairly open
released 09/2017
free support ended 01/2018
module jpms {
requires more.work;
exports migration.challenges;
}
led by Mark Reinhold
launched 12/2008
from the announcement:
Sun’s primary goal in the upcoming JDK 7 release will be to modularize the JDK […], which we hope to deliver early in 2010.
😊
Oracle acquires Sun, Jigsaw is halted (2010)
Jigsaw starts exploratory phase (2011)
releases of Java 7 (2011) and Java 8 (2014)
exploratory phase ends with JSR 376 (2014)
a prototype is released (09/2015)
lacking module isolation
forbidden cyclic dependencies
the concept of automatic modules
migration challenges
and a few more
about Unsafe
et. al.
⇝ jdk.unsupported exports them
about strong encapsulation
⇝ deactivated on JDK 9/10/11
about hostility to reflection
⇝ opens
directive
and a few more
Java 9 release was planned for 09/2016
Jigsaw delays it to 03/2017,
then 07/2017, then 09/2017
public review ballot (05/2017)
public review ballot fails (05/2017)
various fundamental changes requested;
only change: encapsulation turned off
reconsideration ballot passes (06/2017)
¯\_(ツ)_/¯
can lead to very heated discussions
are subject to politics
take feedback into account and
adapt to new requirements
are not as open as they could be
can take a very long time and
delay Java releases
released 03/2018
free support ends 07/2018
local-variable type inference:
var users = new ArrayList<User>();
application class-data sharing (hardly)
More on that later!
release 09/2018
free support ends 01/2019
(yes, no free LTS—more on that later)
Err…
single-file source-code programs:
java HelloWorld.java
reactive HTTP/2 client
Epsilon GC
no language changes
no monumental dev-facing features
this will become common
that’s not a bad thing!
Versions and Features |
The New World |
Projects To Look Out For |
releases are driven by flagship features
new major release roughly every 2 years
Java 7 took 5 years
Java 8 took 3 years
Java 9 took 3.5 years
"Bump an 'almost ready' feature
2+ years into the future?"
⇝ "Better to delay the release."
implemented features provide no value
increases reaction time
puts (political) pressure on projects
makes everybody grumpy
If it hurts, do it more often.
fixed six-month release cadence
(March and September)
ship everything that is ready
All are major releases
with known quality guarantees.
⇝ No "beta versions"!
features are developed in branches
merged into master when (nearly) finished
release branch created 3 months prior
only bug fixes merged to release branch
completed features get out earlier
no pressure to complete features "on time"
easier to incubate features
easier to react to changes in the ecosystem
"Java will change too fast."
"Constant migrations will be expensive."
"Test matrix will explode."
"Ecosystem will fragment."
The rate of innovation doesn’t change. The rate of innovation delivery increases.
Maybe speed will pick up a little:
recent activities target low-hanging fruits
Oracle is focusing on Java core (my impression!)
By and large:
Evolution will be steadier, not faster.
(see Java 11)
Balance shifted between
compatibility vs evolution:
@Deprecated(forRemoval=true)
"one major release" is now 6 months, not 36
increasing bytecode level
incubating features (if used incorrectly)
But not the norm:
Java 10 is trivial
Java 11 is easy
Oracle is still committed
to backwards compatibility!
Remedies:
stick to supported APIs
stick to standardized behavior
stick to well-maintained projects
keep dependencies and tools up to date
Use jlink
to create application images:
contain just the platform modules you need
contain your code and your dependencies
launch with image/bin/your-app
Single deployment unit,
independent of installed JRE.
Independent of installed JRE:
no compatibility issues
no automatic performance gain
no automatic security updates
Works great if you have
complete control
over the deployment.
Not so much if you deliver software.
As the range of supported versions increases…
builds need to run against all of them
developers needs to switch between them
Many tools already support this.
We need to know how.
Also: Moar automization!
"This will be like Python 2/3!"
No.
find a suitable update cadence
build on each release (including EA)
report problems
only rely on standardized behavior
heed deprecation warnings (jdeprscan
)
keep dependencies and tools up to date
Most importantly:
Be aware of what’s coming!
Don’t focus on versions!
Focus on projects and JEPs:
Let’s have a look at what’s coming!
What if you (or your customers)
don’t want to update every six months?
Oracle JDK used to…
contain more features
be perceived as more stable
be perceived as more performant
As of Java 11, on a technical basis
Oracle JDK and OpenJDK are identical.
Only difference is license and support model:
Oracle ships OpenJDK at jdk.java.net/$version,
licensed under GPL+CE
Oracle JDK becomes fully commercial:
from 11 on, no free use in production
⇝ Get used to using on OpenJDK.
What does Oracle support?
free updates for current major OpenJDK version
commercial support for Oracle JDK
for at least 3 years for Java 11, 17, 23, etc.
⇝ No Free LTS by Oracle.
How does Oracle handle bug/security/etc fixes?
usually developed on master (OpenJDK)
merged to current version’s branch (OpenJDK)
merged to current LTS version (internally)
LTS means merging fixes
into old OpenJDK branches.
Commercial LTS by
Oracle
Azul
RedHat
…
Likely free LTS for OpenJDK
by Adopt OpenJDK!
Versions and Features |
The New World |
Projects To Look Out For |
Many great features on the horizon!
Don’t focus on versions!
Focus on projects and JEPs:
Let’s have a look at what’s coming!
(Straw-man syntax ahead!)
Smaller, productivity-oriented language features
Generic specialization and value types
Fibers and continuations
Graal and ahead-of-time compilation
Java on the GPU and APU
Explore and incubate smaller, productivity-oriented Java language features.
Profile:
led by Brian Goetz
launched March 2017, very active
Already delivered var
in Java 10!
Java compared to more modern languages:
can be cumbersome
lacks expressiveness
tends to require boilerplate
Amber wants to improve that situation.
string literals (JEP 326)
switch expressions (JEP 325)
pattern matching (JEP 305)
data classes (exploration)
String html =
`<html>
<body>
<p>"Hello, string literals!"</p>
</body>
</html>`;
Yeah:
multiline strings
no escaping of special characters
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
};
Yeah:
switch
"gets a value"
no more break
!
compiler checks exhaustiveness
String formatted = switch (value) {
case Integer i -> String.format("int %d", i);
case Byte b -> String.format("byte %d", b);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> "unknown " + value.toString();
}
Yeah:
more powerful conditions
no repetition between condition and block
public int eval(Node n) {
return switch(n) {
case IntNode(int i) -> i;
case NegNode(Node n) -> -eval(n);
case AddNode(Node left, Node right) ->
eval(left) + eval(right);
default -> throw new IllegalStateException(n);
};
}
Yeah:
deconstructing complex objects
goodbye visitor pattern!
public datum Range(int low, int high) {
// compiler generates:
// * constructor, deconstructor
// * equals/hashCode/toString
// * accessors low(), high()
}
Yeah:
no boilerplate for plain "data carriers"
no room for error in equals
/hashCode
makes Java more expressive
The API for a data class models the state, the whole state, and nothing but the state.
The deal:
give up encapsulation
couple API to internal state
get API for free
public datum Range(int low, int high) {
@Override
public Range(int low, int high) {
if (low > high)
throw new IllegalArgumentException();
default.this(low, high);
}
public void setLow(int low) {
if (low > this.high)
throw new IllegalArgumentException();
this.low = low;
}
}
Explore and incubate advanced Java VM and Language feature candidates.
Profile:
led by Brian Goetz
launched July 2014, very active
In Java, (almost) everything is a class:
mutable by default
memory access indirection
requires extra memory for header
allows locking and other
identity-based operations
Wouldn’t it be nice to create a custom int
?
public value Point {
private final int x;
private final int y;
// constructor, accessors,
// equals/hashCode/toString,
// and other methods
}
Codes like a class, works like an
int
.
public value Point {
private final int x;
private final int y;
}
Yeah:
enforced immutability
no memory indirection! (flat)
no Object
header (dense)
identity doesn’t matter
makes Java more expressive
Values:
no identity
no self references
no mutability
⇝ flat and dense memory layout
Data Classes:
no encapsulation
⇝ less boilerplate
Might be combinable to "data value types".
When everybody creates their own primitives,
boxing becomes omni-present and very painful!
List<int> ids = new ArrayList<>();
Yeah:
backed by an actual int[]
great performance
works with your value types
Value types and generic specialization together,
have immense effects inside the JDK!
no more manual specializations:
functional interfaces
stream API
Optional
API
better performance
Value types and generic specialization together,
have immense effects on your code!
fewer trade-offs between
design and performance
better performance
can express design more clearly
more robust APIs
Enable Java applications to take advantage of GPUs and APUs […] to improve performance
Profile:
launched June 2014, not much recent activity
Java on the GPU: Where are we now?
by Dmitry Aleksandrov
Why use the GPU?
can be more peformant
can be more energy-efficient
Can’t we do that already?
(Aparapi, JOCL)
not integrated into the JDK
require their own programming model
Basics:
create low-level API to uniformly access GPUs
use streams as high-level API
Ideally:
auto-detection of hardware and software stack
heuristic to decide when offloading makes sense
offload embarrassingly parallel stream pipelines
on error, graceful fall-back to normal CPU execution
For stream operations to offload:
extract lambda function
use Graal to compile to HSA kernel (runs on GPU)
extract lambda arguments and pass to HSA
GPU operates on main memory
and has access to Java heap!
public static void main(String[] args) {
final int length = 8;
int[] ina = new int[length];
int[] inb = new int[length];
int[] out = new int[length];
// ...
}
// offloadable
IntStream.range(0, length).parallel().forEach(p -> {
ina[p] = 1;
inb[p] = 2;
});
// offloadable
IntStream.range(0, length).parallel().forEach(p -> {
out[p] = ina[p] + inb[p];
});
// not offloadable (native code)
IntStream.range(0, length).forEach(p -> {
System.out.println(
out[p] + ", " + ina[p] + ", " + inb[p]);
});
To know what’s coming:
pick a project that interests you
look out for mentions
subscribe to the mailing list
find early access builds and try them
give feedback
Tell your colleagues about it!
⇜ Get my book!
You can hire me:
training (Java 8-11, JUnit 5)
consulting (Java 8-11)
jigsaw: Kevin Dooley, CC-BY 2.0
valhalla: Emil Doepler, public domain