Setx Called From Java Not Working Correctly - java

I'm using the setx command to modify the PATH system environment variable. Here is the command I'm using:
setx PATH "%PATH%;C:\Python34" /M
When this is ran as batch file and as administrator, it works properly and adds the new entry to the PATH.
However if I'm trying to run this from within my Java application it starts to behave weirdly.
First of all, the Java code used to execute the batch file:
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
public class BatchFile
{
public static void execute(String batchFilePath) throws IOException,
InterruptedException
{
Process process = Runtime.getRuntime().exec("cmd /c " + batchFilePath);
process.waitFor();
printResults(process);
}
private static void printResults(Process process) throws IOException
{
String standardOutput = getString(process.getInputStream());
String standardError = getString(process.getErrorStream());
if (!standardOutput.equals(""))
{
System.out.println(standardOutput);
}
if (!standardError.equals(""))
{
System.out.println(standardError);
}
}
private static String getString(InputStream inputStream) throws IOException
{
return IOUtils.toString(inputStream).trim();
}
}
Invoked like this:
BatchFile.execute("MyBat.bat");
Before running, my PATH looks like this:
c:\devkitPro\msys\bin;C:\devkitPro\devkitPPC\bin;C:\devkitPro\devkitPPC\powerpc-eabi\bin;C:\Program Files\Java\jdk1.8.0_45\bin;C:\ProgramData\Oracle\Java\javapath;C:\Python27\Lib\site-packages\PyQt4;C:\devkitPro\devkitARM\bin;C:\Python27\Lib\site-packages\PyQt4;C:\Program Files (x86)\Wiimm\WIT;C:\Windows\System32;C:\MinGW\bin;C:\MinGW\libexec\gcc\mingw32\4.8.1;C:\Python34;C:\MinGW\msys\1.0\bin;C:\Program Files (x86)\Git\cmd;C:\Windows\SysWOW64;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\MiKTeX 2.9\miktex\bin\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files (x86)\Skype\Phone\
After running the Java code however, it turns into this:
C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;c:\devkitPro\msys\bin;C:\devkitPro\devkitPPC\bin;C:\devkitPro\devkitPPC\powerpc-eabi\bin;C:\Program Files\Java\jdk1.8.0_45\bin;C:\ProgramData\Oracle\Java\javapath;C:\Python27\Lib\site-packages\PyQt4;C:\devkitPro\devkitARM\bin;C:\Python27\Lib\site-packages\PyQt4;C:\Program Files (x86)\Wiimm\WIT;C:\Windows\System32;C:\MinGW\bin;C:\MinGW\libexec\gcc\mingw32\4.8.1;C:\Python34;C:\MinGW\msys\1.0\bin;C:\Program Files (x86)\Git\cmd;C:\Windows\SysWOW64;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\MiKTeX 2.9\miktex\bin\;C:\Program Files
The message being printed out on the console is as follows:
D:\Programs\Portable\Eclipse\workspace\My Application>setx PATH "C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;c:\devkitPro\msys\bin;C:\devkitPro\devkitPPC\bin;C:\devkitPro\devkitPPC\powerpc-eabi\bin;C:\Program Files\Java\jdk1.8.0_45\bin;C:\ProgramData\Oracle\Java\javapath;C:\Python27\Lib\site-packages\PyQt4;C:\devkitPro\devkitARM\bin;C:\Python27\Lib\site-packages\PyQt4;C:\Program Files (x86)\Wiimm\WIT;C:\Windows\System32;C:\MinGW\bin;C:\MinGW\libexec\gcc\mingw32\4.8.1;C:\Python34;C:\MinGW\msys\1.0\bin;C:\Program Files (x86)\Git\cmd;C:\Windows\SysWOW64;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\MiKTeX 2.9\miktex\bin\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files (x86)\Skype\Phone\;D:\Programs\Portable\Eclipse;;C:\Python34" /M
SUCCESS: Specified value was saved.
WARNING: The data being saved is truncated to 1024 characters.
As you can see, a lot of rubbish Java directories have been added to the PATH contents at the beginning and it exceed the maximum limit of 1024 characters so it cuts off at the end. At the end there is an unwanted Eclipse directory added and there also are two semicolons before the actual Python path.
How do I get rid of the unwanted behavior when invoking the batch file using Java? I want the correct default behavior like when the setx command is invoked normally on cmd.

A while ago I was stuck at the same problem.
The simple answer is:
Do not use eclipse to start your program.
Eclipse will change your environment variables quite a lot for the execution. (including PATH)
You might have guessed it now but eclipse closes the PATH with a ; so when you call
setx PATH "%PATH%;C:\Python34" /M
you add another ; in front of the python path.
Just check by changing your batch to
echo %PATH%
Then run from eclipse and make another testrun from the command line (java -cp . MyMainClass) to see the difference.
Regarding the "WARNING: The data being saved is truncated to 1024 characters." limitation of setx you might want to have a look there: https://superuser.com/questions/387619/overcoming-the-1024-character-limit-with-setx

Related

Why is Jenkins having problems with UTF 8

I have a Jenkins job running. I just want to get all files. In every file name there is a Chinese letter. So the problem is now that Jenkins has problems reading in those files. Jenkins makes just "?" out of the Asian letter. The second problem is. Actually it is more than 100 files. But Jenkins only gives me 20 files. Maybe now a lot of files will look the same because of the question mark "?" .
Does anyone know how I can fix this. The problem only occurs on Jenkins ( running on Linux ) . On my local machine in Eclipse it works though.
File resourcePath = new File("resources/china_data/");
File[] files = resourcePath.listFiles();
for (final File file : files)
{
System.out.console(file.getName);
}
An alternative solution is to use the new java.nio.Path api in place of the java.io.File api
Also try setting the below in your code initially.
System.setProperty("sun.jnu.encoding","utf-8");
System.setProperty("file.encoding","UTF-8");
Assuming you are using System.out.println, this happens when the program runs with an ASCII locale:
$ cat Main.java
import java.util.*;
import java.io.*;
class Main {
public static void main(String[] args) throws Exception {
File resourcePath = new File("resources/china_data/");
File[] files = resourcePath.listFiles();
for (final File file : files)
{
System.out.println(file.getName());
}
}
}
$ javac Main.java
$ LC_CTYPE=C java Main
???????
When the program runs with a UTF-8 capable locale, either from the environment or configured through Java, you get the expected result:
$ LC_CTYPE=en_US.UTF-8 java Main
中华人民共和国
$ LC_CTYPE=C java -Dfile.encoding=UTF-8 Main
中华人民共和国
If you're not sure how to configure your server, you can also do this from within Java:
System.setOut(new PrintStream(System.out, true, "UTF-8"));

Inputting file name through main function argument (args[0])

EDIT: to run my code i am using "java filename.java input1.txt" is this correct?
I am creating a program where i have to tokenize a string into separate words and that string is in a text file. I have to specify the text file name in the terminal through command line arguments (args[0], etc). I am able to scan and print the content of the text file if i specify through paths but when i try to do it using args[0] it doesn't seem to work. I am using net beans. I will attach my section of code here:
public static void main(String[] args) {
try {
File f = new File(args[0]);
//using this commented out section using paths works File f = new
//File("NetBeansProjects/SentenceUtils/src/input1.txt");
Scanner input = new Scanner(new FileInputStream(f));
while(input.hasNext()) {
String s = input.next();
System.out.println(s);
}
} catch(FileNotFoundException fnfe) {
System.out.println("File not found");
}
SentenceUtils s = new SentenceUtils();
}
java filename.java input1.txt
is not correct for running a java program, you need to compile the *.java file to get a *.class file which you can then run like:
java filename input1.txt
assuming your class is in the default package and you are running the command in the output directory of your compile command, or using the fully qualified class name of the class, i.e. including the package name. For example if your class is in the package foo/bar/baz (sub folders in your source folder) and has the package declaration package foo.bar.baz;, then you need to specify your class like this:
java [-cp your-classpath] foo.bar.baz.filename input1.txt
for input1.txt to be found it has to be in the same directory where you run the command.
your-classpath is a list of directories separated by a system dependent delimiter (; for windows, : for linux, ...) or archives which the java command uses to look up the class to run specified and its dependencies.
NetBeansProjects/SentenceUtils/src/input1.txt is a relative path.
File f = new File("NetBeansProjects/SentenceUtils/src/input1.txt");
if this works then it means that the current working directory (i.e. the directory from which all relative paths are calculated) is the the rectory named NetBeansProjects.
You get FileNotFoundException because your file is expected to be in
NetBeansProjects/input1.txt
To find out which is the current working directory for your running program you can add the following statement:
System.out.println(new File("").getAbsolutePath());
Place input.txt in that directory and it will be found.
Alternatively you can pass the absolute path of your input file. an absolute path is a path that can be used to locate your file from whatever location your program is running from on your local filesystem. For example:
java -cp <your-classpath> <fully-qualified-name-of-class> /home/john/myfiles/myprogects/...../input1.txt
To sum up, what you need to know/do is the following:
the location of your program class and its package (filename)
the location of your input file (input.txt)
pass the correct argument accordingly

ProcessBuilder or Runtime.getRuntime().exec won't complete jar execution

I have a jar which converts one XML to other XML format using XSLT in Java. The jar copies the output to some folder. It is working absolutely fine when am running it on command prompt but running it via Runtime.getRuntime().exec or ProcessBuilder, doesn't complete the process. Just 25 files are converted and it freezes. When i shutdown the process i can see all the files being loaded in the output folder which were not being loaded into the same folder.
Any suggestions?
My Code
private boolean runLoaderScript() throws IOException, InterruptedException {
String args[] = { "java", "-jar", "C:\\Users\\gursahibsahni\\Desktop\\jar\\epnlm_new-1.0.0-jar-with-dependencies_WSJ_stringdate.jar", "-c", "-f", "-d", "7", "C:\\Users\\gursahibsahni\\Desktop\\ConsynInput\\wsjInput\\input" };
ProcessBuilder builder = new ProcessBuilder(args);
Process qq = (builder).start();
qq.waitFor();
return true;
}
private boolean runValidator() throws IOException, InterruptedException {
Process validatorProcess = Runtime.getRuntime().exec("java -jar C:\\Users\\gursahibsahni\\Desktop\\jar\\wsj_jar_20140423.jar -efv -d 7 C:\\Users\\gursahibsahni\\Desktop\\ConsynInput\\wsjInput\\output");
return (validatorProcess.waitFor()) == 0 ? true : false;
}
Additionally, when am trying to import the jar in my project and call the main function to convert the XML, it is not converting the XML properly.
Meaning, the constants are coming up very nicely but the functions which are being called into class files to get data are not being called up during the import.
YES! Running the jar on command line is a success! It works flawlessly. But when imported it is not converting properly. Why such behavior ? Its very strange. Please help.
you have to consume the StdOut (and maybe StdErr) of your process ... otherwise
the process will hang when the buffer is filled up !
if you don't want to code that yourself you might have a look at Apache CommonsExec ... it helps with executing and handling external Processes https://commons.apache.org/proper/commons-exec/tutorial.html
Among other things it captures the subprocesses output using an org.apache.commons.exec.ExecuteStreamHandler.

Paths for images and executables in a jar

I have created a java program in eclipse and I am now ready to export it as a jar. My program uses an image file and an executable file. When testing my program in eclipse I referred to these file with a full path, which I obviously cannot do for the jar. Therefore, I changed them like this:
public static final String DRIVERLOC = "./resources/IEDriverServer.exe";
//some other code
File file = new File(DRIVERLOC);
System.setProperty("webdriver.ie.driver", file.getAbsolutePath());
and
File pic = new File("./images/Open16.gif");
openButton = new JButton("Select the Text File", createImageIcon(pic.getAbsolutePath()));
I put the images and the resources and images directory in the same directory with the jar. Now for some reason when I run the jar the IEDriverServer works fine but the image does not work and the error is that it cannot find the image. I am confused since I cannot seems to tell the difference. I also used "images/Open16.gif" which did not work either. Why would one work but the other does not? What is the easiest way to fix this?
We do this exact same thing with Selenium Drivers.
What you need to do is take the executable file out of the jar and put it some where windows can run it. If you try and open a jar/zip in Windows Explorer and then double click the .exe inside of a jar/zip, windows will extract the file to a temp directory, and then run it. So do the same thing:
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class TestClass {
public static void main (String[] args) throws IOException {
InputStream exeInputStream = TestClass.class.getClassLoader().getResourceAsStream("resources/IEDriverServer.exe");
File tempFile = new File("./temp/IEDriverServer.exe");
OutputStream exeOutputStream = new FileOutputStream(tempFile);
IOUtils.copy(exeInputStream, exeOutputStream);
// ./temp/IEDriverServer.exe will be a usable file now.
System.setProperty("webdriver.ie.driver", tempFile.getAbsolutePath());
}
}
Let's say you save the jar and make it run this main function by default.
Running C:\code\> java -jar TestClass.jar Will run the jar from the C:\code directory. It will create the executable at C:\code\temp\IEDriverServer.exe
With your path set to "./resources/IEDriverServer.exe" you are referring to a file on the hard drive "." which does not exist.
You need to get the path of your .jar-file.
You can do this by using
System.getProperty("java.class.path")
This can return multiple values, seperated by semi-colons. The first one should be the folder your jar is in.
You can also use
<AnyClass>.class.getProtectionDomain().getCodeSource().getLocation()
I hope this helps :)
EDIT:
// First, retrieve the java.class.path property. It returns the location of all jars /
// folders (the one that contains your jar and the location of all dependencies)
// In my test it returend a string with several locations split by a semi-colon, so we
// split it and only take the first argument
String jarLocation = System.getProperty("java.class.path").split(";")[0];
// Then we want to add that path to your ressource location
public static final String DRIVERLOC = jarLocation + "/resources/IEDriverServer.exe";
//some other code
File file = new File(DRIVERLOC);
System.setProperty("webdriver.ie.driver", file.getAbsolutePath());
You can read about this here.

execute jar file in java program

I want to create an java program to compress an css file using YUI
I am new learner in java.
My Code is:
import java.io.BufferedInputStream;
import java.io.IOException;
public class Run extends Object
{
public static void main(String args[]) throws IOException, InterruptedException
{
System.out.println("Calling jar");
Process p = Runtime.getRuntime().exec("java -Xmx32m -jar yui.jar in.css");
BufferedInputStream bis = new BufferedInputStream(p.getInputStream());
synchronized(p)
{
p.waitFor();
}
System.out.println(p.exitValue());
int b = 0;
while((b = bis.read()) > 0)
{
System.out.print((char)b);
}
System.out.println("Called jar");
}
}
I took reference from here.
the command:
java -Xmx32m -jar yui.jar in.css
works fine in cmd but I get no output when I run above program
the output I get for above is:
Calling jar
1
Called jar
Please tell Me what I am doing wrong or what is the right way of doing this.
You are getting the "1" because there is nothing to read in the stream.
I'm guessing that you're trying to run the file from Eclipse or some other IDE. If so, you need to place your yui.jar and in.css files to same directory relative to where your Run class is.
If you're using default run configurations, you'll just want to put the files into the root directory of your eclipse project. For example, this works for me:
Test
src
com
test
Run.java
yui.jar
in.css
A better way to handle your situation is to use absolute or relative paths instead of just specifiying yui.jar or in.css. Create two variables for the two relative paths and then create the command string.

Categories

Resources