# spring-native-app **Repository Path**: arch-builder/spring-native-app ## Basic Information - **Project Name**: spring-native-app - **Description**: A Spring native app based on graalvm jdk17. - **Primary Language**: Java - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-15 - **Last Updated**: 2025-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # spring-native-app ## build native 使用 graalvm jdk 尝试将 spring-boot3 编译为可执行文件,目前纯 spring 部分可以成功编译运行,但是带 mybatis 则无法运行。 构建环境: - graalvm: oracle graalvm jdk21 - gcc: gcc15 编译过程比较消耗 CPU 和内存,可详见构建日志 empty-server.txt 以及 mini-server.txt。 ```bash mvn clean -DskipTests native:compile -Pnative ``` 代码库中包含两个模块: - empty-server 仅包含 spring-boot3 - mini-server 包含一个运行样例 mini-server 运行日志: ```plaintext ## ## _oo0oo_ ## o8888888o ## 88" . "88 ## (| -_- |) ## 0\ = /0 ## ___/`---'\___ ## .' \\| |// '. ## / \\||| : |||// \ ## / _||||| -:- |||||- \ ## | | \\\ - /// | | ## | \_| ''\---/'' |_/ | ## \ .-\__ '-' ___/-. / ## ___'. .' /--.--\ `. .'___ ## ."" '< `.___\_<|>_/___.' >' "". ## | | : `- \`.;`\ _ /`;.`/ - ` : | | ## \ \ `_. \_ __\ /__ _/ .-` / / ## =====`-.____`.___ \_____/___.-`___.-'===== ## `=---=' ## ## ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## ## 佛祖保佑 永不宕机 永无BUG ## 2025-08-24 18:41:09,062 [main] [DEBUG] | AbstractEnvironment.addActiveProfile(313) | - | Activating profile 'native' 2025-08-24 18:41:09,062 [main] [INFO] | StartupInfoLogger.logStarting(53) | - | Starting AOT-processed NativeApp using Java 21.0.8 with PID 8273 (/data/ezio/Projects/Java/spring-native-app/mini-server/target/mini-server started by ezio in /data/ezio/Projects/Java/spring-native-app/mini-server) 2025-08-24 18:41:09,062 [main] [INFO] | SpringApplication.logStartupProfileInfo(658) | - | The following 1 profile is active: "native" 2025-08-24 18:41:09,062 [main] [DEBUG] | AbstractApplicationContext.prepareRefresh(674) | - | Refreshing org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext@63d82d9b 2025-08-24 18:41:09,075 [main] [DEBUG] | DocumentRoot.getArchiveFileDocumentRoot(81) | - | Code archive: /data/ezio/Projects/Java/spring-native-app/mini-server/target/mini-server 2025-08-24 18:41:09,075 [main] [DEBUG] | DocumentRoot.getExplodedWarFileDocumentRoot(125) | - | Code archive: /data/ezio/Projects/Java/spring-native-app/mini-server/target/mini-server 2025-08-24 18:41:09,075 [main] [DEBUG] | DocumentRoot.logNoDocumentRoots(149) | - | None of the document roots [src/main/webapp, public, static] point to a directory and will be ignored. 2025-08-24 18:41:09,076 [main] [INFO] | TomcatWebServer.initialize(111) | - | Tomcat initialized with port 8009 (http) 2025-08-24 18:41:09,076 [main] [INFO] | DirectJDKLog.log(168) | - | Initializing ProtocolHandler ["http-nio-8009"] 2025-08-24 18:41:09,077 [main] [INFO] | DirectJDKLog.log(168) | - | Starting service [Tomcat] 2025-08-24 18:41:09,077 [main] [INFO] | DirectJDKLog.log(168) | - | Starting Servlet engine: [Apache Tomcat/10.1.43] 2025-08-24 18:41:09,083 [main] [INFO] | DirectJDKLog.log(168) | - | Initializing Spring embedded WebApplicationContext 2025-08-24 18:41:09,083 [main] [DEBUG] | ServletWebServerApplicationContext.prepareWebApplicationContext(295) | - | Published root WebApplicationContext as ServletContext attribute with name [org.springframework.web.context.WebApplicationContext.ROOT] 2025-08-24 18:41:09,083 [main] [INFO] | ServletWebServerApplicationContext.prepareWebApplicationContext(301) | - | Root WebApplicationContext: initialization completed in 21 ms 2025-08-24 18:41:09,085 [main] [DEBUG] | ServletContextInitializerBeans.logMappings(254) | - | Mapping filters: characterEncodingFilter urls=[/*] order=-2147483648, formContentFilter urls=[/*] order=-9900, requestContextFilter urls=[/*] order=-105 2025-08-24 18:41:09,085 [main] [DEBUG] | ServletContextInitializerBeans.logMappings(254) | - | Mapping servlets: dispatcherServlet urls=[/] 2025-08-24 18:41:09,085 [main] [DEBUG] | GenericFilterBean.init(240) | - | Filter 'requestContextFilter' configured for use 2025-08-24 18:41:09,086 [main] [DEBUG] | GenericFilterBean.init(240) | - | Filter 'characterEncodingFilter' configured for use 2025-08-24 18:41:09,086 [main] [DEBUG] | GenericFilterBean.init(240) | - | Filter 'formContentFilter' configured for use _ _ |_ _ _|_. ___ _ | _ | | |\/|_)(_| | |_\ |_)||_|_\ / | 3.5.5 2025-08-24 18:41:09,119 [main] [DEBUG] | AbstractHandlerMethodMapping.handlerMethodsInitialized(366) | - | 5 mappings in 'requestMappingHandlerMapping' 2025-08-24 18:41:09,125 [main] [DEBUG] | SimpleUrlHandlerMapping.logMappings(187) | - | Patterns [/webjars/**, /**] in 'resourceHandlerMapping' 2025-08-24 18:41:09,126 [main] [DEBUG] | RequestMappingHandlerAdapter.initControllerAdviceCache(666) | - | ControllerAdvice beans: 0 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 1 ResponseBodyAdvice 2025-08-24 18:41:09,127 [main] [DEBUG] | ExceptionHandlerExceptionResolver.initExceptionHandlerAdviceCache(336) | - | ControllerAdvice beans: 0 @ExceptionHandler, 1 ResponseBodyAdvice 2025-08-24 18:41:09,134 [main] [INFO] | DirectJDKLog.log(168) | - | Starting ProtocolHandler ["http-nio-8009"] 2025-08-24 18:41:09,134 [main] [INFO] | TomcatWebServer.start(243) | - | Tomcat started on port 8009 (http) with context path '/spring-native-app' 2025-08-24 18:41:09,135 [main] [INFO] | StartupInfoLogger.logStarted(59) | - | Started NativeApp in 0.083 seconds (process running for 0.086) 2025-08-24 18:41:09,135 [main] [DEBUG] | ApplicationAvailabilityBean.onApplicationEvent(77) | - | Application availability state LivenessState changed to CORRECT 2025-08-24 18:41:09,135 [main] [DEBUG] | ApplicationAvailabilityBean.onApplicationEvent(77) | - | Application availability state ReadinessState changed to ACCEPTING_TRAFFIC 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [INFO] | DirectJDKLog.log(168) | - | Initializing Spring DispatcherServlet 'dispatcherServlet' 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [INFO] | FrameworkServlet.initServletBean(532) | - | Initializing Servlet 'dispatcherServlet' 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [DEBUG] | DispatcherServlet.initMultipartResolver(533) | - | Detected StandardServletMultipartResolver 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [DEBUG] | DispatcherServlet.initLocaleResolver(557) | - | Detected AcceptHeaderLocaleResolver 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [DEBUG] | DispatcherServlet.initThemeResolver(583) | - | Detected FixedThemeResolver 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [DEBUG] | DispatcherServlet.initRequestToViewNameTranslator(733) | - | Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@44d29a5f 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [DEBUG] | DispatcherServlet.initFlashMapManager(797) | - | Detected org.springframework.web.servlet.support.SessionFlashMapManager@45af659c 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [DEBUG] | FrameworkServlet.initServletBean(549) | - | enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [INFO] | FrameworkServlet.initServletBean(554) | - | Completed initialization in 0 ms 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [DEBUG] | LogFormatUtils.traceDebug(120) | - | POST "/spring-native-app/user/register", parameters={} 2025-08-24 18:41:12,829 [http-nio-8009-exec-1] [DEBUG] | AbstractHandlerMapping.getHandler(533) | - | Mapped to org.example.app.web.UserController#updateUser(UserBO) 2025-08-24 18:41:12,830 [http-nio-8009-exec-1] [DEBUG] | LogFormatUtils.traceDebug(120) | - | Read "application/json;charset=utf-8" to [UserBO(name=admin, email=email7@xxx.com, phone=12345678)] 2025-08-24 18:41:12,832 [http-nio-8009-exec-1] [INFO] | HikariDataSource.getConnection(109) | - | rd_ddl - Starting... 2025-08-24 18:41:12,837 [http-nio-8009-exec-1] [INFO] | HikariPool.checkFailFast(580) | - | rd_ddl - Added connection org.postgresql.jdbc.PgConnection@510e1a62 2025-08-24 18:41:12,837 [http-nio-8009-exec-1] [INFO] | HikariDataSource.getConnection(122) | - | rd_ddl - Start completed. 2025-08-24 18:41:12,916 [http-nio-8009-exec-1] [DEBUG] | AbstractMessageConverterMethodProcessor.writeWithMessageConverters(310) | - | Using 'application/json', given [*/*] and supported [application/json, application/*+json] 2025-08-24 18:41:12,917 [http-nio-8009-exec-1] [DEBUG] | LogFormatUtils.traceDebug(120) | - | Writing [{"code":0,"data":true,"msg":"Success"}] 2025-08-24 18:41:12,917 [http-nio-8009-exec-1] [DEBUG] | FrameworkServlet.logResult(1138) | - | Completed 200 OK ``` ## build and run image ```bash sudo nerdctl build -t mini-server:v0.0.1 . ``` ```plaintext [+] Building 9.8s (10/10) [+] Building 10.0s (10/10) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 204B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build context 1.1s => => transferring context: 114.03MB 1.1s => CACHED [1/6] ADD alpine-minirootfs-3.22.0-x86_64.tar.gz / 0.0s => [2/6] RUN pwd 1.1s => [3/6] RUN mkdir -p /app 0.2s => [4/6] RUN cd /app 0.2s => [5/6] WORKDIR /app 0.1s => [6/6] COPY target/mini-server /app/ 1.0s => exporting to docker image format 5.9s => => exporting layers 5.0s => => exporting manifest sha256:e679ad487a7bd09f7fdc43abd590b2f5e53df60bc76a10d15005af101b51751a 0.0s => => exporting config sha256:e762452a403383fd7097829846d097a01ae2f40ba3830a4a6c285839593b35d8 0.0s => => sending tarball 0.9s Loaded image: docker.io/library/mini-server:v0.0.1 ``` Run image: ```bash sudo ctr run -d --net-host docker.io/library/mini-server:v0.0.1 mini-server ``` Delete image: ```bash sudo ctr images rm docker.io/library/mini-server:v0.0.1 ``` Delete container: ```bash sudo ctr container delete mini-server ``` List task: ```bash sudo ctr task ls ```