Setup a SIMON project in Netbeans 6.9 with help of Maven2

This wiki page will explain you in detail how to setup a client-server project with SIMON 1.1.0 (older versions may use other API methods...) and MAVEN in Netbeans 6.9 (other version behave mostly similiar...)

Create the projects

First of all, start Netbeans

Then you need to create three projects:

  • common project, that contains all the remote interfaces, used by client and server
  • client project
  • server project is done by using the new project wizard. Click on "File" -> "new Project" and follow the following screenshots, that will show you how to create the "MyCommonProject".

Repeat this step with "MyClientProject" and with "MyServerProject". Finally, you should have three projects in your project view:

Setup pom files for use with SIMON

In this step, you have to setup each project's POM file for use with SIMON. Go to "MyCommonProject", open "Project Files" in the tree view, and double-click "pom.xml":

Find the "dependencies" section and add:

<!-- SIMON dependency -->
<dependency>
    <groupId>de.root1</groupId>
    <artifactId>simon</artifactId>
    <version>1.1.0-SNAPSHOT</version>
</dependency>

After the "dependencies" section, add the following sections:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.0.2</version>
            <configuration>
                <!-- Set the version to 1.6 to enable Annotations -->
                <source>1.6</source> 
                <target>1.6</target>
            </configuration>
        </plugin>
    </plugins>
</build>
<repositories>
    <!-- SIMON repo servers -->
    <repository>
        <id>maven.root1.de-releases</id>
        <url>http://maven.root1.de/releases/</url>
    </repository>
    <repository>
        <id>maven.root1.de-snapshots</id>
        <url>http://maven.root1.de/snapshots/</url>
    </repository>
</repositories>

Repeat this step with the other two projects as well.

Add shared interfaces

As we used the "Maven Quickstart Archetype", Maven created in the default package a class named "App" (see following screenshot). You can safely remove this file from each project.

So, for adding the sample code, open the "MyCommonProject" and navigate to the source folder into the default package.

For the common project, create these files:

ServerInterface.java: This is the server interface, that will be used by the server implementation:

package de.root1.mycommonproject;

public interface ServerInterface {

   public void login(ClientCallbackInterface clientCallback);

}

ClientCallbackInterface.java: This is the callback interface, that is used by the client to implement a callback, that later on, the server can use to invoke methods on the client side:

package de.root1.mycommonproject;

public interface ClientCallbackInterface {

   public void callback(String text);

}

IMPORTANT: After adding these two files, right-click in the MyCommonProject and select "Clean and Build". Maven will then compile the interfaces and install them into the local repository, so that the client and server project can make use of it...

Extend Server and Client's POM

Okay, so far we created three projects and setup the common project that contains the shared interfaces. Now we have to create the implementations of this interfaces. But before we start, you have to tell the client and server project that they depend on the common project. Otherwise the client and server project do not have access to the shared interfaces.

Go to the POM file of the client project. Search for the "dependencies" section and add at the end:

<!-- MyCommonProject dependency -->
<dependency>
    <groupId>de.root1</groupId>
    <artifactId>MyCommonProject</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

It should look like this:

Repeat this step with the server project as well.

Add server code

Go to the server project and add the following two classes:

ServerInterfaceImpl.java: the implementation of the server interface which is provided by the common project

package de.root1.myserverproject;

import de.root1.simon.Simon;
import de.root1.mycommonproject.ServerInterface;
import de.root1.mycommonproject.ClientCallbackInterface;
import de.root1.simon.annotation.SimonRemote;

// mark this class as a remote class and export all methods known in ServerInterface
@SimonRemote(value = {ServerInterface.class})
public class ServerInterfaceImpl implements ServerInterface {

    private static final long serialVersionUID = 1L;

    @Override
    public void login(ClientCallbackInterface clientCallback) {

        clientCallback.callback("This is the callback. " 
                + "Your address is " 
                + Simon.getRemoteInetSocketAddress(clientCallback).getAddress()
                + " and your are connected from port " 
                + Simon.getRemoteInetSocketAddress(clientCallback).getPort());

    }
}

Server.java: The base class of the server, that starts the SIMON registry and binds the server implementation to it, to make it available via remote

package de.root1.myserverproject;

import java.io.IOException;
import java.net.UnknownHostException;

import de.root1.simon.Registry;
import de.root1.simon.Simon;
import de.root1.simon.exceptions.NameBindingException;

public class Server {

    public static void main(String[] args)
            throws UnknownHostException, IOException, NameBindingException {

        // create the serverobject
        ServerInterfaceImpl serverImpl = new ServerInterfaceImpl();

        // create the server's registry ...
        Registry registry = Simon.createRegistry(22222);

        // ... where we can bind the serverobject to
        registry.bind("server", serverImpl);

        System.out.println("Server up and running!");

        // some mechanism to shutdown the server should be placed here
        // this should include the following command:
        // registry.unbind("server");
        // registry.stop();
    }
}

Add client code code

After creating the server, there's one thing left: the client.

Create the following two classes in the client project:

ClientCallbackImpl.java: The class, that the client passes to the server, that then the server can use to call methods in the client

package de.root1.myclientproject;

import de.root1.mycommonproject.ClientCallbackInterface;
import de.root1.simon.annotation.SimonRemote;

// mark this class as a remote class and export all methods known in ClientCallbackInterface
@SimonRemote(value = {ClientCallbackInterface.class})
public class ClientCallbackImpl implements ClientCallbackInterface {

    private static final long serialVersionUID = 1L;

    @Override
    public void callback(String text) {

        System.out.println("This message was received from the server: " + text);

    }
}

Client.java: The base class of the client. There we make the connectiono to the server and get the remote object ...

package de.root1.myclientproject;

import de.root1.mycommonproject.ServerInterface;
import de.root1.simon.Lookup;
import de.root1.simon.exceptions.EstablishConnectionFailed;
import java.io.IOException;

import de.root1.simon.Simon;
import de.root1.simon.exceptions.LookupFailedException;

public class Client {

    public static void main(String[] args) throws IOException, LookupFailedException, EstablishConnectionFailed {

        // create a callback object
        ClientCallbackImpl clientCallbackImpl = new ClientCallbackImpl();

        // 'lookup' the server object
        Lookup nameLookup = Simon.createNameLookup("127.0.0.1", 22222);
        ServerInterface server = (ServerInterface) nameLookup.lookup("server");

        // use the serverobject as it would exist on your local machine
        server.login(clientCallbackImpl);

        // do some more stuff
        // ...

        // and finally 'release' the serverobject to release to connection to the server
        nameLookup.release(server);
    }
}

Run it!

That's all folks. You can now run the server, followed by the client. To do this, right-click on the server-project's "Server.java" and select "Run File". Netbeans will build all required files and run the server. Repeat the same with the client project and it's "Client.java". The server console will show (after some Maven compile logs):

Server up and running!

while the client prints:

This message was received from the server: This is the callback. Your address is /127.0.0.1 and your are connected from port 50222

Quite easy, isn't it?

Download the complete sample

I zipped the above explained sample projects so that you can use it as a template or startingpoint for your own projects ...
--> http://dev.root1.de/attachments/98/NetbeansProjects.zip <--

0_Starting_NB69.png (143 KB) achristian, 07/13/2010 01:17 PM

4_create_common_interfaces.png (113 KB) achristian, 07/13/2010 01:18 PM

1.0_new_maven_project.png (55.7 KB) achristian, 07/13/2010 01:18 PM

1.1_new_maven_project.png (52.1 KB) achristian, 07/13/2010 01:18 PM

1.2_new_maven_project.png (53.1 KB) achristian, 07/13/2010 01:18 PM

2_all_projects_created.png (166 KB) achristian, 07/13/2010 01:18 PM

3_setup_pom.png (110 KB) achristian, 07/13/2010 01:18 PM

5_update_client_server_pom.png (115 KB) achristian, 07/13/2010 01:45 PM

NetbeansProjects.zip - This file contains all 3 sample projects (24 KB) achristian, 07/13/2010 04:42 PM