Making a Java Dual-exported server daemon - java

I have the following server class that export himself for JRMP and IIOP:
public class FooServer implements RemoteInt{
FooServer(){
UnicastRemoteObject.exportObject(this);
PortableRemoteObject.exportObject(this);
}
public boolean remoteMethod() throws RemoteException{
// some stuff
return false;
}
}
and the following setup class which creates the server and register it to a running register:
public class Setup{
public static void main(String[] args){
RemoteInt serv = new FooServer();
Naming.rebind("//localhost/server", this);
}
}
The problem is that when Setup finishes its job, it waits for the FooServer to terminate. Instead I would like to exit from Setup class, leaving the FooServer running.
How can I do?

You can't. The remote object is exported from the current JVM and it keeps it running until you unexport it. Note that the main() method does exit, but the RMI/JRMP and RMi/IIOP listening threads are still running so the JVM doesn't exit.

Related

Why is Thread.sleep halting the main thread? [duplicate]

I created my own thread class implementing the Runnable interface. But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself. Is this just an issue within Eclipse or would I also have problem running this on a Server? Do I have to change something calling the thread so that the main method can terminate properly?
Here's my basic self-made thread:
public class OwnThread implements Runnable {
#Override
public void run() {
//do something
}
}
Here's the main class that won't terminate anymore:
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
}
When I debug it, the last called method is the exit()-method of the Thread-class. After going through these lines of code, the process goes on forever:
/**
* This method is called by the system to give a Thread
* a chance to clean up before it actually exits.
*/
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* Speed the release of some of these resources */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
Here's a screenshot of the thread that is running forever. The TestInterface class is where the main-method is located:
But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself.
This is somewhat wrong. Your program does not terminate because there exists at least one non-daemon thread that still is running. The rule is: A Java program is terminated if all non-daemon threads are terminated.
I modified your program to make this behavior clear:
public class OwnThread implements Runnable {
#Override
public void run() {
runForever();
}
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
runForever();
}
private static void runForever() {
while (true) {}
}
}
Running that will create two threads that will run forever. One is the main thread which is started by running the program, and the other is the thread started inside the main method:
Modifying the above code by removing the call to runForever in the main method ...
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
}
... will result in a different thread picture:
Here the main thread is gone because it is terminated. But the other started thread is still running.
Side note: Suddenly another thread appears - DestroyJavaVM. Have a look at the post DestroyJavaVM thread ALWAYS running for more information.
The issue is indeed not caused by the multithreading logic itself, it is caused by Eclipse and the respective JVM. Running the exact same code in Netbeans or on an Tomcat 8 Server did not lead to any problems. A reinstallation of Eclipse did not solve the malfunction within the Eclipse framework, but having the certainty that the issue does not cause any trouble on a server is sufficient for me to close the case.
Thanks to Seelenvirtuose for the hints and his effort.

Use of Thread.currentThread().join() in Java

The following code is taken from an example in the Jersey project. See here.
public class App {
private static final URI BASE_URI = URI.create("http://localhost:8080/base/");
public static final String ROOT_PATH = "helloworld";
public static void main(String[] args) {
try {
System.out.println("\"Hello World\" Jersey Example App");
final ResourceConfig resourceConfig = new ResourceConfig(HelloWorldResource.class);
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, resourceConfig, false);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
server.shutdownNow();
}
}));
server.start();
System.out.println(String.format("Application started.\nTry out %s%s\nStop the application using CTRL+C",
BASE_URI, ROOT_PATH));
//////////////////////////////
Thread.currentThread().join();
//////////////////////////////
} catch (IOException | InterruptedException ex) {
//
}
}
}
I understand what is going on apart from the use of Thread.currentThread().join();.
I'm a Java newbie and my understanding is that this will block the execution of the current thread (in this case, the main thread), and effectively deadlock it. i.e. it will cause the current (main) thread to block until the current (main) thread finishes, which will never happen.
Is this correct? If so, why is it there?
Thread.currentThread().join() blocks the current thread forever. In your example, that prevents the main from exiting, unless the program is killed, e.g. with CTRL+C on Windows.
Without that line, the main method would exit right after the server is started.
An alternative would have been to use Thread.sleep(Long.MAX_VALUE);.
It's a common misunderstanding that if the main thread exits, the program will exit.
This is only true if there is no non-daemon thread running. This may be true here, but usually it is better IMHO to make the background threads this main is "waiting" for non-dameon and let the main thread exit when it doesn't have anything to do. I have see developers put Thread.sleep() wrapped in an infinite loop. etc.
It's an example. It's just not a very good one.
They're trying to show you how to make a thread that runs forever.
Thread.currentThread().join(); is a statement that takes forever to complete. You're supposed to replace it with your own code that runs forever and, presumeably does something useful.

Jar with multiple main

In one package I have two different classes Client.java and Server.java
I want to make this package jar, i mean executable.
First I want the Server class to run and after 2-3 seconds I want Client method to run. Is it possible?
Thank you
You have to leave only one main method and run your server and client in separate threads from it.
To do it, take a look at Runnable interface. Your server class and client class should implement it. Then you have to move the logic, used to start server and client to it's run() method.
class Server implements Runnable {
#Override
public void run() {
//your server starting logic here
}
}
class Client implements Runnable {
#Override
public void run() {
//your client starting logic here
}
}
After that, you can modify your main method, to start server and client, like:
public static void main(String args[]) throws InterruptedException {
Server server = new Server();
Client client = new Client();
Thread tServer = new Thread(server);
tServer.start();
//here you can wait some time to Server started
Thread tClient = new Thread(client);
tClient.start();
}

How to run several methods in a thread? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a problem when I want to run several methods not in the main thread. I created a class extends from Runnable and put all my tasks there. There are a lot of tasks actually. Then in the main thread I created a new instance of Thread and passed my runnable class as a parameter, but what I got is that the run method is the only code which executed in the thread, and if call any method inside the runnable class it will execute in the main thread instead of the new thread.
Example:
public class ConnectionManager implements Runnable {
#Override
public void run() {
login();
}
public void login() {
//Login Logic
}
public void sendMessage() {
//Send Message Via TCP Connection
}
public void updateInfo() {
//Update Information
}
public void logOut() {
//LogOut Logic
}
}
Now I wanted to call any of these methods in another thread, so I did this:
public class Login implements SomeInterface {
private Thread thread;
private ConnectionManager connection;
public void main(String[] args) {
connection = new ConnectionManager();
thread= new Thread(connection);
thread.start(); // This will execute the run method and the login process works fine.
}
#Override
public void someCallback() {
connection.sendMessage();//this call is not executed and block the main thread !!
}
}
What am I supposed to do to run all my methods in another thread without making a new thread for each method?
You should split your logic
public class Logger implements Runnable {
#Override
public void run() {
// login logic here;
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//Send Message Via TCP Connection
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//Update Information
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//LogOut Logic
}
}
And then in some client:
Runnable logger = new Logger(credentials);
Executors.newSingleThreadExecutor().execute(logger);
Well this is how threads work in java. One possibility is to use Actors in java. You will have to download the Akka framework here:http://akka.io/downloads/.
Actors works by messages, they act in a separate process and are even driven messages. In other words depending on the message you send to the actor it will process a corresponding method.
Check in the following link for instances: http://doc.akka.io/docs/akka/snapshot/java/untyped-actors.html
The method run equivalent in java actors is onReceive().
And to send a message to the actor, myActor.tell(...)
Hope this helps you!!!!
Well, that is the way threads work in Java. When You call connection.sendMessage() Your method just treats ConnectionManager and runs it's code. You need to execute Your method in another threads run(), or it will not run. Perhaps You need a way to comunicate with Your thread to make it execute a method in run() or just explore the possibilities that Future objects give You?
That's how does Runnable or Multithread handling work.
You should never call the run() directly and only this function and other function calls inside this function are executed in the new thread.
Basically your Runnable class should only contains one public function: the run() and you should not call it directly...
I suggest you to put other functions in their own classes. As you can see the workflow is not continuous, sendMessage() is not called directly after login() (otherwise you can do it inside run() and don't need that someCallback()).
Otherwise what should that new thread supposed to do in the time between? block and wait for sendMessage()? That's not a good design. So you should start a new thread for sendMessage().

Terminate Java RMI server application

I have set up a client/server project using Java RMI. Below I show parts of the implementation. I
launch the server using
ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/C", "start /B java -jar myServer.jar --start);
this.myProcess = processBuilder.start();
I have added a main method to the server which handles the command line call.
The server starts and runs perfectly. The client is able to connect and perform as I expect it to.
My problems arise when I try to kill the server. This needs to be done from outside. The object which
previously started the process is not available anymore. To actually stop the server, the main method
of the server class calls a stop method (see below). This method now kills the RMI but it does not
the least stop the JVM from running. The process is still available and needs to be killed from the
task manager (on Windows).
Do I miss some fact in my implementation that yields this behavior. Why does the process not stop running?
public class MyServer {
// ...
public void startServer() throws RemoteException {
// the RMI registry
Registry registry;
try {
// find the registry
registry = LocateRegistry.createRegistry(portRMI);
} catch (Exception e) {
// if the registry does not yet exist, try to create a new registry
// entry or use an existing one
registry = LocateRegistry.getRegistry(MyConstants.HOST_NAME, portRMI);
}
// create the object
servantObject = new MyServant();
// bind the object to the server
registry.rebind(MyConstants.SERVER_NAME, servantObject);
}
public void stopServer() throws RemoteException {
try {
// access the service
Registry rmiRegistry = LocateRegistry.getRegistry(MyConstants.HOST_NAME, portRMI);
MyService myService = (MyService) rmiRegistry.lookup(MyConstants.SERVER_NAME);
rmiRegistry.unbind(MyConstants.SERVER_NAME);
// get rid of the service object
UnicastRemoteObject.unexportObject(myService, true);
// get rid of the rmi registry
UnicastRemoteObject.unexportObject(rmiRegistry, true);
} catch (NoSuchObjectException e) {
// ...
} catch (NotBoundException e) {
// ...
}
}
public static void main(String[] args) {
// handle arguments and call either startServer or stopServer
}
}
public class MyServant extends UnicastRemoteObject implements MyService {
// ...
}
public interface MyService extends Remote {
// ...
}
You should add a self writtem RMIService interface available in your RMIServer so that a program that wishes to stop the running server instructs it to stop.
Your app that tries to stop the server just unbinds some object, as it is not the running rmi server process itself it will not have a big effect.
if your rmi sever is process a, you should write an app (using rmi) running as process b to send a message to process a to stop it.

Categories