Let's implement a simple standalone db4o server with a special client that can tell the server to shut itself down gracefully on demand.
First, both the client and the server need some shared configuration information. We will provide this using an interface:
01package com.db4odoc.clientserver; 02
03
/** 04
* Configuration used for {@link StartServer} and {@link StopServer}. 05
*/ 06
public interface ServerConfiguration { 07
08
/** 09
* the host to be used. 10
* <br>If you want to run the client server examples on two computers, 11
* enter the computer name of the one that you want to use as server. 12
*/ 13
public String HOST = "localhost"; 14
15
/** 16
* the database file to be used by the server. 17
*/ 18
public String FILE = "formula1.yap"; 19
20
/** 21
* the port to be used by the server. 22
*/ 23
public int PORT = 0xdb40; 24
25
/** 26
* the user name for access control. 27
*/ 28
public String USER = "db4o"; 29
30
/** 31
* the pasword for access control. 32
*/ 33
public String PASS = "db4o"; 34
}
Now we'll create the server:
01package com.db4odoc.clientserver; 02
03
import com.db4o.*; 04
import com.db4o.messaging.*; 05
06
/** 07
* starts a db4o server with the settings from {@link ServerConfiguration}. 08
* <br><br>This is a typical setup for a long running server. 09
* <br><br>The Server may be stopped from a remote location by running 10
* StopServer. The StartServer instance is used as a MessageRecipient and 11
* reacts to receiving an instance of a StopServer object. 12
* <br><br>Note that all user classes need to be present on the server 13
* side and that all possible Db4o.configure() calls to alter the db4o 14
* configuration need to be executed on the client and on the server. 15
*/ 16
public class StartServer 17
implements ServerConfiguration, MessageRecipient { 18
19
/** 20
* setting the value to true denotes that the server should be closed 21
*/ 22
private boolean stop = false; 23
24
/** 25
* starts a db4o server using the configuration from 26
* {@link ServerConfiguration}. 27
*/ 28
public static void main(String[] arguments) { 29
new StartServer().runServer(); 30
} 31
// end main 32
33
/** 34
* opens the ObjectServer, and waits forever until close() is called 35
* or a StopServer message is being received. 36
*/ 37
public void runServer(){ 38
synchronized(this){ 39
ObjectServer db4oServer = Db4o.openServer(FILE, PORT); 40
db4oServer.grantAccess(USER, PASS); 41
42
// Using the messaging functionality to redirect all 43
// messages to this.processMessage 44
db4oServer.ext().configure().setMessageRecipient(this); 45
46
// to identify the thread in a debugger 47
Thread.currentThread().setName(this.getClass().getName()); 48
49
// We only need low priority since the db4o server has 50
// it's own thread. 51
Thread.currentThread().setPriority(Thread.MIN_PRIORITY); 52
try { 53
if(! stop){ 54
// wait forever for notify() from close() 55
this.wait(Long.MAX_VALUE); 56
} 57
} catch (Exception e) { 58
e.printStackTrace(); 59
} 60
db4oServer.close(); 61
} 62
} 63
// end runServer 64
65
/** 66
* messaging callback 67
* @see com.db4o.messaging.MessageRecipient#processMessage(ObjectContainer, Object) 68
*/ 69
public void processMessage(ObjectContainer con, Object message) { 70
if(message instanceof StopServer){ 71
close(); 72
} 73
} 74
// end processMessage 75
76
/** 77
* closes this server. 78
*/ 79
public void close(){ 80
synchronized(this){ 81
stop = true; 82
this.notify(); 83
} 84
} 85
// end close 86
}
And last but not least, the client that stops the server.
01package com.db4odoc.clientserver; 02
03
import com.db4o.*; 04
import com.db4o.messaging.*; 05
06
/** 07
* stops the db4o Server started with {@link StartServer}. 08
* <br><br>This is done by opening a client connection 09
* to the server and by sending a StopServer object as 10
* a message. {@link StartServer} will react in it's 11
* processMessage method. 12
*/ 13
public class StopServer implements ServerConfiguration { 14
15
/** 16
* stops a db4o Server started with StartServer. 17
* @throws Exception 18
*/ 19
public static void main(String[] args) { 20
ObjectContainer objectContainer = null; 21
try { 22
23
// connect to the server 24
objectContainer = Db4o.openClient(HOST, PORT, USER, PASS); 25
26
} catch (Exception e) { 27
e.printStackTrace(); 28
} 29
30
if(objectContainer != null){ 31
32
// get the messageSender for the ObjectContainer 33
MessageSender messageSender = objectContainer.ext() 34
.configure().getMessageSender(); 35
36
// send an instance of a StopServer object 37
messageSender.send(new StopServer()); 38
39
// close the ObjectContainer 40
objectContainer.close(); 41
} 42
} 43
// end main 44
}