Java syntax escapting symbols? - java

I need to process a command in cmd and the command looks like this:
"c:\Program Files (x86)\HMA! Pro VPN\bin\HMA! Pro VPN.exe" -changeip
But I can't really add the " because I will get errors..
Is there a way to do that? What i've tried causes errors:
cmd.exec(""c:/Program Files (x86)/HMA! Pro VPN/bin/HMA! Pro VPN.exe" -reconnect");
How can I escape that character so it works?
Exception in thread "Thread-1" java.lang.IllegalArgumentException: Executable name has embedded quote, split the arguments
at java.lang.ProcessImpl.isQuoted(Unknown Source)
at java.lang.ProcessImpl.getExecutablePath(Unknown Source)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
at java.lang.ProcessBuilder.start(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at HMACommand.reconnect(HMACommand.java:15)

You can escape characters using a backslash (\).
In your case the result will be this:
String test = "\"c:\\Program Files (x86)\\HMA! Pro VPN\\bin\\HMA! Pro VPN.exe\" -changeip";
You'll also have to escape the backslashes themselves.
Referring to your edit:
This answer explains why you get the error you're getting.
From the cited source:
On Windows platform, the decoding of command strings specified to Runtime.exec(String), Runtime.exec(String,String[]) and Runtime.exec(String,String[],File) methods, has been improved to follow the specification more closely. This may cause problems for applications that are using one or more of these methods with commands that contain spaces in the program name, or are invoking these methods with commands that are not quoted correctly.
Instead, use a ProcessBuilder.

You could use a ProcessBuilder like so
String[] cmdLine = {
"c:/Program Files (x86)/HMA! Pro VPN/bin/HMA! Pro VPN.exe",
"-changeip"
};
try {
ProcessBuilder pb = new ProcessBuilder(cmdLine);
Process p = pb.start();
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

Related

Running linux command in java

I want to run "ls" command in java and my code is-
Note:- I am using WINDOWS.
import java.io.IOException;
public class Example
{
public void fn()
{
Runtime run = Runtime.getRuntime();
Process p = null;
String cmd = "ls";
try {
p = run.exec(cmd);
p.getErrorStream();
p.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
System.out.println("ERROR.RUNNING.CMD");
} finally {
p.destroy();
}
}
public static void main(String[] args) throws IOException
{
Example sp = new Example();
sp.fn();
}
}
but I am getting following error while running this code in eclipse-
java.io.IOException: Cannot run program "ls": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at Example.fn(Example.java:12)
at Example.main(Example.java:28)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
... 6 more
Exception in thread "main" ERROR.RUNNING.CMD
java.lang.NullPointerException
at Example.fn(Example.java:23)
at Example.main(Example.java:28)
what needs to be corrected? what library, etc. should I add to execute this piece of code?
If you want to run any command from Java ensure that executable of this file is present in PATH environment variable.
Or at least you have to set working directory to /usr/bin or similar.
One more solution is to use absolute path to executable, e.g.:
Runtime.getRuntime().exec("/usr/bin/ls");
But it is bad way to specify absolute path to any file.
Why don't you use File#listFiles()?

FileAlreadyExistsException with REPLACE_EXISTING option

Inside my code there is a loop to substitute a file with another file.
This is done with:
java.nio.file.Files.move(Path source, Path target, CopyOption... options) throws IOException
The following exception is thrown:
Exception in thread "main" java.nio.file.FileAlreadyExistsException: C:\BRUTE-FORCE\Test-Loads-2-forces-only.dat.temp -> C:\BRUTE-FORCE\Test-Loads-2-forces-only.dat
at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsFileCopy.move(Unknown Source)
at sun.nio.fs.WindowsFileSystemProvider.move(Unknown Source)
at java.nio.file.Files.move(Unknown Source)
(*) at bruteforce.Main.changeValue(Main.java:260)
at bruteforce.Main.main(Main.java:71)
The line at which the exception is thrown:
(*) at bruteforce.Main.changeValue(Main.java:260):
Files.move(path, path.resolveSibling("DESTINY_FILE"), REPLACE_EXISTING);
Javadoc defines the exception:
...
FileAlreadyExistsException - if the target file exists but cannot be replaced because the REPLACE_EXISTING option is not specified (optional specific exception)
...
The code clearly specifies REPLACE_EXISTING.
Also the option is imported at the beginning of the file:
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
Any hint?
It could be due to the computer (or the HDD) hybernates or something similar?
I have set the enegy options not suspends while using the power grid.
Thanks in advance
Files.move is not an atomic operation (unless of course ATOMIC_MOVE is specified), so what i assume is happenig some other IO got lock on this file.
Please make sure you:
Lunch close() method on this resource or use try-with-resources
Your OS is not using this file (eg. opened in Notepad, you lunch
tail against it)
If you file is often accesed, then you can try to create loop that checks Files.isWritable()

Error in reading Ubuntu 14.04 mouse event file (/dev/input/event3) with java programmig

I want to handle mouse event in Linux terminal via java programming. I wrote two program via c++ and java that they do same process.
when i use c++ programming to open and read file ("/dev/input/event3"-mouse event file), there is no problem while running executable file.
(Ubuntu 14.04 terminal and Ubuntu server 14.04 ---> no problem).
But when i used java programming to open and read the same file ,there is a problem while running executable result file "java -jar program.jar" in Ubuntu 14.04 "terminal". No error for opening file , but reading file make an error like this:
java.io.IOException: Invalid argument
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(Unknown Source)
at eventfileopen.m.main(m.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
But when i run the same jar file on Ubuntu server 14.04, there is no error and the program work perfectly.
How can I resolve the problem?(Problem = run the java program on Ubuntu 14.04 with no error.) I guess the problem is related to Ubuntu GUI and JDK,but no idea for resolving that.
My java program code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
public class m {
public static void main(String[] args) {
File f = new File("/dev/input/event3");
FileInputStream is = null;
try {
is = new FileInputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte[] bytes = new byte[16];
while(true){
try
{
is.read(bytes);
} catch (IOException e)
{
e.printStackTrace(); //-------> error while run on Ubuntu 14.04 and no error on Ubuntu server
}
System.out.println(Arrays.toString(bytes));
}
}
}
Check that your buffer size is correct.
In recent Linux kernels size of input_event structure is dependent on many things, but mainly on cpu architecture. Here's its declaration:
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
On 32-bit systems it's very likely that your buffer size is accepted(16 bytes).
On 64-bit systems it's very likely that the buffer should be no less than 24 bytes. The reason is that timeval struct takes twice as much space(8 bytes more) than on 32-bit systems.
I haven't found a reliable way to get input_event struct size from Java and personally I use JNI for that.

JAVA - path issue (works in eclipse, not in cmd)

Why the following iniciation works in eclipse:
private static MaxentTagger maxentTagger = new MaxentTagger("c:\\DP\\lemma\\models\\english-left3words-distsim.tagger");
but in command line it throws:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoa
der.java:58)
Caused by: java.lang.ExceptionInInitializerError
at dp.beans.MySearch.<init>(MySearch.java:122)
at dp.runable.Main.main(Main.java:25)
... 5 more
Caused by: java.lang.IllegalArgumentException: name
at sun.misc.URLClassPath$Loader.findResource(Unknown Source)
at sun.misc.URLClassPath.findResource(Unknown Source)
at java.net.URLClassLoader$2.run(Unknown Source)
at java.net.URLClassLoader$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findResource(Unknown Source)
at java.lang.ClassLoader.getResource(Unknown Source)
at java.net.URLClassLoader.getResourceAsStream(Unknown Source)
at edu.stanford.nlp.io.IOUtils.findStreamInClasspathOrFileSystem(IOUtils.java:370)
at edu.stanford.nlp.io.IOUtils.getInputStreamFromURLOrClasspathOrFileSystem(IOUtils.java:399)
at edu.stanford.nlp.tagger.maxent.MaxentTagger.readModelAndInit(MaxentTagger.java:646)
at edu.stanford.nlp.tagger.maxent.MaxentTagger.<init>(MaxentTagger.java:284)
at edu.stanford.nlp.tagger.maxent.MaxentTagger.<init>(MaxentTagger.java:248)
at dp.data.Settings.<clinit>(Settings.java:80)
... 7 more
Settings.java:80 corresponding with MaxentTagger iniciation..
Is there a different way to declare windows path, which works in both, eclipse and cmd?
update (the findStreamInClasspathOrFileSystem method):
private static InputStream [More ...] findStreamInClasspathOrFileSystem(String name) throws FileNotFoundException
{
String path = null;
if (name.startsWith("/")) {
path = name.substring(1);
}
// - even though this may look like a regular file, it may be a path inside a jar in the CLASSPATH
// - check for this first. This takes precedence over the file system.
InputStream is = null;
if (path != null) {
is = IOUtils.class.getClassLoader().getResourceAsStream(path);
// windows File.separator is \, but getting resources only works with /
if (is == null) {
is = IOUtils.class.getClassLoader().getResourceAsStream(path.replaceAll("\\\\", "/"));
}
}
// if not found in the CLASSPATH, load from the file system
if (is == null) is = new FileInputStream(name);
return is;
}
update: no matter if i change the path to:
"c:/DP/lemma/models/english-left3words-distsim.tagger");
"c:\\\\DP\\\\lemma\\\\models\\\\english-left3words-distsim.tagger");
its behaviour is still the same (works in eclipce, not in cmd)
Your code seems to load a resource from the classath, using the ClassLoader. The path should take the following form:
com/yourcompany/yourapp/english-left3words-distsim.tagger
where com.yourcompany.yourapp is the package where the file resides.
See http://docs.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html#getResource%28java.lang.String%29
EDIT:
The code of IOUtils.getInputStreamFromURLOrClasspathOrFileSystem() passes two badly formatted paths (c:\... and c:/...) to ClassLoader.getResourceAsStream(), and expects this method to simply return null instead of throwing an exception, which is wrong. I would simply decide where I want to load the resource rom: either the classpath (and thus use ClassLosader.getResourceAsStream()) or the file system (and thus use new FileInputStream()).

Running a command-line operation from within Java

I built a very simple program to test running a command line operation separate of Java. That is: later I want to be able to modify this code from using "move" to any other command I can enter into the command line (including calling other, non-Java, software).
I did search and read probably two dozen answers, but they all either suggested I was trying this correctly, were irrelevent to my simple test or proposed other solutions which did not work (like using the .exec(String[]) method instead of .exec(String) - same result!).
Here is my code:
import java.io.IOException;
public class RunCommand {
private static final String PATH_OUT = "C:\\Users\\me\\Desktop\\Temp\\out\\";
private static final String FILE = "sample.txt";
private static final String PATH_IN = "C:\\Users\\me\\Desktop\\Temp\\in\\";
public static void main(String[] args) {
try {
String command = "move "+PATH_IN+FILE+" "+PATH_OUT;
System.out.println("Command: "+command);
Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is what I see output when I run:
Command: move C:\Users\myingling\Desktop\CDS\Temp\in\sample.txt C:\Users\myingling\Desktop\CDS\Temp\out\
java.io.IOException: Cannot run program "move": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at RunCommand.main(RunCommand.java:13)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
... 5 more
Note that when I copy/paste the command into a command prompt window, the file moves successfully though.
What am I missing? All the other questions I've read seem to indicate this should work.
Thanks!
EDIT Works now, thanks for the help everyone! It's annoying that it's hidden the way "move" is a parameter of cmd.exe. I wish they had made it so if it worked when copy/pasted it worked when you called the .exec() method. Oh well.
The "move" command is part of the cmd.exe interpreter, and not a executable by itself.
This would work:
cmd.exe /c move file1 file2
Try this:
Runtime.getRuntime().exec("cmd.exe /c move "+PATH_IN+FILE+" "+PATH_OUT);
In Windows, unlike UNIX, move isn't a separate program. You need to involke the command processor CMD with move as an argument. Read the command line help on CMD, there's a flag you have to set.
move isn't actually a program, its a shell built-in command. Use something like:
String command = PATH_TO_SYSTEM32 + "\\cmd.exe /c move \""+PATH_IN+FILE+"\" \""+PATH_OUT + "\"";
Good practice is to always use absolute paths for external programs. (Well, good practice in this case would be to use Files.move or an equivalent instead of a platform dependent shell call)

Categories