Class ExternalProcessor
- All Implemented Interfaces:
Closeable
,AutoCloseable
,ArrayProcessor
A tool helping to call external programs (OS processes) for processing AlgART arrays and matrices.
This class helps to solve two following main tasks.
- Creation of some disk directory (work directory) for exchanging data with the called
external program. This class provides automatic creation of the work directory
(in
getInstance(ArrayContext, String, String)
/getInstance(ArrayContext)
methods), automatic deletion of it after finishing usage of an external program (inclose()
method and in thefinalizer
) and the specialcleanup(String)
method for removing all work directories, which were not successfully deleted (usually due to file mapping or abnormal JVM termination) while previous usages of this class or while previous calls of your application.
- Support of the standard AlgART logic of interrupting the algorithm via
ArrayContext.checkInterruption()
method while execution of an external program: the basicexecute(ProcessBuilder)
method periodically callscheckInterruption()
, and if it throws an exception (i.e. the user wants to stop calculations), automatically terminates the external process via java.lang.Process.destroy() call.
This class also contains a collection of static method, useful while implementing inter-application communications.
The instances of this class are thread-safe: all non-static methods are internally synchronized
(besides context()
and getWorkDirectory()
, that always return the same values and don't
require synchronization, and the service methods getWorkFile(String)
,
writeWorkUTF8(String, String)
, readWorkUTF8(String)
).
So, you may use the same instance of this class in several threads; but usually there is not sense to do it.
Unlike this, the static methods of this class (like cleanup(String)
) are not thread-safe,
but are thread-compatible and can be synchronized manually.
- Author:
- Daniel Alievsky
-
Field Summary
Modifier and TypeFieldDescriptionstatic final String
The name of environment variable ("NET_ALGART_ARRAYS_JRE_PATH"), used for finding some custom JRE bygetCustomJREHome()
method.static final String
The name of system property ("net.algart.arrays.jre.path"), used for finding some custom JRE bygetCustomJREHome()
method.static final String
The name of environment variable ("NET_ALGART_ARRAYS_JVM_OPTIONS"), used to get a list of custom JVM options bygetCustomJVMOptions()
method.static final String
The name of system property ("net.algart.arrays.jvm.options"), used to get a list of custom JVM options bygetCustomJVMOptions()
method.static final String
The name of default temporary directory for creating work directories by instances of this class.static final String
The name of a temporary file-marker, created inside work directories while instantiation of this class for internal use (seecleanup(String)
method for more details).static final String
The prefix of unique work directories, created while instantiation of this class. -
Method Summary
Modifier and TypeMethodDescriptionvoid
Cancels automatic removing of the work directory, created while instantiation of this object, inclose()
method.static boolean
cleanup()
Equivalent tocleanup
(getDefaultTempDirectory()
).static boolean
Tries to remove all work directories (recursively, with all their content), which were created by some instances of this class, instantiated bygetInstance(ArrayContext, String, String)
method with the same tempDirectory argument, and which were not successfully deleted yet.void
close()
Tries to fully (recursively) remove the work directory, created while instantiation of this object (if this action was not cancelled bycancelRemovingWorkDirectory()
call), and sets the state of this instance to "closed
".context()
Returns the current context used by this instance for some operations.static File
createTempDirectory
(File parentDirectory, String prefix) Creates a new empty unique subdirectory within the specified parent directory, using the given prefix to generate its name.void
execute
(ProcessBuilder processBuilder) Executes the external program by process=processBuilder.start() call and waits until it will terminate by process.waitFor() call.static File
Returns path to the home directory of the currently executed JRE.static File
Returns path to the home directory of some custom JRE, specified inJRE_PATH_PROPERTY_NAME
system property or inJRE_PATH_ENV_NAME
environment variable, or the home directory of the currently executed JVM if there is no such property / environment variable.static File
getCustomJREHome
(String jreName) Extended analog ofgetCustomJREHome()
method, allowing to specify some "name" of JRE, which is added as a suffix to the name of the corresponding system property or environment variable.Returns the list of JVM options (arguments of "java" executable utility), listed inJVM_OPTIONS_PROPERTY_NAME
system property or inJVM_OPTIONS_ENV_NAME
environment variable, or null if there is no such property / environment variable.getCustomJVMOptions
(String jreName) Extended analog ofgetCustomJVMOptions()
method, allowing to specify some "name" of JRE, which is added as a suffix to the name of the corresponding system property or environment variable.static String
Returns the path to the default disk directory for storing temporary data: some "standard" subdirectory of the system temporary directory will be used.Returns the error stream, set bysetErrorStream(java.io.OutputStream)
method and used byexecute
method for duplication of the error stream of an external program.static File
getExistingPathFromPropertyOrEnv
(String propertyKey, String envVarName) CallsgetExistingPathFromPropertyOrEnv
(propertyKey,envVarName,null) and throws FileNotFoundException in a case of null result.static File
getExistingPathFromPropertyOrEnv
(String propertyKey, String envVarName, File defaultPath) Returns new File(getPropertyOrEnv
(propertyKey,envVarName)), if such file or directory really exists, throws FileNotFoundException, if it does not exist, or returns defaultPath if it is not specified.static ExternalProcessor
getInstance
(ArrayContext context) Equivalent togetInstance
(context,getDefaultTempDirectory()
, "").static ExternalProcessor
getInstance
(ArrayContext context, String tempDirectory, String additionalPrefix) Creates new instance of this class.static File
getJavaExecutable
(File jreHome) Returns the path to the "java" executable utility ("java.exe" on Windows platform), located inside the specified JRE home directory.Returns the output stream, set bysetOutputStream(java.io.OutputStream)
method and used byexecute
method for duplication of the output stream of an external program.static String
getPropertyOrEnv
(String propertyKey, String envVarName) Returns the system property indicated by the specified key propertyKey, if it exists, or, if it is null, the environment variable indicated by the specified name envVarName.Returns the work directory of this processor, created bygetInstance(ArrayContext, String, String)
orgetInstance(ArrayContext)
method.getWorkFile
(String childFileName) Equivalent to new File(getWorkDirectory()
, childFileName).boolean
isClosed()
Returns true if this instance is "closed", i.e. ifclose()
method was called at least once.boolean
Returns true if this instance is "closed" and all its temporary data were successfully removed, i.e. ifclose()
method was called and it has successfully removed thework directory
of this object.boolean
Returns true if and only if the methodcancelRemovingWorkDirectory()
was called at least once.static String
Reads the full content of the given text file and returns it as a String.readWorkUTF8
(String childFileName) Equivalent toreadUTF8
(getWorkFile
(childFileName)).void
setErrorStream
(OutputStream errorStream) Sets the stream for duplication of the error stream of an external program.void
setOutputStream
(OutputStream outputStream) Sets the stream for duplication of the output stream of an external program.void
Equivalent to two calls:setOutputStream
(System.out) andsetErrorStream
(System.err).toString()
Returns a brief string description of this factory.static void
Writes the given text into the file in UTF-8 encoding.void
writeWorkUTF8
(String childFileName, String text) Equivalent towriteUTF8
(getWorkFile
(childFileName),text).
-
Field Details
-
TEMP_SUBDIRECTORY_DEFAULT_NAME
The name of default temporary directory for creating work directories by instances of this class. Such subdirectory is created bygetInstance(ArrayContext)
method in the standard system temporary directory System.getProperty("java.io.tmpdir").The value of this constant is "algart__ep".
-
WORK_DIRECTORY_PREFIX
The prefix of unique work directories, created while instantiation of this class. SeegetInstance(ArrayContext, String, String)
method about "work directory" concept.The value of this constant is "algart__ep_".
Note: if you are planning to use
cleanup(String)
method, you must be sure that your temporary directory, passed to that method, never contains files or directories with names, started with this prefix, besides work directories created by this class. The reason is thatcleanup(String)
method automatically tries to recursively remove all such subdirectories. The simplest way to provide this condition is usage of the default temporary directorygetDefaultTempDirectory()
, for example, viacleanup()
method without arguments: this directory is created by this class itself in the system directory System.getProperty("java.io.tmpdir") and, so, never contain extra files/subdirectories. -
USAGE_MARKER_FILE_NAME
The name of a temporary file-marker, created inside work directories while instantiation of this class for internal use (seecleanup(String)
method for more details). SeegetInstance(ArrayContext, String, String)
method about "work directory" concept.The value of this constant is ".algart__ep_used".
Note: you must guarantee that you will not try to create or write into a file with this name in the work directory.
- See Also:
-
JRE_PATH_PROPERTY_NAME
The name of system property ("net.algart.arrays.jre.path"), used for finding some custom JRE bygetCustomJREHome()
method.- See Also:
-
JRE_PATH_ENV_NAME
The name of environment variable ("NET_ALGART_ARRAYS_JRE_PATH"), used for finding some custom JRE bygetCustomJREHome()
method.- See Also:
-
JVM_OPTIONS_PROPERTY_NAME
The name of system property ("net.algart.arrays.jvm.options"), used to get a list of custom JVM options bygetCustomJVMOptions()
method.- See Also:
-
JVM_OPTIONS_ENV_NAME
The name of environment variable ("NET_ALGART_ARRAYS_JVM_OPTIONS"), used to get a list of custom JVM options bygetCustomJVMOptions()
method.- See Also:
-
-
Method Details
-
getInstance
public static ExternalProcessor getInstance(ArrayContext context, String tempDirectory, String additionalPrefix) Creates new instance of this class.The newly created instance allows to execute, one or several times, some external OS command, usually another command-line application, via the call of
execute(ProcessBuilder)
method. Before finishing usage of this instance, you must callclose()
method; after this, you cannot use this object.This method automatically creates an unique temporary disk subdirectory, called the work directory, inside tempDirectory, which is supposed to be some global disk directory for storing temporary data. Usually you may pass the result of
getDefaultTempDirectory()
method here (or use the alternative methodgetInstance(ArrayContext)
).The created work directory can be used for exchanging data with the external application, called by
execute(ProcessBuilder)
method. The methodclose()
tries to completely remove this directory with all its files and subdirectories (you maycancel
this action). You should understand, that it is possible thatclose()
method will not be able to remove it, because some temporary files can be locked by OS — for example, if you map them viaLargeMemoryModel
. You can usecleanup(String)
method at any time to remove all "garbage", i.e. work directories, created by this class (maybe while previous calls of your application), but not successfully deleted byclose()
methods.The created unique work directory always has a name, started with the character sequence
WORK_DIRECTORY_PREFIX
+ additionalPrefix.
HereWORK_DIRECTORY_PREFIX
allows to detect subdirectories, created by this class, and additionalPrefix allows you (if you want) to distinguish subdirectories, created by different instance of this class for different goals. You must take this into consideration, when you specify some custom tempDirectory (different fromgetDefaultTempDirectory()
). In this case, you should either be sure thatWORK_DIRECTORY_PREFIX
prefix cannot appear in other file/subdirectory names in this directory, or never usecleanup(String)
method — because it will try to remove all subdirectories with names, started withWORK_DIRECTORY_PREFIX
.Important note: this method tries to create the parent directory tempDirectory if and only if it is identical (in terms of String.equals()) to the result of
getDefaultTempDirectory()
method. In other case, the passed tempDirectory must already exist:new File(tempDirectory).exists() must return true.Note: you can use these features, even if you are not going to call external commands via
execute(ProcessBuilder)
method.- Parameters:
context
- the context of execution; may be null, then will be ignored. In the current implementations, it is used only to allow the user to stop the running external application: seecontext()
method.tempDirectory
- the path to the global disk directory for allocating temporary data; in most cases you may pass here the result ofgetDefaultTempDirectory()
.additionalPrefix
- some string, added toWORK_DIRECTORY_PREFIX
to provide unique prefix for the the name of the work directory, created by this class; you may pass "", if you are not interested in it.- Returns:
- new instance of this class.
- Throws:
NullPointerException
- if tempDirectory or additionalPrefix argument is null.SecurityException
- if System.getProperty("java.io.tmpdir") call throws this exception.IOError
- if this method cannot create an unique subdirectory due to some reasons, in particular, if !tempDirectory.equals(getDefaultTempDirectory()
) and the corresponding path does not exist.- See Also:
-
getInstance
Equivalent togetInstance
(context,getDefaultTempDirectory()
, "").- Parameters:
context
- the context of execution; may be null, then will be ignored. In the current implementations, it is used only to allow the user to stop the running external application: seecontext()
method.- Returns:
- new instance of this class.
- Throws:
SecurityException
- if System.getProperty("java.io.tmpdir") call throws this exception.IOError
- if this method cannot create an unique subdirectory due to some reasons, in particular, if !tempDirectory.equals(getDefaultTempDirectory()
) and the corresponding path does not exist.- See Also:
-
cleanup
Tries to remove all work directories (recursively, with all their content), which were created by some instances of this class, instantiated bygetInstance(ArrayContext, String, String)
method with the same tempDirectory argument, and which were not successfully deleted yet.Such situation is possible, for example, when some temporary files, used for exchanging data with an external program, are locked by OS, and we cannot unlock them immediately after termination of the external program. It can be connected with file mapping (in particular, mapping via
LargeMemoryModel
, which is unmapped in Java while garbage collection only). Another typical reasons of appearing non-deleted work directories is canceling automatic deletion of work data for some instance of this class bycancelRemovingWorkDirectory()
method or abnormal termination of your application, whenclose()
were not called for some instance of this class.The cleanup technique, implemented in this method, is based on java.nio.channels.FileLock class. When an instance of this class is created, it places into its
work directory
an empty file with some reserved nameUSAGE_MARKER_FILE_NAME
and locks it via FileLock. When an instance finishes working, i.e. when itsclose()
method is called, it unlocks this file and removes it. It is obvious that all locked files are unlocked when the application is terminated, normally or abnormally. So, if tempDirectory contains some subdirectory, the name of which is started withWORK_DIRECTORY_PREFIX
and which does not contain a file with the nameUSAGE_MARKER_FILE_NAME
or contains such a file, but it is not locked, it means that this subdirectory is a "garbage" and can be removed. This method tries to remove all such subdirectories and returns true, if it has successfully removed all content of tempDirectory.Note: if this method was not able to remove some work directory (a subdirectory with name, started with
WORK_DIRECTORY_PREFIX
), and this directory is not locked viaUSAGE_MARKER_FILE_NAME
file (i.e. it is not in use now), this method performs several attempts to remove the work directory, calling System.gc() between attempts. Usually it helps to release resources (like file mappings), which prevents from removing such unused subdirectories.Note: this method does not try to remove the directory tempDirectory itself.
It is a good idea to call this method while starting your application and, maybe, after calling long-running external applications via
execute(ProcessBuilder)
method, to remove all "garbage" that was not deleted by normal calls ofclose()
method in this or previous calls of your application.- Parameters:
tempDirectory
- the path to the global disk directory for allocating temporary data; should be identical to the same argument ofgetInstance(ArrayContext, String, String)
method, which you use for instantiation this object (or you may usecleanup()
instead of this method, if you usegetInstance(ArrayContext)
method without the second argument).- Returns:
- true if and only this method has successfully removed all subdirectories
of the specified directory tempDirectory with names,
started with
WORK_DIRECTORY_PREFIX
. - Throws:
NullPointerException
- if tempDirectory argument is null.SecurityException
- if System.getProperty("java.io.tmpdir") call throws this exception.- See Also:
-
cleanup
public static boolean cleanup()Equivalent tocleanup
(getDefaultTempDirectory()
). If you usegetInstance(ArrayContext)
method only and don't usegetInstance(ArrayContext, String, String)
with a custom second argument, you can use this method instead ofcleanup(String)
.- Returns:
- true if and only this method has successfully removed all subdirectories
of
getDefaultTempDirectory()
with names, started withWORK_DIRECTORY_PREFIX
. - Throws:
SecurityException
- if System.getProperty("java.io.tmpdir") call throws this exception.
-
getDefaultTempDirectory
Returns the path to the default disk directory for storing temporary data: some "standard" subdirectory of the system temporary directory will be used. Namely, this method returnsnew File(System.getProperty("java.io.tmpdir"),
TEMP_SUBDIRECTORY_DEFAULT_NAME
).getPath()Note: this subdirectory is automatically created in
getInstance(ArrayContext)
method or ingetInstance(ArrayContext, String, String)
method, when its second argument is identical to the result of this method. However, this class never tries to remove this subdirectory: such an attempt could lead to errors if another application simultaneously tries to create this subdirectory. You may remove this subdirectory manually, for example, in the uninstaller of your software.- Returns:
- the default disk directory for storing temporary data.
- Throws:
SecurityException
- if System.getProperty("java.io.tmpdir") call throws this exception.- See Also:
-
getPropertyOrEnv
Returns the system property indicated by the specified key propertyKey, if it exists, or, if it is null, the environment variable indicated by the specified name envVarName. Equivalent to the following operator:System.getProperty(propertyKey) != null ? System.getProperty(propertyKey) : System.getenv(envVarName)
This method is often used to specify parameters of the called external programs, such as a path to the called application, to provide user both mechanisms of customization (system properties and system environment).
- Parameters:
propertyKey
- the key, indicating the system property.envVarName
- the name of the environment variable.- Returns:
- the system property / environment variable with the given key / name; null, if there is no system property with the given key and also there is no environment variable with the given name.
- Throws:
NullPointerException
- if one of the arguments is null.IllegalArgumentException
- if propertyKey is empty.SecurityException
- when this exception was thrown by System.getProperty or System.getenv method.- See Also:
-
getExistingPathFromPropertyOrEnv
public static File getExistingPathFromPropertyOrEnv(String propertyKey, String envVarName, File defaultPath) throws FileNotFoundException Returns new File(getPropertyOrEnv
(propertyKey,envVarName)), if such file or directory really exists, throws FileNotFoundException, if it does not exist, or returns defaultPath if it is not specified. More precisely, equivalent to the following:String s =
getPropertyOrEnv
(propertyKey, envVarName); File result = s != null ? new File(s) : defaultPath; if (result != null && !result.exists()) throw new FileNotFoundException(some message); return result;Note: this method returns null in the only case, when
getPropertyOrEnv
method returns null (there is no system property with the given key and there is no environment variable with the given name) and, at the same time, defaultPath==null. If this method returns some non-null result, then there is a guarantee that it is an existing path, in terms of java.io.File.exists() method.This method is used for retrieving path to some disk file or directory, which must exist, for example, the path to an external executable program, which you want to call.
- Parameters:
propertyKey
- the key, indicating the system property.envVarName
- the name of the environment variable.defaultPath
- the path, returned when both the system property and the environment variable are not specified; may be null.- Returns:
- the existing disk path, containing in the system property / environment variable with the given key / name, or null of there is no system property with the given key, there is no environment variable with the given name and defaultPath==null.
- Throws:
NullPointerException
- if propertyKey or envVarName argument is null.IllegalArgumentException
- if propertyKey is empty.SecurityException
- if this exception was thrown by System.getProperty or System.getenv method.FileNotFoundException
- if 1) the path, specified by the system property / environment variable, or 2) defaultPath if there is no such system property and environment variable, — does not correspond to an existing disk file or directory; note that in the 2nd case the exception is not thrown if defaultPath==null.- See Also:
-
getExistingPathFromPropertyOrEnv
public static File getExistingPathFromPropertyOrEnv(String propertyKey, String envVarName) throws FileNotFoundException CallsgetExistingPathFromPropertyOrEnv
(propertyKey,envVarName,null) and throws FileNotFoundException in a case of null result.This method may be used instead of
getExistingPathFromPropertyOrEnv(String, String, File)
, if you require that either the specified system property, or the environment variable must be specified and contain a correct existing disk path.- Parameters:
propertyKey
- the key, indicating the system property.envVarName
- the name of the environment variable.- Returns:
- the existing disk path, containing in the system property / environment variable with the given key / name; cannot be null.
- Throws:
NullPointerException
- if propertyKey or envVarName argument is null.IllegalArgumentException
- if propertyKey is empty.SecurityException
- if this exception was thrown by System.getProperty or System.getenv method.FileNotFoundException
- if some path is really specified by the system property / environment variable, but this path does not correspond to an existing disk file or directory, or if both System.getProperty and System.getenv method have returned null.- See Also:
-
getCurrentJREHome
Returns path to the home directory of the currently executed JRE. Equivalent to the following:new File(System.getProperty("java.home"));
Note: unlike
getCustomJREHome()
, here is no a strict guarantee that this method always returns an existing path. If the path, got from the system property "java.home", does not exists (very improbable situation), this method still returns it and does not throw FileNotFoundException.Note: if there is no system property "java.home" (also very improbable situation), i.e. if System.getProperty("java.home") returns null, this method throws InternalError.
- Returns:
- the home directory of the currently executed JRE,
- Throws:
SecurityException
- if this exception was thrown by System.getProperty.- See Also:
-
getCustomJREHome
Returns path to the home directory of some custom JRE, specified inJRE_PATH_PROPERTY_NAME
system property or inJRE_PATH_ENV_NAME
environment variable, or the home directory of the currently executed JVM if there is no such property / environment variable. Equivalent to the following:result =
getExistingPathFromPropertyOrEnv
(JRE_PATH_PROPERTY_NAME
,JRE_PATH_ENV_NAME
,getCurrentJREHome()
);Note: there is a guarantee that this method always returns an existing path, in terms of java.io.File.exists() method. If the path, got from system properties / environment, does not exists, this method throws FileNotFoundException.
- Returns:
- the home directory of the JRE, specified by
JRE_PATH_PROPERTY_NAME
/JRE_PATH_ENV_NAME
, or the result ofgetCurrentJREHome()
if it is not specified. - Throws:
SecurityException
- if this exception was thrown by System.getProperty or System.getenv method.FileNotFoundException
- ifgetExistingPathFromPropertyOrEnv(java.lang.String, java.lang.String, java.io.File)
method has thrown this exception.- See Also:
-
getCustomJREHome
Extended analog ofgetCustomJREHome()
method, allowing to specify some "name" of JRE, which is added as a suffix to the name of the corresponding system property or environment variable. It allows to use several different JREs, which you probably need in the same application. The typical recommended example of such usage is specifying the names "32" and "64": jreName="32" means that you need to work with 32-bit JRE, installed on the computer, jreName="64" means that you need to work with 64-bit JRE, installed on the computer, jreName=null means that the difference between JREs is not important and you need to work with some external JRE, globally customized for your application.More precisely, if jreName==null, this method is strictly equivalent to
getCustomJREHome()
method, and if jreName!=null, it is equivalent to the following:File namedHome =
getExistingPathFromPropertyOrEnv
(JRE_PATH_PROPERTY_NAME
+ "." + jreName,JRE_PATH_ENV_NAME
+ "_" + jreName, null); result = namedHome == null ?getCustomJREHome()
: namedHome;For example, if jreName is "64", then this method will check existence of system property "net.algart.arrays.jre.path.64" and environment variable "NET_ALGART_ARRAYS_JVM_OPTIONS_64". If one of them exists, this method will check existence of the disk path (probably folder), specified by this system property / environment variable, and either will return this path (if it exists), or will throw FileNotFoundException (if there is no such disk folder or file). In other case, i.e. if both system property "net.algart.arrays.jre.path.64" and environment variable "NET_ALGART_ARRAYS_JRE_PATH_64" are not found, this method will call
getCustomJREHome()
method, which will try to find JRE home directory, specified in the system property "net.algart.arrays.jre.path" and environment variable "NET_ALGART_ARRAYS_JRE_PATH". If one of them exists, the method, analogously, will check existence of the disk path (probably folder), specified by this system property / environment variable, and either will return this path (if it exists), or will throw FileNotFoundException (if not). At last, if both system property "net.algart.arrays.jre.path" and environment variable "NET_ALGART_ARRAYS_JRE_PATH" are also not found, the current JVM home directory will be returned: System.getProperty("java.home") (also with the check of existence: if this property contains non-existing disk path, FileNotFoundException will be thrown).Note: there is a guarantee that this method always returns an existing path, in terms of java.io.File.exists() method. If the path, got from system properties / environment, does not exists, this method throws FileNotFoundException.
- Parameters:
jreName
- some internal "name" of the required JRE; typical values are "32" or "64"; may be null, then this method is equivalent togetCustomJREHome()
.- Returns:
- the home directory of the JRE, specified by
the corresponding system property or environment variable,
or the result of
getCustomJREHome()
if it is not specified. - Throws:
SecurityException
- if this exception was thrown by System.getProperty or System.getenv method.FileNotFoundException
- ifgetExistingPathFromPropertyOrEnv(java.lang.String, java.lang.String, java.io.File)
orgetCustomJREHome()
method has thrown this exception.
-
getJavaExecutable
Returns the path to the "java" executable utility ("java.exe" on Windows platform), located inside the specified JRE home directory. If this method fails to find java utility, it throws FileNotFoundException.Note: there is a guarantee that this method always returns an existing path, in terms of java.io.File.exists() method (when it does not throw FileNotFoundException).
This method is useful when you want to execute an external program, written in Java: the result of this method should be passed as the first argument of the ProcessBuilder constructor.
- Parameters:
jreHome
- home directory of some JRE (for example, the result ofgetCurrentJREHome()
,getCustomJREHome()
orgetCustomJREHome(String)
method).- Returns:
- the path to "java" executable program, starting JVM of the specified JRE.
- Throws:
NullPointerException
- if the argument is null.FileNotFoundException
- if this method cannot find "java" utility.- See Also:
-
getCustomJVMOptions
Returns the list of JVM options (arguments of "java" executable utility), listed inJVM_OPTIONS_PROPERTY_NAME
system property or inJVM_OPTIONS_ENV_NAME
environment variable, or null if there is no such property / environment variable. JVM options (command line arguments) should be separated by spaces in this system property / environment variable, and there should be no spaces inside each option (argument). This method is typically used together withgetCustomJREHome()
.Equivalent to the following:
String jvmOptions =
getPropertyOrEnv
(JVM_OPTIONS_PROPERTY_NAME
,JVM_OPTIONS_ENV_NAME
); result = jvmOptions == null ? null : java.util.Arrays.asList(jvmOptions.split("\\s+"));We recommend you to include this list into the arguments of the ProcessBuilder constructor, when you are going to execute an external Java program via Java machine, returned by
getJavaExecutable(File)
method.- Returns:
- the list of JVM options, specified by
JVM_OPTIONS_PROPERTY_NAME
/JVM_OPTIONS_ENV_NAME
, or null if it is not specified. - Throws:
SecurityException
- if this exception was thrown by System.getProperty or System.getenv method.- See Also:
-
getCustomJVMOptions
Extended analog ofgetCustomJVMOptions()
method, allowing to specify some "name" of JRE, which is added as a suffix to the name of the corresponding system property or environment variable. It allows to use several settings for several JREs, which you probably need in the application. This method is typically used together withgetCustomJREHome(String)
.More precisely, if jreName==null, this method is strictly equivalent to
getCustomJVMOptions()
method, and if jreName!=null, it is equivalent to the following:String jvmOptions =
getPropertyOrEnv
(JVM_OPTIONS_PROPERTY_NAME
+ "." + jreName,JVM_OPTIONS_ENV_NAME
+ "_" + jreName); result = jvmOptions == null ?getCustomJVMOptions()
: java.util.Arrays.asList(jvmOptions.split("\\s+"));For example, if jreName is "64", then this method will check existence of system property "net.algart.arrays.jvm.options.64" and environment variable "NET_ALGART_ARRAYS_JVM_OPTIONS_64". If one of them exists, it will be parsed and returned; in other case, this method will call
getCustomJVMOptions()
.- Parameters:
jreName
- some internal "name" of the required JRE; typical values are "32" or "64"; may be null, then this method is equivalent togetCustomJVMOptions()
.- Returns:
- the list of JVM options, specified by
the corresponding system property or environment variable,
or the result of
getCustomJVMOptions()
if it is not specified. - Throws:
SecurityException
- if this exception was thrown by System.getProperty or System.getenv method.
-
writeUTF8
Writes the given text into the file in UTF-8 encoding. The file is fully rewritten and will contain this text only.- Parameters:
file
- the file which should be written.text
- some text data, which will be saved into this file.- Throws:
IOException
- if an I/O error occurs.- See Also:
-
readUTF8
Reads the full content of the given text file and returns it as a String. This file is supposed to be written in UTF-8 encoding.- Parameters:
file
- the file which should be read.- Returns:
- the full text content of this file.
- Throws:
IOException
- if an I/O error occurs.- See Also:
-
createTempDirectory
Creates a new empty unique subdirectory within the specified parent directory, using the given prefix to generate its name. It is an analog of java.io.File.createTempFile method, but creates a subdirectory, not a file.
The created subdirectory will be the following:
new java.io.File(parentDirectory, prefix + String.valueOf(n))
where n is some positive long integer value, initialized to some random value while the first call of this method and corrected while each new call. This subdirectory is created by java.io.File.mkdir() method; in a case of failure, several attemps are performed.- Parameters:
parentDirectory
- some parent directory; unlike java.io.File.createTempFile method, null is not allowed here.prefix
- the prefix string; unlike java.io.File.createTempFile method, here is no requirements for its length- Returns:
- new unique subdirectory of parentDirectory, created by this method.
- Throws:
NullPointerException
- if prefix or parentDirectory argument is null.IOException
- if a new subdirectory cannot be created.
-
context
Returns the current context used by this instance for some operations. This context is specified while creating an instance of this class.The context is used in
execute(ProcessBuilder)
method to allow the user to interrupt it. Namely, if the context is not null,execute(ProcessBuilder)
method periodically calls context.checkInterruption()
, and if some exception is thrown, terminates the external process by java.lang.Process.destroy().- Specified by:
context
in interfaceArrayProcessor
- Returns:
- the current context used by this instance; may be null.
-
getWorkDirectory
Returns the work directory of this processor, created bygetInstance(ArrayContext, String, String)
orgetInstance(ArrayContext)
method. SeegetInstance(ArrayContext, String, String)
method about "work directory" concept.The returned object contains an absolute path: File.getAbsoluteFile().
- Returns:
- the work directory of this processor.
- See Also:
-
getWorkFile
Equivalent to new File(getWorkDirectory()
, childFileName).- Parameters:
childFileName
- the child file name.- Returns:
- new File instance, describing the given file inside the work directory of this object.
- See Also:
-
writeWorkUTF8
Equivalent towriteUTF8
(getWorkFile
(childFileName),text).It is a useful method for inter-application communication with the called external program.
- Parameters:
childFileName
- the name of the file inside the work directory of this object.text
- some text data, which will be saved into this file.- Throws:
IOException
- if an I/O error occurs.
-
readWorkUTF8
Equivalent toreadUTF8
(getWorkFile
(childFileName)).It is a useful method for inter-application communication with the called external program.
- Parameters:
childFileName
- the name of the file inside the work directory of this object.- Returns:
- the full text content of this file.
- Throws:
IOException
- if an I/O error occurs.
-
getOutputStream
Returns the output stream, set bysetOutputStream(java.io.OutputStream)
method and used byexecute
method for duplication of the output stream of an external program. The default value is null — it is returned ifsetOutputStream(java.io.OutputStream)
was never called.- Returns:
- the current output stream, used by
execute
method for duplication of the output stream of an external program.
-
setOutputStream
Sets the stream for duplication of the output stream of an external program. If you set some non-null stream by this method, then theexecute(ProcessBuilder)
method will duplicate each line, written to the standard OS output stream by the called program, into this stream.- Parameters:
outputStream
- the output stream for duplication of the standard OS output stream of external programs; may be null, then it will be ignored.- See Also:
-
getErrorStream
Returns the error stream, set bysetErrorStream(java.io.OutputStream)
method and used byexecute
method for duplication of the error stream of an external program. The default value is null — it is returned ifsetErrorStream(java.io.OutputStream)
was never called.- Returns:
- the current error stream, used by
execute
method for duplication of the error stream of an external program.
-
setErrorStream
Sets the stream for duplication of the error stream of an external program. If you set some non-null stream by this method, then theexecute(ProcessBuilder)
method will duplicate each line, written to the standard OS error stream by the called program, into this stream.Note: even when this stream is null (default value), if the called program was finished unsuccessfully, i.e. with non-zero OS exit code, you can get the full content of the error stream of the called program by
getExternalProcessErrorMessage()
method of theExternalProcessException
, thrown byexecute(ProcessBuilder)
method.- Parameters:
errorStream
- the output stream for duplication of the standard OS error stream of external programs; may be null, then it will be ignored.- See Also:
-
setSystemStreams
public void setSystemStreams()Equivalent to two calls:setOutputStream
(System.out) andsetErrorStream
(System.err). -
execute
Executes the external program by process=processBuilder.start() call and waits until it will terminate by process.waitFor() call. In addition to these main actions, this method:
- periodically calls
checkInterruption()
of the currentcontext
of this object (if it is not null), and if that method throws an exception (that means: the user wants to stop calculations), automatically terminates the external process via process.destroy() call and re-throws that exception again (as ifcheckInterruption()
was called in the current thread);
- catches the system output and error streams of the called external program
(via process.getInputStream() and process.getErrorStream())
and, if
setOutputStream(java.io.OutputStream)
and/orsetErrorStream(java.io.OutputStream)
methods were called with non-null argument, duplicates the text, written into output/error stream of the external program, to the specified streams;
- checks the result of process.waitFor() (an exit code of the external application),
and, if it is non-zero, throws
ExternalProcessException
; in this case, you can retrieve the returned exit code and the full content of the OS error stream of the external application viaExternalProcessException.getExternalProcessExitCode()
andExternalProcessException.getExternalProcessErrorMessage()
methods.
Note: this method cannot be used after closing this object by
close()
method.Note: if writing into the streams, set by
setOutputStream(java.io.OutputStream)
orsetErrorStream(java.io.OutputStream)
methods, lead to IOException, this exception is ignored.- Parameters:
processBuilder
- the process builder, which will used for calling external application (by processBuilder.start() call).- Throws:
IOException
- if processBuilder.start() has thrown this exception, or if process.waitFor() has returned non-zero result (it will beExternalProcessException
in the last case).IllegalStateException
- ifclose()
method of this instance was already called.RuntimeException
- this method also can throw all runtime exceptions, which are thrown by processBuilder.start() call.
- periodically calls
-
cancelRemovingWorkDirectory
public void cancelRemovingWorkDirectory()Cancels automatic removing of the work directory, created while instantiation of this object, inclose()
method. If you call this method at least once, then the further call ofclose()
will just set the state of this instance to "successfully closed
" and will not try to remove the temporary disk data, which you possibly used for exchanging information with an external program. It can be useful for debugging needs.Note that this method does not cancel removing data, performed by
cleanup()
andcleanup(String)
methods. -
isRemovingWorkDirectoryCancelled
public boolean isRemovingWorkDirectoryCancelled()Returns true if and only if the methodcancelRemovingWorkDirectory()
was called at least once.- Returns:
- whether automatic removing of the work directory is cancelled by
cancelRemovingWorkDirectory()
method.
-
close
public void close()Tries to fully (recursively) remove the work directory, created while instantiation of this object (if this action was not cancelled bycancelRemovingWorkDirectory()
call), and sets the state of this instance to "closed
". SeegetInstance(ArrayContext, String, String)
method about "work directory" concept.You must call this method after finishing usage of this object. We strongly recommend you to call it in the finally section of your code. After this call, you cannot use
execute(ProcessBuilder)
method, though can use other methods — in particular, you can call this method again.There is no guarantee that this method successfully removes the work directory. This method can fail, for example, when some temporary files, used for exchanging data with an external program, are locked by OS, and we cannot unlock them immediately after termination of the external program — it can be connected with file mapping (in particular, mapping via
LargeMemoryModel
, which is unmapped in Java while garbage collection only).If this method has successfully removed the work directory or if the removing was cancelled by
cancelRemovingWorkDirectory()
call, thenisClosedSuccessfully()
method will return true, and further calls of this method do nothing. If this method was not able to remove all content of the work directory,isClosedSuccessfully()
method will return false. In this case, you may try to call this method again after some time or after a call of System.gc(). In any case, after the first call of this method,isClosed()
method returns true andexecute(ProcessBuilder)
method throws IllegalStateException.- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
- See Also:
-
isClosed
public boolean isClosed()Returns true if this instance is "closed", i.e. ifclose()
method was called at least once. You cannot callexecute(ProcessBuilder)
method for closed objects — it will throw IllegalStateException.- Returns:
- whether this object is already closed and, so, cannot be used for calling external programs.
- See Also:
-
isClosedSuccessfully
public boolean isClosedSuccessfully()Returns true if this instance is "closed" and all its temporary data were successfully removed, i.e. ifclose()
method was called and it has successfully removed thework directory
of this object. If automatic removing of the work directory was cancelled bycancelRemovingWorkDirectory()
method, then call of this method usually returns true afterclose()
(though the temporary data were not removed). If this method returns true, thenisClosed()
method also returns true.- Returns:
- whether this object is already closed and its work directory is successfully completely removed.
-
toString
Returns a brief string description of this factory.The result of this method may depend on implementation.
-