Проблема запуска внешней прогарммы из JAR-файла
От: RussianFellow Россия http://russianfellow.livejournal.com
Дата: 06.11.12 10:30
Оценка:
Сам работаю под Windows. Написал на Java программу, откомпилировал и образовал JAR-файлы test1.jar, consoleapp.jar, consoleapp2.jar . При этом программа test1 вызывает программы consoleapp или consoleapp2. Программа consoleapp просто выводит информацию ан экран в консольном режиме, а программа consoleapp2 сначала осуществляет ввод информации в консольном режиме, а потом осуществляет вывод введённой информации на экран в консольном режиме.

Перебросил их по протоколу FTP на Unix-сервер (оболочка--Korn Shell). Со своего компьютера потом через эмулятор exceed пытаюсь запускать test1, в случае, когда он запускает consoleapp. Там всё нормально, информация выводится без проблем.
А вот если из программы test1 запустить consoleapp2, то сперва происходит ввод всех значений, а потом вывод их на экран, хотя должно сначала вводиться первое значение, потому выводиться это значение на экран, затем вводиться второе значение, потом выводиться на экран и т.д.

В чём причина этого?

Файл test1.java и файлы StreamGobbler1.java и StreamGobbler2.java, которые входят в проект test1:

test1.java:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.nio.*;
import java.lang.*;
import java.util.*;
import java.text.*;

public class test1 {

    private JFrame jFrame = null;  //  @jve:decl-index=0:visual-constraint="10,10"

    private JPanel jContentPane = null;

    private JButton jButton = null;
    
    public boolean canInput = true;
    
    public boolean canOutput = true;

    /**
     * This method initializes jButton    
     *     
     * @return javax.swing.JButton    
     */
    private JButton getJButton() {
        if (jButton == null) {
            jButton = new JButton();
            jButton.setBounds(new Rectangle(31, 31, 164, 29));
            jButton.setText("Запустить программу");
            jButton.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent e) {
                    //System.out.println("mouseClicked()"); // TODO Auto-generated Event stub mouseClicked()
                    boolean  flag = true;
                    byte b[] = new byte[80];
                    
                    System.out.println("Перед блоком try");
                    try {
                        Process proc = Runtime.getRuntime().exec("java -jar consoleapp.jar");
                        /* InputStreamReader  isr = new InputStreamReader(proc.getInputStream());
                        BufferedReader br = new BufferedReader(isr);
                        String line=null;
                        line = br.readLine();
                        line = line + "\n";
                        b = line.getBytes();
                        System.out.write(b, 0, b.length);
                        br.close(); */
                        //Thread.sleep(1000);
                        StreamGobbler1  errorGobbler = new StreamGobbler1(proc.getErrorStream(), "ERROR", proc);
                        errorGobbler.t1 = test1.this;
                        errorGobbler.start();
                        System.out.println("после ERROR");
                        StreamGobbler1  outputGobbler = new StreamGobbler1(proc.getInputStream(), "OUTPUT", proc);
                        outputGobbler.t1 = test1.this;
                        outputGobbler.start();
                        System.out.println("после OUTPUT"); 
                        StreamGobbler2  inputGobbler = new StreamGobbler2(proc.getOutputStream(), "INPUT", proc);
                        inputGobbler.t1 = test1.this;
                        //Thread.sleep(1000);
                        inputGobbler.start();
                        System.out.println("после INPUT");
                        System.out.println("после inputGobbler.start()");
                        int exitVal = proc.waitFor();
                        System.out.println("после proc.waitFor()");
                        System.out.print("Значение exitVal: ");
                        System.out.println(exitVal);
                    } catch (Exception ex) {
                        System.out.print("Ошибка: ");
                        System.out.println(ex.toString());
                        flag = false;
                    }
                    if (flag==true)  System.out.println("после блока try--catch");
                }
            });
        }
        return jButton;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                test1 application = new test1();
                application.getJFrame().setVisible(true);
            }
        });
    }

    /**
     * This method initializes jFrame
     * 
     * @return javax.swing.JFrame
     */
    private JFrame getJFrame() {
        if (jFrame == null) {
            jFrame = new JFrame();
            jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jFrame.setSize(241, 135);
            jFrame.setContentPane(getJContentPane());
            jFrame.setTitle("Application");
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            Dimension frameSize = jFrame.getSize();
            if (frameSize.height > screenSize.height) {
                frameSize.height = screenSize.height;
            }
            if (frameSize.width > screenSize.width) {
                frameSize.width = screenSize.width;
            }
            jFrame.setLocation((screenSize.width - frameSize.width) / 2,
                    (screenSize.height - frameSize.height) / 2);
        }
        return jFrame;
    }

    /**
     * This method initializes jContentPane
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(null);
            jContentPane.add(getJButton(), null);
        }
        return jContentPane;
    }

}


StreamGobbler1.java:


import java.lang.*;
import java.util.*;
import java.text.*;
import java.io.*;
import java.nio.*;

public class StreamGobbler1 extends Thread {
    InputStream  is;
    String  type;
    
    StreamGobbler1 (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)  System.out.println(type + ">" + line);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}


Файл StreamGobbler2.java:

import java.lang.*;
import java.util.*;
import java.text.*;
import java.io.*;
import java.nio.*;

public class StreamGobbler2 extends Thread {
    OutputStream  os;
    String  type;
    
    StreamGobbler2 (OutputStream os, String type) {
        this.os = os;
        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)  System.out.println(type + ">" + line); */
            OutputStreamWriter  osr = new OutputStreamWriter(os);
            BufferedWriter bw = new BufferedWriter(osr);
            byte b[] = new byte[80];
            while (System.in.read(b, 0, 80)!=-1) {
                String s = new String(b);
                s = type + ">" + s;
                bw.write(s);
                bw.newLine();
            }
            System.in.read(b, 0, 80);
            
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}


Файл consoleapp.java:


public class ConsoleApp {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("первая строка");
        System.out.println("вторая строка");
        System.out.println("третья строка");
        System.out.println("четвёртая строка");
    }

}


Файл consoleapp2.java:

public class ConsoleApp2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int i;
        byte b[] = new byte[80];
        
        try {
            System.out.println("Введите четыре строки:");
            for (i=0; i<4; i++) {
                System.in.read(b, 0, b.length);
                String s = new String(b);
                System.out.println(s);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}


То в случае, если в файле test1.java стоит

Process proc = Runtime.getRuntime().exec("java -jar consoleapp.jar");


то тогда на экран терминального окна благополучно выводятся:

первая строка
вторая строка
третья строка
четвёртая строка


а если в файле test1.java стоит

Process proc = Runtime.getRuntime().exec("java -jar consoleapp2.jar");


то после перекомпиляции, пересоздания файла test1.jar и переброски его на этот Unix-сервер на экране появляется

Введите четыре строки:


после этого оператор вводит строку (например, 1). Но после этого 1 не выводится на экран, а происходит ожидание ввода следующей строки. После того, как оператор ввёл её (например, 2), то вместо вывода 2 следует ожидание следующей строки.
И только после того, как оператор последовательно ввёл четыре строки (например, 1, 2, 3, 4), на экран выводятся эти четыре строки:

1
2
3
4


А далее выводится вся та информация, которая должна выводиться в программе test1.jar после запуска из неё программы consoleapp2 .

В чём причина этого? Почему не работает последовательный ввод и вывод информации в терминальном окне?
1613 г. = 2024 г.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.