├── .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 | --------------------------------------------------------------------------------