Execution of bash file with java file from crontab [duplicate] - java

This question already has answers here:
cronjob does not execute a script that works fine standalone
(3 answers)
Closed 6 years ago.
I wrote a bash file in which I am executing java file, its working properly if I am executing it but when I am trying with crontab it is not ,please help.
this is my crontab :
*/5 * * * * /home/import.sh >/dev/null 2>&1
this is my bash file:
- me=$(date +%Y-%m-%d)
mkdir -p /home/importRequirement"$foldername"
{
java -jar ImportRequirement1.jar
java -jar ImportRequirement1.jar
}
2>importRequirement"$foldername"/log$(date +%Y-%m-%d-%H-%M-%S).txt
I have deleted the url.

When a script is intended to be started from a non interactive environment (cron or init), none of the usual goodies such as custom path or other environment variable are set.
The rule is:
ensure all the commands (except at most those in /bin and /usr/bin) use full path
ensure all required environment variables are set
If you use many scripts that way, you could build a setenv script that declares all environment variables and create ones for every command you use. Here it will contain (more or less):
export JAVAHOME=...
export JAVA=/path/to/java
Then you can use in your script:
$(JAVA) -jar ImportRequirement1.jar
but here again you should either have a previous cd to the expected directory or use absolute path of jar

The environment variables for cron jobs is not the same as what users get when they are logged in. Double check the environment variables you need to run your script (ie JAVA_HOME and PATH).
cron might not know with what to interpret your script, you might want to place
#!/bin/bash
on the first line of your bash script.

Related

Replicating `export` command in jar to set environment variable

Scenario
While executing a series of commands using the ProcessBuilder I noticed I am currently not able to set an environment variable such that it remains "known" after a set of commands has been executed.
Question
How do I recreate the effects* of the export TASKDDATA=/var/taskd command in a .jar file?
Attempt 0
ProcessBuilder environment variable in java Provides a way to set the environment variable for each specific command, but when I execute the .jar of that solution and check if the environment variable $u is still set after execution, I find it is not. Whereas $TASKDDATA does remain set after execution. To illustrate:
a#DESKTOP-desktopName:/mnt/e$ echo $TASKDDATA
a#DESKTOP-desktopName:/mnt/e$ TASKDDATA=/var/taskd
a#DESKTOP-desktopName:/mnt/e$ echo $TASKDDATA
/var/taskd
a#DESKTOP-desktopName:/mnt/e$ sudo java -jar autoInstallTaskwarrior.jar
[sudo] password for a:
Process ended with rc=0
Standard Output:
util/
Standard Error:
a#DESKTOP-desktopName:/mnt/e$ echo $TASKDDATA
/var/taskd
a#DESKTOP-desktopName:/mnt/e$ echo $u
Attempt 1
For a single command the environment variable can be using the solution I wrote in: Java ProcessBuilder how to get binary output from command. However that does not conserve the taskvariable for a second command in which it needs to be set again. However, when the export command is used, the environment variable is not required to be set again. Specifically this difference comes to light when the java code is finished and the user wants to enter any additional commands that require the environment variable. In that case, the user needs to first type the export command again.
Attempt 2
An additional difference occurs when a new shell is opened to acquire root priviliges with sudo -s. Not only does setting the environment within the .jar file require setting it again for every separate command but additionally the environment variable is not passsed along to the new shell with root priviliges. For example executing the following commands:
commandLines[53] = new String[4];
commandLines[53][0] = "sudo";
commandLines[53][1] = "-s";
commandLines[53][2] = "taskdctl";
commandLines[53][3] = "start";
commands[53].setCommandLines(commandLines[53]);
commands[53].setEnvVarContent("/var/taskd");
commands[53].setEnvVarName("TASKDDATA");
commands[53].setWorkingPath("/usr/share/taskd/pki");
commandLines[54] = new String[5];
commandLines[54][0] = "sudo";
commandLines[54][1] = "-s";
commandLines[54][2] = "task";
commandLines[54][3] = "sync";
commandLines[54][4] = "init";
commands[54].setCommandLines(commandLines[54]);
commands[54].setEnvVarContent("/var/taskd");
commands[54].setEnvVarName("TASKDDATA");
commands[54].setWorkingPath("/usr/share/taskd/pki");
returns:
53RUNNINGCOMMAND=sudo -s taskdctl start
The TASKDDATA variable must be set.
54RUNNINGCOMMAND=sudo -s task sync
Could not connect to 0.0.0.0 53589
Sync failed. Could not connect to the Taskserver.
Syncing with 0.0.0.0:53589
Note 1
Setting the environment variable $TASKDDATA=/var/taskd before executing the .jar with: TASKDDATA=/var/taskd sudo java -jar autoInstallTaskwarrior.jar does not ensure the environment variable $TASKDDATA remains available after the execution of the .jar file. Furthermore it is beyond the scope of the question as it is not set within the .jar file but outside the .jar file.
Note 2
I understood it is not appropriate to use the export command as a command that is executed by the processbuilder, much like the cd command.
*That is why the question focuses on reproducing the "longterm/lasting" effect/availability of setting the environment variable, rather than "how to execute the export command.".
when I execute the .jar of that solution and check if the environment variable $u is still set after execution, I find it is not.
That is the expected behavior. Some operating systems support the concept of global "environment" variables. But not UNIX. In UNIX like operating systems every process has its own private copy of environment vars. A process cannot modify the environment of another process. This is also why changing the current working directory in a process does not change the cwd of its parent process. Each process has its own cwd.
The usual way to workaround that limitation is for the child process to write the var=val pairs to stdout and the parent shell then evaluates that output to set the vars in its environment. For illustration assume the command is the following shell script, named myscript.sh, rather than a Java program:
#!/bin/sh
echo VAR_A=val_a
echo VAR_B=val_b
Then the parent shell does
export $(./myscript.sh)

Running jar with cron throws error: '/bin/sh: 1: java: not found'

I have scheduled my job to run every day at 12:30 with this command:
30 12 * * * java -jar test.jar
It throws error:
/bin/sh: 1: java: not found
I tried to run this command: java -jar test.jar from shell and it worked just fine.
Now I don't understand. I would say it is happening because JAVA_HOME environment variable is not set, but then why it works from shell?
The error tells you that the shell could not locate the java binary to execute. This has nothing to do with the JAVA_HOME environment variable, but with the PATH variable which is consulted by sh to find any command.
When you run your task from cron, the shell did not receive the same initialization as your interactive shell where the command works for you. You'll equally find that JAVA_HOME isn't set there, either.
Your login shell environment is different from the one your cronjob has. Use envto print your environment.
Check the path on both -
Within cron (something like)
30 08 * * * env > ~/cronenv.
In your login shell just use env. Then compare the PATH variables.
As #Marko Topolnik already stated your PATH within cron obviously does not contain your java executables.
You can add a line into your crontab file that contains the path that you need:
# m h dom mon dow command
PATH=.....
You probably need something like this:
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
You can also use echo $PATH to find out what you have in your regular environment and simply use that value.
Another option i tried is to use the path of the java installed.
Make sure java is installed with below command
java -version
Check the path of java installed
whereis java
provide the full path to run the app
30 12 * * * /path_from_prev_step/java -jar test.jar
This will also allow you to run this jar with different java portable version if the server has a older version installed.

Ubuntu now able to set java path

I have installed oracle jdk in /usr/lib/jvm/ and i have setted up path in etc/environment as
JAVA_HOME=/usr/lib/jvm/jdk1.7.0_51
PATH=$PATH:$JAVA_HOME/bin
But still when i am running javac, I am getting following error. The program 'javac' can be found in the following packages:
* default-jdk
* ecj
* gcj-4.6-jdk
* gcj-4.7-jdk
* openjdk-7-jdk
* openjdk-6-jdk
It means javac is not installed or java path has not setted properly, however i am able to see javac,java,jps and other programs in my /usr/lib/jvm/jdk1.7.0_51. I have searched enough about it but still not able to get solution of this problem.
The file /etc/environment is not a file executed by the shell (like a shell script); you cannot use $SOMETHING references in this file. Variables are not substituted in this file. So,
JAVA_HOME=/usr/lib/jvm/jdk1.7.0_51
PATH=$PATH:$JAVA_HOME/bin
the second line will not work like this. You have to put the exact path in.
JAVA_HOME=/usr/lib/jvm/jdk1.7.0_51
PATH=...:/usr/lib/jvm/jdk1.7.0_51/bin
The javac binary (and probably other java binaries) is/are not in your user's $PATH environment variable. There are several ways you can address this:
Add /usr/lib/jvm/jdk1.7.0_51/bin to your user's $PATH
environment variable. You can do this by adding a line similar to
the following in your user's .bash_profile:
export PATH=${PATH}:/usr/lib/jvm/jdk1.7.0_51/bin
You'll have to restart your terminal session for it to take effect.
Create symbolic links to the java binaries from some directory
that's already part of your path (such as /usr/bin)
sudo ln -s /usr/lib/jvm/jdk1.7.0_51/bin/java /usr/bin/
sudo ln-s /usr/lib/jvm/jdk1.7.0_51/bin/javac /usr/bin/
BTW: There are several other java executables in /usr/lib/jvm/jdk1.7.0_51/bin. see the symlink commands for java and javac above. You should run similar command for any other executables you may want to use.
Use the fully qualified path directly on the command line:
$ /usr/lib/jvm/jdk1.7.0_51/bin/javac
https://help.ubuntu.com/community/Java
have you tried this page? Its where I go when I need Java info. You may not have the one you installed set as default.
Could it be that you did not refresh the shell after change in path variable?
if you echo $PATH are the changes present?

Crontab + ubuntu + java not working

If I directly run the bellow code in terminal it is working perfect.
/usr/bin/java -jar /var/jboss-as-7.1.1.Final/standalone/email_linux/notification_18.jar
But when I set the same as a crontab in ubuntu server then it is not working.
*/3 * * * * /usr/bin/java -jar /var/jboss-as-7.1.1.Final/standalone/email_linux/notification_18.jar
Any one know why unexpected behavior?
The crontab task is executed under a different user from the one with which you are testing the call. JBoss depends on a number of environment variables, which are probably undefined in that context. So find out what that particular JAR needs from the environment and then add it into a shell script which you run from the cron task (instead of directly running java from cron).
Make sure that you have included the absolute paths in the source code if you are reading or writing to a file, even if the jar file and the reading file are in the same directory.
It is resolved after specifying absolute path

Environmental variables not seen in a cron [duplicate]

This question already has answers here:
How to get CRON to call in the correct PATHs
(15 answers)
Closed last year.
So I've run into a bit of an issue. My workplace uses environmental variables on it's machines and we've recently switched our dev / prod servers to unix-based solutions (RHEL 6) and we're trying to get some of our old programs to run with a cron. The envir variables are running on the box itself (Example: Server1=dev-server.intranet.net or something along those lines) but we're running into issues where a cron is in place.
Example.
java -jar MyProgram.jar -- Works fine
MyProg.sh - Works fine
JAVA_HOME=/usr/data/java/current
PATH=$JAVA_HOME/bin
export JAVA_HOME
export PATH
java -jar /usr/data/apps/MyProg/MyProg.jar
When calling MyProg.sh from a cron, it doesn't work, as it can't see the envir variables at all.
Can someone offer some insight to how to make this work with a cron?
Thanks.
JAVA_HOME and PATH doesn't need to be set
Can you try
/usr/data/java/current/java -jar /usr/data/apps/MyProg/MyProg.jar
I ended up solving this problem by doing a
source /etc/profile.d/MyVars.sh
which got my environmental variables back in place.
Cron always runs with a mostly empty environment. HOME, LOGNAME, and SHELL are set; and a very limited PATH.
In order to available all environment variable, We need to load ~/.profile file before running given command.
In my case i used below commands.
40 11 * * * . $HOME/.profile; /shellPath/bin/execute-job.sh START 5 >> /home/sampleuser/cron.log 2>&1
execute-job.sh
nohup java -Dlog4j.configuration=file:/shellPath/conf/log4j.properties -cp /shellPath/libs/scheduler-0.1.jar com.scheduler.Scheduler $1 $2 > /dev/null 2>&1 &

Categories