Call easy_install apps from java with ProcessBuilder/RunTime - java

The title doesn't really explain my question, but I don't know how to ask it in a better way. So, basicly, I'm writing a app that uses the program livestreamer. I installed it on my mac using: easy_install -U livestreamer . So far, so good, it works when I write livestream on my terminal. Now, my issue is that when I try to call it on java:
public static void runLiveStreamer(String channel, String quality) throws IOException{
String[] cmd = new String[]{"livestreamer", "twitch.tv/"+channel, quality};
Process proc = Runtime.getRuntime().exec(cmd);
InputStreamReader isr = new InputStreamReader(proc.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null)
System.out.println(line);
}
I get this error:
Exception in thread "main" java.io.IOException: Cannot run program "livestreamer": error=2, No such file or directory
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
at java.base/java.lang.Runtime.exec(Runtime.java:591)
at java.base/java.lang.Runtime.exec(Runtime.java:450)
at livestream.runLiveStreamer(livestream.java:12)
I know the code works, because if I replace the String[] cmd = new String[]{"livestreamer", "twitch.tv/"+channel, quality}; with, for example, ls, it outputs without any problem. This is my first time messing with this kinds of stuff, so my error is probably a really newbie one. Thanks in advance for all the help!

livestreamer is not in your Java process’s path.
Every Windows and Unix operating system’s execution environment has a concept of a program path. The path is an environment variable (named PATH in all operating systems except Windows, which uses Path). It contains a list of directories, separated by colons :, except on Windows where they’re separated by semicolons (;).
As with any environment variable, each running process may have its own path defined, and child processes usually inherit it from their parent process.
Whenever you try to run a program without any directory separators (for instance, trying to run ls instead of /bin/ls), the system will look for that program in each directory in the path.
In your terminal, your PATH contains a directory which has livestream in it. When you run your Java process, you have a different PATH, one which does not include the directory which contains livestream.
The easiest solution is to refer to livestream by its absolute file name, thus making the system execution path irrelevant:
String[] cmd = { "/usr/bin/livestreamer", "twitch.tv/" + channel, quality };
/usr/bin/livestreamer is just an example. I don’t know where livestreamer was actually installed on your system.
To find it, do which livestreamer in your terminal. That should tell you the absolute location of it. (I think in Windows, the command would be where livestreamer.)

Related

How do you set up command line args in Eclipse for the MAC? (Intent is to submit to online programming challenges)

I know that you must add command line arguments into the "Run Configurations" in Eclipse to get your command line arguments to be passed every time by default. This worked fine on my PC.
The purpose of this question is to create a simple program that can be submitted to an online programming challenge site (like codeeval). The system provides a file path to the command line args[0] and then you manipulate the file and its data.
On the PC I had my Class folder > Default Package > (file.txt and TestCode.java)
The project was set up with a run configuration with simply file.txt in the program arguments section.
On the MAC this doesn't seem to be working. I get a fileNotFoundExcepion. I'm new to MAC so I'm thinking this might be a problem with file extensions not being what I think they are. I saved a file as "file.txt" but if I save it as "file" MAC doesn't show the file extensions and I'm not sure if MAC supports .txt by default.
If it doesn't support .txt, what file type is a "text document"? I tried saving the text document as "file" leaving off any extension, and then adding file.rtf or file.txt or even file to the Program arguments and none of that works. It all gives me a fileNotFoundException.
EDIT
The intent is to be able to develop solutions to the CodeEval (or similar) website and submit them. I have previously solved many problems on CodeEval and turned them in with the code below from a PC. This, however, doesn't work on MAC. The answer involving the use of the URL does not work when run from the solution checking platform (presumably because the program is not actually saved onto the system).
EDIT 2
My entire program:
public class TestCode {
public static void main (String[] args)throws IOException{
File filename = new File(args[0]);
Scanner file = new Scanner(filename); // returns the fileNotFoundException
while( file.hasNextLine()){
String line = file.nextLine();
System.out.println(line);
}
}
}
Under "Run Configurations" in the Arguments tab > Program Arguments I have tried putting file, file.txt, file.rtf all three with a "text document" in the same directory as the above program. I have tried naming that file file, file.txt and file.rtf And i tried every combination of these names.
Did you try to use the absolute file name as command line parameter? This should be something like /Users/name/path/to/your/file. If the file is part of your project, you can also use a variable such as ${project_loc}/file (try the button Variables… below the Program Arguments field.
Replace your code with this
URL resource = TestCode.class.getResource(args[0]);
Scanner file = new Scanner(new File(resource.getFile()).getAbsoluteFile());

Spaces in file path in java

I have a folder which contains few jar files. I am referring to those jar files from another jar file which is in some other location.
My problem is, when I give the path of the jar folder like this C:\Trial Library\jar Folder\ ie. with space in the folder names (Trial Library) then it is unable to locate this folder.
If I give without space ie C:\Trial_Library\jar_Folder\ then it works fine.
Please help me to fix this issue ASAP.
Here is my Batch File
set CURRENT_DIRECTORY=%~dp0
set ANT_HOME=%"CURRENT_DIRECTORY"%ant\apache-ant-1.8.3
ECHO current directory is %CURRENT_DIRECTORY%
ECHO %ANT_HOME%
set Path=%ANT_HOME%\bin
set ADAPTER_LIBRAY_PATH=%1
set USER_JAR_PATH=%2
set CLASS_NAME=%3
set RESULTS_PATH=%4
set JUNIT_PATH=%"CURRENT_DIRECTORY"%ANT\test\junit-4.1.jar
set LIBRAIES_TO_INCLUDE="%JUNIT_PATH%";"%ADAPTER_LIBRAY_PATH%";"%USER_JAR_PATH%"
ECHO %LIBRAIES_TO_INCLUDE%
ECHO %ADAPTER_LIBRAY_PATH%
ECHO %JUNIT_PATH%
ECHO %USER_JAR_PATH%
ECHO %CLASS_NAME%
ECHO %RESULTS_PATH%
ant -lib "%LIBRAIES_TO_INCLUDE%" -Dlibraries="%ADAPTER_LIBRAY_PATH%" -Djunitlibrary="%JUNIT_PATH%" -Djartobeexec="%USER_JAR_PATH%" -Duserclass=%CLASS_NAME% -Dresultspath=%RESULTS_PATH% -buildfile build.xml test-html
Here is where i pass the values to my batch file
String[] commands=new String[5];
commands[0]="driver.bat";
commands[1]=finalLibraryPath;
commands[2]=executingJarLocation;
commands[3]=tempPackageName;
commands[4]=resultsFolderPath;
process = Runtime.getRuntime().exec(commands);
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
StringBuffer errorStr = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
errorStr.append(line);
errorStr.append(System.getProperty("line.separator"));
}
Thanx in advance
Regards,
Prabhu
Okay, from what I understand I'm "guessing" that you are doing something like
Runtime.exec("myBatchFile.bat " + path);
This will end in tears. This is the equivalent of saying:
C:> myBatchFile.bat C:\Path to my jar files
This won't work. Basically, your batch file now thinks it has 5 parameters instead of one.
To fix the problem you need to pass each command/parameter seperatly...
Runtime.exec(new String[] {"mybatchFile.bat", path});
Or better still, use ProcessBuilder
ProcessBuilder pb = new ProcessBuilder("myBatchFile.bar", path);
Wrap the path in quotes. This means that the computer takes it literally. You can have a similar problem with notepad, where it adds a .txt extension on the end even if you supply the extension. Wrapping in quotes solves this problem.
Generally enclosing the path in double quotes ("path") works on platforms like Unix, Linux etc.
The problem only comes on WIN platform. The reason behind this is that as soon as the WIN sees a space in the path of a file to be executed, it reverts to 8.3 naming. In this naming, it takes the first 6 characters of the Sub directory as the param and searches for the pattern.
To solve the issue, you have to append the first 6 characters with a tilde(~) and a number representing the instance of that pattern.
For ex:
**Original PATH : C:/Program Files/Jdk1.6.0_07/bin
PATH to be used : C:/Progra~1/Jdk1.6.0_07/bin**
I have used the similar approach in lots of my Java applications and it has worked correctly all of the times.

How to run bat file from java with arguments (i.e file name with full path) having folder name with space

Am trying to execute the a bat file with some arguments through a JAVA programmes . the arguments are file name with full path, And this path had some folder name with space, which are creating issue and giving me the following error
Error: 'D:\Documents' is not recognized as an internal or external
command
the code is as below
String command = "D:\Documents and Settings\ A.bat" + " " D:\Documents and Settings\B.xml
1. process = Runtime.getRuntime().exec(new String[] {"cmd.exe","/c",command});
2. process.waitFor();
3. exitValue = process.exitValue();
You need to escape the \ in your string (i.e. doubling them: D:\\Documents), but that is not the problem. You can try to escape the spaces Documents\\ and\\ Settings or you use the exec method that does this for you. Just dont build the command line by yourself. Better use ProcessBuilder for starting processes.
String command = "\"D:\Documents and Settings\\" A.bat" + " \"D:\Documents and Settings\B.xml\""
Escape double quotes, so you can include double quotes in the literal, to give:
cmd.exe /x "D:\Documents and Settings\" A.bat "D:\Documents and Settings\B.xml"
I was trying to do the same thing. I googled whole day but didn't make it work. At Last I handled it in this way, I am sharing it if it comes to any use of anybody :
String command = "A.bat D:\\Documents and Settings\\B.xml";
File commandDir = new File ( "D:\\Documents and Settings ");
String[] cmdArray = { "cmd.exe", "/c", command };
1. Process process = Runtime.getRuntime().exec( cmdArray, null, cmdArray );
2. process.waitFor();
3. exitValue = process.exitValue();
I've spent a while searching on SO and the wider Internet and was about to post this as a new question when I came across this, which does seem identical to my issue...
I am trying to call a Windows batch file from Java. The batch file takes several arguments but just the first, which is a path to a data file, is of relevance to this problem. The cut-down command line that I have been experimenting with is essentially:
cmd /c c:\path\to\my\batchfile.bat c:\path\to\my\datafile.mdl
I'm using Apache Commons Exec which ultimately delegates to Runtime.getRuntime().exec(String[] cmdarray, String[] envp, File dir), the 'correct' version as opposed to the overloaded versions taking a single String command. Quoting of the arguments when they contain spaces is therefore taken care of.
Now, both the path to the batch file and/or the path to the data file can have spaces in them. If either the path to the batch file or the path to the data file have spaces in, then the batch file is executed. But if both have spaces in them then the path to the batch file is truncated at the first space.
This has to be a (Java or Windows?) bug, right? I've debugged right down to the native call to create() in java.lang.ProcessImpl and all seems ok. I'm on JDK1.6.

How can i run a .jar file in java

I'm making an update function for my project, it's working great, until i want it to restart, basically I download the new file and replace it with the old one, and then i want to run it again, now for some reason it doesn't wna run, and i don't get any error...
Here is the complete update class:
http://dl.dropbox.com/u/38414202/Update.txt
Here is the method i'm using to run my .jar file:
String currDir = new File("(CoN).jar").getAbsolutePath();
Process runManager = Runtime.getRuntime().exec("java -jar " + currDir);
It's not clear to me, why do you need to run the jar with a call to exec() . Given that you need to run the code in the .jar file from a Java program, you could simply run the main() method as defined in the jar's manifest, and capture its output - wherever that is.
Using exec() is OK when you need to call a program from the underlying operating system, but there are easier ways to do this if both the caller and the callee are Java programs.
Now, if your jar is gonna change dynamically and you need to update your program according to a new jar, there are mechanisms for reloading its contents, for instance take a look ath this other post.
The JavaDocs for the Process class specifically point out that if you don't capture the output stream of the Process and promptly read it that the process could halt. If this is the case, then you wouldn't see the process that you started run.
I think you have to capture the stream like this :
BufferedReader stdInput = new BufferedReader(new InputStreamReader(runManager.getInputStream()),8*1024);
BufferedReader stdError = new BufferedReader(new InputStreamReader(runManager.getErrorStream()));
// read the output from the command
String s = null;
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
The exec function doesn't automatically lookup into the PATH to start a process, so you have to pass the complete path for the java binary.
You can do that by using the java.home system property, see this answer: ProcessBuilder - Start another process / JVM - HowTo?
No one here seemed to help me, so I went to ask my friend and I had it almost right. It abiously required the string to be an array.
solution:
String[] cmd = {"java", "-jar", currDir};
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e1) {
e1.printStackTrace();
}

external program from java doesn't terminate

When I try to execute an external program from java I use this code below :
Process p;
rn = Runtime.getRuntime();
String[] unzip = new String[2];
unzip[0]="unzip";
unzip[1]=archive ;
public void dezip() throws IOException{
p = rn.exec(unzip);
int ret = p.exitValue();
System.out.println("End of unzip method");
But my last System.out is never executed, as if we exit from unzip method.
The unzip() call does only the half of the work, only a part of my archive is unzipped.
When I use ps -x or htop from command line I see that unzip process is still here.
Help please.
You probably need to read the InputStream from the process. See the javadoc of Process
Which states:
Because some native platforms only provide limited buffer size for
standard input and output streams, failure to promptly write the input
stream or read the output stream of the subprocess may cause the
subprocess to block, and even deadlock.
Check if the unzip command is prompting for something, perhaps a warning if the file already exists and if you want to overwrite it.
Also, is that a backquote I see in the middle of a java program?
Make sure external program doesn't wait for user input
Check if the the executable path is quoted when launching on Windows systems to handle directories with spaces or special characters.
PS.
I was using the java.lang.Runtime class but found that the java.lang.ProcessBuilder class is far superior. You can specify current working directory, and most importantly the system environment.
Please try the following:
p = rn.exec(unzip);
p.waitFor()
I hope it will change something.

Categories