[英]Java Modules - Simple Spring Boot application, create custom runtime
我使用start.spring.io
和Maven
、 Java 19
、 Spring Boot 3.0
創建了一個簡單的Spring Boot
應用程序
我只添加了一個額外的依賴項, commons-lang3
pom.xml
<?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>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>19</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
NetBeans 15
構建工程時,有一個target
文件夾包含jar文件demo-0.0.1-SNAPSHOT.jar
我可以運行 jar
java -jar target/demo-0.0.1-SNAPSHOT.jar
我可以看到我的 output 和Spring Boot
標志,它終止了。
java -jar target/demo-0.0.1-SNAPSHOT.jar
MIX
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.0)
2022-11-30T19:47:53.468+01:00 INFO 18179 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT using Java 19.0.1 with PID 18179 (/home/me/NetBeansProjects/demo/target/demo-0.0.1-SNAPSHOT.jar started by neblaz in /home/me/NetBeansProjects/demo)
2022-11-30T19:47:53.470+01:00 INFO 18179 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2022-11-30T19:47:54.131+01:00 INFO 18179 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.172 seconds (process running for 1.666)
主要class很簡單
package com.example.demo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
String mix = "MIX";
if (StringUtils.isNoneBlank(mix)) {
System.out.println(mix);
}
SpringApplication.run(DemoApplication.class, args);
}
}
現在我想用 jlink 創建一個最小化的自定義運行時圖像來運行那個jlink
文件。
我找到這篇文章https://medium.com/azulsystems/using-jlink-to-build-java-runtimes-for-non-modular-applications-9568c5e70ef4但無法弄清楚。
使用jdeps
我得到一些不完全理解的 output
jdeps target/demo-0.0.1-SNAPSHOT.jar
demo-0.0.1-SNAPSHOT.jar -> java.base
demo-0.0.1-SNAPSHOT.jar -> java.logging
demo-0.0.1-SNAPSHOT.jar -> not found
com.example.demo -> java.io java.base
com.example.demo -> java.lang java.base
com.example.demo -> org.apache.commons.lang3 not found
com.example.demo -> org.springframework.boot not found
com.example.demo -> org.springframework.boot.autoconfigure not found
com.example.demo -> org.springframework.context not found
org.springframework.boot.loader -> java.io java.base
org.springframework.boot.loader -> java.lang java.base
org.springframework.boot.loader -> java.lang.invoke java.base
org.springframework.boot.loader -> java.lang.reflect java.base
org.springframework.boot.loader -> java.net java.base
org.springframework.boot.loader -> java.nio.charset java.base
org.springframework.boot.loader -> java.security java.base
org.springframework.boot.loader -> java.util java.base
org.springframework.boot.loader -> java.util.function java.base
org.springframework.boot.loader -> java.util.jar java.base
org.springframework.boot.loader -> java.util.regex java.base
org.springframework.boot.loader -> java.util.stream java.base
org.springframework.boot.loader -> java.util.zip java.base
org.springframework.boot.loader -> org.springframework.boot.loader.archive demo-0.0.1-SNAPSHOT.jar
org.springframework.boot.loader -> org.springframework.boot.loader.jar demo-0.0.1-SNAPSHOT.jar
org.springframework.boot.loader -> org.springframework.boot.loader.util demo-0.0.1-SNAPSHOT.jar
org.springframework.boot.loader.archive -> java.io java.base
org.springframework.boot.loader.archive -> java.lang java.base
org.springframework.boot.loader.archive -> java.lang.invoke java.base
org.springframework.boot.loader.archive -> java.net java.base
org.springframework.boot.loader.archive -> java.nio.file java.base
org.springframework.boot.loader.archive -> java.nio.file.attribute java.base
org.springframework.boot.loader.archive -> java.util java.base
org.springframework.boot.loader.archive -> java.util.function java.base
org.springframework.boot.loader.archive -> java.util.jar java.base
org.springframework.boot.loader.archive -> java.util.zip java.base
org.springframework.boot.loader.archive -> org.springframework.boot.loader.jar demo-0.0.1-SNAPSHOT.jar
org.springframework.boot.loader.data -> java.io java.base
org.springframework.boot.loader.data -> java.lang java.base
org.springframework.boot.loader.jar -> java.io java.base
org.springframework.boot.loader.jar -> java.lang java.base
org.springframework.boot.loader.jar -> java.lang.invoke java.base
org.springframework.boot.loader.jar -> java.lang.ref java.base
org.springframework.boot.loader.jar -> java.lang.reflect java.base
org.springframework.boot.loader.jar -> java.net java.base
org.springframework.boot.loader.jar -> java.nio.charset java.base
org.springframework.boot.loader.jar -> java.security java.base
org.springframework.boot.loader.jar -> java.security.cert java.base
org.springframework.boot.loader.jar -> java.time java.base
org.springframework.boot.loader.jar -> java.time.temporal java.base
org.springframework.boot.loader.jar -> java.util java.base
org.springframework.boot.loader.jar -> java.util.concurrent java.base
org.springframework.boot.loader.jar -> java.util.function java.base
org.springframework.boot.loader.jar -> java.util.jar java.base
org.springframework.boot.loader.jar -> java.util.logging java.logging
org.springframework.boot.loader.jar -> java.util.regex java.base
org.springframework.boot.loader.jar -> java.util.stream java.base
org.springframework.boot.loader.jar -> java.util.zip java.base
org.springframework.boot.loader.jar -> org.springframework.boot.loader.data demo-0.0.1-SNAPSHOT.jar
org.springframework.boot.loader.jarmode -> java.io java.base
org.springframework.boot.loader.jarmode -> java.lang java.base
org.springframework.boot.loader.jarmode -> java.lang.invoke java.base
org.springframework.boot.loader.jarmode -> java.util java.base
org.springframework.boot.loader.jarmode -> org.springframework.core.io.support not found
org.springframework.boot.loader.jarmode -> org.springframework.util not found
org.springframework.boot.loader.util -> java.io java.base
org.springframework.boot.loader.util -> java.lang java.base
org.springframework.boot.loader.util -> java.lang.invoke java.base
org.springframework.boot.loader.util -> java.util java.base
我知道該應用程序使用 Java 模塊java.base
和java.logging
,但有時not found
,有時 jar 文件作為模塊提供。
像嘗試jlink
jlink --module-path $JAVA_HOME/jmods --add-modules java.base,java.logging --output mycustomrt
創建自定義運行時圖像,但運行它
mycustomrt/bin/java -jar target/demo-0.0.1-SNAPSHOT.jar
結果是
19:08:07.912 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
java.lang.NoClassDefFoundError: java/beans/PropertyEditorSupport
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1013)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:149)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at org.springframework.boot.context.properties.bind.BindConverter$TypeConverterConverter.<clinit>(BindConverter.java:180)
at org.springframework.boot.context.properties.bind.BindConverter$TypeConverterConversionService.<init>(BindConverter.java:157)
at org.springframework.boot.context.properties.bind.BindConverter.<init>(BindConverter.java:63)
at org.springframework.boot.context.properties.bind.BindConverter.getSharedInstance(BindConverter.java:133)
at org.springframework.boot.context.properties.bind.BindConverter.get(BindConverter.java:126)
at org.springframework.boot.context.properties.bind.Binder.<init>(Binder.java:190)
at org.springframework.boot.context.properties.bind.Binder.<init>(Binder.java:160)
at org.springframework.boot.context.properties.bind.Binder.<init>(Binder.java:139)
at org.springframework.boot.context.properties.bind.Binder.get(Binder.java:531)
at org.springframework.boot.context.properties.bind.Binder.get(Binder.java:516)
at org.springframework.boot.context.config.ConfigDataEnvironment.<init>(ConfigDataEnvironment.java:141)
at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.getConfigDataEnvironment(ConfigDataEnvironmentPostProcessor.java:101)
at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:96)
at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:89)
at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:109)
at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:94)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131)
at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81)
at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:352)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
at com.example.demo.DemoApplication.main(DemoApplication.java:18)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:95)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
Caused by: java.lang.ClassNotFoundException: java.beans.PropertyEditorSupport
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:149)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 49 common frames omitted
jlink
命令似乎不完全正確,不知道如何正確指定。
查看demo-0.0.1-SNAPSHOT.jar
文件,我發現所有必要的 jars 都是
BOOT-INF
classpath.idx
layers.idx
lib/commons-lang3-3.12.0.jar
lib/spring-boot-3.0.0.jar
lib/...
您可以嘗試將其添加為 vm 參數嗎:
--add-modules java.xml,java.sql,java.prefs,java.desktop
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.