- Start java process windows
- Guide to java.lang.Process API
- Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:
- 1. Introduction
- 2. Using Process Class for Compiling and Running Java Program
- 3. Creating Process
- 4. Destroying Process
- 4.1. Destroying a Process by Reference
- 4.2. Destroying a Process by ID
- 4.3. Destroying a Process by Force
- 5. Waiting for a Process to Complete
- 5.1. waitfor()
- 5.2. waitfor(long timeOut, TimeUnit time)
- 6. exitValue()
- 7. isAlive()
- 8. Handling Process Streams
- 8.1. getErrorStream()
- 8.2. getInputStream()
- 8.3. getOutputStream()
- 8.4. Filter Process Streams
- 9. Conclusion
- Starting a process in Java?
- 3 Answers 3
- Работа с Java в командной строке
- От простого к .
- Один файл
- Отделяем бинарные файлы от исходников
- Используем пакеты
- Если в программе несколько файлов
- Если удивляет результат
- Хорошо бы протестировать
- Создадим библиотеку
- Надо узнать, что у библиотеки внутри
- Лучше снабдить библиотеку документацией
- Можно подписать jar-архив
- Использование библиотеки
- Собираем программу
- Первый способ
- Второй способ
- Третий способ
- Запуск исполняемого jar-файла
- Как быть с приложениями JavaEE
Start java process windows
The methods that create processes may not work well for special processes on certain native platforms, such as native windowing processes, daemon processes, Win16/DOS processes on Microsoft Windows, or shell scripts.
By default, the created process does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via the streams obtained using the methods getOutputStream() , getInputStream() , and getErrorStream() . The parent process uses these streams to feed input to and get output from the process. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the process may cause the process to block, or even deadlock.
The process is not killed when there are no more references to the Process object, but rather the process continues executing asynchronously.
There is no requirement that the process represented by a Process object execute asynchronously or concurrently with respect to the Java process that owns the Process object.
As of 1.5, ProcessBuilder.start() is the preferred way to create a Process .
Subclasses of Process should override the onExit() and toHandle() methods to provide a fully functional Process including the process id, information about the process, direct children, and direct children plus descendants of those children of the process. Delegating to the underlying Process or ProcessHandle is typically easiest and most efficient.
Guide to java.lang.Process API
Last modified: January 2, 2021
Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:
If you have a few years of experience in the Java ecosystem, and you’re interested in sharing that experience with the community (and getting paid for your work of course), have a look at the «Write for Us» page. Cheers, Eugen
1. Introduction
In this tutorial, we’re going to take an in-depth look at the Process API.
For a shallower look into how to use Process to execute a shell command, we can refer to our previous tutorial here.
The process that it refers to is an executing application. The Process class provides methods for interacting with these processes including extracting output, performing input, monitoring the lifecycle, checking the exit status, and destroying (killing) it.
2. Using Process Class for Compiling and Running Java Program
Let’s see an example to compile and run another Java program with the help of Process API:
Thus, the applications of executing Java code within an existing Java code is virtually limitless.
3. Creating Process
Our Java application can call upon any application which is running within our computer system subjective to Operating System restrictions.
Therefore we can execute applications. Let’s see what the different use cases we can run by utilizing the Process API are.
The ProcessBuilder class allows us to create subprocesses within our application.
Let’s see a demo of opening Windows-based Notepad application:
4. Destroying Process
Process also provides us with methods to destroy sub-processes or process. Although, how the application is killed is platform-dependent.
Let’s see different use cases by which are possible.
4.1. Destroying a Process by Reference
Let’s say we’re using Windows OS and want to spawn the Notepad application and destroy it.
As before, we can create an instance of Notepad application by using the ProcessBuilder class and the start() method.
Then we can call the destroy() method on our Process object.
4.2. Destroying a Process by ID
We can also kill processes which are running within our Operating System that might not be created by our application.
Caution should be advised while doing this, as we can unknowingly destroy a critical process that might make the operating system unstable.
We first need to find out the process ID of the current running process by checking the task manager and find out the pid.
Let’s see an example:
4.3. Destroying a Process by Force
On the execution of the destroy() method, the subprocess will get killed as we saw earlier in the article.
In the case when destroy() doesn’t work, we have the option of destroyForcibly().
We should always start with destroy() method first. After that, we can perform a quick check on the sub-process whether by executing isAlive().
If it returns true then execute destroyForcibly():
5. Waiting for a Process to Complete
We also have two overloaded methods, through which we can ensure we can wait for completion of a process.
5.1. waitfor()
When this method is executed, then it will place the current execution process thread in a blocking-wait state unless the sub-process gets terminated.
Let’s take a look at the example:
We can see from the above example for the current thread to continue execution it will keep on waiting for the subprocess thread to end. Once the subprocess ends, the current thread will continue its execution.
5.2. waitfor(long timeOut, TimeUnit time)
When this method is executed, then it will place the current execution process thread in the blocking-wait state unless the sub-process gets terminated or runs out of time.
Let’s take a look at the example:
We can see from the above example for the current thread to continue execution it will keep on waiting for the subprocess thread to end or if the specified time interval has elapsed.
When this method is executed, then it will return a boolean value of true if the subprocess has exited or a boolean value false if the wait time had elapsed before the subprocess exited.
6. exitValue()
When this method is run then the current thread won’t wait for the sub-process to get terminated or destroyed, however, it will throw an IllegalThreadStateException if the subprocess isn’t terminated.
Another way around if the subprocess has been successfully terminated then it will result in an exit value of the process.
It can be any possible positive integer number.
Let’s look at an example when the exitValue() method returns a positive integer when the subprocess has been terminated successfully:
7. isAlive()
When we’d like to perform business processing which is subjective whether the process is alive or not.
We can perform a quick check to find whether the process is alive or not which returns a boolean value.
Let’s see a quick example of it:
8. Handling Process Streams
By default, the created subprocess does not have its terminal or console. All its standard I/O (i.e., stdin, stdout, stderr) operations will be sent to the parent process. Thereby the parent process can use these streams to feed input to and get output from the subprocess.
Consequently, this gives us a huge amount of flexibility as it gives us control over the input/output of our sub-process.
8.1. getErrorStream()
Interestingly we can fetch the errors generated from the subprocess and thereon perform business processing.
After that, we can execute specific business processing checks based on our requirements.
Let’s see an example:
8.2. getInputStream()
We can also fetch the output generated by a subprocess and consume within the parent process thus allowing share information between the processes:
8.3. getOutputStream()
We can send input to a subprocess from a parent process:
8.4. Filter Process Streams
It’s a perfectly valid use-case to interact with selective running processes.
Process provides us the facility to selectively filter running processes based on a certain predicate.
After that we can perform business operations on this selective process set:
9. Conclusion
Process is a powerful class for Operating System level interaction. Triggering terminal commands as well as launching, monitoring and killing applications.
For more reading on the Java 9 Process API, take a look at our article here.
As always, you’ll find the sources over on Github.
Starting a process in Java?
Is there a way to start a process in Java? in .Net this is done with for example:
Is there an equivalent in Java so I can then let the user find the application and then it would work for any OS?
3 Answers 3
You can get the local path using System properties or a similar approach.
See Runtime.exec() and the Process class. In its simplest form:
Note that you also need to read the process’ output (eg: myProcess.getInputStream() ) — or the process will hang on some systems. This can be highly confusing the first time, and should be included in any introduction to these APIs. See James P.’s response for an example.
You might also want to look into the new ProcessBuilder class, which makes it easier to change environment variables and to invoke subprocesses :
The Java Class Library represents external processes using the java.lang.Process class. Processes can be spawned using a java.lang.ProcessBuilder :
or the older interface exposed by the overloaded exec methods on the java.lang.Runtime class:
Both of these will code snippets will spawn a new process, which usually executes asynchronously and can be interacted with through the resulting Process object. If you need to check that the process has finished (or wait for it to finish), don’t forget to check that the exit value (exit code) returned by process.exitValue() or process.waitFor() is as expected (0 for most programs), since no exception is thrown if the process exits abnormally.
Also note that additional code is often necessary to handle the process’s I/O correctly, as described in the documentation for the Process class (emphasis added):
By default, the created subprocess does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via the streams obtained using the methods getOutputStream(), getInputStream(), and getErrorStream(). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock.
One way to make sure that I/O is correctly handled and that the exit value indicates success is to use a library like jproc that deals with the intricacies of capturing stdout and stderr, and offers a simple synchronous interface to run external processes:
Работа с Java в командной строке
От простого к .
Каждая программа обычно содержится в отдельном каталоге. Я придерживаюсь правила создавать в этом каталоге по крайней мере две папки: src и bin. В первой содержатся исходные коды, во второй — результат компиляции. В данных папках будет структура каталогов, зависящая от пакетов.
Один файл
Можно сделать и без лишних папок.
Берем сам файл HelloWorld.java.
Переходим в каталог, где лежит данный файл, и выполняем команды.
В данной папке появится файл HelloWorld.class. Значит программа скомпилирована. Чтобы запустить
Отделяем бинарные файлы от исходников
Теперь сделаем тоже самое, но с каталогами. Создадим каталог HelloWorld и в нем две папки src и bin.
Компилируем
Здесь мы указали, что бинарные файлы будут сохраняться в отдельную папку bin и не путаться с исходниками.
Используем пакеты
А то, вдруг, программа перестанет быть просто HelloWorld-ом. Пакетам лучше давать понятное и уникальное имя. Это позволит добавить данную программу в другой проект без конфликта имен. Прочитав некоторые статьи, можно подумать, что для имени пакета обязательно нужен домен. Это не так. Домены — это удобный способ добиться уникальности. Если своего домена нет, воспользуйтесь аккаунтом на сайте (например, ru.habrahabr.mylogin). Он будет уникальным. Учтите, что имена пакетов должны быть в нижнем регистре. И избегайте использования спецсимволов. Проблемы возникают из-за разных платформ и файловых систем.
Поместим наш класс в пакет с именем com.qwertovsky.helloworld. Для этого добавим в начало файла строчку
В каталоге src создадим дополнительные каталоги, чтобы путь к файлу выглядел так: src/com/qwertovsky/helloworld/HelloWorld.java.
Компилируем
В каталоге bin автоматически создастся структура каталогов как и в src.
Если в программе несколько файлов
HelloWorld.java
Calculator.java
Adder.java
Ошибка возникла из-за того, что для компиляции нужны файлы с исходными кодами классов, которые используются (класс Calculator). Надо указать компилятору каталог с файлами с помощью ключа -sourcepath.
Компилируем
Если удивляет результат
Есть возможность запустить отладчик. Для этого существует jdb.
Сначала компилируем с ключом -g, чтобы у отладчика была информация.
Отладчик запускает свой внутренний терминал для ввода команд. Справку по последним можно вывести с помощью команды help.
Указываем точку прерывания на 9 строке в классе Calculator
Запускаем на выполнение.
Чтобы соориентироваться можно вывести кусок исходного кода, где в данный момент находится курссор.
Узнаем, что из себя представляет переменная а.
Выполним код в текущей строке и увидим, что sum стала равняться 2.
Поднимемся из класса Adder в вызвавший его класс Calculator.
Удаляем точку прерывания
Можно избежать захода в методы, используя команду next.
Проверяем значение выражения и завершаем выполнение.
Хорошо бы протестировать
Запускаем. В качестве разделителя нескольких путей в classpath в Windows используется ‘;’, в Linux — ‘:’. В консоли Cygwin не работают оба разделителя. Возможно, должен работать ‘;’, но он воспринимается как разделитель команд.
Создадим библиотеку
Класс Calculator оказался полезным и может быть использован во многих проектах. Перенесем всё, что касается класса Calculator в отдельный проект.
Измените также назавания пакетов в исходных текстах. В HelloWorld.java нужно будет добавить строку
Делаем архив jar
С помощью ключа -C мы запустили программу в каталоге bin.
Надо узнать, что у библиотеки внутри
Можно распаковать архив zip-распаковщиком и посмотреть, какие классы есть в библиотеке.
Информацию о любом классе можно получить с помощью дизассемблера javap.
Из результата видно, что класс содержит кроме пустого конструктора, ещё один метод sum, внутри которого в цикле вызывается метод add класса Adder. По завершении метода sum, вызывается Adder.getSum().
Без ключа -c программа выдаст только список переменных и методов (если использовать -private, то всех).
Лучше снабдить библиотеку документацией
Изменим для этого класс калькулятора.
Документацию можно создать следующей командой. При ошибке программа выдаст список возможных опций.
В результате получиться следующее
Можно подписать jar-архив
Если требуется подписать свою библиотеку цифровой подписью, на помощь придут keytool и jarsigner.
Генерируем подпись.
Генерируем Certificate Signing Request (CSR)
Содержимое полученного файла отправляем в центр сертификации. От центра сертификации получаем сертификат. Сохраняем его в файле (например, qwertokey.cer) и импортируем в хранилище
Файл qwertokey.cer отправляем всем, кто хочет проверить архив. Проверяется он так
Использование библиотеки
Есть программа HelloWorld, которая использует библиотечный класс Calculator. Чтобы скомпилировать и запустить программу, нужно присоединить библиотеку.
Компилируем
Собираем программу
Это можно сделать по-разному.
Первый способ
Здесь есть тонкости.
В строке
не должно быть пробелов в конце.
Вторая тонкость описана в [3]: в этой же строке должен стоять перенос на следующую строку. Это если манифест помещается в архив сторонним архиватором.
Программа jar не включит в манифест последнюю строку из манифеста, если в конце не стоит перенос строки.
Ещё момент: в манифесте не должно быть пустых строк между строками. Будет выдана ошибка «java.io.IOException: invalid manifest format».
При использовании команды echo надо следить только за пробелом в конце строки с main-class.
Второй способ
В данном способе избегаем ошибки с пробелом в main-class.
Третий способ
Включили код нужной библиотеки в исполняемый файл.
Запуск исполняемого jar-файла
Файл calculator.jar исполняемым не является. А вот helloworld.jar можно запустить.
Если архив был создан первыми двумя способами, то рядом с ним в одном каталоге должна находится папка lib с файлом calculator.jar. Такие ограничения из-за того, что в манифесте в class-path указан путь относительно исполняемого файла.
При использовании третьего способа нужные библиотеки включаются в исполняемый файл. Держать рядом нужные библиотеки не требуется. Запускается аналогично.
Как быть с приложениями JavaEE
Аналогично. Только библиотеки для компиляции нужно брать у сервера приложений, который используется. Если я использую JBoss, то для компиляции сервлета мне нужно будет выполнить примерно следующее
Структура архива JavaEE-приложения должна соответствовать определенному формату. Например
Способы запуска приложения на самом сервере с помощью командной строки для каждого сервера различны.
Надеюсь, данная статья станет для кого-нибудь шпаргалкой для работы с Java в командной строке. Данные навыки помогут понять содержание и смысл Ant-скриптов и ответить на собеседовании на более каверзные вопросы, чем «Какая IDE Вам больше нравится?».