├── .dockerignore
├── multi-release-jar
├── .dockerignore
├── src
│ └── main
│ │ ├── java17
│ │ └── com
│ │ │ └── example
│ │ │ └── Student.java
│ │ └── java
│ │ └── com
│ │ └── example
│ │ ├── Student.java
│ │ └── Application.java
├── run-multi-release-application.cmd
└── pom.xml
├── java17
├── mockito_broken
│ ├── src
│ │ ├── test
│ │ │ ├── resources
│ │ │ │ └── mockito-extensions
│ │ │ │ │ └── org.mockito.plugins.MockMaker
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── ExampleEnumTest.java
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── ExampleEnum.java
│ └── pom.xml
├── mockito_fixed
│ ├── src
│ │ ├── test
│ │ │ ├── resources
│ │ │ │ └── mockito-extensions
│ │ │ │ │ └── org.mockito.plugins.MockMaker
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── ExampleEnumTest.java
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── ExampleEnum.java
│ └── pom.xml
└── pom.xml
├── java16
├── lombok_broken
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ ├── LombokStudent.java
│ │ │ └── LombokService.java
│ └── pom.xml
├── lombok_fixed
│ └── pom.xml
└── pom.xml
├── java11
├── javaee_removed_broken
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ ├── ws
│ │ │ └── WSExample.java
│ │ │ ├── annotation
│ │ │ └── AnnotationExample.java
│ │ │ ├── transaction
│ │ │ └── TransactionExample.java
│ │ │ ├── activation
│ │ │ └── ActivationExample.java
│ │ │ └── bind
│ │ │ ├── JAXBStudent.java
│ │ │ └── JAXBService.java
│ └── pom.xml
├── javaee_removed_fixed_badly
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ ├── ws
│ │ │ └── WSExample.java
│ │ │ ├── transaction
│ │ │ └── TransactionExample.java
│ │ │ ├── activation
│ │ │ └── ActivationExample.java
│ │ │ ├── annotation
│ │ │ └── ActivationExample.java
│ │ │ └── bind
│ │ │ ├── JAXBStudent.java
│ │ │ └── JAXBService.java
│ └── pom.xml
├── javaee_removed_fixed_new_package
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ ├── ws
│ │ │ └── WSExample.java
│ │ │ ├── transaction
│ │ │ └── TransactionExample.java
│ │ │ ├── annotation
│ │ │ └── ActivationExample.java
│ │ │ ├── activation
│ │ │ └── ActivationExample.java
│ │ │ └── bind
│ │ │ ├── JAXBStudent.java
│ │ │ └── JAXBService.java
│ └── pom.xml
├── removed_fonts
│ ├── src
│ │ ├── main
│ │ │ └── java
│ │ │ │ └── removedfonts
│ │ │ │ └── FontExample.java
│ │ └── test
│ │ │ └── java
│ │ │ └── removedfonts
│ │ │ └── FontExampleTest.java
│ └── pom.xml
└── pom.xml
├── DockerfileJava8
├── java15
├── nashorn_broken
│ ├── src
│ │ ├── test
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── NashornExampleTest.java
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── NashornExample.java
│ └── pom.xml
├── nashorn_fixed
│ ├── src
│ │ ├── test
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── NashornExampleTest.java
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── NashornExample.java
│ └── pom.xml
└── pom.xml
├── Dockerfile
├── DockerfileWithFonts
├── pom.xml
├── .gitignore
└── README.md
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/target/
--------------------------------------------------------------------------------
/multi-release-jar/.dockerignore:
--------------------------------------------------------------------------------
1 | target/
--------------------------------------------------------------------------------
/java17/mockito_broken/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker:
--------------------------------------------------------------------------------
1 | mock-maker-inline
2 |
--------------------------------------------------------------------------------
/java17/mockito_fixed/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker:
--------------------------------------------------------------------------------
1 | mock-maker-inline
2 |
--------------------------------------------------------------------------------
/java16/lombok_broken/src/main/java/com/example/LombokStudent.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import lombok.Value;
4 |
5 | @Value
6 | public class LombokStudent {
7 | private String name;
8 | }
9 |
--------------------------------------------------------------------------------
/java17/mockito_broken/src/main/java/com/example/ExampleEnum.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | public enum ExampleEnum {
4 | TEST {
5 | public String retrieve() {
6 | return "test";
7 | }
8 | };
9 | }
--------------------------------------------------------------------------------
/java17/mockito_fixed/src/main/java/com/example/ExampleEnum.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | public enum ExampleEnum {
4 | TEST {
5 | public String retrieve() {
6 | return "test";
7 | }
8 | };
9 | }
--------------------------------------------------------------------------------
/java11/javaee_removed_broken/src/main/java/com/example/ws/WSExample.java:
--------------------------------------------------------------------------------
1 | package com.example.ws;
2 |
3 | import javax.xml.ws.Service;
4 |
5 | public class WSExample {
6 | public void service() {
7 | Service calculatorService = Service.create(null);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_badly/src/main/java/com/example/ws/WSExample.java:
--------------------------------------------------------------------------------
1 | package com.example.ws;
2 |
3 | import javax.xml.ws.Service;
4 |
5 | public class WSExample {
6 | public void service() {
7 | Service calculatorService = Service.create(null);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/java16/lombok_broken/src/main/java/com/example/LombokService.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | public class LombokService {
4 | public void hello() {
5 | LombokStudent lombokExample = new LombokStudent("James");
6 | System.out.println(lombokExample.getName());
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_new_package/src/main/java/com/example/ws/WSExample.java:
--------------------------------------------------------------------------------
1 | package com.example.ws;
2 |
3 | import jakarta.xml.ws.Service;
4 |
5 | public class WSExample {
6 | public void service() {
7 | Service calculatorService = Service.create(null);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/multi-release-jar/src/main/java17/com/example/Student.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | public record Student(String firstName) {
4 |
5 | boolean isBlankName() {
6 | return firstName.isBlank();
7 | }
8 |
9 | static String getInfo() {
10 | return "Java record";
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/java11/javaee_removed_broken/src/main/java/com/example/annotation/AnnotationExample.java:
--------------------------------------------------------------------------------
1 | package com.example.annotation;
2 |
3 | import javax.annotation.PostConstruct;
4 |
5 | public class AnnotationExample {
6 | @PostConstruct
7 | private void postConstruct() {
8 | // Executed after construction
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_badly/src/main/java/com/example/transaction/TransactionExample.java:
--------------------------------------------------------------------------------
1 | package com.example.transaction;
2 |
3 | import javax.transaction.TransactionRequiredException;
4 |
5 | public class TransactionExample {
6 |
7 | public void transactionalMethod() throws TransactionRequiredException {
8 | throw new TransactionRequiredException();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/java11/javaee_removed_broken/src/main/java/com/example/transaction/TransactionExample.java:
--------------------------------------------------------------------------------
1 | package com.example.transaction;
2 |
3 | import javax.transaction.TransactionRequiredException;
4 |
5 | public class TransactionExample {
6 |
7 | public void transactionalMethod() throws TransactionRequiredException {
8 | throw new TransactionRequiredException();
9 | }
10 | }
11 |
12 |
13 |
--------------------------------------------------------------------------------
/java11/javaee_removed_broken/src/main/java/com/example/activation/ActivationExample.java:
--------------------------------------------------------------------------------
1 | package com.example.activation;
2 |
3 | import javax.activation.URLDataSource;
4 | import java.net.URL;
5 |
6 | public class ActivationExample {
7 | public void retrieveFromURL(final URL url) {
8 | final URLDataSource dataSource = new URLDataSource(url);
9 | // more code
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/DockerfileJava8:
--------------------------------------------------------------------------------
1 | FROM maven:3.8.1-openjdk-8-slim
2 |
3 | ADD . /javaupgrades
4 | WORKDIR /javaupgrades
5 |
6 | # Cache dependencies
7 | RUN mvn dependency:go-offline --fail-at-end
8 |
9 | # Used to force Docker to always run the commands below the ARG instead of using the cache
10 | ARG DISABLE_CACHE
11 |
12 | RUN mvn compile --offline --fail-at-end -Dmaven.compiler.target=8 -Dmaven.compiler.source=8
13 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_badly/src/main/java/com/example/activation/ActivationExample.java:
--------------------------------------------------------------------------------
1 | package com.example.activation;
2 |
3 | import javax.activation.URLDataSource;
4 | import java.net.URL;
5 |
6 | public class ActivationExample {
7 | public void retrieveFromURL(final URL url) {
8 | final URLDataSource dataSource = new URLDataSource(url);
9 | // more code
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_badly/src/main/java/com/example/annotation/ActivationExample.java:
--------------------------------------------------------------------------------
1 | package com.example.annotation;
2 |
3 | import javax.activation.URLDataSource;
4 | import java.net.URL;
5 |
6 | public class ActivationExample {
7 | public void retrieveFromURL(final URL url) {
8 | final URLDataSource dataSource = new URLDataSource(url);
9 | // more code
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_new_package/src/main/java/com/example/transaction/TransactionExample.java:
--------------------------------------------------------------------------------
1 | package com.example.transaction;
2 |
3 | import jakarta.transaction.TransactionRequiredException;
4 |
5 | public class TransactionExample {
6 |
7 | public void transactionalMethod() throws TransactionRequiredException {
8 | throw new TransactionRequiredException();
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_new_package/src/main/java/com/example/annotation/ActivationExample.java:
--------------------------------------------------------------------------------
1 | package com.example.annotation;
2 |
3 | import jakarta.activation.URLDataSource;
4 | import java.net.URL;
5 |
6 | public class ActivationExample {
7 | public void retrieveFromURL(final URL url) {
8 | final URLDataSource dataSource = new URLDataSource(url);
9 | // more code
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_new_package/src/main/java/com/example/activation/ActivationExample.java:
--------------------------------------------------------------------------------
1 | package com.example.activation;
2 |
3 | import jakarta.activation.URLDataSource;
4 |
5 | import java.net.URL;
6 |
7 | public class ActivationExample {
8 | public void retrieveFromURL(final URL url) {
9 | final URLDataSource dataSource = new URLDataSource(url);
10 | // more code
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/java15/nashorn_broken/src/test/java/com/example/NashornExampleTest.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import javax.script.ScriptException;
6 |
7 | public class NashornExampleTest {
8 |
9 | @Test
10 | public void printHelloWorldTest() throws ScriptException {
11 | NashornExample nashornExample = new NashornExample();
12 | nashornExample.printHelloWorld();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/java15/nashorn_fixed/src/test/java/com/example/NashornExampleTest.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import javax.script.ScriptException;
6 |
7 | public class NashornExampleTest {
8 |
9 | @Test
10 | public void printHelloWorldTest() throws ScriptException {
11 | NashornExample nashornExample = new NashornExample();
12 | nashornExample.printHelloWorld();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/multi-release-jar/src/main/java/com/example/Student.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | public class Student {
4 | final private String firstName;
5 |
6 | public Student(String firstName) {
7 | this.firstName = firstName;
8 | }
9 |
10 | boolean isBlankName() {
11 | return firstName == null || firstName.trim().isEmpty();
12 | }
13 |
14 | static String getInfo() {
15 | return "Java class";
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/java15/nashorn_broken/src/main/java/com/example/NashornExample.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import javax.script.ScriptEngine;
4 | import javax.script.ScriptEngineManager;
5 | import javax.script.ScriptException;
6 |
7 | public class NashornExample {
8 | public void printHelloWorld() throws ScriptException {
9 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
10 | engine.eval("print('Hello World!');");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/java15/nashorn_fixed/src/main/java/com/example/NashornExample.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import javax.script.ScriptEngine;
4 | import javax.script.ScriptEngineManager;
5 | import javax.script.ScriptException;
6 |
7 | public class NashornExample {
8 | public void printHelloWorld() throws ScriptException {
9 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
10 | engine.eval("print('Hello World!');");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG JDK_VERSION=16
2 | FROM maven:3.8.1-openjdk-$JDK_VERSION-slim
3 |
4 | # Without this, the ARG isn't available after the FROM
5 | ARG JDK_VERSION
6 |
7 | ADD . /javaupgrades
8 | WORKDIR /javaupgrades
9 |
10 | # Cache dependencies
11 | RUN mvn test dependency:go-offline --fail-at-end -Dmaven.compiler.release=$JDK_VERSION; exit 0
12 |
13 | # Used to force Docker to always run the commands below the ARG instead of using the cache
14 | ARG DISABLE_CACHE
15 |
16 | RUN mvn test --offline --fail-at-end -Dmaven.compiler.release=$JDK_VERSION
17 |
--------------------------------------------------------------------------------
/java15/nashorn_broken/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java15
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | nashorn_broken
13 |
--------------------------------------------------------------------------------
/java17/mockito_broken/src/test/java/com/example/ExampleEnumTest.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.junit.jupiter.api.extension.ExtendWith;
5 | import org.mockito.Mock;
6 | import org.mockito.junit.jupiter.MockitoExtension;
7 |
8 | import static org.junit.jupiter.api.Assertions.assertNotNull;
9 |
10 | @ExtendWith(MockitoExtension.class)
11 | public class ExampleEnumTest {
12 |
13 | @Mock
14 | private ExampleEnum exampleEnum;
15 |
16 | @Test
17 | public void testEnumWithMethods() {
18 | assertNotNull(exampleEnum);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/java17/mockito_fixed/src/test/java/com/example/ExampleEnumTest.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.junit.jupiter.api.extension.ExtendWith;
5 | import org.mockito.Mock;
6 | import org.mockito.junit.jupiter.MockitoExtension;
7 |
8 | import static org.junit.jupiter.api.Assertions.assertNotNull;
9 |
10 | @ExtendWith(MockitoExtension.class)
11 | public class ExampleEnumTest {
12 |
13 | @Mock
14 | private ExampleEnum exampleEnum;
15 |
16 | @Test
17 | public void testEnumWithMethods() {
18 | assertNotNull(exampleEnum);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/java11/javaee_removed_broken/src/main/java/com/example/bind/JAXBStudent.java:
--------------------------------------------------------------------------------
1 | package com.example.bind;
2 |
3 | import javax.xml.bind.annotation.XmlElement;
4 | import javax.xml.bind.annotation.XmlRootElement;
5 |
6 | @XmlRootElement
7 | public class JAXBStudent {
8 |
9 | String name;
10 |
11 | @XmlElement
12 | public void setName(String name) {
13 | this.name = name;
14 | }
15 |
16 | public String getName() {
17 | return name;
18 | }
19 |
20 | public JAXBStudent() {
21 | }
22 |
23 | public JAXBStudent(String name) {
24 | this.name = name;
25 | }
26 | }
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_badly/src/main/java/com/example/bind/JAXBStudent.java:
--------------------------------------------------------------------------------
1 | package com.example.bind;
2 |
3 | import javax.xml.bind.annotation.XmlElement;
4 | import javax.xml.bind.annotation.XmlRootElement;
5 |
6 | @XmlRootElement
7 | public class JAXBStudent {
8 |
9 | String name;
10 |
11 | @XmlElement
12 | public void setName(String name) {
13 | this.name = name;
14 | }
15 |
16 | public String getName() {
17 | return name;
18 | }
19 |
20 | public JAXBStudent() {
21 | }
22 |
23 | public JAXBStudent(String name) {
24 | this.name = name;
25 | }
26 | }
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_new_package/src/main/java/com/example/bind/JAXBStudent.java:
--------------------------------------------------------------------------------
1 | package com.example.bind;
2 |
3 | import jakarta.xml.bind.annotation.XmlElement;
4 | import jakarta.xml.bind.annotation.XmlRootElement;
5 |
6 | @XmlRootElement
7 | public class JAXBStudent {
8 |
9 | String name;
10 |
11 | @XmlElement
12 | public void setName(String name) {
13 | this.name = name;
14 | }
15 |
16 | public String getName() {
17 | return name;
18 | }
19 |
20 | public JAXBStudent() {
21 | }
22 |
23 | public JAXBStudent(String name) {
24 | this.name = name;
25 | }
26 | }
--------------------------------------------------------------------------------
/multi-release-jar/src/main/java/com/example/Application.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | public class Application {
4 |
5 | public static void main(String[] args) {
6 | System.out.println("Java version " + System.getProperty("java.version"));
7 | System.out.println("Implementation " + Student.getInfo());
8 |
9 | Student studentBlank = new Student(" ");
10 | System.out.println("Student name with one space is blank: " + studentBlank.isBlankName());
11 |
12 | Student student = new Student("James");
13 | System.out.println("Student name James is blank: " + student.isBlankName());
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/multi-release-jar/run-multi-release-application.cmd:
--------------------------------------------------------------------------------
1 | docker run -v /c/Work/JavaUpgrades/multi-release-jar/target:/target eclipse-temurin:8u372-b07-jre-alpine java -jar /target/multi-release-jar-1.0-SNAPSHOT.jar
2 | docker run -v /c/Work/JavaUpgrades/multi-release-jar/target:/target eclipse-temurin:11.0.19_7-jre-alpine java -jar /target/multi-release-jar-1.0-SNAPSHOT.jar
3 | docker run -v /c/Work/JavaUpgrades/multi-release-jar/target:/target eclipse-temurin:17.0.7_7-jre-alpine java -jar /target/multi-release-jar-1.0-SNAPSHOT.jar
4 | docker run -v /c/Work/JavaUpgrades/multi-release-jar/target:/target openjdk:21-slim java -jar /target/multi-release-jar-1.0-SNAPSHOT.jar
5 |
--------------------------------------------------------------------------------
/DockerfileWithFonts:
--------------------------------------------------------------------------------
1 | ARG JDK_VERSION=16
2 | FROM maven:3.6.3-openjdk-$JDK_VERSION-slim
3 |
4 | # Without this, the ARG isn't available after the FROM
5 | ARG JDK_VERSION
6 |
7 | ADD . /javaupgrades
8 | WORKDIR /javaupgrades
9 |
10 | # Cache dependencies
11 | RUN mvn dependency:go-offline --fail-at-end -Dmaven.compiler.release=$JDK_VERSION
12 |
13 | # Used to force Docker to always run the commands below the ARG instead of using the cache
14 | ARG DISABLE_CACHE
15 |
16 | # Adding fonts as Java no longer includes them by default on Java 11
17 | RUN apt-get update
18 | RUN apt install fontconfig -y
19 |
20 | RUN mvn test --offline --fail-at-end -Dmaven.compiler.release=$JDK_VERSION
21 |
--------------------------------------------------------------------------------
/java11/removed_fonts/src/main/java/removedfonts/FontExample.java:
--------------------------------------------------------------------------------
1 | package removedfonts;
2 |
3 | import org.apache.poi.xssf.streaming.SXSSFSheet;
4 | import org.apache.poi.xssf.streaming.SXSSFWorkbook;
5 |
6 | // https://www.basis.com/content/kb-removal-fonts-jdk-11
7 | // https://dzone.com/articles/the-font-of-all-knowledge-about-java-and-fonts
8 | // https://wiki.openjdk.java.net/pages/viewpage.action?pageId=17957183
9 | public class FontExample {
10 | public void createWorkBook() {
11 | SXSSFWorkbook workbook = new SXSSFWorkbook(-1);
12 | SXSSFSheet sheet = workbook.createSheet("testsheet");
13 | }
14 |
15 | {
16 | SXSSFWorkbook workbook = new SXSSFWorkbook(-1);
17 | SXSSFSheet sheet = workbook.createSheet("testsheet");
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/java11/javaee_removed_broken/src/main/java/com/example/bind/JAXBService.java:
--------------------------------------------------------------------------------
1 | package com.example.bind;
2 |
3 | import javax.xml.bind.JAXBContext;
4 | import javax.xml.bind.JAXBException;
5 | import javax.xml.bind.Marshaller;
6 | import java.io.StringWriter;
7 |
8 | public class JAXBService {
9 | public String convertToXML() throws JAXBException {
10 | JAXBStudent jaxbStudent = new JAXBStudent("Mike");
11 |
12 | JAXBContext context = JAXBContext.newInstance(JAXBStudent.class);
13 | Marshaller marshaller = context.createMarshaller();
14 | marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
15 | StringWriter stringWriter = new StringWriter();
16 | marshaller.marshal(jaxbStudent, stringWriter );
17 | return stringWriter.toString();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/java15/nashorn_fixed/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java15
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | nashorn_fixed
13 |
14 |
15 |
16 | org.openjdk.nashorn
17 | nashorn-core
18 | 15.4
19 |
20 |
21 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_badly/src/main/java/com/example/bind/JAXBService.java:
--------------------------------------------------------------------------------
1 | package com.example.bind;
2 |
3 | import javax.xml.bind.JAXBContext;
4 | import javax.xml.bind.JAXBException;
5 | import javax.xml.bind.Marshaller;
6 | import java.io.StringWriter;
7 |
8 | public class JAXBService {
9 | public String convertToXML() throws JAXBException {
10 | JAXBStudent jaxbStudent = new JAXBStudent("Mike");
11 |
12 | JAXBContext context = JAXBContext.newInstance(JAXBStudent.class);
13 | Marshaller marshaller = context.createMarshaller();
14 | marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
15 | StringWriter stringWriter = new StringWriter();
16 | marshaller.marshal(jaxbStudent, stringWriter );
17 | return stringWriter.toString();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/java11/removed_fonts/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java11
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | removed_fonts_broken_on_Java11
13 |
14 |
15 |
16 | org.apache.poi
17 | poi-ooxml
18 | 4.1.2
19 |
20 |
21 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_new_package/src/main/java/com/example/bind/JAXBService.java:
--------------------------------------------------------------------------------
1 | package com.example.bind;
2 |
3 | import jakarta.xml.bind.JAXBContext;
4 | import jakarta.xml.bind.JAXBException;
5 | import jakarta.xml.bind.Marshaller;
6 |
7 | import java.io.StringWriter;
8 |
9 | public class JAXBService {
10 | public String convertToXML() throws JAXBException {
11 | JAXBStudent jaxbStudent = new JAXBStudent("Mike");
12 |
13 | JAXBContext context = JAXBContext.newInstance(JAXBStudent.class);
14 | Marshaller marshaller = context.createMarshaller();
15 | marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
16 | StringWriter stringWriter = new StringWriter();
17 | marshaller.marshal(jaxbStudent, stringWriter );
18 | return stringWriter.toString();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | 4.0.0
6 |
7 | com.example
8 | javaupgrades
9 | pom
10 | 1.0-SNAPSHOT
11 |
12 | java11
13 | java15
14 | java16
15 | multi-release-jar
16 | java17
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/java16/lombok_broken/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java16
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | lombok_broken
13 |
14 |
15 |
16 | org.projectlombok
17 | lombok
18 | 1.18.18
19 | provided
20 |
21 |
22 |
--------------------------------------------------------------------------------
/java16/lombok_fixed/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java16
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | lombok_fixed
13 |
14 |
15 |
16 | org.projectlombok
17 | lombok
18 | 1.18.20
19 | provided
20 |
21 |
22 |
--------------------------------------------------------------------------------
/java11/javaee_removed_broken/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java11
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | javaee_removed_broken
13 |
14 |
15 | org.apache.poi
16 | poi-ooxml
17 | 4.1.2
18 |
19 |
20 | org.junit.jupiter
21 | junit-jupiter-api
22 | 5.7.0
23 | test
24 |
25 |
26 |
--------------------------------------------------------------------------------
/java11/removed_fonts/src/test/java/removedfonts/FontExampleTest.java:
--------------------------------------------------------------------------------
1 | package removedfonts;
2 |
3 | import org.apache.poi.ss.usermodel.Row;
4 | import org.apache.poi.ss.usermodel.Sheet;
5 | import org.apache.poi.ss.usermodel.Workbook;
6 | import org.apache.poi.xssf.usermodel.XSSFWorkbook;
7 | import org.junit.jupiter.api.Test;
8 |
9 | import java.awt.*;
10 | import java.io.IOException;
11 |
12 |
13 | public class FontExampleTest {
14 | @Test
15 | public void testCreateWorkBook() {
16 | FontExample fontExample = new FontExample();
17 | fontExample.createWorkBook();
18 | }
19 |
20 | @Test
21 | public void listFonts() {
22 | String[] names = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
23 |
24 | System.out.println("Found " + names.length + " fonts:");
25 |
26 | for (String name : names) {
27 | System.out.println(name);
28 | }
29 | }
30 |
31 | @Test
32 | public void testExample() {
33 | final Workbook workbook = new XSSFWorkbook();
34 | final Sheet sheet = workbook.createSheet("Asset requests");
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/java17/mockito_broken/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java17
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | mockito_broken
13 |
14 |
15 | 5.7.2
16 | 3.11.0
17 |
18 |
19 |
20 |
21 | org.junit.jupiter
22 | junit-jupiter
23 | ${junit.jupiter.version}
24 | test
25 |
26 |
27 | org.mockito
28 | mockito-junit-jupiter
29 | ${mockito.version}
30 | test
31 |
32 |
33 |
--------------------------------------------------------------------------------
/java17/mockito_fixed/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java17
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | mockito_fixed
13 |
14 |
15 | 5.7.2
16 | 3.11.2
17 |
18 |
19 |
20 |
21 | org.junit.jupiter
22 | junit-jupiter
23 | ${junit.jupiter.version}
24 | test
25 |
26 |
27 | org.mockito
28 | mockito-junit-jupiter
29 | ${mockito.version}
30 | test
31 |
32 |
33 |
--------------------------------------------------------------------------------
/java16/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | com.example
7 | 1.0-SNAPSHOT
8 | java16
9 | pom
10 |
11 |
12 | lombok_broken
13 | lombok_fixed
14 |
15 |
16 |
17 | 16
18 |
19 |
20 |
21 |
22 |
23 | org.apache.maven.plugins
24 | maven-compiler-plugin
25 | 3.11.0
26 |
27 | ${maven.compiler.release}
28 |
29 |
30 |
31 | org.apache.maven.plugins
32 | maven-dependency-plugin
33 | 3.5.0
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/java17/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | com.example
7 | 1.0-SNAPSHOT
8 | 4.0.0
9 | pom
10 | java17
11 |
12 |
13 | mockito_broken
14 | mockito_fixed
15 |
16 |
17 |
18 | 17
19 | 3.11.0
20 | 3.0.0
21 |
22 |
23 |
24 |
25 |
26 | org.apache.maven.plugins
27 | maven-compiler-plugin
28 | ${maven-compiler-plugin.version}
29 |
30 | ${maven.compiler.release}
31 |
32 |
33 |
34 | org.apache.maven.plugins
35 | maven-surefire-plugin
36 | ${maven-surefire-plugin.version}
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/java15/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | com.example
6 | 1.0-SNAPSHOT
7 | 4.0.0
8 | pom
9 | java15
10 |
11 |
12 | nashorn_broken
13 | nashorn_fixed
14 |
15 |
16 |
17 | 11
18 |
19 |
20 |
21 |
22 | org.junit.jupiter
23 | junit-jupiter
24 | 5.7.0
25 | test
26 |
27 |
28 |
29 |
30 |
31 | org.apache.maven.plugins
32 | maven-compiler-plugin
33 | 3.8.1
34 |
35 | ${maven.compiler.release}
36 |
37 |
38 |
39 | org.apache.maven.plugins
40 | maven-surefire-plugin
41 | 3.0.0-M5
42 |
43 |
44 | org.apache.maven.plugins
45 | maven-dependency-plugin
46 | 3.1.2
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/java11/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | com.example
6 | 1.0-SNAPSHOT
7 | 4.0.0
8 | pom
9 | java11
10 |
11 |
12 | javaee_removed_broken
13 | javaee_removed_fixed_badly
14 | javaee_removed_fixed_new_package
15 | removed_fonts
16 |
17 |
22 |
23 |
24 | org.junit.jupiter
25 | junit-jupiter
26 | 5.9.2
27 | test
28 |
29 |
30 |
31 |
32 |
33 | org.apache.maven.plugins
34 | maven-compiler-plugin
35 | 3.11.0
36 |
37 | ${maven.compiler.release}
38 |
39 |
40 |
41 | org.apache.maven.plugins
42 | maven-surefire-plugin
43 | 3.0.0
44 |
45 |
46 | org.apache.maven.plugins
47 | maven-dependency-plugin
48 | 3.3.0
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_badly/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java11
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | javaee_removed_fixed_badly
13 |
14 |
15 |
16 |
17 | javax.xml.bind
18 | jaxb-api
19 | 2.3.1
20 |
21 |
22 | org.glassfish.jaxb
23 | jaxb-runtime
24 | 2.3.1
25 |
26 |
27 |
28 |
29 | com.sun.activation
30 | javax.activation
31 | 1.2.0
32 |
33 |
34 |
35 |
36 | javax.annotation
37 | javax.annotation-api
38 | 1.3.2
39 |
40 |
41 |
42 |
43 | javax.transaction
44 | javax.transaction-api
45 | 1.3
46 |
47 |
48 |
49 |
50 | javax.xml.ws
51 | jaxws-api
52 | 2.3.1
53 |
54 |
55 | com.sun.xml.ws
56 | jaxws-rt
57 | 2.3.3
58 |
59 |
60 |
--------------------------------------------------------------------------------
/java11/javaee_removed_fixed_new_package/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | java11
7 | com.example
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | javaee_removed_fixed_new_package
13 |
14 |
15 |
16 |
17 | jakarta.xml.bind
18 | jakarta.xml.bind-api
19 | 3.0.0
20 |
21 |
22 | org.glassfish.jaxb
23 | jaxb-runtime
24 | 3.0.0
25 | runtime
26 |
27 |
28 |
29 |
30 | com.sun.activation
31 | jakarta.activation
32 | 2.0.1
33 |
34 |
35 |
36 |
37 | jakarta.annotation
38 | jakarta.annotation-api
39 | 2.0.0
40 |
41 |
42 |
43 |
44 | jakarta.transaction
45 | jakarta.transaction-api
46 | 2.0.0
47 |
48 |
49 |
50 |
51 | jakarta.xml.ws
52 | jakarta.xml.ws-api
53 | 3.0.0
54 |
55 |
56 | com.sun.xml.ws
57 | jaxws-rt
58 | 3.0.0
59 |
60 |
61 |
--------------------------------------------------------------------------------
/multi-release-jar/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | com.example
7 | 1.0-SNAPSHOT
8 | multi-release-jar
9 |
10 |
11 | 17
12 | 17
13 |
14 |
15 |
16 |
17 |
18 | org.apache.maven.plugins
19 | maven-compiler-plugin
20 | 3.11.0
21 |
22 |
23 | compile-java-8
24 |
25 | compile
26 |
27 |
28 | 1.8
29 | 1.8
30 |
31 |
32 |
33 | compile-java-17
34 | compile
35 |
36 | compile
37 |
38 |
39 | 17
40 |
41 | ${project.basedir}/src/main/java17
42 |
43 | true
44 |
45 |
46 |
47 |
48 |
49 | org.apache.maven.plugins
50 | maven-jar-plugin
51 | 3.3.0
52 |
53 |
54 |
55 | true
56 |
57 |
58 | com.example.Application
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/java,maven,intellij
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=java,maven,intellij
4 |
5 | ### Intellij ###
6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
8 |
9 | # User-specific stuff
10 | .idea/**/workspace.xml
11 | .idea/**/tasks.xml
12 | .idea/**/usage.statistics.xml
13 | .idea/**/dictionaries
14 | .idea/**/shelf
15 |
16 | # Generated files
17 | .idea/**/contentModel.xml
18 |
19 | # Sensitive or high-churn files
20 | .idea/**/dataSources/
21 | .idea/**/dataSources.ids
22 | .idea/**/dataSources.local.xml
23 | .idea/**/sqlDataSources.xml
24 | .idea/**/dynamic.xml
25 | .idea/**/uiDesigner.xml
26 | .idea/**/dbnavigator.xml
27 |
28 | # Gradle
29 | .idea/**/gradle.xml
30 | .idea/**/libraries
31 |
32 | # Gradle and Maven with auto-import
33 | # When using Gradle or Maven with auto-import, you should exclude module files,
34 | # since they will be recreated, and may cause churn. Uncomment if using
35 | # auto-import.
36 | # .idea/artifacts
37 | # .idea/compiler.xml
38 | # .idea/jarRepositories.xml
39 | # .idea/modules.xml
40 | # .idea/*.iml
41 | # .idea/modules
42 | # *.iml
43 | # *.ipr
44 |
45 | # CMake
46 | cmake-build-*/
47 |
48 | # Mongo Explorer plugin
49 | .idea/**/mongoSettings.xml
50 |
51 | # File-based project format
52 | *.iws
53 |
54 | # IntelliJ
55 | out/
56 |
57 | # mpeltonen/sbt-idea plugin
58 | .idea_modules/
59 |
60 | # JIRA plugin
61 | atlassian-ide-plugin.xml
62 |
63 | # Cursive Clojure plugin
64 | .idea/replstate.xml
65 |
66 | # Crashlytics plugin (for Android Studio and IntelliJ)
67 | com_crashlytics_export_strings.xml
68 | crashlytics.properties
69 | crashlytics-build.properties
70 | fabric.properties
71 |
72 | # Editor-based Rest Client
73 | .idea/httpRequests
74 |
75 | # Android studio 3.1+ serialized cache file
76 | .idea/caches/build_file_checksums.ser
77 |
78 | ### Intellij Patch ###
79 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
80 |
81 | # *.iml
82 | # modules.xml
83 | # .idea/misc.xml
84 | # *.ipr
85 |
86 | # Sonarlint plugin
87 | # https://plugins.jetbrains.com/plugin/7973-sonarlint
88 | .idea/**/sonarlint/
89 |
90 | # SonarQube Plugin
91 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
92 | .idea/**/sonarIssues.xml
93 |
94 | # Markdown Navigator plugin
95 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
96 | .idea/**/markdown-navigator.xml
97 | .idea/**/markdown-navigator-enh.xml
98 | .idea/**/markdown-navigator/
99 |
100 | # Cache file creation bug
101 | # See https://youtrack.jetbrains.com/issue/JBR-2257
102 | .idea/$CACHE_FILE$
103 |
104 | # CodeStream plugin
105 | # https://plugins.jetbrains.com/plugin/12206-codestream
106 | .idea/codestream.xml
107 |
108 | ### Java ###
109 | # Compiled class file
110 | *.class
111 |
112 | # Log file
113 | *.log
114 |
115 | # BlueJ files
116 | *.ctxt
117 |
118 | # Mobile Tools for Java (J2ME)
119 | .mtj.tmp/
120 |
121 | # Package Files #
122 | *.jar
123 | *.war
124 | *.nar
125 | *.ear
126 | *.zip
127 | *.tar.gz
128 | *.rar
129 |
130 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
131 | hs_err_pid*
132 |
133 | ### Maven ###
134 | target/
135 | pom.xml.tag
136 | pom.xml.releaseBackup
137 | pom.xml.versionsBackup
138 | pom.xml.next
139 | release.properties
140 | dependency-reduced-pom.xml
141 | buildNumber.properties
142 | .mvn/timing.properties
143 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar
144 | .mvn/wrapper/maven-wrapper.jar
145 | .flattened-pom.xml
146 |
147 | # End of https://www.toptal.com/developers/gitignore/api/java,maven,intellij
148 | **.iml
149 | **.idea/
150 |
151 | .project
152 | .settings
153 | .classpath
154 | .factorypath
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Java upgrade example errors and solutions
2 | This project shows the errors encountered during a Java upgrade and the necessary fixes.
3 |
4 | Per Java version there is a Maven module to show what went wrong starting in that version and how it can be fixed.
5 |
6 | This project uses Maven, however the issues will be the same with other buildtools.
7 |
8 | This readme first describes the issues and solutions for Java in general and then for each specific Java version. After that the various ways to run multiple JDK's on one machine are described.
9 |
10 | The last part also describes how to run the examples. For instance the Java 15 examples work on Java 14. When run on Java 15 the broken examples will fail, while the fixed ones will succeed.
11 |
12 | # Upgrading Java automatically
13 | [OpenRewrite](https://docs.openrewrite.org/) offers various recipes to upgrade your application automatically and even improve your code. It will make the changes locally and then you can decide if you want to commit all of them, or if you want to make changes. Using OpenRewrite can save a lot of time, compared to upgrading manually.
14 |
15 | Some of the recipes they provide:
16 | - [Migrate to Java 17](https://docs.openrewrite.org/running-recipes/popular-recipe-guides/migrate-to-java-17)
17 | - [Migrate from JUnit 4 to JUnit 5](https://docs.openrewrite.org/running-recipes/popular-recipe-guides/migrate-from-junit-4-to-junit-5)
18 |
19 |
20 | # Java general challenges
21 | This document describes the bigger changes of Java. There are many more (smaller) items of Java removed. This chapter lists the various categories which were removed. For detailed information, please look at the release notes:
22 |
23 | Java release notes
24 | - [Java 10](https://www.oracle.com/java/technologies/javase/10-relnote-issues.html)
25 | - [Java 11](https://www.oracle.com/java/technologies/javase/11-relnote-issues.html)
26 | - [Java 12](https://www.oracle.com/java/technologies/javase/12-relnote-issues.html)
27 | - [Java 13](https://www.oracle.com/java/technologies/javase/13-relnote-issues.html)
28 | - [Java 14](https://www.oracle.com/java/technologies/javase/14-relnote-issues.html)
29 | - [Java 15](https://www.oracle.com/java/technologies/javase/15-relnote-issues.html)
30 | - [Java 16](https://www.oracle.com/java/technologies/javase/16-relnote-issues.html)
31 | - [Java 17](https://www.oracle.com/java/technologies/javase/17-relnote-issues.html)
32 |
33 | Security roadmap
34 | - [Oracle JRE and JDK Cryptographic Roadmap](https://java.com/en/jre-jdk-cryptoroadmap.html)
35 |
36 | OpenJDK features
37 | - [Java 9](https://openjdk.java.net/projects/jdk9/)
38 | - [Java 10](https://openjdk.java.net/projects/jdk/10/)
39 | - [Java 11](https://openjdk.java.net/projects/jdk/11/)
40 | - [Java 12](https://openjdk.java.net/projects/jdk/12/)
41 | - [Java 13](https://openjdk.java.net/projects/jdk/13/)
42 | - [Java 14](https://openjdk.java.net/projects/jdk/14/)
43 | - [Java 15](https://openjdk.java.net/projects/jdk/15/)
44 | - [Java 16](https://openjdk.java.net/projects/jdk/16/)
45 | - [Java 17](https://openjdk.java.net/projects/jdk/17/)
46 | - [Java 21](https://openjdk.java.net/projects/jdk/21/)
47 |
48 | ## Removal of VM flags/options
49 | For instance
50 | ```bash
51 | -XX:+AggressiveOpts
52 | ```
53 | and
54 | ```bash
55 | -Xoptimize
56 | ```
57 |
58 | ## Removed (root) certificates
59 | "The T-Systems Deutsche Telekom Root CA 2 certificate has expired and was removed from the cacerts keystore"
60 |
61 | ## Removed encryption algorithms
62 | Algorithms deemed unsafe are removed.
63 |
64 | ## Removed garbage collectors
65 | For instance the Concurrent Mark and Sweep (CMS) garbage collector was removed in 14.
66 |
67 | ## Removed from API
68 | Parts of the API such as methods can be deprecated and later removed.
69 |
70 | It's possible to see the deprecated and removed parts of the API per Java version. For instance via the [The Java Version Almanac](https://javaalmanac.io/) or via [foojay](https://foojay.io/almanac/jdk-16/)
71 |
72 | ## Removed tools
73 | Some are no longer available, others such as JDK Mission Control and JavaFX now are available as separate builds from various vendors.
74 |
75 | Some JDK's such as ojdkbuild and some builds of Liberica JDK still offer a JDK which includes some of the tools.
76 |
77 |
78 | # Issues and solutions per Java version
79 | ## Java 11
80 | ### JEP 320: Remove the Java EE and CORBA Modules
81 | The EE packages were removed in Java 11. If you still need them, you can add them as Maven/Gradle dependencies.
82 |
83 | **Please be aware that you should use the new jakarta packages as the old packages are no longer updated.**
84 |
85 | For instance JAXB can be added with the dependency listed below. However, it's no longer updated, the latest version is 2.3.0.
86 | ```xml
87 |
88 | javax.xml.bind
89 | jaxb-api
90 | 2.3.0
91 |
92 | ```
93 | You should instead use the Jakarta dependency which has the newer 3.0.0 version.
94 | ```xml
95 |
96 | jakarta.xml.bind
97 | jakarta.xml.bind-api
98 | 3.0.0
99 |
100 | ```
101 | #### Removal of javax.activation
102 |
103 | ##### Example error
104 | *Example code can be found under java11/javaee_removed_broken*
105 |
106 | ```bash
107 | package javax.activation does not exist
108 | ```
109 | ```bash
110 | cannot find symbol
111 | [ERROR] symbol: class URLDataSource
112 | ```
113 | ##### Solution
114 | *Example code can be found under java11/javaee_removed_fixed_new_package*
115 |
116 | Add the necessary dependencies:
117 | ```xml
118 |
119 | com.sun.activation
120 | jakarta.activation
121 | 2.0.1
122 |
123 | ```
124 | #### Removal of javax.annotation
125 |
126 | ##### Example error
127 | *Example code can be found under java11/javaee_removed_broken*
128 |
129 | ```bash
130 | package javax.annotation does not exist
131 | ```
132 | ```bash
133 | cannot find symbol
134 | [ERROR] symbol: class PostConstruct
135 | ```
136 | ##### Solution
137 | *Example code can be found under java11/javaee_removed_fixed_new_package*
138 |
139 | Add the necessary dependencies:
140 | ```xml
141 |
142 | jakarta.annotation
143 | jakarta.annotation-api
144 | 2.0.0
145 |
146 | ```
147 | #### Removal of javax.transaction
148 |
149 | ##### Example error
150 | *Example code can be found under java11/javaee_removed_broken*
151 |
152 | ```bash
153 | package javax.transaction does not exist
154 | ```
155 | ```bash
156 | cannot find symbol
157 | [ERROR] symbol: class TransactionRequiredException
158 | ```
159 | ##### Solution
160 | *Example code can be found under java11/javaee_removed_fixed_new_package*
161 |
162 | Add the necessary dependencies:
163 | ```xml
164 |
165 | jakarta.transaction
166 | jakarta.transaction-api
167 | 2.0.0
168 |
169 | ```
170 |
171 | #### Removal of javax.xml.bind
172 | ##### Example error
173 | *Example code can be found under java11/javaee_removed_broken*
174 |
175 | ```bash
176 | package javax.xml.bind.annotation does not exist
177 | ```
178 | ```bash
179 | cannot find symbol
180 | [ERROR] symbol: class XmlRootElement
181 | ```
182 | ```bash
183 | cannot find symbol
184 | [ERROR] symbol: class JAXBException
185 | ```
186 | ##### Solution
187 | *Example code can be found under java11/javaee_removed_fixed_new_package*
188 |
189 | Add the necessary dependencies:
190 |
191 | For the API there's:
192 | ```xml
193 |
194 | jakarta.xml.bind
195 | jakarta.xml.bind-api
196 | 3.0.0
197 |
198 | ```
199 |
200 | For the implementation there are a few options listed below. If you already use one of them as a transitive dependency then it's probably best to use that one to avoid conflicts.
201 |
202 | The following command can be used to check if you already use one of the implementations via a transitive dependency:
203 | ```bash
204 | mvn dependency:tree -Dincludes=org.glassfish.jaxb:jaxb-runtime
205 | mvn dependency:tree -Dincludes=com.sun.xml.bind:jaxb-impl
206 | ```
207 |
208 | If you don't have a JAXB implementation as a transitive dependency then it's probably best to use the following Glassfish implementation.
209 | ```xml
210 |
211 | org.glassfish.jaxb
212 | jaxb-runtime
213 | 3.0.0
214 | runtime
215 |
216 | ```
217 | Or the jaxb-impl which is now called the [Old JAXB Runtime](https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl)
218 | ```xml
219 |
220 | com.sun.xml.bind
221 | jaxb-impl
222 | 3.0.0
223 |
224 | ```
225 |
226 |
227 | #### Removal of javax.jws javax.xml.soap javax.xml.ws
228 |
229 | ##### Example error
230 | *Example code can be found under java11/javaee_removed_broken*
231 |
232 | ```bash
233 | package javax.xml.ws does not exist
234 | ```
235 | ```bash
236 | cannot find symbol
237 | [ERROR] symbol: class Service
238 | ```
239 | ##### Solution
240 | *Example code can be found under java11/javaee_removed_fixed_new_package*
241 |
242 | Add the necessary dependencies:
243 | ```xml
244 |
245 | jakarta.xml.ws
246 | jakarta.xml.ws-api
247 | 3.0.0
248 |
249 |
250 | com.sun.xml.ws
251 | jaxws-rt
252 | 3.0.0
253 |
254 | ```
255 | #### Removal of Corba javax.activity javax.rmi.*
256 | There's no official replacement/dependency released for Corba
257 | #### Solution
258 | Migrate away from Corba or use something like glassfish-corba
259 |
260 | ### Font removal
261 | The JDK contained some fonts, but they were removed in Java 11. If the application used these fonts and the operating system doesn't provide them, then an error occurs.
262 |
263 | More info from [Azul](https://www.azul.com/the-font-of-all-knowledge-about-java-and-fonts/) and [AdoptOpenJDK](https://blog.adoptopenjdk.net/2021/01/prerequisites-for-font-support-in-adoptopenjdk/)
264 |
265 | #### Example errors
266 | *Example code can be found under java11/removed_fonts*
267 |
268 | ```bash
269 | java.lang.UnsatisfiedLinkError: /usr/local/openjdk-11/lib/libfontmanager.so:
270 | libfreetype.so.6: cannot open shared object file: No such file or directory
271 | ```
272 |
273 | ```bash
274 | java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager
275 | ```
276 |
277 | #### Solution
278 | *Example code can be found in DockerfileWithFonts*
279 |
280 | Install the necessary fonts, for instance with:
281 | ```
282 | apt install fontconfig
283 | ```
284 |
285 | Depending on your [scenario](https://blog.adoptopenjdk.net/2021/01/prerequisites-for-font-support-in-adoptopenjdk/) you might need to add some extra packages such as: libfreetype6 fontconfig fonts-dejavu.
286 |
287 | Some JDK's automatically install the needed packages.
288 |
289 | ### JavaFX removal
290 | JavaFX is removed from the JDK and continued as OpenJFX.
291 |
292 | Some vendors offer builds of OpenJFX such as [Gluon](https://gluonhq.com/products/javafx/)
293 |
294 | Some vendors offer JDK builds which include OpenJFX such as [Liberica's full version](https://bell-sw.com/pages/products/) and [ojdkbuild](https://github.com/ojdkbuild/ojdkbuild/wiki/Motivation)
295 |
296 | Use the (Maven) dependencies of [OpenJFX](https://openjfx.io/)
297 |
298 | ### Java Mission Control (JMC) removed
299 | Use one of the builds of JDK Mission control:
300 | - [Oracle](https://www.oracle.com/java/technologies/jdk-mission-control.html)
301 | - [AdoptOpenJDK](https://adoptopenjdk.net/jmc.html)
302 |
303 | ## Java 15
304 | ### JEP 372: Remove the Nashorn JavaScript Engine
305 | Nashorn is no longer included in the standard JDK.
306 |
307 | #### Example errors
308 | *Example code can be found under java15/nashorn_broken*
309 |
310 | ```bash
311 | java.lang.NullPointerException: Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null
312 | ```
313 |
314 | #### Solution
315 | *Example code can be found under java15/nashorn_fixed*
316 |
317 | Add the necessary dependencies:
318 | ```xml
319 |
320 | org.openjdk.nashorn
321 | nashorn-core
322 | 15.4
323 |
324 | ```
325 |
326 | ## Java 16
327 | ### JEP 396: Strongly Encapsulate JDK Internals by Default
328 | Internals of the JDK can no longer be used by default. This mainly impacts tooling which uses low level features of the JDK.
329 |
330 | #### Example errors
331 | *Example code can be found under java16/lombok_broken*
332 |
333 | ```bash
334 | [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project broken: Fatal error compiling: java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor (in unnamed module @0x21bd20ee) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing to unnamed module @0x21bd20ee -> [Help 1]
335 | ```
336 |
337 | #### Solution
338 | *Example code can be found under java16/lombok_fixed*
339 |
340 | Preferably use a new version of the dependency which causes the issue. For instance Lombok 1.18.20 includes support for Java 16:
341 | ```xml
342 |
343 | org.projectlombok
344 | lombok
345 | 1.18.20
346 | provided
347 |
348 | ```
349 |
350 | If there's no new dependency available it's possible to open up the JDK internals, so they can be used. However, this is not the prettiest solution:
351 | ```xml
352 |
353 | org.apache.maven.plugins
354 | maven-compiler-plugin
355 | 3.8.1
356 |
357 | true
358 |
359 | -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
360 | -J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
361 | -J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
362 | -J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
363 | -J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
364 | -J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
365 | -J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
366 | -J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
367 | -J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED
368 |
369 |
370 |
371 | ```
372 |
373 | ## Java 17
374 |
375 | ### Gradle
376 | - Update to Gradle 7.3 to get Java 17 [support](https://github.com/gradle/gradle/issues/16857)
377 | - Update to Kotlin 1.6.0 to be able to set jvmTarget to 17
378 |
379 | ### JEP 403: Strongly Encapsulate JDK Internals
380 | Launcher option --illegal-access no longer works to access internal JDK API's.
381 |
382 | #### Example errors
383 | ```bash
384 | java.lang.reflect.InaccessibleObjectException: Unable to make … accessible: module java.base does not "opens …" to unnamed module …
385 | ```
386 | #### Solution
387 | - If triggered by a dependency, upgrade the dependency
388 | - Refactor code to no longer use internal JDK API's
389 | - As a last resort use ```--add-opens``` for instance:
390 | ```xml
391 |
392 | org.apache.maven.plugins
393 | maven-surefire-plugin
394 |
395 |
396 | --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED
397 |
398 |
399 |
400 | ```
401 |
402 | ### JEP ?
403 |
404 | Mockito raises an exception when Mocking an enum which uses methods in values, such as for example:
405 | ```java
406 | public enum ExampleEnum {
407 | TEST {
408 | public String retrieve() {
409 | return "test";
410 | }
411 | };
412 | }
413 | ```
414 | ```java
415 | @ExtendWith(MockitoExtension.class)
416 | public class ExampleEnumTest {
417 |
418 | @Mock
419 | private ExampleEnum exampleEnum;
420 |
421 | @Test
422 | public void testEnumWithMethods() {
423 | assertNotNull(exampleEnum);
424 | }
425 | }
426 | ```
427 |
428 | #### Example errors
429 | *Example code can be found under java17/mockito_fixed*
430 |
431 | ```bash
432 | org.mockito.exceptions.base.MockitoException:
433 |
434 | Mockito cannot mock this class: class com.example.ExampleEnum.
435 |
436 | If you're not sure why you're getting this error, please report to the mailing list.
437 |
438 |
439 | Java : 17
440 | JVM vendor name : Oracle Corporation
441 | JVM vendor version : 17-ea+24-2164
442 | JVM name : OpenJDK 64-Bit Server VM
443 | JVM version : 17-ea+24-2164
444 | JVM info : mixed mode, sharing
445 | OS name : Linux
446 | OS version : 4.19.76-linuxkit
447 |
448 |
449 | You are seeing this disclaimer because Mockito is configured to create inlined mocks.
450 | You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.
451 |
452 | Underlying exception : org.mockito.exceptions.base.MockitoException: Could not modify all classes [class com.example.ExampleEnum, interface java.lang.constant.Constable, class java.lang.Object, interface java.lang.Comparable, interface java.io.Serializable, class java.lang.Enum]
453 | Caused by: org.mockito.exceptions.base.MockitoException: Could not modify all classes [class com.example.ExampleEnum, interface java.lang.constant.Constable, class java.lang.Object, interface java.lang.Comparable, interface java.io.Serializable, class java.lang.Enum]
454 | Caused by: java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the class NestHost, NestMembers, Record, or PermittedSubclasses attribute
455 | ```
456 |
457 | #### Solution
458 | Not yet available, see issue in [Mockito GitHub](https://github.com/mockito/mockito/issues/2315) repo, which mentions a workaround.
459 |
460 | ## Java 21
461 | #### Example errors
462 | EqualsVerifier via Bytebuddy
463 | ```bash
464 | -> Java 21 (65) is not supported by the current version of Byte Buddy which officially supports Java 20 (64) - update Byte Buddy or set net.bytebuddy.experimental as a VM property
465 | ```
466 |
467 | #### Solution
468 | Upgrade to a version of Bytebuddy which supports Java 21 or use the workaround:
469 | ```xml
470 |
471 | org.apache.maven.plugins
472 | maven-surefire-plugin
473 |
474 | -Dnet.bytebuddy.experimental=true
475 |
476 |
477 | ```
478 |
479 | ## All Java versions
480 | #### Example errors
481 | ```bash
482 | An error has occurred in JaCoCo Aggregate report generation. Error while creating report: Error while analyzing … Unsupported class file major version X
483 | ```
484 | ```bash
485 | Execution default of goal org.pitest:pitest-maven:1.4.10:mutationCoverage failed: Unsupported class file major version 61
486 | ```
487 | ```bash
488 | Execution repackage of goal org.springframework.boot:spring-boot-maven-plugin:2.2.10.RELEASE:repackage failed: Unsupported class file major version 61
489 | ```
490 | #### Solution
491 | The class file major version 61 is used for Java 17. Make sure your plugins/dependencies are up to date and support Java 17.
492 |
493 | - Update your plugins/dependencies
494 |
495 |
496 | # Running multiple JDK's on one machine
497 |
498 | ## Set JAVA_HOME before running an example
499 | The value of `JAVA_HOME` is used by Maven to select the JDK.
500 |
501 | Display the current `JAVA_HOME`
502 | ```bash
503 | echo $JAVA_HOME
504 | C:\Program Files\AdoptOpenJDK\jdk-16.0.0.36-hotspot
505 | ```
506 |
507 | Set `JAVA_HOME` to another JDK:
508 | ```bash
509 | JAVA_HOME="[location of JDK]"
510 | ```
511 |
512 | Then use the following Maven command inside one of the Java directories (java11, java16...) to build all submodules and continue when something goes wrong:
513 | ```bash
514 | mvn compile --fail-at-end -Dmaven.compiler.release=[Specify JDK version. Don't use this on Java 8 as it's not supported]
515 | ```
516 | Or the shorter version:
517 | ```bash
518 | mvn compile -fae -Dmaven.compiler.release=[Specify JDK version. Don't use this on Java 8 as it's not supported]
519 | ```
520 | The version of the script for Java 8
521 | ```bash
522 | mvn compile -fae -Dmaven.compiler.target=8 -Dmaven.compiler.source=8
523 | ```
524 | Or change the Maven releases in the `pom.xml`:
525 | ```xml
526 |
527 | 7
528 |
529 | ```
530 |
531 | ## Using Docker containers
532 | Then use the following Docker command inside one of the Java directories (java11, java16...):
533 |
534 | Change the JDK_VERSION to whatever version (11 or greater) you want:
535 | ```shell script
536 | docker build -t javaupgrades -f ..\Dockerfile --build-arg DISABLE_CACHE="%date%-%time%" --build-arg JDK_VERSION=17 --progress=plain .
537 | ```
538 |
539 | Or to build on Java 8, which requires a different configuration:
540 | ```shell script
541 | docker build -t javaupgrades -f ..\DockerfileJava8 --build-arg DISABLE_CACHE="%date%-%time%" .
542 | ```
543 |
544 |
545 | ## Maven Toolchains
546 | Maven Toolchains can be used to configure the JDK's present on your machine and then select one to use in the `pom.xml` of the project.
547 |
548 | First create a `toolchains.xml` located in *${user.home}/.m2/*
549 |
550 | ```xml
551 |
552 |
553 |
554 | jdk
555 |
556 | 8
557 |
558 |
559 | /path/to/jdk/8
560 |
561 |
562 |
563 | jdk
564 |
565 | 11
566 |
567 |
568 | /path/to/jdk/11
569 |
570 |
571 |
572 | jdk
573 |
574 | 16
575 |
576 |
577 | /path/to/jdk/16
578 |
579 |
580 |
581 | jdk
582 |
583 | 17
584 |
585 |
586 | /path/to/jdk/16
587 |
588 |
589 |
590 | ```
591 |
592 | Then in the `pom.xml` configure which JDK from the toolchains.xml you want to use:
593 | ```xml
594 |
595 |
596 |
597 | org.apache.maven.plugins
598 | maven-toolchains-plugin
599 | 3.0.0
600 |
601 |
602 |
603 | ${maven.compiler.release}
604 |
605 |
606 |
607 |
608 |
609 |
610 | toolchain
611 |
612 |
613 |
614 |
615 |
616 |
617 | ```
618 |
619 | Make sure to update the Maven Compiler Plugin. When using an older version, combined with the Toolchains Plugin, the errors are not really detailed:
620 | ```shell script
621 | [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project broken: Compilation failure -> [Help 1]
622 | ```
623 |
624 | When using a newer version of the Maven Compiler Plugin the error message provides more detailed information:
625 | ```shell script
626 | [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile (default-compile) on project lombok_broken: Compilation failure
627 | [ERROR] java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor (in unnamed module @...) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironme
628 | nt (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing to unnamed module @...
629 | ```
630 |
631 | # Interesting other things
632 |
633 | ## Multi release JAR
634 | Multi release JAR's make it possible to create one JAR file which supports multiple Java versions for backward compatibility.
635 |
636 | This example uses records and ```String.isBlank()``` which was introduced in Java 11. The example has two main directories:
637 | - src/main/java used on Java versions below Java 17
638 | - src/main/java17 used by Java version 17 and above
639 |
640 | The JAR file for this example should be build on Java 17 and can then be used on various Java versions.
641 |
642 | The following command can be used to build the examples on Java 17 and then run them on 8, 11 and 17:
643 | ```shell script
644 | mvn package
645 | run-multi-release-application.cmd
646 | # docker build -t multi-release-jar --build-arg DISABLE_CACHE="%date%-%time%" --progress=plain .
647 | ```
648 |
649 | Make sure your code for all Java versions contains the same public API's, else you might run into runtime issues. IntelliJ checks this and Java 17 now [contains](https://github.com/openjdk/jdk/pull/3971) the ```jar --validate``` option to verify a JAR file. Build tools like Maven don't verify it automatically.
650 |
--------------------------------------------------------------------------------