Bug 4559 - How does JobOperator#getJobNames() work?
How does JobOperator#getJobNames() work?
Status: RESOLVED WORKSFORME
Product: jbatch
Classification: Unclassified
Component: source
1
All All
: P5 major
: ---
Assigned To: cvignola
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2013-01-18 15:51 UTC by mminella
Modified: 2014-05-11 07:24 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description mminella 2013-01-18 15:51:16 UTC
In section 7.8.10 on page 98, the JobOperator defines a method, getJobNames().  How can the runtime be aware of more than one job if jobs are loaded only when launched (per section 7.6.  Section 7.6 should actually be clarified to include JobOperator.restart as well).  Is this a list of all jobs that have run/been run?  In SB, it is the list of all jobs that can be launched via the start method, however that depends on a JobRegistry backing it (which is not a feature defined in the spec).
Comment 1 cvignola 2013-01-23 18:49:15 UTC
It returns a list of unique job names from across all JobInstances stored in the job repository.  Section 4.4 identifies that the job repository contains JobInstances.
Comment 2 mminella 2013-01-23 21:42:55 UTC
To clarify, since we do not prescribe what the repository is (persistent or not, etc) in the spec, this means that JobOperator#getJobNames() would return at least the names of any Jobs that have run since the runtime was bootstrapped.  We cannot guarantee anything more than that.  Is that correct?
Comment 3 cvignola 2013-01-24 02:13:32 UTC
(In reply to comment #2)

Yes, I would say that is correct.

> To clarify, since we do not prescribe what the repository is (persistent or
> not, etc) in the spec, this means that JobOperator#getJobNames() would return
> at least the names of any Jobs that have run since the runtime was
> bootstrapped.  We cannot guarantee anything more than that.  Is that correct?
Comment 4 hbeto 2014-04-15 12:06:21 UTC
If JobOperator#getJobNames() returns "... at least the names of any Jobs that have run since the runtime was bootstrapped", we won't be able to do simple things like enabling the user/admin to chose which job he/she wants to start from the user interface. We would need to hardcode the names in the application, which is not elegant.

It's also weird that the method JobOperator#getJobNames() is named like that when it actually returns ids, not names.

It would be interesting to have the API extended to show jobs' metadata, as described in the XML files.
Comment 5 ScottKurz 2014-04-15 13:47:38 UTC
The values returned by JobOperator#getJobNames() are "job names", not "Job XML names".   And yes, "job name" = job @id value.

Given that the "jobXMLName" parameter passed to JobOperator.start() is resolved in an implementation-specific way (except for the META-INF/batch-jobs usecase), the two values aren't necessarily going to have affinity in the general case (the common denominator imposed by the spec).
Comment 6 hbeto 2014-04-19 15:55:08 UTC
I believe that's semantically incorrect when an API names a method getNames() when it actually returns ids.

You say that "the values returned by JobOperator#getJobNames() are 'job names', not 'Job XML names'", but I don't see the difference because right after you say that the "jobXMLName" parameter is passed to JobOperator.start(). However, when the method JobOperator#getJobNames() eventually works, returning "job names" not "job XML names", we can use those names in the method JobOperator.start().

As a user, it's very frustrating when we call JobOperator#getJobNames() and don't get any result sometimes. I would like to give this feedback here to help on the maintenance release that is on going.
Comment 7 BrentDouglas 2014-04-19 18:33:21 UTC
I would look at it like JobOperator#getJobNames() returns a set of the result of calling JobInstance#getJobName() for each JobInstance persisted in the underlying job repository. I also wouldn't go passing them into #start(...) as these values are in no way required to be related to the name of the jobXML file (as Scott said).

If you have been observing that this 'works' it is probably because you have been following a naming convention of <job id="blah">...</job> goes in blah.xml. If you want to determine the names of the XML files in the batch-jobs directory you should read them directly. Something like this but with more thought and less typos:

public static Set<String> getJobXmlNames() {
    final ClassLoader loader = ClassFromYourJar.class.getClassLoader();
    URL url = loader.getResource("META-INF/batch-jobs");
    if (url == null) {
        url = loader.getResource("WEB-INF/classes/META-INF/batch-jobs");
    }
    if (url == null) {
        return Collections.<String>emptySet();
    }
    final Set<String> names = new HashSet<String>();
    for (final String filename : new File(url.toURI()).list()) {
        if (filename.endsWith(".xml") {
            names.add(filename.substring(0, filename.length() - 4);
        }
    }
    return names;
}

Of course implementations are required to provide their own job loader as well so to get job XML names from them you would need to consult their documentation.
Comment 8 hbeto 2014-04-21 18:52:17 UTC
Thanks for the clarification.

Indeed, I'm lucky that I've named XML files the same way I've set ids parameters. Otherwise, JobOperator#start() wouldn't work. 

But I'm still wondering why the API works with two distinct names, using jobXMLName to start a job and jobName to get job instances or number of instances or running executions. It's confuse that we load a job with the name of the XML file and we end up with another name (id) during runtime.

Btw, I have tried the method to retrieve the list of XML files. That's cool, but it's not portable. Here is the most portable code I could get: https://github.com/htmfilho/yougi/blob/master/src/main/java/org/cejug/yougi/business/JobSchedulerBean.java#L83, but still not sure it is 100%. This portability issue would be perfectly addressed by different implementations, where each provider would implement their getJobXmlNames() according to the peculiarities of their app servers.
Comment 9 ScottKurz 2014-05-09 17:29:31 UTC
(In reply to hbeto from comment #8)

hbeto, 

I just wanted to note that I'm not planning on including this in the current maintenance release, which I've been presenting in terms of "clarifying existing behaviors without introducing new APIs".   

I think the API behavior is clear enough (not the most straightforward to begin with) for now.  Introducing a more standard way to get at the Job XML name would then be something for "later", potentially.

Just as a process note:  I don't mind having a conversation on a "RESOLVED" bug, but if we need to keep something open for the future it's best to open a new one, so I don't filter it out going forward.

Thanks
Comment 10 hbeto 2014-05-11 07:24:15 UTC
That's ok Scott. Thanks for your feedback.