public class JesClient extends Object implements Closeable
JES spool entries can be filtered and listed using
list(String, JobStatus, String) and
listFilled(String, JobStatus, String) methods, while the later one
gathers more information, but takes some more time.
submit(String) submits JCLs based on the FTP users permissions.
waitFor(Job, Duration, Duration) can be used to wait until a job
terminates. Job outputs can be retrieved using retrieve(JobOutput)
and removed using delete(Job).
Usage example: The following shows the JesClient used inside a try-with-resource statement. The constructor descriptions describe further details.
// Connect and login via simplified constructor
try (JesClient jesClient = new JesClient(hostname, port, username, password)) {
// Submit JCL
Job job = jesClient.submit(jclContent);
// Wait for job to be finished
if (!jesClient.waitFor(job)) {
// Handle the case, a finished job cannot be found inside JES spool any longer
throw ...;
}
// Gather job status details
Job detailedJob = jesClient.getJobDetails(job);
// Gather finished jobs outputs
List<JobOutput> jobOutput = jesClient.get(job);
// Delete job from JES spool
jesClient.delete(job);
// Logout and disconnect using try-with-resource (close method)
}
In case filtering jobs does not work as expected, check the JES Interface
Level of your server using getServerProperties(). This class
requires JESINTERFACELEVEL = 2. The JES Interface Level can be
configured by a mainframe administrator inside FTP.DATA.
| Modifier and Type | Field and Description |
|---|---|
static String |
FILTER_WILDCARD
Wildcard value to be used for name and owner filters, meaning "any" value.
|
static int |
LIST_LIMIT_MAX
Maximum limit of spool entries (including)
|
| Constructor and Description |
|---|
JesClient()
Expert constructor.
|
JesClient(String hostname,
int port,
String username,
String password)
Simplified constructor.
|
| Modifier and Type | Method and Description |
|---|---|
void |
close()
Logs out and disconnects the FTP connection.
|
void |
delete(Job job)
Removes a given
job from JES spool. |
void |
enterJesMode()
Enters the IBM z/OS FTP servers JES file type mode using a SITE command.
|
boolean |
exists(Job job,
JobStatus status)
Reloads the job from server and returns
true if the job is still
available and matches the given job status. |
org.apache.commons.net.ftp.FTPClient |
getFtpClient()
FTP Client used by the current JES client instance.
|
String |
getJesOwner()
Current JES spool user
|
Optional<Job> |
getJobDetails(Job job)
Retrieves up-to-date job details for
job. |
Map<String,String> |
getServerProperties()
Retrieves and parses a map of server properties, such as
"JESJOBNAME", "JESSTATUS", "JESOWNER" and
"INTERFACELEVEL". |
List<Job> |
list(String nameFilter)
Returns a list of all job IDs boxed into
Job objects matching the
given filters. |
List<Job> |
list(String nameFilter,
JobStatus status)
Returns a list of all job IDs boxed into
Job objects matching the
given filters. |
List<Job> |
list(String nameFilter,
JobStatus status,
String ownerFilter)
Returns a list of all job IDs boxed into
Job objects matching the
given filters. |
List<Job> |
list(String nameFilter,
JobStatus status,
String ownerFilter,
int limit)
Returns a list of all job IDs boxed into
Job objects matching the
given filters. |
List<Job> |
listFilled(String nameFilter)
Returns a list of all
Job objects matching the given filters. |
List<Job> |
listFilled(String nameFilter,
JobStatus status)
Returns a list of all
Job objects matching the given filters. |
List<Job> |
listFilled(String nameFilter,
JobStatus status,
String ownerFilter)
Returns a list of all
Job objects matching the given filters. |
List<Job> |
listFilled(String nameFilter,
JobStatus status,
String ownerFilter,
int limit)
Returns a list of all
Job objects matching the given filters. |
void |
login(String username,
String password)
Shortcut method to perform a FTP login, set the internal JES owner and enter
JES mode.
|
String |
retrieve(JobOutput jobOutput)
Retrieves the content of
jobOutput. |
Map<JobOutput,String> |
retrieveOutputs(Job job)
Retrieves all job outputs of
job. |
protected void |
setJesFilters(String nameFilter,
JobStatus status,
String ownerFilter,
int limit)
Sends
FTPCmd.SITE commands to set the
given filter values. |
void |
setJesOwner(String jesOwner)
Current JES spool user
|
Job |
submit(String jclContent)
Submits the given JCL and returns a related
Job object containing the
started jobs ID. |
protected List<Job> |
throwIfLimitReached(int limit,
List<Job> jobs)
In case the last FTP responses string contains the spool entries limit
warning, a
JesLimitReachedException is thrown, else jobs are
returned. |
boolean |
waitFor(Job job,
Duration waiting,
Duration timeout)
Waits for
job to be finished using Thread#sleep(long) for
waiting between exists(Job, JobStatus) calls and timing out after a
given duration. |
boolean |
waitFor(Job job,
Duration waiting,
Duration timeout,
Consumer<Duration> wait)
Waits for
job to be finished using wait for waiting between
exists(Job, JobStatus) calls and timing out after a given duration. |
public static final String FILTER_WILDCARD
public static final int LIST_LIMIT_MAX
public JesClient()
Usage example 1 (using a simplified login)
// Construct the JES client and its internal FTP client
try (JesClient jesClient = new JesClient()) {
// Connect via FTP
jesClient.getFtpClient().connect(...);
// Simplified login using the JES client
jesClient.login(...);
...
// Logout and disconnect using try-with-resource (close method)
}
Usage example 2: (using a custom login)
// Construct the JES client and its internal FTP client
try (JesClient jesClient = new JesClient()) {
// Connect via FTP
jesClient.getFtpClient().connect(...);
// Login via FTP client
jesClient.getFtpClient().login(...);
// Set the JES spool owner
jesClient.setJesOwner(...);
// Enter JES mode of the FTP connection
jesClient.enterJesMode();
...
// Logout and disconnect using try-with-resource (close method)
}
public JesClient(String hostname, int port, String username, String password) throws IOException, JesException
The JesClient can store a JES spool owner. This constructor initializes the JES spool owner using the given username.
The default port is FTP.DEFAULT_PORT.
Warning: This constructor calls the overridable method
login(String, String), which might lead to uninitialized fields when
overriding that method.
hostname - FTP hostnameport - FTP portusername - FTP username and JES spool ownerpassword - FTP passwordIOException - Technical FTP failureJesException - Logical JES failurepublic void close()
throws IOException
close in interface Closeableclose in interface AutoCloseableIOExceptionpublic void delete(Job job) throws IOException, JesException
job from JES spool. This method cares only about the
jobs ID.
In case you do not already have a Job object, deleting by job ID
works as follows:
String jobId = ...; jesClient.delete(new Job(jobId, JesClient.FILTER_WILDCARD, JobStatus.ALL, JesClient.FILTER_WILDCARD));
job - Job to be deletedIOException - Technical FTP failureJesException - Logical JES failurepublic void enterJesMode()
throws IOException,
JesException
IOException - Technical FTP failureJesException - Logical JES failurepublic boolean exists(Job job, JobStatus status) throws IOException, JesException
true if the job is still
available and matches the given job status.job - the job to search forstatus - job status or ALLtrue if the job is still availableIOException - Technical FTP failureJesException - Logical JES failurepublic Optional<Job> getJobDetails(Job job) throws IOException, JesException
job. That includes all
Job attributes, including a list of JobOutput instances for
held jobs.job - job to get up-to-date details forOptional.empty() in case the job is no longer
available inside JES spoolIOException - Technical FTP failureJesException - Logical JES failurepublic Map<String,String> getServerProperties() throws IOException, JesException
"JESJOBNAME", "JESSTATUS", "JESOWNER" and
"INTERFACELEVEL".IOException - Technical FTP failureJesException - Logical JES failurepublic List<Job> list(String nameFilter) throws IOException, JesException
Job objects matching the
given filters. This method has a much higher performance compared to
listFilled(String), though that method fills in additional
Job fields.
nameFilter is allowed to end with the wildcard character "*".
JES does not list more than LIST_LIMIT_MAX entries. In case more
entries are available, a JesLimitReachedException is thrown,
containing all entries up to the limit.
nameFilter - filter by job namesIOException - Technical FTP failureJesException - Logical JES failurepublic List<Job> list(String nameFilter, JobStatus status) throws IOException, JesException
Job objects matching the
given filters. This method has a much higher performance compared to
listFilled(String, JobStatus), though that method fills in
additional Job fields.
nameFilter is allowed to end with the wildcard character "*".
JES does not list more than LIST_LIMIT_MAX entries. In case more
entries are available, a JesLimitReachedException is thrown,
containing all entries up to the limit.
nameFilter - filter by job namesstatus - filter by job statusIOException - Technical FTP failureJesException - Logical JES failurepublic List<Job> list(String nameFilter, JobStatus status, String ownerFilter) throws IOException, JesException
Job objects matching the
given filters. This method has a much higher performance compared to
listFilled(String, JobStatus, String), though that method fills in
additional Job fields.
nameFilter and ownerFilter are allowed to end with the
wildcard character "*".
JES does not list more than LIST_LIMIT_MAX entries. In case more
entries are available, a JesLimitReachedException is thrown,
containing all entries up to the limit.
nameFilter - filter by job namesstatus - filter by job statusownerFilter - filter by job ownerIOException - Technical FTP failureJesException - Logical JES failurepublic List<Job> list(String nameFilter, JobStatus status, String ownerFilter, int limit) throws IOException, JesException
Job objects matching the
given filters. This method has a much higher performance compared to
listFilled(String, JobStatus, String, int), though that method fills
in additional Job fields.
nameFilter and ownerFilter are allowed to end with the
wildcard character "*".
JES does not list more than limit entries. In case more entries are
available, a JesLimitReachedException is thrown, containing all
entries up to the limit. limit can be from LIST_LIMIT_MIN
(including) to LIST_LIMIT_MAX (including).
nameFilter - filter by job namesstatus - filter by job statusownerFilter - filter by job ownerlimit - limit of spool entriesIOException - Technical FTP failureJesException - Logical JES failurepublic List<Job> listFilled(String nameFilter) throws IOException, JesException
Job objects matching the given filters. This
method has a worse performance compared to list(String), though it
fills in additional Job fields.
nameFilter is allowed to end with the wildcard character "*".
JES does not list more than LIST_LIMIT_MAX entries. In case more
entries are available, a JesLimitReachedException is thrown,
containing all entries up to the limit.
nameFilter - filter by job namesIOException - Technical FTP failureJesException - Logical JES failurepublic List<Job> listFilled(String nameFilter, JobStatus status) throws IOException, JesException
Job objects matching the given filters. This
method has a worse performance compared to list(String, JobStatus),
though it fills in additional Job fields.
nameFilter is allowed to end with the wildcard character "*".
JES does not list more than LIST_LIMIT_MAX entries. In case more
entries are available, a JesLimitReachedException is thrown,
containing all entries up to the limit.
nameFilter - filter by job namesstatus - filter by job statusIOException - Technical FTP failureJesException - Logical JES failurepublic List<Job> listFilled(String nameFilter, JobStatus status, String ownerFilter) throws IOException, JesException
Job objects matching the given filters. This
method has a worse performance compared to
list(String, JobStatus, String), though it fills in additional
Job fields.
nameFilter and ownerFilter are allowed to end with the
wildcard character "*".
JES does not list more than LIST_LIMIT_MAX entries. In case more
entries are available, a JesLimitReachedException is thrown,
containing all entries up to the limit.
nameFilter - filter by job namesstatus - filter by job statusownerFilter - filter by job ownerIOException - Technical FTP failureJesException - Logical JES failurepublic List<Job> listFilled(String nameFilter, JobStatus status, String ownerFilter, int limit) throws IOException, JesException
Job objects matching the given filters. This
method has a worse performance compared to
list(String, JobStatus, String), though it fills in additional
Job fields.
nameFilter and ownerFilter are allowed to end with the
wildcard character "*".
JES does not list more than limit entries. In case more entries are
available, a JesLimitReachedException is thrown, containing all
entries up to the limit. limit can be from LIST_LIMIT_MIN
(including) to LIST_LIMIT_MAX (including).
nameFilter - filter by job namesstatus - filter by job statusownerFilter - filter by job ownerlimit - limit of spool entriesIOException - Technical FTP failureJesException - Logical JES failurepublic void login(String username, String password) throws IOException, JesException
Is similar to the following lines of code.
// Login via FTP client jesClient.getFtpClient().login(...); // Set the JES spool owner jesClient.setJesOwner(...); // Enter JES mode of the FTP connection jesClient.enterJesMode();
username - the user id to be used for FTP login and internal JES ownerpassword - the users passwordIOException - Technical FTP failureJesException - Logical JES failurepublic String retrieve(JobOutput jobOutput) throws IOException, JesException
jobOutput.jobOutput - job output to be requestedIOException - Technical FTP failureJesException - Logical JES failurepublic Map<JobOutput,String> retrieveOutputs(Job job) throws IOException, JesException
job.job - job to request all outputs ofIOException - Technical FTP failureJesException - Logical JES failureprotected void setJesFilters(String nameFilter, JobStatus status, String ownerFilter, int limit) throws IOException, JesException
FTPCmd.SITE commands to set the
given filter values.
nameFilter and ownerFilter are allowed to end with the
wildcard character "*".
limit can be from LIST_LIMIT_MIN (including) to
LIST_LIMIT_MAX (including). While that restriction is not checked by
this method, values outside that range might result in a server side error
message thrown as JesException.
nameFilter - filter by job namesstatus - filter by job statusownerFilter - filter by job ownerlimit - limit of spool entriesIOException - Technical FTP failureJesException - Logical JES failurepublic void setJesOwner(String jesOwner)
jesOwner - JES spool ownerpublic Job submit(String jclContent) throws IOException, JesException
Job object containing the
started jobs ID.
In addition to the jobs ID this method tries to extract the jobs name from
the given JCL. The returned owner is set to the internal JES owner, which can
be set using setJesOwner(String).
jclContent - JCL to submitJob object containing the started jobs IDIOException - Technical FTP failureJesException - Logical JES failureprotected List<Job> throwIfLimitReached(int limit, List<Job> jobs) throws JesLimitReachedException
JesLimitReachedException is thrown, else jobs are
returned.
The thrown exception contains the current spool entries limit and all entries, which were read already.
limit - current spool entries limitjobs - list of jobsjobs in case the spool entries limit is not reachedJesLimitReachedException - if the last FTP responses string contains
the spool entries limit warningpublic boolean waitFor(Job job, Duration waiting, Duration timeout) throws InterruptedException, IOException, JesException
job to be finished using Thread#sleep(long) for
waiting between exists(Job, JobStatus) calls and timing out after a
given duration. waiting allows to specify the duration to wait.
The given jobs status specifies, which status are waited for:
JobStatus.ALL: waiting for JobStatus.INPUT and
JobStatus.ACTIVE
JobStatus.INPUT: waiting for JobStatus.INPUT and
JobStatus.ACTIVE
JobStatus.ACTIVE: waiting for JobStatus.ACTIVE only
JobStatus.OUTPUT: returning true with no checks and
without waiting
job - the job to wait forwaiting - duration to waittimeout - timeout durationtrue if the job finished and false if the timeout has
been reachedInterruptedException - if any thread has interrupted the current threadIOException - Technical FTP failureJesException - Logical JES failurepublic boolean waitFor(Job job, Duration waiting, Duration timeout, Consumer<Duration> wait) throws IOException, JesException
job to be finished using wait for waiting between
exists(Job, JobStatus) calls and timing out after a given duration.
waiting allows to specify the duration to wait.
The given jobs status specifies, which status are waited for:
JobStatus.ALL: waiting for JobStatus.INPUT and
JobStatus.ACTIVE
JobStatus.INPUT: waiting for JobStatus.INPUT and
JobStatus.ACTIVE
JobStatus.ACTIVE: waiting for JobStatus.ACTIVE only
JobStatus.OUTPUT: returning true with no checks and
without waiting
job - the job to wait forwaiting - duration to waittimeout - timeout durationwait - method to use for waitingtrue if the job finished and false if the timeout has
been reachedIOException - Technical FTP failureJesException - Logical JES failurepublic org.apache.commons.net.ftp.FTPClient getFtpClient()
public String getJesOwner()
Copyright © 2025. All rights reserved.