How to integrate Spring batch command line invocation in a shell script - shell

I am having a spring batch application, that is invoked through the command line. I would want to put that invocation in a shell script, so that I can run a script rather than the entire command.
For example, my invocation looks like:
java -jar run=1
The problem is for each run, the job parameter needs to be incremented. Is there a way through which i can achieve that in a shell script?
Thanks

You need an incrementer for this as usual.
<bean id="simpleIncrementer"
class="org.springframework.batch.core.launch.support.RunIdIncrementer"/>
<job id="myJob" incrementer="simpleIncrementer">
</job>
The trick for this incrementer to work with CommandLineJobRunner is adding the -next parameter when running the task.
-next: (optional) to start the next in a sequence according to the JobParametersIncrementer in the Job
Something like this:
java –jar myjob.jar jobs/myjob.xml myjob -next

You can do it n times (in a terminal) using a for loop this way:
for i in {1..10}; do java -jar run=$i; done

Related

How to pass command line arguments to Spring Batch

This is my first time working on a spring batch project. So I need to know how to pass arguments to the main class in a .sh file. The project is currently working and .sh file has a command line like this:
java -Xmx2048M -jar somebatch-SNAPSHOT.jar applicationContext.xml
And I want to pass arguments by changing this command. the project runs all jobs at the main class so job names are not specified in the command. What I want to do is pass arguments so I can select which jobs will run. Something like this:
java -Xmx2048M -jar somebatch-SNAPSHOT.jar --argument 1 applicationContext.xml
I don't need to pass the arguments to the jobParameters like java -jar somejar.jar somejob value=1 as shown in some examples. I only need a value in the main class.
Any help is appreciated.
I don't need to pass the arguments to the jobParameters like java -jar somejar.jar somejob value=1 as shown in some examples. I only need a value in the main class.
In this case, you can pass parameters on the command line with -Dparam=value and then get them in your main class using System.getProperty("param").

Pentaho running script from outside spoon directory

I have a shell script that should run the pentaho transforamtion job but it fails with the following error:
/data/data-integration/spoon.sh: 1: /data/data-integration/spoon.sh: ldconfig: not found
Here's the shell script which sits in:
/home/tureprw01/
and the script:
#!/bin/sh
NOW=$(date +"%Y%m%d_%H%M%S")
/data/data-integration/./pan.sh -file=/data/reporting_scripts/op/PL_Op.ExtlDC.kjb >> /home/tureprw01/logs/PL_Op.ExtDC/$NOW.log
I'm completely green in terms of Java but need to make it work somehow
Using command line executions for Pan / Kitchen is simple, This Documentation should help you create the Batch/SH command and make it work.
Though i see you are using variable creation on the command line, personally i do not know if the Batch/SH variable is passed down correctly to the PDI parameters, you'd have to test that yourself, or use this variable definition within the PDI structure, not as a named parameter.
use this :
!/bin/sh
NOW=$(date +"%Y%m%d_%H%M%S")
cd /data/reporting_scripts/op/
/data/data-integration/spoon.sh -main org.pentaho.di.pan.Pan -initialDir /data/data-integration -file=/data/reporting_scripts/op/PL_Op.ExtlDC.kjb
#!/bin/bash
# use for jobs if you want to run transform change :
# "org.pentaho.di.kitchen.Kitchen" to "org.pentaho.di.pan.Pan" and insert ktr file
export PENTAHO_JAVA_HOME=/root/app/jdk1.8.0_91
export JAVA_HOME=/root/app/jdk1.8.0_91
cd /{kjb path}/;
/{spoon path}/spoon.sh -main org.pentaho.di.kitchen.Kitchen -initialDir /{kjb path}//{kjb file}.kjb -repo=//{kjb path}/{resource file}.xml -logfile=/{log file}.log -dir=/{kjb path}

Calling two functions in Windows batch file one after the other

I have two scripts which are to be executed and i am using Windows batch script for automating of running the scripts.
I have to read 10 user input values and then run the two scripts using those parameters.
I am successful in executing the first script and failing with the second script.
Issue is that the cmd prompt exits after completing the first script.
How to make cmd prompt run the second script as well using the input parameters.
Any Help on this??
Thanks in Advance.
You have two options to execute a batch script from you code. It's either START or CALL:
START will execute your code in it's own variable scope, means the variables you've set in the first script won't be available. Further both scripts will be executed in parallel and not one after another (unless you use START /WAIT).
CALL on the other hand will do exactly what you need. It will start the first script in the same scope (previously set variables are variable), execute it and afterwards it will run the second sript (also in the same scope).
TL;DR this will work:
...
CALL BatchScript1.bat
CALL BatchScript2.bat
...
If you call scripts from another script you have to use the call command:
#echo off
call first.cmd
call second.bat
echo Here I'm back again !

Cannot execute shell script without command line manual classpath update first

I hope this is fairly simple but I'm struggling to get this to work.
I have a java package which I want to execute using a shell script command...
/jdk1.7.0/bin/java .path.to.classname.ClassToExecute >> /var/log/output.log
...so essentially...
./SCRIPT_NAME
...should run the above from the command line.
The problem is there is a classpath update needed every time first from the command line to enable the session to see a particular JAR...
export CLASSPATH=$CLASSPATH:/path/to/jar/file/lib/JAR_NAME.jar:.
If I don't put this line in first the shell script will not execute throwing errors of NoClassDefFoundError relating to the JAR I need to add manually.
Can anyone tell me where I need to edit this classpath update so that it's ALWAYS available to the script and also to the cron as ultimately I want to call it from the cron?
Thanks,
ForestSDMC
Your shell script should look like this.
#!/bin/bash
export CLASSPATH=$CLASSPATH:/path/to/jar/file/lib/JAR_NAME.jar:.
/jdk1.7.0/bin/java .path.to.classname.ClassToExecute >> /var/log/output.log
You also need to change the permissions of the script so that it is executable
chmod 700 SCRIPT_NAME
700 = owner can only execute the script
770 = owner and members of a group can run the script
777 = everyone who has access to the server can run the script.
Noticed that you want to run this from cron. You need to source your .profile either from the crontab entry or from within the script.
Just found the answer and works fine so hopefully others will find this useful...
You can dynamically generate the classpath variable within the shell script and then apply it as an attribute to the java command line execution. Like this...
THE_CLASSPATH=
for i in `ls /path/to/the/JARS/lib/*.jar`
do
THE_CLASSPATH=${THE_CLASSPATH}:${i}
done
/usr/bin/java -cp ".:${THE_CLASSPATH}" path.to.the.class.ClassName >> /var/log/logfile.log

Get unix script to behave as if it was run from a different folder

I am using a scheduler to run a unix script which starts up my application. The script is in the PATH of the user used by the scheduler. Hence, can be run from an y
My application log files are created relative to where the script is run from. Unfortunatley, the scheduler does not run the script from the folder I had hoped hence log files are not going to correct folder.
Is there any way in I get the script to run and behaves as it was run from a specified folder, e.g. ./ScriptName.sh Working_Folder | Run_Folder
Note: I cannot change the script
if your scheduler run your tasks using a shell (which it probably do) you can use { cd /log/dir ; script; } directly as command.
if not, you need to use a wrapper script as stated by #Gilles but i would do:
#!/bin/sh
cd /log/dir
exec /path/to/script "$#"
to save a little memory. The extra exec will make sure only the script interpreter is in memory instead of both (sh and the script interpreter).
If you can't change the script, you'll have to make the scheduler run a different command, not the script directly. For example, make the scheduler run a simple wrapper script.
#!/bin/sh
cd /desired/directory/for/log/files
/path/to/script "$#"

Resources