Spaces in file path in java - 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.

Related

How to deal with a directory that has a space in it being passed to ProcessBuilder and then to Exp.exe?

I am working on an issue where spaces in a directory cause a program that runs exp.exe to crash. The user first selects a .dmp file from any directory they want, which is then used to build an argument list. This argument list contains the command to be run, in this case, exp.exe, the .dmp file name, a log file created in the directory the file name comes from, along with some other parameters. ProcessBuilder is then used to do the following:
public static ProcessBuilder build;
build = new ProcessBuilder();
build.command(args);
build.redirectErrorStream(true);
process = build.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
When the directory the file comes from does not have any spaces, exp.exe runs as intended and line prints as expected. However, when the directory the file comes from does contain spaces, exp.exe does not run and terminates after outputting error code LRM-00101: unknown parameter name.
This is an example of a directory that does not work
C:\Users\Me\OneDrive - Folder\Desktop\test\log.dmp
A directory such as that one would be processed incorrectly and output
LRM-00101: unknown parameter name 'Folder\Desktop\test\log.dmp'
And this is an example of a directory that does run
C:\Users\Me\Downloads\test\log.dmp
In the example directory that does not work, ProcessBuilder is incorrectly getting the directory by treating everything before the "- " as not part of the directory, which is causing it to fail. I have already tried to escape the directory with double quotes when it is being read in initially by doing
"\""+dmp_filename+"\""
but that does not work and other suggestions in similar threads do not seem to apply.
This is the exact code for the args being passed in
args = [exp.exe, userid=123#test, buffer=50000000, file=C:\Users\Me\OneDrive - Folder\Desktop\test\log.dmp, owner=test, compress=n, grants=y, indexes=y, direct=no, log=C:\Users\Me\OneDrive - Folder\Desktop\exp_log_test.log, rows=y, consistent=y, object_consistent=y, triggers=y, statistics=none, constraints=y]
I would appreciate any help.
Spaces in file or directory names have to escape by \!
String file = "C:\Users\Me\OneDrive - Folder\Desktop\test\log.dmp";
file = file.replaceAll(" ", "\\ ");
The double escaping isn't really nice!

Call easy_install apps from java with ProcessBuilder/RunTime

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.)

Expanding files with 7zip

I am trying to expand a zip file using 7zip but I keep getting the 7zip Usage printout.
The zip exist in c:\temp
The same command succeed in batch window :
C:\TEMP>7z x "tryThis.zip"
I tried adding the workdir path to the file,And also without the working dir,
nothing help. - I can probably run this using CMD/c command but I prefer to keep the code clean
What am I doing wrong?
Thank you!
String pathTo7ZipExe = "c:\\program files\\7-zip\\7z.exe";
String fileName ="tryThis.zip";
String workingDir = "c:\\temp\\";
Process process = Runtime.getRuntime().exec(
new String[]{pathTo7ZipExe},
new String[]{" x \"" + fileName +"\""},
new File(workingDir));
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
// wait for zip to end.
int exitVal = process.waitFor();
Please have a look at the documention for Runtime.exec
What you were actually trying to do is calling 7-zip without arguments and providing the arguments as your environment. Environment is something like Windows PATH etc.
so you would probably want to do something like:
Runtime.getRuntime().exec(new String[]{pathToZipExe, "x", fileName}, null, new File(workingDir));
On the other hand I would strongly advise to have a look on ZipInputStream which is included in java - using that you can also unpack zip files.
Cheers
You're invoking the overload of exec which accepts envp array as the second argument. This envp array is not for arguments at all, so actually you don't pass any arguments: that's why you get the usage printout.
Quotes and spaces aren't themselves part of arguments: they are used for separation into argv (with minor reservations, it's also true for Windows: that's how CommandLineToArgW works, even though full original command line with quotes and spaces is always available).
So it should be something like this:
Runtime.getRuntime().exec(new String[]{pathTo7ZipExe, "x", fileName},
new String[]{}, new File(workingDir));
(too bad I don't know Java, so the code might be unidiomatic, but it should work).

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.

Java command Runtime.getRuntime().exec() in Mac OS

I´m using Mac OS Lion, with java version 1.6.0_26
I'm making a small app for Mac in Java with a main menu for the user, so he can choose several options.
One of them is install an app using a .pkg
Everything was working fine with these commands:
File instFolder = new File(System.getProperty("user.dir") + "/foldername/appInstaller.pkg");
String s = "open "+ instFolder.toString();
Process p = Runtime.getRuntime().exec(s);
Then I realized that there is a problem when foldername has spaces or if I copy this java file with the needed subfolders to a USB pen drive with "NO NAME" as name (or some name with spaces).
Because s will become something like:
open /Volumes/NO NAME/foldername/appInstaller.pkg
or
open /Users/user1/Desktop/folder name/appInstaller.pkg
So when you run the p process, the command will finish where the first space appears on the path
open /Volumes/NO
or
open /Users/user1/Desktop/folder
To try to fix this I changed the s definition for something like this:
String s = "open "+ "\"" + instFolder.toString() + "\"";
It stopped working fine. The strange thing is that if i copy the s value (after creating the s variable) and paste it in the terminal it works:
open "/Users/user1/Desktop/folder name/appInstaller.pkg"
but running it from Java it does't work.
Could you help me, please?
Thanks.
In order to properly escape arguments, you can use the following:
Runtime.getRuntime().exec(new String[] { "open", instFolder.toString() });
Though I would probably to use the more modern ProcessBuilder:
ProcessBuilder pb = new ProcessBuilder("open", instFolder.toString());
Process p = pb.start();
int exitCode = p.waitFor();
Though this may be worth a read depending on what you want to do with the processes output.
Note: edited to reflect question in comment
it seems your path does not have quotes when turned into the shell.
You should probably add "'" on both sides of your path, so the final shell command will look like:
open 'your path'
instead of
open your path
Here's a little trick that came out from the answers mentioned above:
ProcessBuilder pb = new ProcessBuilder(commandString.split(" "));
Say commandString = "killall Mail" then the split will separate the words making it a String[] parameter to the ProcessBuilder.

Categories