<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    好好生活,努力工作,天天向上!

    BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
      46 Posts :: 1 Stories :: 178 Comments :: 0 Trackbacks

        你是不是在找將Java程序注冊(cè)成系統(tǒng)服務(wù)的方法?試試Java Service Wrapper這個(gè)工具吧,你可以從這個(gè)網(wǎng)站上面下載你喜歡的版本:http://wrapper.tanukisoftware.org/ ,Java Service Wrapper提供了適合市面上流行的操作系統(tǒng)的版本。

        使用WrapperJava程序注冊(cè)成系統(tǒng)服務(wù)有三種方式可供選擇:

        第一種是使用WrapperSimpleApp 這個(gè)幫助類(lèi)來(lái)運(yùn)行你的程序,這個(gè)是最簡(jiǎn)單的方法,也是官方推薦使用的方式,但是這樣可能會(huì)對(duì)你的程序有改動(dòng),如果你在項(xiàng)目初期就開(kāi)始考慮的話,這個(gè)方法還是不錯(cuò)的。像JBoss也是使用這種方式。

        第二種方式是使用WraperStartStopApp這個(gè)類(lèi)來(lái)實(shí)現(xiàn)功能,這個(gè)方法適合那些通過(guò)ClassA類(lèi)來(lái)負(fù)責(zé)啟動(dòng)服務(wù),ClassB類(lèi)來(lái)負(fù)責(zé)停止服務(wù)的應(yīng)用場(chǎng)景。

        我使用的是第三種方式,這種方式好處是對(duì)程序改動(dòng)比較小,只要讓你的啟動(dòng)類(lèi)實(shí)現(xiàn)WrapperListener接口,并實(shí)現(xiàn)接口中的start(String[] args) 和 stop(String [] args)方法,然后通過(guò)WrapperManager來(lái)啟動(dòng)。其他的一些配置比如要運(yùn)行的主類(lèi)全名、Java類(lèi)路徑、依賴Java庫(kù)的路徑、還有服務(wù)顯示的名稱,都可以通過(guò)配置文件conf/wrapper.conf來(lái)配置,相對(duì)來(lái)說(shuō)比較靈活,像我目前在做的RCP項(xiàng)目有自動(dòng)更新功能,更新下來(lái)的插件要比那些原來(lái)的插件的版本號(hào)要更新,雖然說(shuō)會(huì)定期刪除那些過(guò)期的插件,但有時(shí)還是會(huì)產(chǎn)生延遲,那么配置文件里面配置的Java類(lèi)路徑必須也要鏈接到最新的插件的地址,我是通過(guò)一個(gè)Java類(lèi)來(lái)管理這個(gè)wrapper.confg文件,如果有更新的插件,通過(guò)Java類(lèi)來(lái)得到最新插件的路徑,將這些信息寫(xiě)入到wrapper.confg文件中,這樣就能保證配置文件中的類(lèi)路徑是最新的了。
       下面是程序的結(jié)構(gòu):

      

       這里主頁(yè)介紹一下wrapper.conf的配置,這個(gè)配置文件是Java常用的屬性文件格式,

       wrapper.java.command=java: 指定要運(yùn)行的Java,如果你不想設(shè)置環(huán)境變量的話,你也可以指定JDKbin文件路徑

       wrapper.java.mainclass=test.Main: 指定要運(yùn)行的類(lèi),這個(gè)類(lèi)必須實(shí)現(xiàn)WrapperListener接口和接口中的startstop方法,通過(guò)WrapperManager類(lèi)來(lái)初始化服務(wù)。如果啟動(dòng)服務(wù)過(guò)程中出現(xiàn)與不能取得JVM信息的情況,可能是接口實(shí)現(xiàn)的問(wèn)題。

       wrapper.java.classpath.1=../lib/wrapper.jar:配置Java的類(lèi)路徑,這里的將wrapper.jar也包含在內(nèi),這里可以設(shè)置參數(shù)的位置,而且這個(gè)位置必須得從開(kāi)始,不能跳過(guò),必須順序指定,指定類(lèi)路徑的時(shí)候還有根據(jù)依賴關(guān)系來(lái)排列,被依賴的排在前面,否則會(huì)出現(xiàn)ClassNotFoundException的錯(cuò)誤,這里支持覺(jué)得路徑和相對(duì)路徑,也支持通配符"*",比如wrapper.java.classpath.1=../lib/wrapper*,不過(guò)這個(gè)通配符只能用于匹配文件名,不能用于匹配文件夾名稱。

       wrapper.java.library.path.1=../lib指定Wrapper自帶的類(lèi)庫(kù)文件存放文件夾,比如Wrapper.DLL文件等,只要指定到對(duì)應(yīng)的上級(jí)目錄名稱就行,支持通配符。

       wrapper.java.library.path.1=../lib指定Wrapper自帶的類(lèi)庫(kù)文件存放文件夾,比如Wrapper.DLL文件等,只要指定到對(duì)應(yīng)的上級(jí)目錄名稱就行,支持通配符。

       wrapper.app.parameter.1= :指定運(yùn)行類(lèi)的main方法參數(shù)。

       wrapper.daemonize=TRUE:將服務(wù)注冊(cè)成守護(hù)線程,就算程序關(guān)閉的話不影響服務(wù)的運(yùn)行

       wrapper.ntservice.hide-console=false:不顯示控制臺(tái)

       wrapper.filter.trigger.1= , wrapper.filter.action.1 :指定過(guò)濾器和觸發(fā)器,可以對(duì)控制臺(tái)的輸出信息進(jìn)行監(jiān)聽(tīng),然后觸發(fā)相應(yīng)的操作

       wrapper.disable_shutdown_hook=TRUE:是否禁用 "關(guān)閉Hook" ,關(guān)閉的話在出現(xiàn)一般異常的情況下面可以忽略掉異常繼續(xù)執(zhí)行

       wrapper.console.loglevel=INFO配置控制臺(tái)的顯示信息的級(jí)別,NONE不顯示任何輸出信息,FATAL只顯示致命的錯(cuò)誤消息,ERROR顯示所有的錯(cuò)誤消息,STATUS顯示服務(wù)狀態(tài)的改變,包括服務(wù)啟動(dòng)和停止等信息,INFO顯示所有程序輸出的信息和JVM顯示的信息,如果程序無(wú)法正常啟動(dòng),可以使用DEBUG顯示詳細(xì)的調(diào)試信息。

       wrapper.logfile.loglevel=INFO配置日志記錄文件要記錄的輸出信息的級(jí)別,參數(shù)值和wrapper.console.loglevel功能一致

       wrapper.logfile.maxsize=0配置日志文件的最大大小,如果為0表示不限制日志文件的大小,支持標(biāo)記符,“k”代表KB,“m”代表MB,如果要設(shè)置最大大小為100KB的話可以這樣:wrapper.logfile.maxsize=100k

       wrapper.console.title=Wrapper Demo 控制臺(tái)窗口顯示標(biāo)題,

       wrapper.ntservice.name=testwrapper: 系統(tǒng)服務(wù)的名稱

       wrapper.ntservice.displayname=Wrapper Demo在服務(wù)管理中顯示的名稱

       wrapper.ntservice.description=Wrapper Demo的介紹信息: 在服務(wù)管理器顯示服務(wù)的描述信息

       wrapper.ntservice.starttype=AUTO_START: 配置服務(wù)啟動(dòng)方式,可以選擇AUTO_START(自動(dòng))DEMAND_START(手動(dòng))兩種方式。默認(rèn)為自動(dòng)。


       前幾天在看Jetty源代碼的時(shí)候發(fā)現(xiàn)它也是使用Wrapper注冊(cè)成系統(tǒng)服務(wù),使用的是第三種方式,可以參考一下,

    import java.io.PrintStream;
    import org.mortbay.jetty.Server;
    import org.mortbay.start.Main;
    import org.tanukisoftware.wrapper.WrapperListener;
    import org.tanukisoftware.wrapper.WrapperManager;

    public class JettyServiceWrapperListener implements WrapperListener {
      
    private static Server __server = null;

      
    public void controlEvent(int event) {
        
    if ((WrapperManager.isControlledByNativeWrapper()) || ((event != 200&& (event != 201&& (event != 203)))
          
    return;
        WrapperManager.stop(
    0);
      }

      
    public Integer start(String[] args) {
        
    for (int i = 0; i < args.length; ++i) {
          System.out.println(
    "ARG[" + i + "] = " + args[i]);
        }
        Main.main(args);
        
    return null;
      }

      
    public int stop(int code) {
        
    try {
          System.out.println(
    "JettyServiceWrapperListener: Stopping Jetty 6 Service!!!");
          __server.stop();
          System.out.println(
    "JettyServiceWrapperListener: Jetty 6 Service Stopped!!!");
          
    return code;
        }
        
    catch (Exception e) {
          System.out.println(
    "Stop Server Error");
          e.printStackTrace();
        }
        
    return -1;
      }

      
    public static void setServer(Server server) {
        __server 
    = server;
      }

      
    public static Server getServer() {
        
    return __server;
      }

      
    public static void main(String[] args) {
        String[] newStrArgs 
    = new String[args.length + 1];
        newStrArgs[
    0= System.getProperty("jetty.home"+ "etc/jetty-win32-service.xml";
        
    for (int i = 0; i < args.length; ++i) {
          newStrArgs[(i 
    + 1)] = args[i];
        }
        WrapperManager.start(
    new JettyServiceWrapperListener(), newStrArgs);
      }
    }

       這個(gè)類(lèi)實(shí)現(xiàn)了WrapperWrapperListener 并實(shí)現(xiàn)了它的startstop方法,start方法在服務(wù)器啟動(dòng)的時(shí)候調(diào)用,不過(guò)這里要注意,如果在30秒內(nèi)你不能執(zhí)行完start方法,系統(tǒng)會(huì)自動(dòng)放棄這個(gè)服務(wù)的啟動(dòng),解決辦法可以在start方法使用線程,將比較耗時(shí)的操作放在這個(gè)線程執(zhí)行,比如加載Spring文件等。而且如果在start方法執(zhí)行出現(xiàn)異常,會(huì)終止服務(wù)的運(yùn)行。這點(diǎn)要注意。

      Stop方法在服務(wù)停止啟動(dòng),startstop方法的參數(shù)可以在wrapper.conf文件里面配置。一般按照這樣配置的話你的程序應(yīng)該可以通過(guò)執(zhí)行StartApp-NT.bat正常啟動(dòng)了,

    posted on 2009-08-05 12:27 VWPOLO 閱讀(3643) 評(píng)論(1)  編輯  收藏 所屬分類(lèi): Java 技術(shù)

    Feedback

    # re: 使用Java Service Wrapper 將Java程序注冊(cè)成系統(tǒng)服務(wù) 2009-08-06 10:53 VWPOLO
    如果想忽略掉一般的異常可以在配置文件里面添加:wrapper.disable_shutdown_hook=TRUE   回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 99热在线观看免费| 一本大道一卡二大卡三卡免费| 久久久久国色av免费看| 亚洲精品偷拍视频免费观看| 亚洲国产精品无码中文lv| 最近中文字幕无吗免费高清| 国产精品亚洲片在线va| 四虎成人精品一区二区免费网站| 国产 亚洲 中文在线 字幕| 三年片在线观看免费大全| 亚洲人成电影在线观看青青| 成人免费视频软件网站| 极品色天使在线婷婷天堂亚洲| 国产国产人免费人成免费视频| 特级毛片A级毛片100免费播放| 亚洲另类激情专区小说图片| ww在线观视频免费观看w| 亚洲乱码一区二区三区在线观看| 日本高清免费观看| 亚洲成a人片在线观| 成年美女黄网站色大免费视频| 亚洲爆乳无码精品AAA片蜜桃| 亚洲AV永久无码精品一区二区国产| 日本免费精品一区二区三区 | 真人无码作爱免费视频| 免费人成在线观看网站视频| 中文字幕成人免费高清在线| 日韩精品一区二区亚洲AV观看 | 亚洲av麻豆aⅴ无码电影| 免费无码H肉动漫在线观看麻豆| 亚洲美女一区二区三区| 卡一卡二卡三在线入口免费| 一级黄色免费毛片| 91精品国产亚洲爽啪在线影院 | 亚洲精品av无码喷奶水糖心| 亚洲高清偷拍一区二区三区| 最近新韩国日本免费观看| 亚洲欧洲av综合色无码| 亚洲色自偷自拍另类小说| 亚洲一级毛片免费观看| 黄色一级毛片免费看|