如何从Java应用程序创建Windows服务


220

我刚刚继承了一个Java应用程序,该应用程序需要作为服务安装在XP和Vista上。自从我以任何形式使用Windows至今已有8年了,而且我从未创建过服务,更不用说从Java应用程序之类的东西了了(我为该应用程序提供了一个jar,并且有一个依赖项jar-log4j )。使它作为服务运行所需的魔术是什么?我已经知道了源代码,因此尽管可以避免进行代码修改,但还是可以的。



1
仅出于完整性考虑:在serverfault.com/a/259195上表示应用程序需要响应Service Control Manager回调。阅读本教程,它使用Procrun ticklingmind.blogspot.com/2010/03/...
Broken_Window

Answers:


69

对Java Service Wrapper感到很幸运


11
Java Service Wrapper看起来非常有用。但是我看了一下功能列表。您只需要知道社区版本未获得在服务器上使用的许可。
Brian Matthews

那可能是个问题。几年前我用过它。猜猜他们决定收费。
sblundy

许多开放源码项目都使用此包装器,包括Jakarta Apache上的几个,例如ActiveMQ。
托德

7
wrapper.tanukisoftware.org/doc/english/licenseCommunity.html 闭源使用GPL并不限制私有软件供内部使用而开发,该内部使用取决于GPL下的软件,只要该软件在未获得完整许可的情况下就不会分发即可。整个应用程序可供所有用户使用。尽管我们鼓励公司和政府用户使用服务器或开发许可协议,但只要该应用程序供内部使用或始终随其完整src一起分发,则可以接受社区许可协议。
弗拉基米尔2009年

1
@Vladimir tanuki包装器不再为64位
架构

100

Apache Commons Daemon是一个很好的选择。它Procrun为Windows服务,并JSVC用于UNIX守护进程。它使用的Apache许可证限制较少,而Apache Tomcat则将其用作Windows和Linux本身的一部分!要使其工作起来有些棘手,但是有一篇详尽的文章带有工作示例。

除此之外,您还可以查看Apache Tomcat中的bin \ service.bat以了解如何设置服务。在Tomcat中,它们将Procrun二进制文件重命名(prunsrv.exe-> tomcat6.exe,prunmgr.exe-> tomcat6w.exe)。

我在使用Procrun时遇到了麻烦,您的start和stop方法必须接受参数(String [] argv)。例如,“ start(String [] argv)”和“ stop(String [] argv)”将起作用,但是“ start()”和“ stop()”将导致错误。如果您无法修改这些调用,请考虑创建一个引导程序类,以对这些调用进行调整以满足您的需求。


使用反射,您可能可以解决上一段中提到的问题。另外,我知道只有Apache Commons守护程序具有预构建的64位二进制文​​件供免费使用。
djangofan 2011年

每个JVM选项之间都需要回车。例如,如果您在同一行上-Dopt1 = a -Dopt2 = b,则可能不起作用。要解决它,您需要编写--JvmOptions=-Dopt=a#-Dopt2=b。由于这个原因,我从一个蚂蚁脚本运行该命令,并奋斗了好几天。希望能帮助到你。
悉尼

您谈论的文章已不复存在...您还有办法解决吗?我无法让Apache Commons Daemon来完成我需要的工作。
11101101b 2012年

3
@ 11101101,阿帕奇似乎已经附着文章的胆量其自己的wiki页面 ...
卢卡斯

@community Wiki,我将Apache Commons Daemon用于64位Windows计算机,它成功添加了服务。当我对32位Windows 7计算机使用相同的进程时,无法添加服务。
沙吉2014年

59

使用Apache Commons Daemon,您现在可以拥有一个自定义的可执行文件名称和图标! 您还可以获得带有您自己的名称和图标的自定义Windows托盘监视器!

我现在使用自己的名称和图标(prunsrv.exe)运行服务,并且系统任务栏监视器(prunmgr.exe)也使用自己的自定义名称和图标!

  1. 下载Apache Commons Daemon二进制文件(您将需要prunsrv.exe和prunmgr.exe)。
  2. 将它们分别重命名为MyServiceName.exeMyServiceNamew.exe
  3. 下载WinRun4J并使用其RCEDIT.exe随附的程序来修改Apache可执行文件以嵌入您自己的自定义图标,如下所示:

    > RCEDIT.exe /I MyServiceName.exe customIcon.ico
    > RCEDIT.exe /I MyServiceNamew.exe customTrayIcon.ico
    
  4. 现在像这样安装Windows服务(有关更多详细信息和选项,请参阅文档):

    > MyServiceName.exe //IS//MyServiceName \
      --Install="C:\path-to\MyServiceName.exe" \
      --Jvm=auto --Startup=auto --StartMode=jvm \
      --Classpath="C:\path-to\MyJarWithClassWithMainMethod.jar" \
      --StartClass=com.mydomain.MyClassWithMainMethod
    
  5. 现在,您有了Jar的Windows服务,它将以您自己的图标和名称运行!您也可以启动监视器文件,它将以自己的图标和名称在系统托盘中运行。


1
我已根据您的操作方法进行了所有操作,但未更改系统托盘图标..知道为什么吗?
outofBounds 2012年

抱歉@outofBounds,直到现在我才看到您的评论。RCEDIT.exe程序可以修改服务可执行文件的图标。确保您具有有效的.ico文件,并且正确定义了每个文件的大小。你可以看到如何在这里建立一个适当的.ico文件:stackoverflow.com/questions/4354617/...
11101101

2
请注意,服务名称中不能有空格。
13101101b 2013年

1
是@Shakthi它工作正常,在32位和64位Windows XP,7,8,8.1,Server 2003中,2008年,和2012年
11101101

1
是的,@ Syamsoul Azrein,在10和任何服务器版本上均适用。
11101101b

31

一种简单的方法是NSSM Wrapper Wrapper(请参阅我的博客条目)。


7
NSSM摇滚!即使从我的Java程序,我也很容易包装。简单,轻巧,有效-100kb的幸福感!谢谢!
cynepnaxa 2014年

1
任何示例,如何使用NSSM Wrapper在系统启动时在后台将Java应用程序实例(我正在使用HelioSearch)作为Windows服务启动?
Krunal

@GiordanoMaestro您的博客条目不再可用。您还有其他链接吗?
Matthieu 2015年

2
与Apache Commons Daemon,wrapper.tanukisoftware.org和yajsw相比,NSSM是将简单的Java应用程序转换为Windows服务的最快,最简单的选择
Jeffrey Knight

我正在尝试使用NSSM运行我的spring boot可执行jar。我收到此错误,“响应START控件的状态异常SERVICE_PAUSED”。
Kiran Kumar

26

一种选择是WinRun4J。这是一个可配置的Java启动器,可以兼用作Windows服务主机(32位和64位版本)。它是开源的,对其使用没有任何限制。

(完整披露:我正在从事这个项目)。


3
谢谢你 我尝试过YAJWS,首先下载了19mb,这使我感到害怕,并且在按照说明进行操作后,它显示“错误解析命令行”。我看过PROCRUN,它对于快速设置太麻烦了。INSTSRV / SRVANY需要更改注册表!Launch4J在EXE内打包了JAR,因此使部署变得复杂。WinRun4J非常适合。唯一的缺点是,它需要用作服务的特殊类(而不是简单地调用标准主类)。但总体而言,它是99%完美的。
fernacolo 2011年

2
仅供参考,最新版本具有标准主类的包装。
彼得·史密斯

嗨,您能举任何说明如何使用此功能的示例吗?我想用它来启动HelioSearch实例,作为系统启动时的后台Windows服务。
Krunal

17

另一个答案是“ 另一个Java服务包装程序”,这似乎可以更好地替代Java Service Wrapper,因为它具有更好的许可。从JSW到YAJSW的迁移也很容易。对于我来说当然是Windows服务器的全新产品,并且试图使Java应用程序作为服务运行,它非常易于使用。

我找到了其他一些,但最终没有使用:

  • Java Service Launcher我没有使用它,因为它看起来比YAJSW更复杂。我不认为这是包装纸。
  • JSmooth创建Window的服务不是其主要目标,但可以实现。我没有使用它,因为自2007年以来没有任何活动。

向我+1,因为这是“开箱即用”对我来说最快的解决方案,并且不需要修改Java应用,这无疑是加分。
日绿色节

我发现这张非常引人注目的比较表将YAJSW与其他一些常见的服务包装程序进行了比较。 yajsw.sourceforge.net/#mozTocId284533
格林

6

我认为Java Service Wrapper运作良好。请注意,有三种方法可以集成您的应用程序。听起来,如果您不想更改代码,那么选项1最适合您。配置文件可能会有些疯狂,但是请记住,(对于选项1)您正在启动的程序(将为其指定参数)是其帮助程序,该程序随后将启动您的程序。他们为此提供了一个示例配置文件


5

如果您使用Gradle Build Tool,则可以尝试使用Windows-service-plugin,它有助于使用Apache Commons Daemon Procrun

要使用插件创建Java Windows Service应用程序,您需要执行几个简单的步骤。

  1. 使用适当的方法创建一个主服务类。

    public class MyService {
    
        public static void main(String[] args) {
            String command = "start";
            if (args.length > 0) {
                command = args[0];
            }
            if ("start".equals(command)) {
                // process service start function
            } else {
                // process service stop function
            }
        }
    
    }
  2. 将插件包含到您的build.gradle文件中。

    buildscript {
      repositories {
        maven {
          url "https://plugins.gradle.org/m2/"
        }
      }
      dependencies {
        classpath "gradle.plugin.com.github.alexeylisyutenko:windows-service-plugin:1.1.0"
      }
    }
    
    apply plugin: "com.github.alexeylisyutenko.windows-service-plugin"

    用于Gradle 2.1中引入的新的,可孵化的插件机制的相同脚本片段:

    plugins {
      id "com.github.alexeylisyutenko.windows-service-plugin" version "1.1.0"
    }
  3. 配置插件。

    windowsService {
      architecture = 'amd64'
      displayName = 'TestService'
      description = 'Service generated with using gradle plugin'   
      startClass = 'MyService'
      startMethod = 'main'
      startParams = 'start'
      stopClass = 'MyService'
      stopMethod = 'main'
      stopParams = 'stop'
      startup = 'auto'
    }
  4. 运行createWindowsService gradle任务以创建Windows服务分发。

这就是创建简单的Windows服务所需要做的。该插件将自动下载Apache Commons Daemon Procrun二进制文件,将此二进制文件解压缩到服务分发目录,并创建用于安装/卸载服务的批处理文件。

${project.buildDir}/windows-service目录中,您将找到服务可执行文件,用于安装/卸载服务的批处理脚本以及所有运行时库。要安装服务运行,<project-name>-install.bat以及是否要卸载服务运行<project-name>-uninstall.bat。要启动和停止服务,请使用<project-name>w.exe可执行文件。

请注意,方法处理服务启动应创建并启动一个单独的线程来执行处理,然后返回。启动和停止服务时,从不同的线程调用main方法。

有关更多信息,请阅读有关插件和Apache Commons Daemon Procrun的信息。


被低估的答案!
TaylanUB '18


4

使用Java 8,我们无需任何外部工具即可处理这种情况。Java 8 附带的javapackager工具提供了一个创建自包含应用程序捆绑包的选项:

-native type生成独立的应用程序捆绑包(如果可能)。使用-B选项可为正在使用的捆绑程序提供参数。如果指定了type,则仅创建此类型的捆绑包。如果未指定类型,则全部使用。

以下值对类型有效:

-native type
Generate self-contained application bundles (if possible). Use the -B option to provide arguments to the bundlers being used. If type is specified, then only a bundle of this type is created. If no type is specified, all is used.

The following values are valid for type:

all: Runs all of the installers for the platform on which it is running, and creates a disk image for the application. This value is used if type is not specified.
installer: Runs all of the installers for the platform on which it is running.
image: Creates a disk image for the application. On OS X, the image is the .app file. On Linux, the image is the directory that gets installed.
dmg: Generates a DMG file for OS X.
pkg: Generates a .pkg package for OS X.
mac.appStore: Generates a package for the Mac App Store.
rpm: Generates an RPM package for Linux.
deb: Generates a Debian package for Linux.

如果是Windows,请参考以下文档,我们可以根据需要创建msi或exe。

exe: Generates a Windows .exe package.
msi: Generates a Windows Installer package.

4
这个答案没有解决这个问题。javapackager不能用于直接创建Windows服务,而只能创建一个自包含的可执行文件,例如包括jre和其他资源。
tobias_


3

这很简单,因为您必须输入快捷方式

Windows 7 C:\users\All Users\Start Menu\Programs\Startup(管理员)或User home directory(%userProfile%)

Windows 10: 运行中 shell:startup

在它的属性->快捷方式->目标-> java.exe -jar D:\..\runJar.jar

注意:此操作仅在您登录后运行


具有管理员权限

sc create serviceName binpath= "java.exe -jar D:\..\runJar.jar" 将创建Windows服务

如果您使用超时,cmd /c D:\JAVA7~1\jdk1.7.0_51\bin\java.exe -jar d:\jenkins\jenkins.war但是即使超时,也会在后台启动java.exe。签入任务管理器

注意:这将在Windows登录启动时运行(登录之前,基于服务' Startup Type')

创建Windows服务的详细说明



2

我以前使用过JavaService并取得了成功。它已经有两年没有更新了,但是当我使用它时,它的确坚不可摧。


GForge已停产
6

2

我不喜欢Java Service Wrapper的许可。我和ActiveState Perl一起编写了可以完成这项工作的服务。

我曾考虑过用C#编写服务,但时间紧迫。


您能提供使用“ perl”完成的示例黑客吗?
PeaceUser '16

2

我总是只使用sc.exe(请参阅http://support.microsoft.com/kb/251192)。它应该从SP1安装在XP上,如果不是Vista风格的,则可以使用Vista资源工具包下载它。

我使用Java并没有做任何复杂的事情,但是使用完全限定的命令行参数(x:\ java.exe ....)或使用Ant创建脚本以包含依赖关系和设置参数对我来说都很好。


1
这样一来,您就可以将某项服务作为服务启动,但是据我所知,它将被分离,即您无法通过服务停止它或自动重新启动,等等。尽管如此,我可能是完全错误的-只是开始研究它。
原子


1

我目前需要它来运行基于Eclipse的应用程序,但我需要首先设置一些对该应用程序本地的变量。sc.exe仅允许可执行文件,而不允许脚本,因此我转向Windows 2003资源工具包中的 autoexnt.exe 。它将服务限制为单个批处理文件,但是我只需要将一个批处理脚本转换为服务即可。

再见!


-1

尽管它不是免费的,但Exe4j是一个非常好的选择。在Exe4j上签出。在创建.exe文件的向导中,可以选择创建服务。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.