SpringBoot 瘦身Jar + Java Service Wrapper 部署为 Windows 系统服务(踩坑全记录)


一、前言

日常开发中 SpringBoot 项目打包后直接用 java -jar 运行,关闭 CMD 窗口程序就停止,无法后台常驻。本文采用 Java Service Wrapper 将项目注册为 Windows 系统服务,同时实现 Jar 包瘦身(分离依赖、配置文件),并解决服务注册权限、类找不到、日志行数限制等一系列实战踩坑问题。

环境说明:

  • 🖥️ 系统:Windows 10 / Windows 11
  • ☕ JDK:1.8
  • 🍃 框架:SpringBoot
  • 🔧 工具:Java Service Wrapper 3.5.14

二、项目 Jar 包瘦身(分离依赖 & 配置)

传统 SpringBoot 可执行 Jar 会把所有依赖、配置全部打进一个包,体积大、更新麻烦,这里做目录拆分。

2.1 最终目录结构

F:\test\gasMonitorTwo          # 项目根目录
├─ gas-monitor.jar             # 瘦身之后的主程序Jar(仅业务代码)
├─ lib                         # 所有第三方依赖Jar + wrapper.jar
├─ resources                   # 项目配置文件(application.yml/properties)
├─ logs                        # 日志目录(手动新建)
└─ wrapper.conf                # Wrapper核心配置文件

F:\test\wrapper_3.5.14_src\bin # Wrapper工具目录
└─ wrapper.exe、wrapper.dll    # 服务启动/注册程序

2.2 瘦身打包思路

  1. 正常打包 SpringBoot 完整 Jar;
  2. 解压完整 Jar,将 BOOT-INF/lib 下所有依赖 Jar 拷贝到项目 lib 目录;
  3. BOOT-INF/classes 下所有配置文件(yml/properties)拷贝到 resources 目录;
  4. 剔除原 Jar 中依赖与配置,保留纯业务代码,得到瘦身主 Jar gas-monitor.jar

三、wrapper.conf 完整配置

3.1 完整配置文件

wrapper.ntservice.name=gasMonitorTwo
# Java Application
#wrapper.java.command=java

wrapper.java.command=C:\Program Files\Java\jdk1.8.0_131\bin\java.exe

# Java Main class.  This class must implement the WrapperListener interface
#  or guarantee that the WrapperManager class is initialized.
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

# Java Classpath (include wrapper.jar)  Add class path elements as
#  needed starting from 1
wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=F:\test\gasMonitorTwo\gas-monitor.jar
wrapper.java.classpath.3=F:\test\gasMonitorTwo\lib\*.jar
wrapper.java.classpath.4=F:\test\gasMonitorTwo\resources

# Java Library Path (location of Wrapper.DLL or libwrapper.so)
wrapper.java.library.path.1=../lib

# Application parameters.  Add parameters as needed starting from 1
#wrapper.app.parameter.1=org.springframework.boot.loader.JarLauncher
wrapper.app.parameter.1=com.gas.monitor.GasMonitorApplication

# Initial Java Heap Size (in MB)
wrapper.java.initmemory=3

# Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=512

# Title to use when running as a console
wrapper.console.title=DataExchange Application

# Log file to use for wrapper output logging.
wrapper.logfile=F:\test\gasMonitorTwo\wrapperlogs\wrapper.log

# Log Level for wrapper output logging.
wrapper.logfile.loglevel=INFO

# 日志滚动配置(关键)
wrapper.logfile.rollmode=SIZE
wrapper.logfile.maxsize=1MB
wrapper.logfile.maxfiles=1
wrapper.logfile.linecount=1000

# Log file to use for application output logging.
wrapper.java.logfile=F:\test\gasMonitorTwo\wrapperlogs\application.log

# Log Level for application output logging.
wrapper.java.logfile.loglevel=INFO

1.不要在配置文件中任何的注释,不然启动的时候容易报如,
在这里插入图片描述
2.为了复用wrapper,所以必须在wrapper里面每一个服务配置一次不同的日志路径,wrapper.logfile和wrapper.java.logfile从新配置过

3.对于项目gasMonitorTwo 运行在yml配置的日志啊,要写绝对路径,不然全部的日志就会跑到wrapper的bin目录下了,因为是wrapper运行,如下修改

logging:
  file:
    path: F:\test\gasMonitorTwo\logs   # ← 新增,可修改为任意绝对/相对路径

3.2 关键配置说明

  1. wrapper.app.parameter.1
    瘦身项目下必须填写项目自身 SpringBoot 主启动类全限定名,不要使用 org.springframework.boot.loader.JarLauncher,瘦身 Jar 下该类会报 ClassNotFoundException。如果不是瘦身项目就填org.springframework.boot.loader.JarLauncher

  2. classpath
    依次加载 wrapper.jar、主 Jar、全部依赖、resources 配置目录,保证类和配置正常加载。

  3. 日志限制
    wrapper.logfile.linecount=100 实现日志文件只保留最新 100 行,防止日志无限膨胀。


四、前台测试运行(先验证程序可用性)

注册服务前必须先前台启动测试,排除代码、依赖、配置问题。

  1. 管理员身份打开 CMD;
  2. 跨盘符进入 Wrapper bin 目录:
F:
cd F:\test\wrapper_3.5.14_src\bin
  1. 前台启动命令:
wrapper.exe -c "F:\test\gasMonitorTwo\wrapper.conf"

正常输出日志、项目正常启动、接口可访问,说明配置无误,再进行服务注册。


五、Windows 系统服务注册、启停、删除

5.1 问题说明

直接使用 wrapper.exe -i 注册服务大概率出现 拒绝访问 (0x5) 权限错误,推荐使用 Windows 原生 sc 命令注册服务,兼容性更强、权限问题更少。

5.2 创建(注册)系统服务

管理员 CMD 执行:

sc create gasMonitorTwo binPath= "F:\test\wrapper_3.5.14_src\bin\wrapper.exe -s \"F:\test\gasMonitorTwo\wrapper.conf\"" type= own start= auto displayname= "gasMonitorTwo 气体监测服务"

⚠️ 注意:binPath= 后面必须带一个空格,引号成对书写。

  • start= auto:设置为开机自启
  • displayname:服务在系统服务列表显示的名称

出现 [SC] 创建服务成功 即为注册完成。

5.3 启动服务

net start gasMonitorTwo

5.4 停止服务

net stop gasMonitorTwo

5.5 删除(卸载)服务

修改配置、重新注册前,先停止再删除:

net stop gasMonitorTwo
sc delete gasMonitorTwo

出现 [SC] DeleteService 成功 表示服务已彻底移除。


六、核心踩坑总结(高频问题)

6.1 报错 ClassNotFoundException: JarLauncher

  • 原因:瘦身 Jar 移除了 SpringBoot 内置加载器,JarLauncher 找不到。
  • 解决wrapper.app.parameter.1 改为项目自身 SpringBoot 主启动类全类名。

6.2 wrapper.exe -i 注册服务 拒绝访问 (0x5)

  • 原因:系统权限、杀毒软件 / 防火墙拦截、目录权限不足。
  • 解决:放弃 wrapper.exe -i,改用 Windows 原生 sc create 命令注册服务。

6.3 CMD 无法切换跨盘符目录

  • 错误写法
cd F:\test\wrapper_3.5.14_src\bin
  • 正确写法(先切盘符,再切目录):
F:
cd F:\test\wrapper_3.5.14_src\bin

6.4 日志文件无限增大

  • 解决:在配置中增加 linecount 限制行数,配合 rollmode 做日志滚动:
wrapper.logfile.linecount=100
wrapper.logfile.rollmode=SIZE
wrapper.logfile.maxsize=1MB
wrapper.logfile.maxfiles=1

6.5 服务启动后瞬间停止

  1. 检查 logs 目录是否手动创建;
  2. 查看 wrapper.logapplication.log 具体异常堆栈;
  3. 核对 lib 目录是否缺失依赖 Jar;
  4. 核对 resources 目录配置文件路径。

七、window查看日志实时输出的方法,必须要使用

windows PowerShell 实时查看日志文件内容:

Get-Content "F:\test\gasMonitorTwo\logs\gas-monitor.log" -Tail 100 -Wait -Encoding UTF8

八、下载相应系统的wrapper

https://download.tanukisoftware.com/wrapper/3.5.14/,如果是32位的可以直接使用,如果是64位要认证的,我的已经破解,需要的可以去我的百度网盘下载通过网盘分享的文件:wrapper_3.5.14.zip
链接: https://pan.baidu.com/s/1bi1OP1kRicjhDtYHjRv22w 提取码: 8ppu

在这里插入图片描述

九、总结

  1. ✅ 瘦身 Jar 适合频繁更新、依赖较多的项目,分离代码、依赖、配置,维护更方便;
  2. ✅ 前台 wrapper.exe -c 先测试,再注册服务,分层排错;
  3. ✅ Windows 环境优先使用 sc 命令注册服务,规避 Wrapper 自带注册的权限问题;
  4. ✅ 合理配置日志行数与滚动策略,避免磁盘被日志占满;
  5. ✅ 所有操作均建议管理员 CMD 执行,规避权限类报错。

更多推荐