How to exit rmi server application - java

if we are to have an RMI server application which runs permanently via autosys and then shuts down for a few hours over night, how to we send the shutdown message if the application was started from the command line.
for example, we start the jar using java -jar server.jar and now the application is running. if it contained a applicationClose() method how could we call it - we could parse the message from the client but of course this is undesirable?

It is perfectly acceptable to make a closedown request method available, that returns OK and then calls System.exit().
You might want to protect it with some sort of required credentials before it can be called, but other than that there is no reason why you can't.
The other option is for the process to have another TCP port open with your own protocol for shutting down, or to have a JMX extension installed to remotely shut down the service.

Related

Remote shutdown of client system using Java

How do i remotely shutdown client/s system from server end ?
Also, how do i run any command on client/s command prompt ?
How do i send the line of codes to the client end from the server side ?
I've used ArrayList to send messages across the client earlier.
I guess this is what you are looking for:
Shutting down a computer
Already been asked on here :)
For shutting down a computer remotely use:
shutdown /s /m <Computer_Name>
Link to that post aswell: Shutdown Remote Computer in Java- Cannot initiate shutdown but no errors

wait with systemd until a service socket becomes available and then start a depended service

Currently I have slow starting java service in systemd which takes about 60 seconds until it opens its HTTP port and serves other clients.
Another client service expects this service to be available (is a client of the this service), otherwise it dies after a certain retry. It also started with systemd. This is to be clear also a service. But uses the former like database.
Can I configure systemd to wait until the first service has made his socket available? (something like if the socket is actually listens , then the second client service should start).
Initialization Process Requires Forking
systemd waits for a daemon to initialize itself if the daemon forks. In your situation, that's pretty much the only way you have to do this.
The daemon offering the HTTP service must do all of its initialization in the main thread, once that initialization is done and the socket is listening for connections, it will fork(). The main process then exits. At that point systemd knows that your process was successfully initialized (exit 0) or not (exit 1).
Such a service receives the Type=... value of forking as follow:
[Service]
Type=forking
...
Note: If you are writing new code, consider not using fork. systemd already creates a new process for you so you do not have to fork. That was an old System V boot requirement for services.
"Requires" will make sure the process waits
The other services have to wait so they have to require the first to be started. Say your first service is called A, you would have a Requires like this:
[Unit]
...
Requires=A
...
Program with Patience in Mind
Of course, there is always another way which is for the other services to know to be patient. That means try to connect to the HTTP port, if it fails, sleep for a bit (in your case, 1 or 2 seconds would be just fine) then try again, until it works.
I have developed both methods and they both work very well.
Note: A powerful aspect to this method, if service A gets restarted, you'd get a new socket. This server can then auto-reconnect to the new socket when it detects that the old one goes down. This means you don't have to restart the other services when restarting service A. I like this method, but it's a bit more work to make sure it's all properly implemented.
Use the systemd Auto-Restart Feature?
Another way, maybe, would be to use the restart on failure. So if the child attempts to connect to that HTTP service and fails, it should fail, right? systemd can automatically restart your process over and over again until it succeeds. It's sucky, but if you have no control over the code of those daemons, it's probably the easiest way.
[Service]
...
Restart=on-failure
RestartSec=10
#SuccessExitStatus=3 7 # if success is not always just 0
...
This example waits 10 seconds after a failure before attempting to restart.
Hack (last resort, not recommended)
You could attempt a hack, although I do not ever recommend such things because something could happen that breaks such... in the services, change the files so that they have a sleep 60 then start the main process. For that, just write a script like so:
#!/bin/sh
sleep 60
"$#"
Then in the .service files, call that script as in:
ExecStart=/path/to/script /path/to/service args to service
This will run the script instead of directly your code. The script will first sleep for 60 seconds and then try to run your service. So if for some reason this time the HTTP service takes 90 seconds... it will still fail.
Still, this can be useful to know since that script could do all sorts of things, such as use the nc tool to probe the port before actually starting the service process. You could even write your own probing tool.
#!/bin/sh
while true
do
sleep 1
if probe
then
break
fi
done
"$#"
However, notice that such a loop is blocking until probe returns with exit code 0.
You have several options here.
Use a socket unit
The most elegant solution is to let systemd manage the socket for you. If you control the source code of the Java service, change it to use System.inheritedChannel() instead of allocating its own socket, and then use systemd units like this:
# example.socket
[Socket]
ListenStream=%t/example
[Install]
WantedBy=sockets.target
# example.service
[Service]
ExecStart=/usr/bin/java ...
StandardInput=socket
StandardOutput=socket
StandardError=journal
systemd will create the socket immediately (%t is the runtime directory, so in a system unit, the socket will be /run/example), and start the service as soon as the first connection attempt is made. (If you want the service to be started unconditionally, add an Install section to it as well, with WantedBy=multi-user.target.) When your client program connects to the socket, it will be queued by the kernel and block until the server is ready to accept connections on the socket. One additional benefit from this is that you can restart the service without any downtime on the socket – connection attempts will be queued until the restarted service is ready to accept connections again.
Make the service signal readiness to systemd
Alternatively, you can set up the service so that it signals to systemd when it is ready, and order the client after it. (Note that this requires After=example.service, not just Requires=example.service! Dependencies and ordering are orthogonal – without After=, both will be started in parallel.) There are two main service types that might make this possible:
Type=forking: systemd will consider the service to be ready as soon as the main program exits. Since you can’t fork in Java, I think you would have to write a small shell script which starts the server in the background and then waits until the socket is available (while ! test -S /run/example; do sleep 1s; done). Once the script exits, the service is considered ready.
Type=notify: systemd will wait for a message from the service before it is considered ready. Ideally, the message should be sent from the service PID itself: check if you can call the sd_notify function from libsystemd via JNI/JNA/whatever (specifically, sd_notify(0, "READY=1")). If that’s not possible, you can use the systemd-notify command-line tool (--ready option), but then you need to set NotifyAccess=all in the service unit (by default, only the main process may send notifications), and even then it likely will not work (systemd needs to process the message before systemd-notify exits, otherwise it will not be able to verify which cgroup the message came from).

Deploying a Play Framework application on port 80 beside Apache

I'm looking for a way to deploy my Play-Framework-1.0 application on the port 80.
So first I made the zip file with 'dist' command, then I unzipped it.
When I run the command to lauch the application (play-java-1.0-SNAPSHOT/bin/play-java -Dhttp.port=80 -Dhttp.adresse=127.0.0.1), I get this error :
[error] p.c.s.NettyServer - Failed to listen for HTTP on /0.0.0.0:80!
Oops, cannot start the server.
play.core.server.ServerListenException: Failed to listen for HTTP on /0.0.0.0:80!
at play.core.server.NettyServer.play$core$server$NettyServer$$bindChannel(NettyServer.scala:215)
at play.core.server.NettyServer$$anonfun$1.apply(NettyServer.scala:203)
at play.core.server.NettyServer$$anonfun$1.apply(NettyServer.scala:203)
at scala.Option.map(Option.scala:146)
at play.core.server.NettyServer.<init>(NettyServer.scala:203)
at play.core.server.NettyServerProvider.createServer(NettyServer.scala:266)
at play.core.server.NettyServerProvider.createServer(NettyServer.scala:265)
at play.core.server.ServerProvider$class.createServer(ServerProvider.scala:25)
at play.core.server.NettyServerProvider.createServer(NettyServer.scala:265)
at play.core.server.ProdServerStart$.start(ProdServerStart.scala:53)
at play.core.server.ProdServerStart$.main(ProdServerStart.scala:22)
at play.core.server.ProdServerStart.main(ProdServerStart.scala)
Moreover, in the real server, Apache has been installed. So I wonder, whether that will be a problem.
Thanks!
Optionally, also remember that on most systems, running processes on ports lower than 8000 is disabled in default, in such case you need to allow it, i.e. on Unix servers, just using sudo command(prefix).
If you are using a Linux server, you can try 'fuser 80/tcp' to see whether another process is already running on that port (80). If so (there's showing a process-id, when you enter the command), you cannot use the same port for 2 processes.
Either, you have to start the Play-app in a different port or you can kill the already running process by 'sudo fuser -k 80/tcp' and start the Play-app on the same port (80).
It's not possible to have two processes running on the same host listening on the same port.
However, you could run you Play application on different port, e.g. 8080 and set up Apache as a reverse proxy (Nginx would do too, but you mentioned that you already have Apache running on the server) to forward requests to your Play application.
Example guide how to do that:
https://www.digitalocean.com/community/tutorials/how-to-use-apache-http-server-as-reverse-proxy-using-mod_proxy-extension

Best way to program a server status feature

Some background information.
- Running a java server on localhost
- Running a webserver on localhost
I would like a webpage to have a 'server status' feature which lets me know whether the server is running or not. My question, what is the best way to do this?
When I launch the java server, I write a flag in the database to signify that it is running.
Javascript/PHP sockets to try and bind on the same port. (Not sure if possible yet)
Shell script to locate the program in the task list.
Thanks!
When I launch the java server, I write
a flag in the database to signify that
it is running.
would not be of much help if the server should segfault.
Maybe have a look at http://mmonit.com/monit/
what is pretty much what you are looking for
I suspect the simplest method is simply for your web service (backend) to try and connect to the port that your server is running on, and provide an automatically refreshing page that reports this status. If your server goes down then you'll get an faster notification than if you're polling (say) the process table.
Of course the fact that you can connect to the port doesn't really give you an indication of whether it's working other than it's opened a port (e.g. it may have no resources etc. to service requests) but it's a start.

Starting and reconnecting to a spring bean from console

I like to write a little server application being controlled by a little console app (start, pause, stop, etc). For the server spring should be used (part of it already exist). So what I do to start the server is something like this:
start a server thread and exit main method
and then, in the thread:
load application context from xml
start some worker threads connecting to beans doing stuff
Now I want the server to be stopped by another command. How can I connect to the already running context and shut it down?
Thanks for your help,
Alexander
The classical way to manage running Java code is through JMX.
Spring lets you export beans as MBeans.
And for accessing JMX via the command line, look at the answers to this recent question:
Calling JMX MBean method from a shell script
You could create a pid file, when the server starts, it should log the pid to a file, server.pid. When you do a stop, you can read the process and kill it. Or even simpler, have a ever running thread in your main class which keeps looking for a file in some folder. As soon as the file becomes available or gets modified, it will stop the server.

Categories