码迷,mamicode.com
首页 > 编程语言 > 详细

多个平台的Java Launcher脚本

时间:2015-06-09 17:55:22      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:

通常对于服务来说,过长的命令往往让人感到厌烦,人们需要的只是简单的操作,并且能够支持复杂的功能,对于Java开发的服务来说更是如此。
一个比较复杂的Jar服务使用Java启动,命令如下

java -Xms512m -Xmx512m -jar fuck.jar –config config.server -port 10086

实际上许多虚拟机的语言的Host命令格式也是类似的。
我们分析可以知道对于基于虚拟机的语言,命令行基本上是 host+vm运行参数+执行文件路径+输入参数。
当然如果参数较少,我们完全不用写一个Launcher脚本来管理服务。

Launcher脚本需要提供的命令至少有:
1. start
2. stop
3. restart
4. status
5. help

实现

在Linux系统上,启动脚本应该是简单的,不许要过多依赖的,一般而言推荐使用shell脚本,实际上很多软件在Linux上的Launcher都是使用Shell语言。android studio,brackets Codebox ,甚至Chrome Firefox都有shell脚本的启动器。
在Windows上早期,部分软件使用cmd来写启动器,然而cmd的功能孱弱,微软适时的推出了PowerShell,PowerShell在功能上非常强大,甚至要优于Shell,所以采用PowerShell来写启动器,并且写一个cmd辅助脚本启动PowerShell。

@echo off

if not exist "%~dp0launcher.ps1" goto NotFound
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ‘‘; [System.Threading.Thread]::CurrentThread.CurrentUICulture = ‘‘;& ‘%~dp0launcher.ps1‘ %*"
goto :EOF
:NotFound
echo Not Found launcher.ps1 in %~dp0,Please reset your launcher
PAUSE

配置文件的读取

选择合适的配置文件能够简化操作,对于简单的Shell脚本而言,复杂的配置文件是难以实现的。我将Launcher的配置文件分为两类,一个是JVM的参数,也就是上面的 “-Xms512m -Xmx512m” 这种文件的格式就是按行读取,行首存在‘#’字符就抛弃。
另一类是基于INI-Style 的配置文件,主要是JDK的路径,需要运行的jar包的路径,以及重定向的设置,由于Windows和Linux的文件系统存在差异,所以在涉及到文件系统的设置迁移到了Windows和Posix节

Bash解析Ini文件:



function GetPrivateProfileString() { if [ ! -f $1 ] || [ $# -ne 3 ];then return 1 fi blockname=$2 fieldname=$3 begin_block=0 end_block=0 cat $1 | while read line do if [ "X$line" = "X[$blockname]" ];then begin_block=1 continue fi if [ $begin_block -eq 1 ];then end_block=$(echo $line | awk ‘BEGIN{ret=0} /^\[.*\]$/{ret=1} END{print ret}‘) if [ $end_block -eq 1 ];then #echo "end block" break fi need_ignore=$(echo $line | awk ‘BEGIN{ret=0} /^#/{ret=1} /^$/{ret=1} END{print ret}‘) if [ $need_ignore -eq 1 ];then #echo "ignored line:" $line continue fi field=$(echo $line | awk -F= ‘{gsub(" |\t","",$1); print $1}‘) #####Fix Me We Support Space Value value=$(echo $line | awk -F= ‘{gsub("","",$2); print $2}‘) #echo "‘$field‘:‘$value‘" if [ "X$fieldname" = "X$field" ];then #echo "result value:‘$result‘" echo $value break fi fi done return 0 }

PowerShell解析Ini文件:


Function Parser-IniFile { param( [Parameter(Position=0,Mandatory=$True,HelpMessage="Enter Your Ini File Path")] [ValidateNotNullorEmpty()] [String]$File ) $ini = @{} $section = "NO_SECTION" $ini[$section] = @{} switch -regex -file $File { "^\[(.+)\]$" { $section = $matches[1].Trim() $ini[$section] = @{} } "^\s*([^#].+?)\s*=\s*(.*)" { $name,$value = $matches[1..2] # skip comments that start with semicolon: if (!($name.StartsWith(";"))) { $ini[$section][$name] = $value.Trim() } } } $ini }

JDK的检测

查看Java路径,通常来说,launcher脚本会从launcher.cfg读取Posix(Windows) 节的JAVA_HOME键值,如果没有JAVA_HOME的变量就读取环境变量的JAVA_HOME,如果存在JAVA_HOME,但实际路径上并不存在,或者没有存在JAVA_HOME,那么再从查找java的路径。而JAVA_HOME的设置可以在有多个JDK的时候仍然正确的选择JDK.而不用带来冲突。

	jdkenv=$(GetPrivateProfileString launcher.cfg Posix JAVA_HOME)
	javabin=`which java`
	if [ -f "$jdkenv/bin/java" ]; then
		javabin="$jdkenv/bin/java"
	fi

Get-JavaSE函数是为了支持从注册表查询JDK安装。所以单独的写了一个函数。



Function Get-JavaSE { $jdk=$env:JAVA_HOME #This is regedit search java return $jdk } $JdkRawEnv=$IniAttr["Windows"]["JAVA_HOME"] $JavaEnv="$env:JAVA_HOME" IF($JdkRawEnv -eq $null) { $JavaEnv=Get-JavaSE }else{ $JavaEnv=$JdkRawEnv }

进程的管理

先说PowerShell,PowerShell是面向对象的,我们可以轻松的获得进城对象。
我们使用Start-Process 启动一个进程。在这个cmdlet中 我们添加 -PassThru就可以得到一个进程对象


$ProcessObj= Start-Process -FilePath "${JavaExe}" -PassThru -Argumentlist "${VMOptions} -jar ${PrefixDir}\${AppPackage} $Parameters" -RedirectStandardOutput "${StdoutFile}" -RedirectStandardError "${StdErrorFile}" -WindowStyle Hidden

$ProcessObj 可以拿到进程的Id,进程的镜像名,以及进程的资源占用情况。
当然进程对象在Get-Process也是可用的。
使用Get-Process获得一个进程,如果有进程id再好不过。如果不存在id对应的进程则会抛出异常

$Obj=Get-Process -Id $javaid

结束一个进程需要Stop-Process 只需要输入 -Id id即可。
而对于Linux,有文件系统/proc,同样可以实现PowerShell的功能。判断进程是否存在可以检测 /proc/id是否存在,可以检查/proc/id/status 查看资源占用什么的。
我们在launcher脚本所在目录(通常也是jar包所在目录)当启动java进程成功后,我们将pid写入到launcher.lock.pid 在需要停止和重启的时候使用launcher.lock.pid存储的id来操作即可。
在PowerShell中可以用Get-Content 读取pid。在Linux中可以用cat。

最终

上述代码已经托管到GIT@OSC
项目:ServiceLauncher 使用MIT协议,欢迎Pull Request.

多个平台的Java Launcher脚本

标签:

原文地址:http://my.oschina.net/GIIoOS/blog/464667

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!