The Overall Problem
When I install a simple Java application that I wrote to run on boot in the background through /etc/init.d/, it works on the liveUSB that I explicitly install it on. When I make a copy of that stick, it never boot successfully. When booting the liveUSB copy the Java application will always hang when the liveUSB boot process reaches my script. My script, which does do exactly what it is supposed to do, even every 5 minutes and will continue running forever until you power down the machine.
My script is blocking everything else
Nothing loads beyond my script
You cannot cancel my script
There is no GUI
The only text you can see is the command line output from my script
Setup & Test - Everything goes well :)
I have a Linux liveUSB with 3 partitions. Simple standard Xubuntu image is loaded.
sda1 > 2gb stoage
sda2 > 2gb system
sda3 > remaining gb for casper
I have created a simple Java application that runs in the background on start up. To get this far, I followed these steps:
Compiled java application into classes
Placed class files in /home/user/folder/
Copied my startup.sh script into /etc/init.d/
While inside /etc/init.d/
Typed "update-rc.d startup.sh start 20 2 5 . stop 20 0 1 6 ."
This updated run levels successfully
Now I can restart / reboot / shutdown whatever operation and everything runs perfectly!
The Copy - Here's where it gets tricky!
When creating a copy of this stick, I follow these steps:
Mount sda2
copy everything from that folder to /home/user/Desktop/tmp-system/
Mount sda3
copy everything from that folder to /home/user/Desktop/tmp-casper/
Go into /home/user/Desktop/tmp-system/
Type "tar -cvf system.tar ."
Go into /home/user/Desktop/tmp-casper/
Type "tar -cvf casper.tar ."
Umount
sda2
sda3
Plug in empty USB (sdb for example)
Set up partitions (Same as the stick you are copying from)
Untar into partitions
tar -xvf system.tar ... into sdb2
tar -xvf casper.tar ... into sdb3
Testing - Here's where everything goes wrong!
Plug in newly created liveUSB into a computer
Boot from USB
Everything starts to boot fine
Java application that I wrote gets triggered
Boot process hangs forever
No cmd prompt available
NO GUI available
It is as if the thread is running (and it is! The output can be viewed every 5 minutes - which is exactly the way it should be)
Solution Attempts & Gotchas
1
I can mount the copied liveUSB edit the startup.sh to not start my Java application and it will still not boot (just as I suspected?).
2
If I use "dd if=sda of=sdb" the copy of the liveUSB will work perfectly fine. However this is not an acceptable solution. If I were to copy a 16gb stick with dd to a 64gb stick, that would turn the 64gb stick into a 16gb.
3
Tested many variations of startup.sh and the Java application itself. All of which produce the same error.
4
The method I am using to copy works for every other form of application, file or anything else.
5
I would also like to try and avoid using any additional libraries or programs to help run the Java application.
What you might better do is to use a method to quickly create a liveUSB Linux stick, then add the Java program settings and directories.
Here is some help - Bootable pendrive as live cd
I definitely like point number 1 that you mention. Copy liveUSB even without the Java program does not work. You have spent quite some time to debug that program. I have the feeling that you are interested in making many liveUSB with the Java program installed. Since dd is not an option, my guess is that it's more meaningful to somehow use a Kickstart procedure for quick LiveUSB installations and then copy the Java things.
Thanks.
Related
On CentOS 7 i have /home/www/html/java-server/Objects/server.jar file which time to time crash for good reason and need to re-start again automatic so that its always running.
How to use forever like tool or any other similar for Java on CentOS?
For example on my NodeJS server i use as below.
forever start --minUptime 1000 --spinSleepTime 1000 SERVER.js
or
forever -m5 server.js
EDIT:
Reference: https://stackoverflow.com/a/28704296/285594
Wrap your jar in a shell script (this is optional but often useful) and use Supervisor to monitor it. Supervisor is highly customizable so you can set how many times your process can be restarted in a period of time, etc.
Here is how I did it.
I was trying to get a spring boot executable jar to run.
I created a bash script like the following
#!/bin/bash
forever start -c bash ./my-app.jar
The key here is to use "-c bash" otherwise forever failed to run the jar. Forever kept trying to run with node
You can write a class in Java that loops. It would call your application and catch exceptions, restarting the application after each exception. Make sure the wrapper class releases references to the application so that it can be GC'ed.
I am fairly new to Amazon. I have a Java file which reads GBs of crawled data and I am running this using AWS ToolKit for Eclipse. The disadvantage here is, I have to keep my machine running for weeks if I need to read the entire crawled data and that is not possible. Apart from that, I can't download GBs of data in to my local PC (Because it is reading data).
Is there any way that I can upload the Jar to Amazon, and Amazon run it without engaging with my computer? I have heard about web crawlers running in Amazon for weeks without downloading data into the developers machine, and without letting the developer to turn on his machine without shutting down for months.
The feature I am asking is just like "job flows" in Amazon Elastic Map-Reduce. You upload the code, it runs it inside. It doesn't matter whether you keep "your" machine turned on or not.
You can run with the nohup command for *nix
nohup java -jar myjar.jar 2>&1 >> logfile.log &
This will run your jar file, directing the output [stderr and stdout] to logfile.log. The & is needed so that it runs in the background, freeing up the command line / shell/
!! EDIT !!
It's worth noting that the easiest way I've found for stopping the job once it's started is:
ps -ef | grep java
Returns ec2-user 19082 19056 98 18:12 pts/0 00:00:11 java -jar myjar.jar
Then kill 19082.
Note, you can tail -f logfile.log or other such derivatives [less, cat, head] to view the output from the jar.
Answer to question/comment
Hi. You can use System.out.println(), yes, and that'll end up in logfile.log. The command that indicates that is the 2&>1 which means "redirect stream 2 into stream 1". In unix speak that means redirect/pipe stderr into stdout. We then specify >> logfile.log which means "append output to logfile.log". As System.out.println() writes to stdout it'll end up in logfile.log.
However, if you're app is set up to use Log4j/commons-logging then using LOG.info("statement"); will end up in the configured 'log4j.properties' log file. With this configuration the only statements that will end up in logfile.log will be those that are either System generated (errors, linux internal system messages) or anything that's written explicitly to the stdout (ie System.out.println()) statements;
Have you had experience with running a jar file using a command line, wrapped in a Windows service?
I'm trying to find a way to run a jar file without being logged into the machine, and since it allows command shell, I was wondering if it's a good idea.
Thanks!
Original Post:
I'm trying to run Associated Press's Web Feeds Manager, which is basically a jar file that can be run when logged in by double clicking it.
I'd like to run the same file but without being logged in to the machine. In their manual (http://wfm.ap.org/admin/content/help/Running_Agent_on_a_Remote_Server.htm) they write how to do that, using a commandline parameter.
Basically I'd like the jar to run as a Windows service, regardless of who's logged in, but Googling it showed it was problematic.
Have you had experience with remotely running jar files? What are the pitfalls?
Thanks!
On a google search, I came across this article -
Running Jar Applications as a Windows Service
It mentions about open source Java Service Wrapper project from Tanukisoftware.org for accomplishing this task.
Note: I've not used this personally.
If you are not interested in having the service started/stopped at boot/shutdown, but you just want the program to be started manually and keep running after logout, here is what you do:
$ nohup java -jar foobar.jar > foobar.log 2>&1 &
which means: start my foobar.jar (java -jar) and keep it running after I logout (nohup) redirect stdout to foobar.log (>) and also the stderr (2>&1), and make it running in background (& at the end).
Instead, if you are interested in installing a "service" in your linux box, there are many options, depending on what distribution you are using.
The most common are upstart (for ubuntu) and System V init scripts (Redhat or others). Also cron can be used to start/stop services at startup/shutdown.
You can find an example of installing a java app (hudson) on an init system here, or doing the same thing with upstart. Or, as I said, cron could be an option.
On Windows, there is Java Service Wrapper. And not much more.
For windows Java Service Wrapper is a better choice
My favourite is the upstart on linux, but it is Ubuntu only.
On Windows I see many alternatives according to this forum.
In a project, I'm trying to set up an automated build system for Apache Karaf (there are several commands I need to run in Karaf to set up a working environment on a fresh install). Karaf contains a batch/script file that sets several parameters, and then calls the actual Java program. Essentially, I'd like to be able to do something like:
java MyProgramClass.class < commandTextFile.txt
But when I try this it doesn't do anything. My goal is to simply copy the karaf.bat file, modify it slightly (as below) to make a "karaf-install.bat" that I can just run. The part I've modified of karaf.bat is below, and all I've done is add < "C:\commandFile.txt at the end (the following is all on one line, broken for readability):
"%JAVA%" %JAVA_OPTS% %OPTS% -classpath "%CLASSPATH%"
-Djava.endorsed.dirs="%JAVA_HOME%\jre\lib\endorsed;%JAVA_HOME%\lib\endorsed;%KARAF_HOME%\lib\endorsed"
-Djava.ext.dirs="%JAVA_HOME%\jre\lib\ext;%JAVA_HOME%\lib\ext;%KARAF_HOME%\lib\ext"
-Dkaraf.instances="%KARAF_HOME%\instances" -Dkaraf.home="%KARAF_HOME%"
-Dkaraf.base="%KARAF_BASE%" -Dkaraf.data="%KARAF_DATA%"
-Djava.util.logging.config.file="%KARAF_BASE%\etc\java.util.logging.properties"
%KARAF_OPTS% %MAIN% %ARGS% < "C:\commandFile.txt"
However, Karaf shows nothing. It just runs as if I executed it as normal; my commands are not executed. Is there a way to redirect INTO a java program from the console? Am I doing it way wrong?
For what it's worth, this will eventually be done on both Windows and OS X, but I'm focusing on Windows at the moment.
Update: turns out that this seems to work for me on OS X (Karaf struggles (by saying "Command not found: "), but I think it's because it's getting the commands before it's initialized everything), but Windows is still doesn't even get the commands. I'll poke around more.
When piping INTO, you can read it from System.in.
Consider it a Reader, not an InputStream.
I'm just going to write this issue off as Karaf weirdness, seeing as it works on OS X. I was able to work around it by using the client program that comes with Karaf by doing (on OS X in a .sh file):
"$KARAF/bin/client" "karaf_command_here"
or (on Windows in a .bat file)
call "%KARAF%\bin\client.bat" "karaf_command_here"
And instead of having a list of commands to pipe into Karaf, I just made the list of commands a shell/batch script file that would call Karaf's client for each command. Not as pretty as I'd have liked it, but it got the job done.
(Note you need to start Karaf before using the client with start (and close it with stop)).
I have developed a MPI application using Java and MPJ Expresss. It works perfectly in the multi-core configuration.
Recently, it was given to my access to the distributed memory environment in order to test my application. First, I did the MPJ HelloWorld application to check that the cluster configuration was working well. After that, I proceeded to run my application, but it freezes after showing:
MPJ Express (0.38) is started in the cluster configuration
To make things worse, I killed the process with Ctrl+C and I couldn't run the HelloWorld application. I had to kill the MPJ daemon in all machines and start them again.
I even replace the content of my main class with the same content of the HelloWorld class to see if it printed something. It didn't. Also, I created a HelloWorld application with a similar package structure to my application and the HelloWorld worked great.
One of the big differences I can notice between the HelloWorld and my application is that I have a set of libraries which size is around 29.8 MB, so I tried not adding the libraries to the execution class path. It worked, but of course, my application is useless because it can't find its required libraries at run time.
I would appreciate any comments and advices.
Thanks!
Visit mpj-express.org/readme.html and select a file based on your platform:
Linux / UNIX / Mac - http://mpj-express.org/docs/readme/README
Windows - http://mpj-express.org/docs/readme/README-win.txt
The (Windows) service "MPJ Daemon" should be installed once.
Nevertheless, threads are to be started before and halted after every MPJ application,
if you are using Eclipse IDE.
Note: On command line, you can start threads, run as many programs as you wish and finally terminate them.
Write 'machine' file
Start daemons: mpjboot machines
Compile: javac -cp .:$MPJ_HOME/lib/mpj.jar HelloWorld.java
Execute: mpjrun.sh -np 4 -dev niodev HelloWorld
Stop daemons: mpjhalt machines