简体   繁体   English

Java 模块 - 简单 Spring 引导应用程序,创建自定义运行时

[英]Java Modules - Simple Spring Boot application, create custom runtime

I created a simple Spring Boot application using start.spring.io with Maven , Java 19 , Spring Boot 3.0我使用start.spring.ioMavenJava 19Spring Boot 3.0创建了一个简单的Spring Boot应用程序

I added just one additional dependency, commons-lang3我只添加了一个额外的依赖项, 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>

When NetBeans 15 builds the project, there is a target folder containing the jar file demo-0.0.1-SNAPSHOT.jar NetBeans 15构建工程时,有一个target文件夹包含jar文件demo-0.0.1-SNAPSHOT.jar

I can run that jar with我可以运行 jar

java -jar target/demo-0.0.1-SNAPSHOT.jar

I can see my output and the Spring Boot logo and it terminates.我可以看到我的 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)

The main class is simple主要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);
    }

}

Now I want to create a minimized custom runtime image with jlink to run that jar file with it.现在我想用 jlink 创建一个最小化的自定义运行时图像来运行那个jlink文件。

I found this article https://medium.com/azulsystems/using-jlink-to-build-java-runtimes-for-non-modular-applications-9568c5e70ef4 but cannot figure it out.我找到这篇文章https://medium.com/azulsystems/using-jlink-to-build-java-runtimes-for-non-modular-applications-9568c5e70ef4但无法弄清楚。

With jdeps I get some not fully understandable output使用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

I understand that the application uses the Java modules java.base and java.logging , but sometimes not found and sometimes the jar file are give as modules.我知道该应用程序使用 Java 模块java.basejava.logging ,但有时not found ,有时 jar 文件作为模块提供。

Trying jlink like像尝试jlink

jlink --module-path $JAVA_HOME/jmods --add-modules java.base,java.logging --output mycustomrt

creates the custom runtime image, but running it with创建自定义运行时图像,但运行它

mycustomrt/bin/java -jar target/demo-0.0.1-SNAPSHOT.jar

results in结果是

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

The jlink command seems not to be fully correct, don't know how to specify it correctly. jlink命令似乎不完全正确,不知道如何正确指定。

Looking into the demo-0.0.1-SNAPSHOT.jar file I see that all necessary jars are查看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/...

Can you try with adding this as vm argument:您可以尝试将其添加为 vm 参数吗:

--add-modules java.xml,java.sql,java.prefs,java.desktop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring 启动应用程序中的 Java 运行时错误 - Java runtime error in Spring Boot application 在 java spring 引导应用程序运行期间从资源文件夹创建和访问 zip 文件 - Create and access zip file from resource folder during runtime in java spring boot application 简单的弹簧启动应用程序不起作用 - Simple spring boot application not works 创建简单作业 spring 启动 - Create a simple job spring boot Java Spring 引导自定义属性在 application.yml 中不起作用 - Java Spring Boot custom properties dont work in application.yml 如何在Spring Boot Java应用程序中提高自定义异常的可读性 - How to improve readability of custom exceptions in a Spring Boot Java application 在 spring 启动 java 应用程序中调用自定义 Rest 模板 - Calling Custom Rest Template in spring boot java application 关于在 Hibernate Java Spring 启动应用程序中自动创建表 - About auto create table in Hibernate Java Spring boot application 在 Java Spring Boot 中创建并返回自定义 Http 响应代码 - Create and Return a custom Http response code in Java Spring Boot 为 Z1D78DC8ED51214E5018B5114AE24 创建自定义 java json spring 引导解析器<string, integer></string,> - Create custom java json spring boot parser for map<string, integer>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM