Javaw.exe — случайно появляющееся окно консолиJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Javaw.exe — случайно появляющееся окно консоли

Сообщение Anonymous »

У меня есть графическое приложение JavaFX, которое запускает вторичный дочерний процесс с помощью Javaw.exe. Javaw.exe выбран потому, что я не хочу, чтобы окно консоли было видимым. Через небольшой промежуток времени подпроцесс самопроизвольно создает пустое окно консоли.
На снимке экрана показана ситуация, когда это происходит. Я знаю, что это за процесс. Это процесс с PID 10972.
Изображение

Я никогда раньше не видел появления консоли javaw.exe, поэтому даже не знаю, с чего начать поиск, чтобы потенциально найти основную причину.
Сейчас я подозреваю, что это какой-то собственный код вызывает появление окна консоли. Это приложение действительно загружает некоторые библиотеки DDS RTI и выполняет экземпляр службы записи RTI через эти библиотеки. Учитывая, что это мое подозрение, я ищу предложения по некоторым вещам, которые стоит проверить. Я действительно даже не знаю, с чего начать поиск.
Я попробовал запустить это приложение с помощью java.exe, чтобы посмотреть, нет ли каких-либо странных выводов консоли, которые могли бы исходить из собственного кода, о которых я не знаю, но я их не заметил.
В течение некоторого времени это была хроническая проблема для моего пакета программного обеспечения, и я просто ищу какое-то направление. Кто-нибудь когда-нибудь видел, чтобы подобное происходило раньше?
Вот фотография дерева процессов, показывающая проблемное окно консоли в приложении javaw.exe.
Изображение

Ниже приведен код, который я использую для запуска дочернего процесса процесс javaw.exe. В этом сценарии ведение журнала отключено, и поэтому выполняется SwallowProcessOutput. Стоит отметить, что у меня есть еще 4 подпроцесса, которые вызываются таким же образом с отключенным ведением журнала, и у них никогда не появляется консольное окно javaw.exe.
Вы можете спросить, почему я потребляю выходные данные для процесса javaw.exe, которого изначально не должно быть, и в настоящее время у меня нет хорошего ответа на этот вопрос. Все, что я знаю, это то, что у меня были проблемы с зависанием подпроцессов, если я не использовал вывод консоли во время разработки несколько лет назад. В любом случае я не подозреваю, что это является причиной появления окна консоли, но решил, что об этом следует упомянуть.
На самом деле я просто ищу какое-то направление, как устранить эту неполадку. Любые предложения будут полезны при попытке выяснить, что может быть причиной этого, будь то сторонние инструменты отладки, трюки Windows или что-то еще.
Информация о системе

Код: Выделить всё

Microsoft Windows 10 Enterprise 10.0.17763
openjdk version "19.0.36" x86

Код: Выделить всё

/**
* Executes the command that will launch this server application. This method will start a new instance of the
* server application each time it is called.
*/
public void launch()
{
Map envMap = new HashMap();
environment.variables.forEach(eVar -> envMap.put(eVar.varName, eVar.varValue));
final File workingDir = new File(workingDirectory);
if ((!workingDir.exists() || !workingDir.isDirectory()) && !workingDir.mkdirs())
{
LOG.error("Unable to create working directory for app {}", this);
}
launcher = new ProcessBuilder(command.commandArguments).directory(workingDir);
launcher.environment().putAll(envMap);

try
{
if (!command.commandArguments.isEmpty())
{
LOG.info("Launching server app {} with command {}", getName(), String.join(" ", command.commandArguments));
Process launchedAppProcess = launcher.start();

if (logging.enabled)
{
LOG.info("Output will be logged for server application {}", getName());
final String threadName = getName().contains(".") ? getName().split("\\.")[0] : getName();
Utils.logProcessOutput(launchedAppProcess, LogManager.getLogger("com.company.logging." + threadName), logging.lineExclusions);
}
else
{
LOG.info("Output will not be logged for server application {}", getName());
Utils.swallowProcessOutput(launchedAppProcess); /* We need to read the output or else the app may hang if using javaw.exe */
}
}
else
{
LOG.warn("Command not found for server app {}.  App was not launched.", getName());
}
}
catch (Exception e)
{
LOG.error("Error launching server app {}", name, e);
}
finally
{
try
{
LOG.info("Pausing for {} milliseconds before launching the next server app", postLaunchPauseMS);
Thread.sleep(postLaunchPauseMS);
}
catch (InterruptedException e)
{
LOG.warn("Post launch pause of app {} was interrupted", name);
Thread.currentThread().interrupt();
}
}
}

/**
* Reads a given process's output and does nothing with it
*
* @param p process to swallow output
*/
public static void swallowProcessOutput(Process p)
{
ScheduledExecutorService loggerService = Executors.newScheduledThreadPool(2, DAEMON_THREAD_FACTORY);

loggerService.schedule(() ->
{
try (Scanner sc = new Scanner(p.getInputStream()))
{
while (!p.isAlive())
{
//noinspection BusyWait
Thread.sleep(250);
}
while (sc.hasNextLine() && p.isAlive())
{
sc.nextLine(); /* Do nothing */
}
}
catch (InterruptedException i)
{
Thread.currentThread().interrupt();
}
catch (Exception e)
{
LOG.catching(e);
}
}, 0, TimeUnit.MILLISECONDS);

loggerService.schedule(() ->
{
try (Scanner sc = new Scanner(p.getErrorStream()))
{
while (!p.isAlive())
{
//noinspection BusyWait
Thread.sleep(250);
}
while (sc.hasNextLine() && p.isAlive())
{
sc.nextLine(); /* Do nothing */
}
}
catch (InterruptedException i)
{
Thread.currentThread().interrupt();
}
catch (Exception e)
{
LOG.catching(e);
}
}, 0, TimeUnit.MILLISECONDS);
}
Я попытался запустить приложение с помощью javaw.exe, но через неопределенное время появилось окно консоли.
Я попытался запустить приложение с помощью java.exe, чтобы проверить, есть ли какие-либо выходные данные консоли, поступающие из собственного кода, но дополнительные выходные данные не удалось идентифицировать. Если я намеренно запускаю консоль, это делает практически невозможным узнать, когда возникает проблема, поскольку сама проблема - это окно консоли.
Я ожидаю, что при использовании Javaw.exe окно консоли никогда не появится.
Изменить 1:
Пытался проверить вызовы AllocConsole с помощью procmon, как было предложено Botje, но это не дало результатов даже после появления консоли.
Изображение


Подробнее здесь: https://stackoverflow.com/questions/794 ... -appearing
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»