This is the material for Tampere workshop on 14th May 2018.
How to combine modern technologies such as Java 10, Spring Boot 2, Docker, to create more lightweight and modern microservices - or any services you like.
2. Who am I?
• Arto Santala
• Work as software architect in Solita, producing tailored
solutions to accelerate customer business
• More than 20 years of experience making customers
dreams come true with application of proper technologies
and methodologies
• Guilty of writing a lot of horrible code in the 90’s that
should be burned with fire. Always aiming to improve.
• Passionate about agile and automation. Trying to make
every moment worthy of living.
3. Java 8 as platform
• Java 8 is product of more than 20 years of development. Every
release, more and more have been added, nothing has never
been removed
• Today Java 8 is a heavy platform with a lot of libraries that you
will never need
• Midi instruments, 1995 version of java.util.Date, Corba IIOP, applets,
AWT, …
• Heavier images, larger memory footprint, more attack area for
vulnerabilities
6. Java 10 as platform
• Not such a revolution, just a bit of evolution
• Hard transition from Java 8 to Java 9
• Easy transition from Java 9 to 10 and 11
• GA is out there now – but do note the short support lifetime for both Java 9 and 10
var item1 = ”HELLO”;
var list1 = List.of(item1,”WORLD”);
7. Java 10 + Spring Boot Helloworld
Still fat, but getting better!
Pssst, minimal Java 10 + Apache Spark web services
9. JLINK
jlink --module-path $JAVA_HOME/jmods --verbose --add-modules
java.base,java.logging,java.xml,jdk.unsupported,java.sql,java.naming,java.desktop,java.man
agement,java.security.jgss,java.instrument --compress 2 --no-header-files --output jdk-9-
minimal-osx --no-man-pages
Jlink is a new tool that allows to link modules and even JRE together as a platform specific
executable.
For example, you can generate a custom JRE with just the modules you need to run Spring
Boot, like this:
Much less attack surface, less to update, less disk use, less memory use, faster startup, etc
13. Spring Boot 2
• Spring Boot 1.x is not going to support Java 9 or above, ever
• Spring Boot 2 is out there, with support to Java 9 (and to some extent also
10)
• Easiest to get started with Spring Initializr at https://start.spring.io/
14. Quick (stupid) test
@RestController
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public Map getGreeting() {
var now = Instant.now();
return Map.of("message", String.format("It's %s", now));
}
}
15. Typical pitfalls with Java 9/10
• package javax.xml.bind.annotation.adapters is not visible
• More and more core modules are missing from core of core, so you need to either add them via
command line switches, or declare module dependencies – or just as dependencies
• --add-modules java.xml.bind
• Illegal reflective access by org.springframework.cglib.core.ReflectUtils
• Java 9/10 is starting to be more precise on accessing non-public APIs, so primarily you should find
libraries that are not accessing internal APIs
• Ironically, with Spring you can make this warning go away by setting –illegal-access=deny
• In some cases. as short-term solution you can also play with --add-
exports $module/$package=$readingmodule and --add-opens $module/$package=$readingmodule to
open up types and members for deep reflection of also private internals
• So mostly, just make sure dependencies and modules are declared properly, and find libraries
that play nicely with Java 9/10/11 and do not leverage the deprecated internals
• In future, more and more modules and packages will go out of core, so get used to this
16. Typical pitfalls with Java 9/10
• IllegalArgumentException at testCompilation/test phase
• Maven compiler/surefire might be using older version of ASM, which can be fixed like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<release>10</release>
</configuration>
<dependencies>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>6.1.1</version> <!-- Use newer version of ASM -->
</dependency>
</dependencies>
</plugin>
17. Other non-default (EE) modules
• java.activation with javax.activation package
• java.corba with javax.activity, javax.rmi, javax.rmi.CORBA, andorg.omg.* packages
• java.transaction with javax.transaction package
• java.xml.bind with all javax.xml.bind.* packages
• java.xml.ws with javax.jws, javax.jws.soap, javax.xml.soap, and alljavax.xml.ws.* packages
• java.xml.ws.annotation with javax.annotation package
• Java 11 will remove all these, so it will not be enough to just --add-modules forever, you
need to find the actual libraries and declare as real, external dependencies
18. XML modules will go out from core
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
19. Evaluating old code
• java --list-modules
• jdeps --jdk-internals -R --class-path 'libs/*' $project
• --illegal-access=$value option, where $value can be:
• permit: Access to all JDK-internal APIs is permitted to code on the class path. For reflective access,
a single warning is issued for the first access to each package. (Default is Java 9, but will be
removed in a future release.)
• warn: Behaves like permit but a warning is issued for each reflective access.
• debug: Behaves like warn but a stack trace is included in each warning.
• deny: The option for those who believe in strong encapsulation:
• All illegal access is forbidden by default.
• jar –file=mylib.jar --describe-modules
• To figure out automatic module name for the .jar
20. Typical pitfalls with Spring Boot 2
• Security module has changed a lot: Now you only get what you declare, unlike previously
when there were a lot of defaults
• Spring Data APIs have changed a lot: Now there’s a lot more of Optional use for return
values, and more descriptive names for methods
• Later version of Flyway, not checksum compatible with old version possibly
• References to old versions of Spring modules, or third party modules that depend on 1.x
versions
21. Docker
• Docker is a lovely way to start experimenting with Java 9/10 without installing it on your
own machine
• docker run -it solita/jdk10
• You can map folders to Docker so you can access files in them, such as .jar files, libraries,
etc – you can also expose ports where services run to host machines
• docker run -it -p 8080:8080 -v `pwd`:/root solita/jdk10
• This is just an example, you can take a look and create your own docker images
• How about two-phased Docker image, one step will build the modular JRE, second will
package your .jar with it?
22. Two-phase dockerfile example
FROM solita/jdk10 as packager
# First stage: JDK 10 with modules required for Spring Boot
RUN /opt/jdk-10/bin/jlink
--module-path /opt/jdk-10/jmods
--verbose
--add-modules
java.base,java.logging,java.xml,jdk.unsupported,java.sql,java.naming,java.desktop,java.management,java.secu
rity.jgss,java.instrument
--compress 2
--no-header-files
--output /opt/jdk-10-minimal
# Second stage, add only our custom jdk9 distro and our app
FROM solita/jdk10
COPY --from=packager /opt/jdk-10-minimal /opt/jdk-10-minimal
COPY target/*.jar /opt/
ENV JAVA_HOME=/opt/jdk-10-minimal
ENV PATH="$PATH:$JAVA_HOME/bin"
EXPOSE 8080
CMD java -jar /opt/*.jar
26. Hackathexerciseon
• Let’s try to build something with all this
• Idea: API for registering thumbs up/thumbs down signals for presentation
• Presentations have a name, and we register thumbs-up/thumbs-down entries for them
• Let’s assume presentations have shorter code that can be used to refer to it.
• Anyone can give as many entries as they like, not limited in this exercise
• API should also let us know total number of thumbs-up/thumbs-down for a presentation, and could
let us know most highly/lowly rated presentations
• Extra exercise:
• Simple UI for pressing thumbs-up/thumbs-down for a presentation
• Another UI for showing outcomes
• Websockets, real-time tracking of +/-
• CI pipeline, AWS Fargate/EKS deployment, self-healing capabilities, go crazy
27. Hackathexerciseon
• So, form small groups, experiment with either larger challenge or some
substeps
• Pull JDK10 docker image, or install JDK 10 locally, try jshell, jlink, syntax
• Create Spring Boot 2.0 initializr project, compile and run with JDK 10
• Create some API and Services, to push it further. Include db?
• Minimize the JDK 10 environment, see if it still runs. How are the resources doing? Can
you measure them? Can you compare them?
• Ask questions, try things, break things