I am working on a Java application (a Spring Boot application). On my Ubuntu development machine I have used this JDK version:
andrea@ubuntu:~$ java --version
java 17 2021-09-14 LTS
Java(TM) SE Runtime Environment (build 17 35-LTS-2724)
Java HotSpot(TM) 64-Bit Server VM (build 17 35-LTS-2724, mixed mode, sharing)
This is the pom.xml file of my Spring Boot application:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.notariato</groupId>
<artifactId>UpdateInfoBatch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>UpdateInfoBatch</name>
<description>Recupera ed aggiorna le informazioni relative alla lista dei notai ed ai distretti notarili</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.4.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
I obtained the .jar application and I have no problem running it on my development machine.
The problem happened when I tried to move this .jar file on the production machine.
Here the Java version is the following one:
webadmin@webadmin.spaccount.it [~/java/jre1.8.0_311/bin]# ./java -version
java version "1.8.0_311"
Java(TM) SE Runtime Environment (build 1.8.0_311-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.311-b11, mixed mode)
webadmin@webadmin.spaccount.it [~/java/jre1.8.0_311/bin]#
So, as you can see, here the JAVA version seems to be the 1.8.0_311
Running my application I obtained this error message:
webadmin@webadmin.spaccount.it [~/java/jre1.8.0_311/bin]# ./java -jar /home/webadmin/notartel-import-data-batch/UpdateInfoBatch-0.0.1-SNAPSHOT.jar
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/notariato/updateInfo/UpdateInfoBatchApplication has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:473)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:46)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
It seems that the installed JRE is too old. I was trying to manually download the JRE package for JAVA 17 but I cannot find it.
What version of the JRE have I to use? Where can I download this JRE package version? (not with the yum package manager, I need to download the tar file containing the JRE and then extract it on my system).
Thank you
CodePudding user response:
Traditional JREs no longer exist since Java 9 (although some vendors offer JRE-like packages). In order to get a Java runtime to run your application you can use the jlink
tool, which also comes with JDK 17, like this for a modular application:
jlink -p <directory app jar> --add-modules <name of your module> --output custom_runtime
If your application is non-modular, you will have to find out which modules you need, for instance using jdeps
(also a tool that comes with JDK 17):
$ mvn dependency:build-classpath -DincludeScope=runtime -Dmdep.outputFile=cp.txt
$ jdeps -classpath "<contents of cp.txt>" --multi-release 17 --print-module-deps --ignore-missing-deps <app jar>
Which prints something like mod1,mod2,mod3
. Pass them to the --add-modules
flag instead:
jlink --add-modules mod1,mod2,mod3 --output custom_runtime
This will generate a custom_runtime
folder with a Java runtime you can use to run your app, which can then be deployed on the target machine.
If your app is non-modular you will also have to deploy the app .jar
file, and all of it's dependencies (there should be no external runtime dependencies for a Spring Boot project, since it bundles all dependencies in the app jar). Then, use the java
executable in the custom runtime to run the app:
/path/to/custom/runtime/java -jar <app jar>