This tutorial provides information that will help you make best use of Project Darkstar support plugins for NetBeans. Project Darkstar is software infrastructure to simplify the development and operation of massively scalable online games, virtual worlds, and social networking applications.
This document is designed to get you going as quickly as possible. For more information on working with NetBeans IDE, see the Support and Docs page on the NetBeans website.
This tutorial assumes you have knowledge of, or programming experience with, the following technologies.
If you aren't interested in building your own plugin modules from the latest sources you can just grab the current NBMs (NetBeans Binary Modules) from https://darkstarmobile.dev.java.net, and install them via Tools -> Plugins menu. In the Plugins dialog select the Downloaded tab and press the Add Plugins button.
and skip forward in this tutorial to Managing Darkstar server instances and applications inside NetBeans. However if you do want build the latest & greatest from sources then continue reading.
![]() |
In Netbeans open the DarkStarSuite project with "Open Required Projects" checked. This will open the following projects in your IDE:
![]() |
Then also open the 3 remaining projects located inside the DarkStarSuite project directory:
![]() |
Here is module functionality breakdown:
![]() |
this library is referenced by the DarkStarWebProxy project and used to connect to Darkstar server applications.
The next step is to build all 6 projects, and then 'Run' the DarkStarSuite project. This will start another instance of NetBeans that contains our additional PDS functionality. You can verify that the PDS plugins are installed by looking at the 'Services' tab which should now contain a 'Darkstar Servers' node.
![]() |
Tools menu should contain a 'Darkstar server' submenu.
The 3 new project templates we added should be availabe When creating a new project. The DarkStarWebProxy template:
![]() |
![]() |
If all the above are correct than you have successfully built and deployed the required plugins.
This first part of the tutorial will focus on getting you familiar with the Project Darkstar server management console plugin. This plugin allows you to manage server applications without the need for command line. It allows you to start and stop server applications inside your server instances by integrating these actions into natural work-flow within the IDE.
Our goal in this part of the tutorial is to add an instance of the Project Darkstar server installation to the IDE and to execute the included HelloEcho server application.
![]() |
this will result in a server child node srv1 being added to the Darkstar node:
![]() |
![]() |
Press OK to create a new application node as shown below:
![]() |
When you right-click the application node you will be able to select from options to edit application settings, start and stop the application in a server or remove it.
Create a new Mobility project from template Project Darkstar Mobile Socket Client as shown below, using default settings.
![]() |
Once the project is created you may need to switch from the default emulator WTK 2.5.2 to one that you have available. Nearly all J2ME devices and emulators should be sufficient as the project only requires CLDC 1.0 and MIDP 1.0.
The DarkStarSocketClient and supporting classes that already exist in your project implement all of the networking functionality required to communicate with the Darkstar server application. The existing source code is quite simple and can easily be customized to suit your specific purposes and/or environment. It contains some J2ME specific functionality as well as a port of the J2SE client.
The task of writing a HelloEchoSocketMidlet is simple. Example of a finished source file is here: HelloEchoSocketMidlet.java
.
The last step (implement abstract methods) will require a little bit of work on side of the developer. Lets take a closer look at them one by one as they are implemented in our demo app.
public void startApp() {
socketClient = new DarkStarSocketClient("localhost", 1139, this);
try {
socketClient.connect();
socketClient.login("kaja", "pwd");
} catch (IOException ex) {
ex.printStackTrace();
}
}
Creates a new instance of the DarkStarSocketClient class that handles all the networking details, and use it to create a socket connection. Once the connection is established log in to the server.
public void destroyApp(boolean unconditional) {
try {
socketClient.disconnect();
} catch (IOException ex) {
ex.printStackTrace();
}
this.notifyDestroyed();
}
Disconnect from the server.
public void loggedIn() {
System.out.println("< loggedIn");
System.out.println("> sendToSession: hello world");
try {
socketClient.sendToSession("hello world".getBytes());
} catch (IOException ex) {
ex.printStackTrace();
}
}
Callback is invoked when server notifies the client that log in was successful. Our implementation sends a session message "hello world".
public void loginFailed(String reason) {
System.out.println("< loginFailed : " + reason);
}
Callback is invoked when server notifies the client that log in failed.
public void receivedSessionMessage(byte[] msg) {
System.out.println("receivedSessionMessage: " + new String(msg));
System.out.println("> log out");
try {
socketClient.logout(false);
} catch (IOException ex) {
ex.printStackTrace();
}
}
Callback is invoked when server notifies the client with a session message. Our implementation prints the received message and requests a log out.
public void reconnecting() {
System.out.println("< reconnecting");
}
Callback is invoked when the client is attempting to reconnect to the server.
public void reconnected() {
System.out.println("< reconnected");
}
Callback is invoked when the client is reconnected to the server.
public void disconnected(boolean graceful, String reason) {
System.out.println("< disconnected : graceful=" + graceful + ",reason=" + reason);
}
Callback is invoked when the client is disconnected from the server.
public void joinedChannel(String clientChannelName) {
System.out.println("joinedChannel");
System.out.println("clientChannelName: " + clientChannelName);
}
Callback is invoked when server notifies the client that it joined the channel. Our implementation prints the channel name.
public void leftChannel(String clientChannelName) {
System.out.println("leftChannel");
System.out.println("clientChannelName: " + clientChannelName);
}
Callback is invoked when server notifies the client that it left the channel. Our implementation prints the channel name.
public void receivedChannelMessage(String clientChannelName, byte[] message) {
System.out.println("receivedChannelMessage");
System.out.println("channel: " + clientChannelName + ", msg: " + new String(message));
}
Callback is invoked when server notifies the client with a channel message. Our implementation prints the received message.
Before we execute the HelloEchoSocketMidlet the Darkstar application HelloEcho must be running, you can register the application with the IDE as described in section Configure server applications and then start/stop it using the Darkstar server node in the Services view. When the application is successfully started the last line of output should be: INFO: HelloEcho: application is ready
When the client is executed the expected output of running the HelloEchoSocketMidlet is:
Starting emulator in execution mode Running with storage root C:\Documents and Settings\kherink\j2mewtk\2.5.2\appdb\temp.DefaultColorPhone34 Running with locale: English_United States.1252 Running in the identified_third_party security domain < loggedIn > sendToSession: hello world receivedSessionMessage: hello world > log out
This output informs us that the client has:
Create a new Web project from template Project Darkstar Web Proxy as shown below, using default settings.
![]() |
Deploying the Web Poxy is also simple. Edit project properties and in the Run tab select you favourite servlet container. For the purposes of this tutorial I am using GlassFish but Tomcat, Resin or any other recent servlet container will do just fine.
Create a new Mobility project from template Project Darkstar Mobile HTTP Client as shown below, using default settings.
![]() |
Once the project is created you may need to switch from the default emulator WTK 2.5.2 to one that you have available. Nearly all J2ME devices and emulators should be sufficient as the project only requires CLDC 1.0 and MIDP 1.0.
The DarkstarHTTPMidlet and supporting classes that already exist in your project implement all of the networking functionality required to communicate with the Web Proxy. The existing source code is quite simple and can easily be customized to suit your specific purposes and/or environment.
The task of writing a HelloEchoHTTPMidlet is simple. Example of a finished source file is here: HelloEchoHTTPMidlet.java
.
The last step (implement abstract methods) will require a little bit of work on side of the developer. All together there are 16 abstract methods which is quite a few, however they include equivalents of all methods provided by the DarkStar client API (from both SimpleClientListener and ClientChannelListener) and not all of them need a meaningful implementation, depending on your needs. Lets take a closer look at them one by one as they are implemented in our demo app.
public String getDarkStarProxyURL() {
return "http://localhost:8080/DarkStarWebProxy/DarkStarProxyServlet";
}
Our implementation of getDarkStarProxyURL() returns the URL of the DarkStarProxyServlet this value is used by the MIDlet to connect tot the Web Proxy. It is important to remember that we need to return the URL of the web proxy servlet and not just the web apps context path, otherwise the MIDlet will fail.
public String getLoginName() {
return "kaja";
}
In this example we can return pretty much any string for the login name, in more advanced the value will most likely be retrieved from the user.
public String getPassword() {
return "password";
}
In this example we can return pretty much any string for the password, in more advanced the value will most likely be retrieved from the user.
public String getDarkStarServerHost() {
return "localhost";
}
Returns the hostname of the Darkstar server host. This value is passed to the Web Proxy so that it can establish a connection on behalf of the MIDlet client.
public String getDarkStarServerPort() {
return "1139";
}
Returns the port number for the Darkstar server application we wish to access. This value is passed to the Web Proxy so that it can establish a connection on behalf of the MIDlet client.
public long getPollPeriod() {
return 10000;
}
This value is used to set the polling period (in milliseconds) of MIDlet's HTTP communication mechanism. Setting it to a higher value will cause the MIDlet to issue HTTP requests less often.
public void commBroken() {
System.out.println("< commBroken");
}
Method is called when MIDlets communication mechanism determines that it is unable to connect to the Web Proxy.
public void loggedIn() {
System.out.println("< loggedIn");
System.out.println("> sendToSession: hello world");
try {
communicator.sendToSession("hello world".getBytes());
} catch (IOException ex) {
ex.printStackTrace();
}
}
This method is called to notify us that we've successfuly logged in. This is in-fact an event generated by the Darkstar server application and passed to the MIDlet. In our implementation we immediately send a message to the server session (and expect that at some point we'll receive an event with the same message back as an echo from the server).
public void loginFailed(String reason) {
System.out.println("< loginFailed : " + reason);
}
This method is called back in case the login request was not successful. In our example we don't really need to worry about that too much since the there are no restrictions on login/password values.
public void receivedSessionMessage(byte[] msg) {
System.out.println("receivedSessionMessage: " + new String(msg));
System.out.println("> log out");
try {
communicator.logout(false);
} catch (IOException ex) {
ex.printStackTrace();
}
}
This method is called to notify us that the client received a message from the server session. In our implementation we immediately log out of the server.
public void reconnecting() {
System.out.println("< reconnecting");
}
This method is called to notify us that the client is currently reconnecting.
public void reconnected() {
System.out.println("< reconnected");
}
This method is called to notify us that the client reconnected successfully.
public void disconnected(boolean graceful, String reason) {
System.out.println("< disconnected : graceful=" + graceful + ",reason=" + reason);
}
This method is called to notify us that the client has disconnected.
public void joinedChannel(String clientChannelName) {
}
This method is called to notify us that the client has joined a channel.
public void leftChannel(String clientChannelName) {
}
This method is called to notify us that the client has left a channel.
public void receivedChannelMessage(String clientChannelName, byte[] message) {
}
This method is called to notify us that the client has received a channel message.
Now that all the puzzle pieces are in place each component must also be running and ready to relay comunications:
Once these two prerequisites are met we can run the HelloEchoHTTPMidlet. To complete the MIDlet's execution may take a while since it uses HTTP polling to receive events from the Darkstar server.
Expected output of running the HelloEchoHTTPMidletis:
Starting emulator in execution mode Running with storage root C:\Documents and Settings\kherink\j2mewtk\2.5.2\appdb\temp.DefaultColorPhone34 Running with locale: English_United States.1252 Running in the identified_third_party security domain handling response type: 17 < loggedIn > sendToSession: hello world handling response type: 48 receivedSessionMessage: hello world > log out handling response type: 34 < disconnected : graceful=false,reason=
This output informs us that the client has:
However, if the prerequisites are NOT met (if for example we forget to start the HelloEcho Darkstar application) we can expect to see the following output:
Starting emulator in execution mode Running with storage root C:\Documents and Settings\kherink\j2mewtk\2.5.2\appdb\temp.DefaultColorPhone36 Running with locale: English_United States.1252 Running in the identified_third_party security domain handling response type: 34 < disconnected : graceful=false,reason=Connection refused: no further information Execution completed.
This output informs us that the client's proxy has not been able to connect to the server application.
| HelloEchoHTTPMidlet.java | ![]() |
2218 bytes |
| HelloEchoMidlet.java | ![]() |
2214 bytes |
| HelloEchoSocketMidlet.java | ![]() |
2539 bytes |
| app_node.png | ![]() |
22604 bytes |
| checkout_dir_struct.png | ![]() |
78754 bytes |
| client_lib.png | ![]() |
104298 bytes |
| dialog_server_app_settings.png | ![]() |
46731 bytes |
| dialog_server_app_settings_empty.png | ![]() |
10508 bytes |
| dialog_server_app_settings_full.png | ![]() |
12992 bytes |
| dialog_server_settings.png | ![]() |
28339 bytes |
| mobile_template.png | ![]() |
48719 bytes |
| mobility_create_http_project.png | ![]() |
89956 bytes |
| mobility_create_project.png | ![]() |
48929 bytes |
| mobility_create_socket_project.png | ![]() |
80710 bytes |
| projects_1.png | ![]() |
30473 bytes |
| projects_2.png | ![]() |
35912 bytes |
| server_node.png | ![]() |
20909 bytes |
| services.png | ![]() |
19157 bytes |
| web_proxy_create_project.png | ![]() |
43595 bytes |
| web_template.png | ![]() |
85452 bytes |