Is it possible to run an entire, large, powershell script in a java application without calling it externally by launching a powershell process with the -file parameter? (passing it via the encodedcommand parameter won't work either because of the commandline lenght limitation).
I.e. is there a java library that enables you to paste your powershellscript inside your java app and run it?
I currently embed the powershellscript inside the java application and write it to disk, but I'm looking for a fileless approach.
Since you want to pass a large program, piping from the Java program to the PS script is more suitable than using the command line or environment variables. Since I don't know too much Java and don't have it installed, I'll simulate it from the PS command line in the snippet below. Your Java program would read the lines of the program from a list or some other suitable data structure (whereas this example reads it from the file system). I did see hits on google for piping from Java to an externally executed command.
cat my.ps1|
powershell -command {$scr="";foreach ($line in $input){$scr+=$line+"`n"} echo bxb $s cxc}
After your PS stub has received the program rather than echo it, it would execute it: iex $scr.
If you need to pass parameters from Java to PS you could either pipe them along with the program (for example as lines of code that set global variables) or they could be global variables set in stub code. Other, more complex, variations are possible.
Can any one tell me how to get status report from shell script to java code.
Use case : I run a shell script from java code and if I get any error in shell script(while running) then I need to send some message from shell script to my java code.
So how I can acheive that.
I'm sure there is a better way, but an easy way to do this is to have the shell script pipe error output to a file, which you then read by the Java application.
I'm assuming you are using a ProcessBuilder launch your shell script.
Once you build the process you can use getInputStream() which will give you the output stream from the Shell Script, then just copy the stream to where you want to go.
There also is a redirectOutput but I have limited experiences using it. I'm assuming it does what I'm describing above.
You can use something like this:
Process proc = Runtime.getRuntime().exec("ls -la")
// To get the error code (0=success)
int outCode = proc.exitValue()
If you need to send something from the script to the application executing it, you may be able to do that writing to stdErr in the script and using proc.getErrorStream in your java program.
I am trying to do something using system exec in Java
Runtime.getRuntime().exec(command);
Surprisingly everything that is related with paths, directories and files is not working well
I don't get why and just want to know is there any alternatives?
The alternative is to use the ProcessBuilder class, which has a somewhat cleaner interface, but your main problem is probably related to how the OS processes command lines, and there isn't much Java can do to help you with that.
As noted above, cd is a shell builtin. i.e. it's not an executable. You can determine this using:
$ which cd
cd: shell built-in command
As it's not a standalone executable, Runtime.exec() won't be able to do anything with it.
You may be better off writing a shell script to do the shell-specific stuff (e.g. change the working directory) and then simply execute that shell script using Runtime.exec(). You can set PATH variables etc. within your script and leave Java to simply execute your script.
One thing that catches people out is that you have to consume your script's stdout/stderr (even if you throw it away). If you don't do this properly your process will likely block. See this SO answer for more details.
The exec() method can take three arguments. The third is the directory your subprocess should use as its working directory. That solves your "cd" problem, anyway.
I am trying to write a simple application that takes in a command line arguement (which will be a Powershell ps1 file) and then run it. So I have experemented with a number of different approaches and seem to be running into a problem. If I attempt to invoke powershell from within java, the windows process is started and is visible via process explorer, however powershell never returns, it hangs in some sort of loop by the looks of it. The command I am using is:
String command = "powershell -noprofile -noninteractive \"&C:\\new\\tst.ps1\"";
The command is then executed using:
Runtime systemRuntime = Runtime.getRuntime();
Process proc = systemRuntime.exec(command);
At the moment I am hard coding the location to the ps1 file as I was trying to rule this out as an issue. Using a process explorer I can see the hanging powershell process and the command that was passed to it was :
powershell -noprofile -noninteractive "&C:\new\tst.ps1"
which when copied into a cmd window, works to launch the tst.ps1 file. The file itself is incredibly simple in this example and I think I can rule it out being the cause of the freeze as I have tried to launch other ps1 files the same behaviour can be seen.
To further add to the confusion, if I use the java code posted above and pass in powershell commands instead of a file name then it successfully runs.
I've scoured the web and see lots of people experiencing the same issue but no one seems to have posted there solution, I hope its a simple oversight on my part and can be easily fixed.
Any hints/tips are appreciated :D
Alan
You have to close OutputStream in order for Powershell to exit.
Runtime systemRuntime = Runtime.getRuntime();
Process proc = systemRuntime.exec(command);
proc.getOutputStream().close();
Is your external program writing to the standard outputs (err and out)?
If yes, it can hang waiting for you to consume them from the java parent process.
You can get those as InputStreams by calling
Process.getInputStream()
and
Process.getErrorStream()
There's more details here:
Javadoc for Process
I have a Java program that I'd like to daemonize on a linux system. In other words, I want to start running it in a shell and have it continue running after I've logged out. I also want to be able to stop the program cleanly.
I found this article which uses a combination of shell scripting and Java code to do the trick. It looks good, but I'd like something simpler, if possible.
What's your preferred method to daemonize a Java program on a Linux system?
Apache Commons Daemon will run your Java program as Linux daemon or WinNT Service.
If you can't rely on Java Service Wrapper cited elsewhere (for instance, if you are running on Ubuntu, which has no packaged version of SW) you probably want to do it the old fashioned way: have your program write its PID in /var/run/$progname.pid, and write a standard SysV init script (use for instance the one for ntpd as an example, it's simple) around it. Preferably, make it LSB-compliant, too.
Essentially, the start function tests if the program is already running (by testing if /var/run/$progname.pid exists, and the contents of that file is the PID of a running process), and if not run
logfile=/var/log/$progname.log
pidfile=/var/run/$progname.pid
nohup java -Dpidfile=$pidfile $jopts $mainClass </dev/null > $logfile 2>&1
The stop function checks on /var/run/$progname.pid, tests if that file is the PID of a running process, verifies that it is a Java VM (so as not to kill a process that simply reused the PID from a dead instance of my Java daemon) and then kills that process.
When called, my main() method will start by writing its PID in the file defined in System.getProperty("pidfile").
One major hurdle, though: in Java, there is no simple and standard way to get the PID of the process the JVM runs in.
Here is what I have come up with:
private static String getPid() {
File proc_self = new File("/proc/self");
if(proc_self.exists()) try {
return proc_self.getCanonicalFile().getName();
}
catch(Exception e) {
/// Continue on fall-back
}
File bash = new File("/bin/bash");
if(bash.exists()) {
ProcessBuilder pb = new ProcessBuilder("/bin/bash","-c","echo $PPID");
try {
Process p = pb.start();
BufferedReader rd = new BufferedReader(new InputStreamReader(p.getInputStream()));
return rd.readLine();
}
catch(IOException e) {
return String.valueOf(Thread.currentThread().getId());
}
}
// This is a cop-out to return something when we don't have BASH
return String.valueOf(Thread.currentThread().getId());
}
I frequently find myself writing scripts or command lines which essentially look like this, if I want to:
Run a program that is immune to sighups
That is completely disconnected from the shell which spawns it, and
Produces a log file from stderr and stdout the contents of which are displayed as well, but
Allows me to stop viewing the log in progress and do other stuff without disrupting the running process
Enjoy.
nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &
I prefer the nohup command. The blog post says there are better ways, but I don't think they're enough better.
You could try Java Service Wrapper, the community edition is free and meets your needs.
My preferred way on Ubuntu is to use the libslack 'daemon' utility. This is what Jenkins uses on Ubuntu (which is where I got the idea.) I've used it for my Jetty-based server applications and it works well.
When you stop the daemon process it will signal the JVM to shutdown. You can execute shutdown/cleanup code at this point by registering a shutdown hook with Runtime.addShutdownHook().
That depends. If it's just a one-time thing, I want to daemonize it and then go home, but usually I wait for the results, I might do:
nohup java com.me.MyProgram &
at the command line. To kill it cleanly, you have a lot of options. You might have a listener for SIGKILL, or listen on a port and shutdown when a connection is made, periodically check a file. Difference approaches have different weaknesses. If it's for use in production, I'd give it more thought, and probably throw a script into /etc/init.d that nohups it, and have a more sophisticated shutdown, such as what tomcat has.
DaemonTools :- A cleaner way to manage services at UNIX https://cr.yp.to/daemontools.html
Install daemon tools from the url https://cr.yp.to/daemontools/install.html
follow the instruction mentioned there,for any issues please try instructions https://gist.github.com/rizkyabdilah/8516303
Create a file at /etc/init/svscan.conf and add the below lines.(only required for cent-os-6.7)
start on runlevel [12345]
stop on runlevel [^12345]
respawn
exec /command/svscanboot
Create a new script named run inside /service/vm/ folder and add the below lines.
#!/bin/bash
echo starting VM
exec java -jar
/root/learning-/daemon-java/vm.jar
Note:
replace the Jar with your own Jar file. or any java class file.
Reboot the system
svstat /service/vm should be up and running now !.
svc -d /service/vm should bring vm down now !.
svc -u /service/vm should bring vm up now !.
This question is about daemonizing an arbitrary program (not java-specific) so some of the answers may apply to your case:
Take a look here:
http://jnicookbook.owsiak.org/recipe-no-022/
for a sample code that is based on JNI. In this case you daemonize the code that was started as Java and main loop is executed in C. But it is also possible to put main, daemon's, service loop inside Java.
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo029
Have fun with JNI!
nohup java -jar {{your-jar.jar}} > /dev/null &
This may do the trick.