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 Closeable
close
in interface AutoCloseable
IOException
public 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.