I have a JAVA code to create and execute .sh file. The problem is - .sh file is getting created but not getting executed via the JAVA code. When run manually from terminal or cronjob, it gets executed. The big problem is - same code is working fine on all DEV servers but not on client PROD environment with CentOS 6.8. It is also working fine on Client UAT environment with CentOS 6.5.
The code creates executable sh file on the application server and executes it. sh file contained commands sqlldr and sqlplus to upload data via batch upload mechanism. When executed successfully, a log file is created with output of execution. Any errors like are written in the log file. When sh file is not executed, log file is also not created. When executed manually from terminal, sh file is executed and log file is also created. Below are the contents of sh file
sqlldr user/pass#db CONTROL=CTL_1000004453.ctl silent=all
echo -e "UPDATE QT_BATCH_UPLOAD SET UPLOAD_STATUS = 20 WHERE UPLOAD_ID = 1000004453;
commit;
exit;
" > SET_STATUS_1000004453.SQL
sqlplus user/pass#db #SET_STATUS_1000004453.SQL
No error is getting obtained in application and server logs. Application is running on Weblogic server. I have checked and eradicated all permission related issues.
Please help if anyone has encountered such non-replicating issue ever.
Below is the code.
try
{
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(new String[] { "/bin/bash", "-c", "cd " + path + " ;chmod a+x " + exeFile + "; sh " + exeFile + ";" });
BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
FileOutputStream file3 = new FileOutputStream(path + "CONSOLE_" + uploadID + ".LOG");
String line; while ((line = br.readLine()) != null) { String line;
System.out.println(line);
file3.write((line + System.getProperty("line.separator")).getBytes());
file3.flush();
}
file3.close();
}
Issue has been resolved. No change in code was required. Actually the app server (Weblogic) was being run via console. I did some R&D and asked the client to run it via putty/terminal, post which, the code ran fine.
I would still look for solutions to get the same working when weblogic runs via console.
Related
Converting several of my shell scripts to Node, so I can learn Node, in shell I typically run a JAR file with the command:
java -jar validate.jar test.json >> results.txt
When researching how to run a JAR in Node I ran across "How to run a jar file with node.js child_process API?" with the accepted answer indicating the .jar extension is not needed.
Following the advise I did a npm install child_process after reading "How to Create JAR file and Using child_process OR shell script to Execute"
wrote my my script and received an error which was the same error:
Error: Unable to access jarfile /home/example/Applications/example.jar
After stepping through I found that on my Mac the .jar extension was required to work properly. I understand the answer is from 2012 and it's 2019 but is the answer incorrect or is it OS dependent to call the extension?
Here is the code I've written:
let jarFile = __dirname + '/validate.jar'
let theFile = 'test.json'
let outputFile = 'result.txt'
let runCommand = '/usr/bin/java -jar ' + jarFile + ' ' + theFile
// return console.log(runCommand)
var exec = require('child_process').exec
child = exec(runCommand, function (error, stdout, stderr) {
if(error !== null) {
console.log('exec error: ' + error)
} else {
console.log('stdout: ' + stdout);
}
})
The code works fine but before learn how to write to a file I want to understand when calling a JAR file is the extension required or not and is that different depending on the OS? I'm currently using Node v6.12.3.
I need to restart the tomcat from Java code.
For eg, if a query is not executed for a certain time Period then it will restart the tomcat automatically.
I have tried the following shutdown and startup code, but when we shutdown the tomcat then the java code will not run and tomcat not started.
Note :- I am running this code from a application and restarting the same tomact which the same application is using.
Following the code
try {
PreparedStatement.setQueryTimeout(10);
rs = PreparedStatement.executeQuery();
} catch (SQLException ex) {
System.out.println("IN CATCH BLOCK FOR THE REFRESH INVOICE");
String shutcommand = "killall java";
Process shutchild = Runtime.getRuntime().exec(shutcommand);
System.out.println("JAVA PROCESS KILLED");
String locationCommand = "cd /root/cluster/tomcat6/bin";
Process locationChild = Runtime.getRuntime().exec(locationCommand);
String strtcommand = "./startup.sh";
Process strtchild = Runtime.getRuntime().exec(strtcommand);
}
Killing tomcat after SQLException this is not good idea to handle this exception. Probably the problem is on database site.
But if you are sure, that it is what you need you can kill this java proces in this section, but to run tomcat you should use for example bash and cron. Why? Beacues after killing your executing code will stop, so you don't achieve the line to start tomcat.
How to check tomcat: Is Tomcat running?
TL;DR
File binaryDir = new File(System.getProperty("catalina.home") + File.separator + "bin");
String restartCommand = "\"shutdown.bat & ping 0.0.0.0 -n 4 & C:\\WINDOWS\\system32\\net start Tomcat8\"";
new ProcessBuilder("cmd", "/c", restartCommand).directory(binaryDir).start();
Survive
Creating new process will survive JVM shutdown. If you combine commands in one line
it should work fine according to my tests and this.
shutdown.bat
You need to use shutdown.bat instead stopping windows service because it often fails on Windows with message Cannot stop service Apache Tomcat...
ping 0.0.0.0 -n 4
You need to wait some time after shutdown otherwise you will get Service is already starting. Try again later error message. Also note I use ping instead timeout because it causes problems on some systems.
C:\WINDOWS\system32\net start Tomcat8
I'm starting windows service because invoking startup.bat won't work for me. Also remember to replace Tomcat8 if you using different tomcat or custom service name for example Tomcat7
Redirect I/O
Don't redirect input or output of process instance or command will shutdown with JVM, and Tomcat won't start.
You can execute this native command using java
String command = "c:\program files\tomcat\bin\startup.bat";//for linux use .sh
Process child = Runtime.getRuntime().exec(command);
You should consider using ProcessBuilder instead of Runtime exec. Also, you should split all the arguments when you want to execute a command.
I suggest this :
ProcessBuilder shutcommand = new ProcessBuilder("killall", "java");
Process shutchild = shutcommand.start();
System.out.println("JAVA PROCESS KILLED");
ProcessBuilder strtcommand = new ProcessBuilder("/root/cluster/tomcat6/bin/startup.sh", "java");
Process strtchild = strtcommand.start();
I am trying to run a mysql command from java that takes input from an sql script file using apache commons-exec as shown below
filepath = /path/to/file.sql
CommandLine commandLine = new CommandLine("mysql -uuser -ppassword dbname");
commandLine.addArgument("<");
commandLine.addArgument(filepath);
Executor executor = new DefaultExecutor();
executor.execute(commandLine);
But I keep getting the following error
[junit] java.io.IOException: Cannot run program "mysql -uuser
-ppassword dbname" (in directory "."): error=2, No such file or directory
When I run on the terminal,
the command executes normally and db gets modified. Why is this happening ?
Try CmdTool library.
String filepath ="/path/to/file.sql";
List<String> commandLine = new ArrayList<>(Arrays.asList("mysql", "-uuser", "-ppassword", "dbname"));
commandLine.add("<");
commandLine.add(filepath);
new Cmd().command(commandLine).execute();
Or simpler
new Cmd().command("mysql", "-uuser", "-ppassword", "dbname", "<", filepath).execute();
You can find more examples here.
I have been breaking my head for two days trying to fix the file permissions for my tomcat7 server. I have a library class (.jar file included in myapp/WEB-INF) which needs to run a shell script. The library is written by me and works fine within NetBeans ie. no hassle in creating,reading and deleting files. That is because NetBeans runs the program as blumonkey(my username on my Ubuntu System). But when I import this into tomcat and run it, tomcat "executes" the command, produces no definite output, tries to check for a file(which will be generated when the script succeeds) and throws a FileNotFoundException.
More Details as follows:
Tomcat7 installed using apt-get, has its data in 2 locations - /var/lib/tomcat7 with conf and webapps folders and /usr/share/tomcat7 with the bin and lib folders
The user uploads a .zip file which is stores to /home/blumonkey/data. Rest of the program runs on the documents stored here. All new folders/files uploaded by tomcat have, obviously, tomcat7 as the owner.
I have tried things like changing the ownership to blumonkey, adding tomcat7 to blumonkey user group but none of the methods worked (Somewhere around here I probably messed up changing permissions carelessly :/ ). Apparently tomcat7 is unable to process on the files it owns.(How can this be?).
The script works when I run it in the terminal. But it doesn't work when I do a sudo -u tomcat7 script.sh, ie run it as tomcat7. It just exits with no message. I doubt that this it what is happening as I have tried to debug by redirecting the errors and outputs in ProcessBuilder but they came empty.
Any help regarding how to fix the issue and get the script running would be greatly appreciated. Please comment if you need any more info.
The code for script execution
private static void RunShellCommandFromJava(String command,String fn, String arg1,String arg2) throws Exception
{
try
{
System.out.println(System.getProperty("user.name"));
ProcessBuilder pbuilder = new ProcessBuilder("/bin/bash",command,fn,arg1,arg2);
System.out.println(pbuilder.command());
pbuilder.redirectErrorStream(true);
Process p = pbuilder.start();
p.waitFor();
}
catch(Exception ie)
{
throw ie;
}
}
The command which needs to be executed
"/bin/bash /abs/path/to/script.sh /abs/path/to/doc/in/data-folder maxpages=30 maxsearches=3"
PS : I have followed this question but it didn't help. I also tried other options like Runtime.exec(), bash,/bin/bash/ and /bin/bash/ -c, some of them don't work at all, others give no results.
Try to use Runtime and check standard error to find out what was the problem (probably permissions or paths):
// run command
String[] fixCmd = new String[] { "/bin/bash", "/abs/path/to/script.sh", "/abs/path/to/doc/in/data-folder", "maxpages=30", "maxsearches=3" };
Process start = Runtime.getRuntime().exec(fixCmd);
// monitor standard error to find out what's wrong
BufferedReader r = new BufferedReader(new InputStreamReader(start.getErrorStream()));
String line = null;
while ((line = r.readLine()) != null) {
System.out.println(line);
}
I have a .bat file on a remote machine. I want to invoke it through http call. I dont want to make any changes on the remote machine. Is there a way to do it using java and http?
String command = "cmd /C start C:/Users/abc/Desktop/test.bat";
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);
The above works good to invoke a .bat file on local machine. I would not mind considering other ways too, but invoking it through http would be the first choice.
EDIT:
I am using paramiko to do this now. However,I am unable to run the remote commands on the command prompt.
ssh = paramiko.SSHClient()
print "Enter the IP address"
ip = raw_input("ip>")
print "Enter the username"
user = raw_input("username>")
print "Enter the password"
pwd = raw_input("password>")
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip, username=user, password=pwd, allow_agent = False)
print "connection successfull"
i, o, e = ssh.exec_command("echo test") # example command
s = e.read()
if s: # an error occurred
raise RuntimeError, s
result = o.read()
print result
Somehow it says AllowDesktopAccess failed
You need a service on the remote machine, for example an http server that is configured to run this script on demand (eg via cgi) or an ssh server you can connect to to issue the command.
Since you're using windows (I assume) then PsExec may be the service you need.
http://technet.microsoft.com/en-us/sysinternals/bb897553