int (@NotNull CompileContext context, @NotNull List<String> commands, @NotNull JpsJLinkProperties properties) { File arg_file = null; try { final AtomicInteger exitCode = new AtomicInteger(); final @NlsSafe StringBuilder errorOutput = new StringBuilder(); final List<@NlsSafe String> delayedInfoOutput = new ArrayList<>(); arg_file = FileUtil.createTempFile("jlink_arg_file", null); CommandLineWrapperUtil.writeArgumentsFile(arg_file, commands.subList(1, commands.size()), StandardCharsets.UTF_8); List<String> newCommands = Arrays.asList(commands.get(0), "@" + arg_file.getCanonicalPath()); final Process process = new ProcessBuilder(CommandLineUtil.toCommandLine(newCommands)).start(); BaseOSProcessHandler handler = new BaseOSProcessHandler(process, newCommands.toString(), null); handler.addProcessListener(new ProcessAdapter() { @Override public void processTerminated(@NotNull ProcessEvent event) { exitCode.set(event.getExitCode()); } @Override public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { String message = StringUtil.trimTrailing(event.getText()); if (outputType == ProcessOutputTypes.STDERR) { errorOutput.append(event.getText()); } else { if (properties.verbose) { info(context, message); } else { delayedInfoOutput.add(message); } } } }); handler.startNotify(); handler.waitFor(); int result = exitCode.get(); if (result != 0) { final String message = errorOutput.toString(); if (!StringUtil.isEmptyOrSpaces(message)) { error(context, message); } for (@NlsSafe String info : delayedInfoOutput) { error(context, info); } } return result; } catch (Throwable e) { error(context, e.getMessage()); LOG.error(e); return -1; } finally { if (arg_file != null) { FileUtil.delete(arg_file); } } }