Java魔法堂:以Windows服务的形式运行Java程序
一、前言
由于防止维护人员误操作关闭Java控制台程序,因此决定将其改造为以Windows服务的形式运行。弄了一个上午总算搞定了,下面记录下来,以供日后查阅。
二、Java Service Wrapper
官网地址:http://wrapper.tanukisoftware.com/doc/english/download.jsp
JavaServiceWrapper以守护进程或windows服务的方式运行java程序。JSW提供四种方案改造原有项目,以实现守护进程或windows服务的方式运行。而且还提供JVM监控功能和自动重启功能,反正十分强大的样子。
方式1:WrapperSimpleApp
用于通过同一个类实现启动和关闭的程序。 官方推荐使用该方式加工原有项目,好处是简单,且不用修改原有项目的代码。
步骤1:下载并解压得到工具包,目录结构如下
/ |-- bin,wrapper控制windows服务的bat文件 |-- conf,wrapper配置文件 |-- doc,教程 |-- lib,wrapper的依赖包 |-- logs,日志 |-- src,模板 |-- conf |-- bin
步骤2:搭建项目结构:新建项目发布目录(假设为agent),然后将src下的conf和bin复制到agent下,并且将conf和bin下的文件重命名,去掉`.in`后缀。然后将bin/wrapper.exe复制到agent/bin/下,再将lib复制到agent下,得到目录结构如下
agent |-- lib |-- wrapper.dll |-- wrapper.jar |-- conf |-- wrapper.conf |-- bin |-- wrapper.exe |-- 一堆bat文件 最后将原有项目的文件复制到bin目录下。
步骤3:配置agent/conf/wrapper.conf的参数
# 配置java命令路径
wrapper.java.command=jre/bin/java
# 配置CLASSPATH路径(并不会修改全局的环境变量)
# 若原有项目还依赖其他jar包,均需要添加进来
wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=.
# 配置lib路径
wrapper.java.library.path.1=../lib
# 配置服务的main class(就是原有项目的程序入口类)
wrapper.app.parameter.1=agent.Daemon
# 配置wrapper日志文件
wrapper.logfile=logs/Agent.log
# 配置系统服务名称
wrapper.ntservice.name=AgentService
# 配置系统服务显示的名称
wrapper.ntservice.displayname=AgentService
# 配置系统服务描述
wrapper.ntservice.description=AgentService
# 配置系统服务的启动方式,取值范围是AUTO_START或DEMAND_START
wrapper.ntservice.starttype=AUTO_START
# 配置内存溢出则重启服务
wrapper.filter.trigger.1001=Exception in thread "*" java.lang.OutOfMemoryError
wrapper.filter.allow_wildcards.1001=TRUE
wrapper.filter.action.1001=RESTART
wrapper.filter.message.1001=The JVM has run out of memory.
步骤4:安装、卸载服务
点击对应的Install.bat和Uninstall.bat即可。
2. 方式2:WrapperStartStopApp
用于像tomcat那样,启动程序和关闭程序是分开的项目。该方式同样不用修改原来项目的代码。
3. 方式3:WrapperListener
该方式需要修改原来项目的代码,但最灵活。
4. 方式4:WrapperJarApp
用于原有项目已经打包为jar或war包的情况,配置方式与`WrapperSimpleApp`相似,但`wrapper.app.parameter.1=jar或war包路径`。该方式同样不用修改原来项目的代码
三、总结
官方文档以JBOSS为例子说明WrapperSimpleApp的使用,十分不好懂,幸好有前人记录实操过程我才从苦海得救,感谢感谢。
四、参考
http://blog.csdn.net/arjick/article/details/4526392
- 【宅男宅女们的福音】电影天堂最新电影爬取及搜索脚本
- 把模块有关联的放在一个文件夹中 在python2中调用文件夹名会直接失败 在python3中调用会成功,但是调用不能成功的解决方案
- numpy用法小结
- 凯撒密码加解密及破解实现原理
- linux bash Shell脚本经典 Fork炸弹演示及命令详解
- python易错盲点排查之+=与+的区别分析以及一些赋值运算踩过的坑
- Selenium2+python自动化57-捕获异常(NoSuchElementException)
- 你真的会用ABAP, Java和JavaScript里的constructor么?
- 【Python学习笔记之三】lambda表达式用法小结
- Selenium2+python自动化58-读取Excel数据(xlrd)
- 软件测试金字塔
- Selenium2+python自动化59-数据驱动(ddt)
- 浅谈我对动态规划的一点理解---大家准备好小板凳,我要开始吹牛皮了~~~
- Selenium2+python自动化60-异常后截图(screenshot)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java 水题系列(4)数组合并
- SpringBoot 整合 SpringDataJPA
- Codeforces Beta Round #51 C. Pie or die(博弈 思维)
- SpringDateJPA 系列之 JPA 中的相关操作
- python Turtle 画出“精美碎花小清新树”快来拿代码!
- SpringDataJPA 系列之 JPA 简介
- Leetcode 264. 丑数 II (数论,三指针,类dp)
- Leetcode 628. 三个数的最大乘积 (数学)
- Vue 组件化开发
- Spring Boot 基础配置
- 读懂 Java 单例模式
- 数值分析第一次实习题报告
- Leetcode 409. 最长回文串 (Hash)
- Vue 前后端交互基础
- Spring Boot 入门