BAT-файл не был выполнен полностью с помощью Runtime.exec () - PullRequest
0 голосов
/ 06 января 2012

У меня есть BAT-файл, который создает несколько CSV-файлов путем чтения таблиц БД. Для этой цели используется bcp.exe, поэтому для каждого CSV, созданного из таблицы, существует отдельный вызов bcp.exe. Все они находятся в BAT-файле, который я вызываю с помощью Runtime.exec ().

Теперь проблема, с которой я сталкиваюсь, случайна. Его нельзя воссоздать в среде разработчика, но время от времени это происходит в производственной среде.

Иногда после выполнения BAT-файла создаются только несколько CSV-файлов, а остальные отсутствуют. Но когда вы повторяете то же самое, вы получаете все CSV.

Вот код:

        String command = "cmd /C " + batFilePath + " " + batParams;
        LOGGER.info("Executing : " + command);
        Runtime rt = Runtime.getRuntime();
        Process process = rt.exec(command);

        process.getInputStream();
        is = process.getInputStream();
        isr = new InputStreamReader(is);
        br = new BufferedReader(isr);

        String line;

        while ((line = br.readLine()) != null) {
            LOGGER.info(line);
        }

Буду очень признателен, если кто-нибудь сможет рассказать мне о том, как это может произойти, поскольку я все в море по этому поводу.

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

-Raj.

Ответы [ 2 ]

3 голосов
/ 06 января 2012

Всего пара баллов.

Во-первых, я никогда не понимал, почему Java настаивает на получении выходного потока процесса с getInputStream - это просто странно. Но это только я ругаю, с этим мало что можно поделать: -)

Во-вторых, я не уверен, почему у вас в коде "голый" process.getInputStream();. Я не думаю, что это плохо, но кажется ненужным.

В-третьих (и, честно говоря, это единственный, который, я думаю, может помочь), вам нужно отладить сам пакетный файл, а не код Java.

Это можно сделать с помощью следующих двух предложений.

Сначала получите поток ошибок и посмотрите на него. Вполне возможно, что cmd доставляет информацию об ошибке, которую вы просто игнорируете.

Во-вторых, измените командный файл, чтобы выводить обильное количество операторов отладки, один за каждой строкой, если это необходимо. Мы надеемся, что это точно определит проблему в определенном месте командного файла.

Если это происходит только в производстве (и с перерывами), это сложнее, но мы, как правило, обнаруживаем, что наши клиенты более чем готовы принять временные исправления в стиле отладки, чтобы мы могли собирать информацию для устранения проблем, с которыми они сталкиваются.

Вывод из пакетного файла, который просто регистрируется, также является изменением низкого риска. Какой-то отладочный код не настолько низок для риска, и мы должны тщательно протестировать * , прежде чем задействовать производственные системы заказчика. Некоторые откажутся в упор, и это неразумная позиция.

2 голосов
/ 06 января 2012

Возможно, вы выходите из кода входного потока до завершения выполнения пакетного сценария.

После:

Process process = rt.exec(command);

вам, вероятно, следует добавить:

process.waitFor();

Если это * , то вы можете проверить это в своей среде разработчика, умышленно замедляя работу пакетного сценария и проверяя, не возникла ли у вас проблема.Попробуйте вставить что-то вроде этого:

PING 1.1.1.1 -n 1 -w 5000 > NUL

в ваш командный файл.Это приостановит ваш сценарий на 5 секунд.

...