java process builder adding path to environment not working - java

I am using intellij both on my imac and mac book. when i run the following code on my mac book, everything works.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class Main {
public ProcessBuilder pb;
public Main(){
try {
pb = new ProcessBuilder();
pb.directory(new File("~/IdeaProjects/test"));
Map<String, String> env;
env = pb.environment();
env.put("PATH", "/usr/local/fsl/bin/");
} catch (Exception e) {
e.printStackTrace();
}
}
public void getMeanImage(String base, String file){
List<String> cmd = new LinkedList<>();
cmd.add("fslmaths");
cmd.add(base + file);
cmd.add("-Tmean");
cmd.add(base + file + "_mean");
pb.command(cmd);
try {
String s = "";
Process p = pb.start();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String [ ] args) {
Main m = new Main();
m.getMeanImage("", "scan.nii.gz");
}
}
On the imac I run into problems. I copied the PATH value used by printenv.
env.put("PATH", "/usr/local/fsl/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin");
I get the exception:
java.io.IOException: Cannot run program "fslmaths" (in directory "~/IdeaProjects/test"): error=2, No such file or directory
Why can't the process builder find the program fslmaths in /usr/local/fsl/bin on the imac?
which fslmaths
/usr/local/fsl/bin/fslmaths
thanks in advance,
Martin

I found the solution. In the 'Run/Debug Configurations' of intellij under 'Environment Variables' the checkbox 'Include parent environment variables' was not enabled.

Related

how to run Run a linux command(curl) through java and to get the xml response

I want to execute a Linux command (curl) using java code
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class ExecuteShellCommand {
public String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
public static void main(String args[]) {
ExecuteShellCommand com = new ExecuteShellCommand();
System.out.println(com.executeCommand(
"curl -u '<username><pw>' -k <host>/services/search/jobs -d search=\"abc""));
System.out.println("hello");
The console output is printing hello only with no errors though when i tried the command in git bash it will give a xml response.

Problem in setting date and time from java code

I am trying to set the date and time of a linux system from a remote system using Java. In order to do that I have created a server to accept time from the remote system as:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Set_date_n_time {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
String date_time = new String();
//#SuppressWarnings("resource")
ServerSocket s1 = new ServerSocket(7105);
System.out.println("server started");
while (true) {
Socket sckt = s1.accept();
InputStream input = sckt.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
date_time = reader.readLine();
String command="sudo date -s "+"\""+date_time+"\"";
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
System.out.println ("date set");
p.destroy();
} catch (Exception e) {}
}
}
}
and the remote system from which the time will be copied as:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Fix_my_Date {
public static void main(String args[]) throws IOException {
String addr_list=args[0];
String[] hostList = readAddressList(addr_list);
for(int i=0; i<hostList.length;i++) {
setDate(hostList[i]);
}
}
//#SuppressWarnings("resource")
private static void setDate(String address) throws IOException {
{
Scanner sc = new Scanner(System.in);
Socket s = null;
String date =new String();
String time = new String();
try {
s = new Socket(address, 7105);
System.out.println("connection to "+address+" done");
Process p, p1;
try {
p = Runtime.getRuntime().exec("date +%Y%m%d");
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
date = br.readLine();
br.close();
p.waitFor();
p.destroy();
p1 = Runtime.getRuntime().exec("date +%H:%M:%S");
BufferedReader br1 = new BufferedReader(
new InputStreamReader(p1.getInputStream()));
time = br1.readLine();
br1.close();
p1.waitFor();
p1.destroy();
PrintStream pr = new PrintStream(s.getOutputStream());
pr.print(date+" "+time+"");
sc.close();
s.close();
} catch (Exception e) {
System.out.println("Problem Setting date and time");
}
//s.close();
} catch (Exception e) {
System.out.println("Couldn't connect to: "+address+"");
sc.close();
//s.close();
}
}
return;
}
private static String[] readAddressList(String addr_list) throws IOException {
FileReader fileReader = new FileReader(addr_list);
BufferedReader bufferedReader = new BufferedReader(fileReader);
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = bufferedReader.readLine()) != null)
{
lines.add(line);
}
bufferedReader.close();
System.out.println("Loaded the host list");
return lines.toArray(new String[lines.size()]);
}
}
But the time is not being set by the server code. Where is my mistake?
The mistake I, you, and lots of others make is also (besides the other helpful answers here) that you don't read Standard Output and Standard Error and if your command produces any output or error it blocks because there is no buffer that it can write to which you may observe with strace.
This could be fixed with an extra thread as described here: https://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
If you use sudo it might fail depending on the sudo settings if it doesn't allow sudo without a terminal (requiretty), see for more info e.g.: https://bugzilla.redhat.com/show_bug.cgi?id=1196451
Are you trying to set the time on a VM? If that's the case, it may be set to synchronise to the host which overwrites your date -s command.
I could not get it to work (yet) with Runtime.exec(), but it works perfectly with ProcessBuilder. Here it is:
package set_date_n_time;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Set_date_n_time {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
String date_time = new String();
//#SuppressWarnings("resource")
ServerSocket s1 = new ServerSocket(7105);
System.out.println("server started");
while (true) {
Socket sckt = s1.accept();
InputStream input = sckt.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
date_time = reader.readLine();
ProcessBuilder builder = new ProcessBuilder("date", "--set=" + date_time + "");
final Process p = builder.start();
p.waitFor();
p.destroy();
}
}
}
Obviously you have to run as root and make sure you run
sudo systemctl stop systemd-timesyncd.service
or something similar to make sure the system does not override you date fixing.
In case you need, or prefer, to use Runtime.exec() then (don't ask me why) just change:
String command = "sudo date -s " + "\"" + date_time + "\"";
to
String[] command = new String[]{"sudo", "date", "-s", date_time};
in class Set_date_n_time.
Replace this:
} catch (Exception e) {}
With this:
} catch (Exception e) {
throw new IllegalStateException("Unexpected exception", e);
}
As Ole V.V. said, the empty catch-block in your code is almost certainly discarding real failures you care about. I would guess that either sudo is rejecting the call or the command itself is malformed. The exception will tell you exactly what is going wrong.
If you discover there are exceptions being thrown that you really do want to ignore, handle them separately, but you should almost never catch (Exception e) and throw away the exception.
It's also a good idea to use ProcessBuilder instead of Runtime.exec(). This is a more powerful and flexible API for interacting with sub-processes. In particular, never use Runtime.exec(String); although it works for simple commands it is not a shell, and will fail in surprising ways for commands with special characters, like quotes or whitespace.
For example:
p = new ProcessBuilder("sudo", "date", "-s", date_time).start();

How do I open any installed software in my pc using a java program?

I want to open installed softwares in my pc using a java program. For Example- If I want to open Microsoft Outlook using java program, how would I do it? Thanks in advance!!
You can use Java ProcessBuilder to launch any program.
Example from this site
package com.javacodegeeks.process;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ProcessBuilderExample {
public static void main(String[] args) throws InterruptedException,
IOException {
ProcessBuilder pb = new ProcessBuilder("echo", "This is ProcessBuilder Example from JCG");
System.out.println("Run echo command");
Process process = pb.start();
int errCode = process.waitFor();
System.out.println("Echo command executed, any errors? " + (errCode == 0 ? "No" : "Yes"));
System.out.println("Echo Output:\n" + output(process.getInputStream()));
}
private static String output(InputStream inputStream) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + System.getProperty("line.separator"));
}
} finally {
br.close();
}
return sb.toString();
}
}

Scraping Google App Store for Meta Data

I am noob in Java trying to to build a scraper in a Java which could do the following things.
Ability to read data from a CSV file.
Use the URIs in that file and scrape the complete App info from the Google Playstore.
Export the scraped data and other meta data from the CSV file into an XML file
Can any one guide me in this how to go from here ?
Till now I have made the following three classes
main.java (This is the main method where I call other two classes)
import java.io.IOException;
public class main {
public static void main(String[] args) throws IOException {
ReadCVS obj = new ReadCVS();
obj.run();
AppInfo obj1 = new AppInfo();
obj1.readFile();
}
}
ReadCVS.java (This file reads the CSV file and give the output in a txt file)
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
public class ReadCVS {
public void run() {
// Replace the file path to the appropriate path.
String csvFile = "\\Desktop\\https---play_google_com-store-apps-details-id=.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ";";
try {
File file = new File("\\Desktop\\output.txt");
FileOutputStream fos = new FileOutputStream(file);
PrintStream ps = new PrintStream(fos);
System.setOut(ps);
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] country = line.split(cvsSplitBy);
System.out.println("URL = " + country[0] + " "
);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Done");
}
}
AppInfo.java (This file reads the input from the saved output.txt and tries to out put in the console. But it is not currently working)
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class AppInfo {
public void readFile(){
String fileName = "\\Desktop\\output.txt";
//read file into stream, try-with-resources
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
The problem is that whenever I try to run this code the program get hanged and does not terminate.
Can any one help me with my problem ?

getting text from command-line into Java

I'm trying to parse some text that is generated by a command-line command. The command-line command I want to use is Ubuntu's landscape-sysinfo. In an attempt to run this, I'm using the following Java code:
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(new String[] { "landscape-sysinfo" });
The thing I'm not sure of is, how do I get the output of the command-line command into a string that I work with in my Java app?
Thank you so much for your valuable insights!
Hope this one helps its what the Apprentice Queue said
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class BatchExecuteService {
public static void main(String[] args) {
BatchExecuteService batchExecuteService = new BatchExecuteService();
batchExecuteService.run();
}
public void run() {
try {
String cmds[] = {"D:\\test.bat"};
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(cmds);
process.getOutputStream().close();
InputStream inputStream = process.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputStream);
BufferedReader bufferedrReader = new BufferedReader(inputstreamreader);
String strLine = "";
while ((strLine = bufferedrReader.readLine()) != null) {
System.out.println(strLine);
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
Reference

Categories