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

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

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

    隨筆-124  評(píng)論-194  文章-0  trackbacks-0
    今天搞了一天,JAVA調(diào)用一個(gè)PERL程序,得不得就退不出,千試萬試,LOG精細(xì)到逐行,知道在哪停住了,但打死不知道為什么。
    后來吃個(gè)飯都放棄了,居然又找到答案,要沒看到它,那真以為里面有鬼了。

    大概原因是,調(diào)用Runtime.getRuntime().exec后,如果不及時(shí)捕捉進(jìn)程的輸出,會(huì)導(dǎo)致JAVA掛住,看似被調(diào)用進(jìn)程沒退出。所以,解決辦法是,啟動(dòng)進(jìn)程后,再啟動(dòng)兩個(gè)JAVA線程及時(shí)的把被調(diào)用進(jìn)程的輸出截獲。

    一下子,整個(gè)世界清爽多了。。。多謝這么仁兄,下面轉(zhuǎn)一下:



    轉(zhuǎn)自:http://pudding.sharera.com/blog/BlogTopic/31232.htm

    碰到一個(gè)項(xiàng)目需要從Java中運(yùn)行Perl程序,這個(gè)Perl程序調(diào)用客戶的Web service,每次發(fā)送一個(gè)請(qǐng)求,接受一個(gè)響應(yīng)。Java程序中包含多個(gè)請(qǐng)求,需要多次調(diào)用Perl程序,并且接受和解析響應(yīng)(這個(gè)爛設(shè)計(jì)可不是我干 的,我實(shí)在不明白強(qiáng)大的Java Web Service為什么要弄成這樣,不過客戶是老大)。使用Java Runtime的exec()方法,發(fā)現(xiàn)運(yùn)行一段時(shí)間后,進(jìn)程就被掛起了(之前的響應(yīng)完全正確)。于是分析原因,發(fā)現(xiàn)我在運(yùn)行exec()方法后,立刻執(zhí) 行了Process的waitFor()方法,這里出了問題。在網(wǎng)上找到一篇文章講述這個(gè)問題:
    地址:http://brian.pontarelli.com/2005/11/11/java-runtime-exec-can-hang/

    Java Runtime exec can hang

    November 11, 2005 on 4:40 pm | In Java |

    The next version of Savant is going to focus heavily on the stand-alone runtime and support for dialects and plugins. Supporting all that is largely handled by using a simple executor framework I wrote around Java 1.4 and lower’s Runtime.exec method. A few things to keep in mind when using this:

    1. Always read from the streams prior to calling waitFor. Otherwise you could end up waiting forever on Windows and other OS platforms whose I/O buffers can’t store enough from standard out and standard error to ensure the program has finished. These platforms will pause the execution of whatever is running until something reads the buffered content from standard out and standard error. I would imagine all platforms suffer from this, but some platforms have larger buffers than others. Needless to say, always read from the streams first.
    2. Always read from standard error first. I ran across a bug where some OS platforms will always open standard out, but never close it. What this means is that if you read from standard out first and the process only writes to standard error, you’ll hang forever waiting to read. If you read from standard error first, you’ll always be okay on these platforms because the OS seems to shutdown standard error. I think however, that the best way to handle all cases is to check both standard error and standard out for readiness and only read from them if they have something to offer. The downside I could see here is that error isn’t ready, but eventually will be.
    可以看出:
    • 永遠(yuǎn)要在調(diào)用waitFor()方法之前讀取數(shù)據(jù)流
    • 永遠(yuǎn)要先從標(biāo)準(zhǔn)錯(cuò)誤流中讀取,然后再讀取標(biāo)準(zhǔn)輸出流
    于是將waitFor()方法放在讀取數(shù)據(jù)流后調(diào)用,目前沒有發(fā)現(xiàn)什么問題。


    正好解決了我心中的疑問,非常感謝!

    我們的程序一開始就是exec完了接著waitFor(),但bat文件執(zhí)行不完整:

    Process proc = Runtime.getRuntime().exec(cmd);
                    proc.waitFor();

    后面的build中在waitFor()之前讀取了數(shù)據(jù)流,bat文件就可以完整執(zhí)行了:

    Process proc = Runtime.getRuntime().exec(cmd);
         StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "Error");           
                     StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "Output");
                     errorGobbler.start();
                     outputGobbler.start();

         proc.waitFor();

    class StreamGobbler extends Thread {
     InputStream is;

     String type;

     StreamGobbler(InputStream is, String type) {
      this.is = is;
      this.type = type;
     }

     public void run() {
      try {
       InputStreamReader isr = new InputStreamReader(is);
       BufferedReader br = new BufferedReader(isr);
       String line = null;
       while ((line = br.readLine()) != null) {
        if (type.equals("Error"))
         LogManager.logError(line);
        else
         LogManager.logDebug(line);
       }
      } catch (IOException ioe) {
       ioe.printStackTrace();
      }
     }
    }

    TestPrint.bat:

    echo P1=%1  >D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
    echo P2=%2 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
    echo P3=%3 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
    echo P4=%4 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
    echo P5=%5 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log
    echo P6=%6 >>D:"2.1.2env"2.1.2home"CompuSet"output"TestPrint.log

    Bad_TestPrint.log:

    P1=C:"xPression"CompuSet"output"MartyTestOut1.afp 
    P2=Literal1
    P3="Rick Skinner"
    P4=Parameter3

    Good_TestPrint.log

    P1=C:"xPression"CompuSet"output"MartyTestOut1.afp 
    P2=Literal1
    P3="Rick Skinner"
    P4=Parameter3
    P5=Parameter4
    P6=Parameter5



    posted on 2009-05-15 21:04 我愛佳娃 閱讀(14242) 評(píng)論(4)  編輯  收藏 所屬分類: Perl

    評(píng)論:
    # re: 哭了:整一天Java Runtime exec的掛死(不退出)問題,原來是醬子 2009-05-30 13:25 | 墻頭草
    # re: 哭了:整一天Java Runtime exec的掛死(不退出)問題,原來是醬子 2009-07-09 22:18 | 大仙
    我好像也遇到過類似的問題
    是在調(diào)用 一個(gè)hsqldb的時(shí)候,發(fā)生過
    好像1.5 才會(huì),  回復(fù)  更多評(píng)論
      
    # re: 哭了:整一天Java Runtime exec的掛死(不退出)問題,原來是醬子 2013-07-29 06:10 | cheligeer
    同樣發(fā)現(xiàn)這類問題,謝謝樓主指明。  回復(fù)  更多評(píng)論
      
    # re: 哭了:整一天Java Runtime exec的掛死(不退出)問題,原來是醬子[未登錄] 2016-04-16 17:40 | 123
    原來是這樣,多謝樓主  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 成人区精品一区二区不卡亚洲| 日韩免费一区二区三区在线| 亚洲国产美女精品久久久| 久久精品国产精品亚洲毛片| 亚洲国产精品碰碰| 毛片网站免费在线观看| 免费人妻无码不卡中文字幕系| 一级毛片在线免费视频| 亚洲精品色在线网站| 亚洲最大天堂无码精品区| 亚洲欧洲国产视频| 亚洲一区二区在线视频| 国产AV无码专区亚洲A∨毛片| 亚洲日本va午夜中文字幕久久| 国内大片在线免费看| 97在线线免费观看视频在线观看| 91香蕉国产线观看免费全集| 日本免费久久久久久久网站| 七次郎成人免费线路视频| 男女污污污超污视频免费在线看| 亚洲丁香婷婷综合久久| 亚洲va中文字幕| 羞羞漫画登录页面免费| 黄页网站在线免费观看| 日本亚洲中午字幕乱码| 国产亚洲女在线线精品| 最好2018中文免费视频| 污视频网站在线观看免费| 九九九精品视频免费| 男女一边桶一边摸一边脱视频免费 | 亚洲一区二区三区在线观看精品中文| 国产一级一片免费播放| 韩国二级毛片免费播放| 国产精品va无码免费麻豆| 国产福利免费观看| 亚洲高清免费视频| 亚洲中文字幕久久精品无码喷水| 伊人久久大香线蕉亚洲| 国产成人亚洲综合无码精品| 亚洲免费精彩视频在线观看| 91亚洲精品麻豆|