将jboss 7安装成系统服务

本文自:https://community.jboss.org/wiki/RunningJBossAS7AsAWindowsService

首先从地址 http://www.jboss.org/jbossweb/downloads/jboss-native-2-0-10 下载最新的jboss native文件,将其copy到jboss的bin目录下,原bin目录是不会有native包里的东西的。然后依次进行以下操作即可

  1. 修改service.bat文件,将里面的SVCNAME, SVCDISP and SVCDESC分别修改为自己想要安装成服务的相关信息,即服务名,服务标识以及服务描述信息。
  2. 修改里面的JAVA_OPTS信息配置信息,以配置相应的java内存配置信息,在原service.bat文件中,有默认的-Xrs选项,不过这个选项先不能删掉,以避免某些远程桌面信息会导致jboss停掉的问题。此外,还需要配置比如JAVA_HOME等信息。
  3. 将service.bat中的所有run.bat修改为standalone.bat,在最新的jboss版本中,已不再使用call.bat了。
  4. 将service.bat中关于停止服务的 call shutdown 部分修改为 call jboss-cli.bat –connect command=:shutdown >> shutdown.log 2>&1。因为已经没有shutdown.bat这个文件,如果不修改的话,此调用将直接重启机器。此外,如果配置多个jboss,只需要在后面追加 –controller=host:mport 即可。
  5. 在cmd下运行 service.bat install安装服务,然后在服务中将其启动方式修改为auto即可。

继续阅读“将jboss 7安装成系统服务”

针对WebService使用Service类获取Port类的一个参数问题解释

最后在学习WebService时,看到对于官方的例子是这样写的.

private static final QName PORT_NAME
        = new QName("http://server.hw.demo/", "HelloWorldPort");
        Service service = Service.create(SERVICE_NAME);
        String endpointAddress = "http://localhost:9000/helloWorld";
        service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
        
        HelloWorld hw = service.getPort(HelloWorld.class);

注意看上面的PORT_NAME的定义,是一个QName,其就有namespaceURI和一个name值,而在使用serivce获取port时直接传递了接口名参数。
这样的例子是可以运行的,这就导致了本人在编写参考例子时,直接Copy了相应的代码,但是修改了各项名称,在运行时,即始终运行不起来,相应的错误为

java.net.MalformedURLException: Invalid address. Endpoint address cannot be null.

以上的错误直接让人找不到方向,而实际问题是,service根据所传递的信息,在只传递了接口信息时,会默认构建一个QName的信息,再从service中寻找,如果寻找不到,自然就会产生上面的错误了。
在官方的例子中,它会默认构建HelloWorldPort这样qname去寻找,而在进行service.add时,恰好添加的就是HelloWorldPort这个qname,那么就恰好寻找到了。

而我们的例子,由于做了很多处理,导致默认添加到service的port的name并不是Service.class.getName+Port的组合,那么自然就找不到相应的port了。而正确的做法,其实也很简单,就是在获取port的时候,手动地指定要获取port类的qname,如下所示:

		QName userServicePortQName = new QName("http://cxf.java.study.m_ylf.com/", "abcPort");
		service.addPort(userServicePortQName, SOAPBinding.SOAP11HTTP_BINDING, "http://localhost:8080/userService");
		UserService userService = service.getPort(userServicePortQName, UserService.class);

即在往service时添加什么样的port,那么在获取时就使用什么样的qname。再一步理解,addPort这个方法就可以理解为以键值对的方式往service里追加port,那么在获取的时候自然就要提供相应的key值了。如果不提供,就会使用默认的生成策略创建一个key值,那这个key值与addPort使用的key值不一样的话,自然就会产生上面的错误了。

在64位windows下使用instsrv.exe和srvany.exe创建windows服务

在32位的windows下,包括windows7,windows xp以及windows 2003,都可以使用instsrv.exe和srvany.exe来创建自定义的windows服务。比如,我们有一个bat文件,用于将指定的程序作为服务进行启动,使用一般的工具都不可以进行此类工作,而使用由windows 2003的资源工具包windows toolkit中所带的instsrv就可以。

详细的用法这里就不再具体叙述,简单一点就是使用instsrv将相应的srvany注册成服务,然后在注册表中增加相应的Application和AppDirectory参数,用于srvany启动我们所相应的服务。如下列代码所示://将相应程序生成成服务

set s32=%windir%\system32
%s32%\instsrv.exe %service_name% %s32%\srvany.exe

//在注册表中更新相应的参数
echo Windows Registry Editor Version 5.00> %reg_file% 
echo >> %reg_file%
echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\%service_name%\Parameters] >> %reg_file%
echo "Application"="%prog_path%\\%prog_name%" >> %reg_file%//程序地址
echo "AppDirectory"="%prog_path%" >> %reg_file%//程序目录

以上的代码在所有的32位系统之上都可以正常的运行,包括windows 2000。然而,在64位的windows下,以上的代码却失效了。会报一个以下错误:

Unable to find the file at the given path

在仔细检查了参数之后,确定这是由于系统原因所引起的。

最终的原因在于,我们所使用的instsrv和srvany是32位的,而windows现在没有相对应的64位相对应工具发布。而程序本身是没有问题的,问题在于我们将instsrv和Srvany放到windows/system32正面,而在64位系统中,这里应该存放64位的程序,所以最终的解决问题很简单。我们只需要将这两个程序再copy至32位程序应该放置的地方,比如windows/sysWow64目录,这样就可以了。原先的相应步骤以及程序根本就不需要作任何改动。instsrv会自动地找到原先应该放在system32下的程序,而这个程序现在被放置在了SysWow64目录下。

简单一点的解决方法就是,将instsrv和srvany程序在windows/sysWow64目录下再copy一份,相当于在system32和sysWow64下都有程序,这样问题即解决。更底层的原因,也许只有微软能解释了,简而言之,在64位系统下,32位程序是看不到放置在system32下面的程序的,而它应该访问的system32目录被系统映射到了sysWow64目录下了,在运行时系统会自动地将相应的sysWow64目录映射为程序所认为的system32。
参考文档:http://en.wikipedia.org/wiki/WoW64