Say you have some cli app, which calculates something for very long and outputs it into file. I want to run it as a normal app, say java -jar ..., get control immediately back to shell (let it be bash/... or windows terminal), while the actual java app still runs on background.
In linux I know about & or better nohup java -jar ... &>/dev/null &, I'm not asking about that. I'm asking how to get this 'nohup' behavior, in multiplatform way without using nohup etc.
I never did that, but I guess I could start some launcher jar, run yet another one somehow in detached way (no idea how) and then quit. Is it somehow attainable within single jar?
Related
how to run a jar file in background in windows cmd
this below jar file cmd i want to run in background
java -Djavax.net.ssl.trustStore=cacerts_appedo_agent-Djavax.net.ssl.trustStorePassword=changeit -jar appedo_tomcat_agent_2.0.063.jar
You can't do this in a platform-independent manner.
In Unix/Linux, you would call the fork() system call, which duplicates your process. With Java, that means duplicating the entire JVM. Then, you'd have to figure out whether it's the parent process or the child process, which you can determine from the process ID that the fork() call gives you. If it's the parent process, you exit. If it's the child process, you have to close standard input, standard output and standard error.
In Windows, there appears to be the FreeConsole function, but I know next to nothing about Windows programming.
So conceivably, you could write a JNA library that figures out on which platform you are, and invokes the appropriate calls to achieve this. But it's probably not the best idea to get rid of the console window when starting a Java application.
Use javaw, although you won't get any console output either, which is inconvenient.
I made a way to make my program, written in Java, update itself. The final JAR is wrapped in a EXE file, through Launch4j tool.
You need to know this piece of code:
System.getProperty("java.class.path").replaceAll("\\;\\.$", "")
gives me the actual path of the EXE. I tested it and it seems to be always working. This is important for the problem.
Now, basically the program pings a webpage and reads a series of values, which one of them is the latest version of the program. If it's greater, the program notifies the user for the update. So, the program downloads the remote data (updated EXE file) and stores them in the current running EXE file, whose filename is obtained through the method explained above. It works, but here comes the problem.
I could simply launch the downloaded EXE file and System.exit the current one, but I cannot do this, because my program works with smart cards: if two or more programs use the same smart cards, the new one won't work (I don't know why, I even restart the provider each time, but this is another story). So I prevent users from starting multiple istances of the program.
(My customers are not so smart to manually open the program each time they need it, so I needed to override the close button to make it stay in traybar, and wake up everytime it is needed. I even make it starts when Windows boots up).
So I have to close the current instance of the program, and launch again.
How I do this? I write a batch file which will basically look like this:
#echo off
taskkill /f /pid <pid of the exe program>
ping 127.0.0.1 -n 3 (this is a way to wait. I will eventually lower the waiting)
C:\Users\Mark\Desktop\program.exe (string generated by the method above. It should launch the program)
exit
Once written to disk, I execute it through Java:
Runtime.getRuntime().exec("cmd /c start " + batchFile.toString());
"batchFile" variable is a File object.
The problem is that the new downloaded program is not launched. A console window appears, shows the result of "taskkill" and "ping" (I will eventually mute them), but the program does not start. If I launch the batch file manually, it does.
Why? I really don't understand this behaviour.
Do you have any advice?
Thanks in advance!
TL;DR version:
The batch file executed by my Java program does not start the exe file written in it. Why?
I have the feeling you are trying to overwrite an executable file (EXE) that is currently running. AFAIK Windows locks such files and thus your updates should never happen.
To resolve your problem: I would split your application in two.
One part ensures the other part has the latest version, then executes that latest version.
For Java, something like this has been developed many years ago as WebStart technology, was marked as deprecated for Java 9 and removed thereafter. Meanwhile there is the project https://openwebstart.com/ that you might want to check out.
I executed a Java program from the command line in terminal app A. I want to move the console to terminal app B without having to exit and re-execute the program.
I can think of a few potential ways to solve this, ranging from:
A) In Java implement a new InputStream and OutputStream that somehow can be wired to a new process started in terminal app B.
...to
B) Find a way to put the main Java process in terminal app A in the "background" so that original process can be reopened in a terminal app B.
Ideally, I want to be able to "log in to" and "log out of" my Java process from any terminal on my computer. Has anything like this already been accomplished, and which approach would be best to make it myself? I am open to solutions that involve Java code, shell scripts, or both.
My specs:
OSX: 10.12.4
Usually running zsh on iTerm
If I was using Linux, the perfect solution would be reptyr, a command line tool that allows you to easily switch terminal windows.
On Mac, the best solution I have found is screen. It can also be used to switch terminal windows but must be invoked before running java in order to work and seems a lot more complex.
Is it possible to have several command prompts running simultaneously and switch between them, without using a GUI?
Background
I have installed CentOS-5.5-i386 without any extras, so I have a bash command prompt with root access but no GUI as far as I know.
I have written a simple Java servlet using Jetty. When I run it, it gets to a couple of commands like this;
server.start();
server.join();
where it waits for incoming requests forever - ie. it never returns to the command prompt.
I want to run a web server without the overhead of a GUI. How can I run my Java program and also continue to use the server from a command prompt?
I apologise for the waffly nature of this question but I am both a Linux newbie and a Java newbie.
Regards,
Nigel
In the general case you want screen or tmux. For running daemons, though, take a look at nohup my-daemon & or even just my-daemon &.
You can switch between consoles using Alt+F1 to Alt+F6. For more shortcuts take a look here: http://linux.about.com/od/linux101/l/blnewbie5_1.htm
This is probably really simple, but all my Google results came back with JRuby, which isn't what I want to know. I'm curious if a regular Ruby app (e.g. a Rails app or a Sinatra app) could somehow be made to reference and call a Java library that's in the classpath? Ideally one that works on Heroku.
Not directly. Java libraries run within the JVM, Ruby apps in their own VM. If you want those two to communicate, you will need to create some kind of a comms channel between them (there are various solutions, see f.e. http://code.google.com/p/activemessaging/).
I succeeded calling my Java program like this from Rails controller:
system "java -cp postgresql-9.0-801.jdbc4.jar:./ Main"
Couple of things to note:
I've compiled my Main class and put it in root of my rails app (and git-pushed it to heroku).
This call blocks rails app until java program finishes execution
It would probably work better with delayed_job gem (I'm working on it now)
http://rjb.rubyforge.org/
another option would be if the jar is executable and do something like
execute system command and run it in a 'session'/terminal
You can perform the block of commands inline of ruby (jruby) file:
importString = <<-eos
java -version
ls -l
eos
exec importString
This OK for Mac, but Windows jruby has some limitations.