HTMLUnit webClient.getPage (locationToPing) блокируется, когда JAR вызывается из Runtime.exec () - PullRequest
0 голосов
/ 04 июня 2011

Я пишу приложение, которое должно периодически загружать банку.Jar извлекает содержимое веб-сайта с использованием HTMLUnit. Когда этот JAR-файл запускается из командной строки, он запускается, как и ожидалось.Но когда я запускаю его с использованием Java-кода, используя Runtime, он блокируется на месте, page = webClient.getPage (locationToPing);и не следует дальше.

Jar содержит только один класс java, как указано ниже,

package tempproj2;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Fetcher {

String locationToPing;
volatile WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
HtmlPage page ;
public static final long SLEEP_TIME_IF_CONNECTION_WAS_REFUSED=10000; //SECS
public long connectionRefusedTime=0;

private static Fetcher theOnlyInstanceOfThisClass=new Fetcher();

public static Fetcher getInstance(){
    return theOnlyInstanceOfThisClass;
}
private Fetcher(){
    init();
    fetchUsingGet();
}
private void init(){
    locationToPing="http://www.mail.yahoo.com";
}

private  void fetchUsingGet(){
    try {
        System.out.println("-----------Start  1 --------------")            ;
        webClient.setUseInsecureSSL(true);
        webClient.setThrowExceptionOnScriptError(false);
        System.out.println("-----------Start  2 --------------")            ;
        webClient.setJavaScriptEnabled(true);
        System.out.println("-----------Start  3 --------------")            ;
        webClient.setTimeout(5000);  //30 secs - its int n not long be careful abt it.
        System.out.println("-----------Start  4 --------------locationToPing="+locationToPing)            ;
        page= webClient.getPage(locationToPing);
        System.out.println("-----------Start  5 --------------"+page.asXml())            ;
    } catch (Exception ex) {
        System.out.println("-----------IC Fetecher     Error here --------------"+ex.getMessage())            ;
        connectionRefusedTime=System.currentTimeMillis();
       ex.printStackTrace();
    }
}

private void reload(){

    if(page==null){
        fetchUsingGet();
        return;
    }
    try {

        page=(HtmlPage)page.refresh();
    } catch (java.net.SocketTimeoutException ex) {
        fetchUsingGet();
        ex.printStackTrace();
    }catch(IOException ex){
        ex.printStackTrace();
    }
}


public static void main(String ar[]){
    Fetcher fetcher=new Fetcher();
    while(true){
        try {
            Thread.sleep(4*1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Fetcher.class.getName()).log(Level.SEVERE, null, ex);
        }
        fetcher.reload();

    }


}

}

Ниже приведены различные способы, которые я пытался запустить вышеcode

  1. Запустите класс как есть - отлично работает.
  2. Создайте Jar-файл из указанного выше класса и запустите из командной строки, используя java -jar, команда - Отлично работает.
  3. Создайте Jar указанного выше класса и запустите его из другого java-класса, используя следующий код:

    try {
        String execCmd="java -jar "+downloadApplicationJarLocation.getAbsolutePath();
        Process pr=Runtime.getRuntime().exec(execCmd) ;
    
            InputStreamReader is = new InputStreamReader(pr.getInputStream());
            BufferedReader br = new BufferedReader(is);
            String line = null;
            String processMessage="";
            while ((line = br.readLine()) != null) {
                System.err.println("Line 1 "+line)    ;            
                processMessage+=line;
            }
            System.out.println("Finished ");
            is.close();
            br.close();
    
    
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    

Но когда я пробую приведенный выше код, толькокод до page = webClient.getPage (locationToPing);выполняется и блокируется.«Старт 5» никогда не печатается на экране.

  1. Я модифицировал приведенный выше код и вместо прямого вызова команды e Java -jar в Runtime.exec () я поместил ее в пакетфайл и называется этот пакетный файл.Процесс pr = Runtime.getRuntime (). Exec (batchFileLocation);Теперь он выполняется должным образом и не блокирует код. Также «Экран 5» выводится на экран.

Моему приложению необходимо периодически вызывать jar из java и уничтожать предыдущий процесс, если таковой имеется.Поэтому вариант 4 мне не подходит, так как подпроцесс все еще жив и его не так просто уничтожить.

Вариант 3 - идеальный способ для меня, но я совершенно не в состоянии понять, почему он блокируется ибольше не продолжается?Это как-то связано с потоками?Использую ли я HTMLUnit так, как предполагается его использовать?

Заранее спасибо

...