Kohei Nozaki's blog 

Entries tagged [jbatch]

Restarting a stopped job with jberetweb


Posted on Friday Jan 09, 2015 at 09:30PM in jberetweb


Assume that there is a job execution which is STOPPED on the Job Executions table like following. let's see a drop-down list at right end of the row. you can take some actions for each job executions with this "Action" drop-down list.

スクリーンショット 2015-01-09 19.58.29.png

This drop-down list contains some actions like following (for STOPPED one).

スクリーンショット 2015-01-09 19.59.00.png

There are 3 actions available. "Restart" means restarting this execution as a new execution but inherit job instance from previous one. "Abandon" means abandoning this execution as won't be used again. after abandoning, restarting will be impossible. "Re-execute as new instance" means opening "Start Job" window with inheriting both of job name and job parameters of selected instance. also "Stop" is available for running executions.

After selection of Restart, pop-up window will be appeared like following.

スクリーンショット 2015-01-09 20.02.51.png

This window looks similar to "Start Job" window, but Job Name editing is prohibited because this is about to restarting of previous execution. you can edit Job Parameters as well as regular job execution but initial value of them will be inherited if they exists in previous execution.


How to make jberetweb to invoke BatchRuntime.getJobOperator() directly


Posted on Wednesday Jan 07, 2015 at 07:32PM in jberetweb


While I prefer to deploy both of jberetweb.war and your batch application archive independently and invoke JobOperator through remote EJB invocation, there is an another option which make jberetweb to invoke BatchRuntime.getJobOperator() directly instead of remote EJB lookup.

Just suppress mvn parameter "-DjobOperator.jndi" when you build your jberetweb WAR (please refer README.md), then jberetweb starts invoke BatchRuntime directly instead of using remote interface. of course, then you have to embed or merge your batch application archive and jberetweb into one WAR or EAR.

I don't recommend this way because this makes deployment time of your application longer due to JSF and JPA initializing. and you have to care about consistency for both of JSF and JPA configuration between your application and jberetweb. but it might be a solution where remote EJB invocation is not allowed by some security reasons (EJBAccessException might be occured when jberetweb tries to lookup remote JobOperator interface on such environment).


Index needed on jobexecutionid column in step_execution table


Posted on Monday Jan 05, 2015 at 09:56PM in jberetweb


Today I deployed new jberetweb to my production system which have 1 million rows in step_execution table, and felt jberetweb slow. I looked it and found the cause is sequential scan.

jbatch=# explain analyze select * from step_execution where jobexecutionid = 384846;
                                                    QUERY PLAN                                                    
------------------------------------------------------------------------------------------------------------------
 Seq Scan on step_execution  (cost=0.00..36817.53 rows=4 width=626) (actual time=101.046..101.047 rows=2 loops=1)
   Filter: (jobexecutionid = 384846)
   Rows Removed by Filter: 1102459
 Total runtime: 101.074 ms
So I created an index on jobexecutionid column in step_execution table, then jberetweb starts running fast.
jbatch=# create index step_execution_jobexecutionid_idx on step_execution (jobexecutionid);
CREATE INDEX
jbatch=# explain analyze select * from step_execution where jobexecutionid = 384846;
                                                                     QUERY PLAN                                                                     
----------------------------------------------------------------------------------------------------------------------------------------------------
 Index Scan using step_execution_jobexecutionid_idx on step_execution  (cost=0.43..8.50 rows=4 width=626) (actual time=0.054..0.056 rows=2 loops=1)
   Index Cond: (jobexecutionid = 384846)
 Total runtime: 0.113 ms
Maybe more indexes are needed for default JBeret schema if I implement some filtering function to jberetweb.


jberetweb TODOs


Posted on Sunday Jan 04, 2015 at 10:37PM in jberetweb


Just for memo. I think this list could be moved to GitHub's issue tracker.

  • Operation support for various application archive / remote interface
  • Save preferences such as visible columns to cookie
  • Change some of Integer id columns to Long
  • Refreshing of execution detail part
  • Variable / closable table area
  • In-cell editing of a value of job parameter table
  • Add clear button to job parameter table
  • Improve pagination for larger data set
    • Jump to specified execution id or page number directly
    • Clickable page numbers (1 2 3 4 5...)
    • Selection of number of rows in single page
  • Job schedule managing (like cron) with EJB programmatic timer
  • Job name completion (with JobOperator#getJobNames() ?)
  • Filtering / Sorting
    • Show BatchStatus=FAILED only etc
    • Sorting in ascending order
  • Covering omitted information
    • job_execution.exitstatus, job_execution.restartposition etc
    • Checkpointinfo would be useful. just pass it to String.valueOf() after deserialize
  • Testing against MySQL, Derby, H2, newer WildFly etc
  • Row highlighting/coloring for various statuses (STARTING/STARTED/STOPPING/STOPPED/ABANDONED). currently cares COMPLETED/FAILED only.
  • Refactoring (especially I think current CSS/HTML design is terrible due to my bad in client side web technology)
  • Use of REST API (would following spec of BatchEE be good?)


Job operation features are implemented to jberetweb


Posted on Sunday Jan 04, 2015 at 09:26PM in jberetweb


Now jberetweb is able to operate JobOperator interface through remote EJB invocation, so finally jberetweb can start batch jobs. the Start Job window popups when "Start Job" anchor is clicked on the upper right corner. here's a screenshot:

スクリーンショット 2015-01-04 20.53.13

To use this feature, some preparation are needed. first, you have to expose a remote EJB interface of javax.batch.operations.JobOperator from your batch application archive. an example of simplest one is available here. also entire of the project is here.

You can just put this class to any package in your batch application archive. after that, you can see some notification of JNDI names in your WildFly console at every deployment like this:

21:06:45,501 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-10) JNDI bindings for session bean named JobOperatorFacade in deployment unit deployment "jbatchtest-1.0-SNAPSHOT.war" are as follows:

java:global/jbatchtest-1.0-SNAPSHOT/JobOperatorFacade!javax.batch.operations.JobOperator
java:app/jbatchtest-1.0-SNAPSHOT/JobOperatorFacade!javax.batch.operations.JobOperator
java:module/JobOperatorFacade!javax.batch.operations.JobOperator
java:jboss/exported/jbatchtest-1.0-SNAPSHOT/JobOperatorFacade!javax.batch.operations.JobOperator
java:global/jbatchtest-1.0-SNAPSHOT/JobOperatorFacade
java:app/jbatchtest-1.0-SNAPSHOT/JobOperatorFacade
java:module/JobOperatorFacade

Then save first one of yours ("java:global/jbatchtest-1.0-SNAPSHOT/JobOperatorFacade!javax.batch.operations.JobOperator" for example), then put that string to a build parameter of jberetweb (after "-DjobOperator.jndi="). please refer "How to use" section of README.md for build instruction.

Other operations such as restart, stop, abandon are implemented too so I will write more about it later. jberetweb can be obtained from GitHub.