graniteds.orgCommunity Documentation

Chapter 1. Getting Started

1.1. Requirements (Free Tools)
1.2. Hello World, POJO

This section introduces:

You need at least the following four free development tools:

This section will guide you through the setting up of a very basic GraniteDS project deployed in Tomcat and a Java command line client. Expected result is a typical "Hello, world" application.

The client program will pass its argument to the remote service and display the result which should be a string:



"Hello " + <argument> + "!"
        

In order to create, build, and deploy this sample application you need these free tools:

  • Java 6+ (6+ working): Download Sun JDK and install it.

  • Eclipse 3.5+: Download Eclipse and unzip it somewhere.

  • Tomcat 7+: Download Tomcat and unzip it somewhere. For example, /apache-tomcat-7.0.29 (for Windows users: C:\apache-tomcat-7.0.29).

  • granite.jar: You may take it from any of the GraniteDS sample applications or from GraniteDS source distribution in the build folder. Download it here.

  • granite-client.jar and granite-java-client.jar: You may take it from any of the GraniteDS sample applications or from GraniteDS source distribution in the build folder. Download it here.

Creation of the project in Eclipse:

Start Eclipse and create a new Java project named helloworld. You may just type in helloworld for Project name and accept all other default settings.

We are now going to create a new POJO service named HelloWorldService. Right-click on the java source folder and select New / Class, enter org.test for Package and HelloWorldService for Name in the following dialog, and then click on the Finish button. In the Java source file editor, modify the code so it is just as follows:



package org.test;
public class HelloWorldService {
    public String sayHello(String name) {
        return "Hello " + name + "!";
    }
}
        

Next we have to create the GraniteDS configuration file services-config.xml and the web application web.xml at the root of the project.

Copy and paste the following code into these files:



<?xml version="1.0" encoding="UTF-8"?>
<services-config>

    <services>
        <service
            id="granite-service"
            class="flex.messaging.services.RemotingService"
            messageTypes="flex.messaging.messages.RemotingMessage">
            <destination id="helloWorldService">
                <properties>
                    <scope>application</scope>
                    <source>org.test.HelloWorldService</source>
                </properties>
            </destination>
        </service>
    </services>
</services-config>
        


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                        http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd">

    <!-- general information about this web application -->
    <display-name>Hello World</display-name>
    <description>Hello World Sample Application</description>

    <!-- read services-config.xml file at web application startup -->
    <listener>
        <listener-class>org.granite.config.GraniteConfigListener</listener-class>
    </listener>

    <!-- handle AMF requests ([de]serialization) -->
    <filter>
        <filter-name>AMFMessageFilter</filter-name>
        <filter-class>org.granite.messaging.webapp.AMFMessageFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AMFMessageFilter</filter-name>
        <url-pattern>/graniteamf/*</url-pattern>
    </filter-mapping>

    <!-- handle AMF requests (execution) -->
    <servlet>
        <servlet-name>AMFMessageServlet</servlet-name>
        <servlet-class>org.granite.messaging.webapp.AMFMessageServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>AMFMessageServlet</servlet-name>
        <url-pattern>/graniteamf/*</url-pattern>
    </servlet-mapping>

</web-app>
        

Next we have to build and deploy the server application:

Create a folder named lib at the root of the project and put granite.jar in this folder. Create a new file named build.xml at the root of the project and copy/paste the following content into it; you may have to modify TOMCAT_HOME to reflect your environment:



<?xml version="1.0" encoding="UTF-8"?>
<project name="hello-world" default="deploy">

    <!-- Modify TOMCAT_HOME properties to reflect your environment -->
    <property name="TOMCAT_HOME" value="/apache-tomcat-7.0.29"/>
    
    <!-- Build a war suitable for Tomcat (and other) -->
    <target name="war">
        <mkdir dir="build"/>
        <war destfile="build/helloworld.war" webxml="web.xml">
            <zipfileset file="services-config.xml" prefix="WEB-INF/flex" />
            <lib dir="lib"/>
            <classes dir="bin"/>
        </war>
    </target>

    <!-- Deploy the war in Tomcat -->
    <target name="deploy" depends="war">
        <copy todir="${TOMCAT_HOME}/webapps" file="build/helloworld.war"/>
    </target>

</project>
        

You may now right-click on the build.xml file and select Run As / Ant Build. This will launch the build process, create a WAR (Web Archive), and copy it into your Tomcat webapps directory.

Then start Tomcat. Go to the directory bin just under your Tomcat installation directory, /apache-tomcat-7.0.29/bin for example, and double-click on startup.bat, or startup.sh for Unix/Mac users. After a short while, you should see in the console that Tomcat has started.

You should now see something like the following picture under Eclipse:

Now let create the Java client code, for this example we are simply going to create a command line application but we could use any Java view technology, such as Swing, JavaFX or SWT.

Create a new Java project named helloworld-client. Create a new class directly in this new folder and name it HelloWorldClient in the package org.test.client by right-clicking on the src folder and selecting New / Class. In the editor, type in the following code:



package org.test.client;
import java.net.URI;
import java.util.concurrent.TimeUnit;
import org.granite.client.messaging.RemoteService;
import org.granite.client.messaging.ResultFaultIssuesResponseListener;
import org.granite.client.messaging.channel.amf.AMFRemotingChannel;
import org.granite.client.messaging.events.FaultEvent;
import org.granite.client.messaging.events.IssueEvent;
import org.granite.client.messaging.events.ResultEvent;
import org.granite.client.messaging.transport.apache.ApacheAsyncTransport;
public class HelloWorldClient {
    public static void main(String[] args) throws Exception {
        ApacheAsyncTransport transport = new ApacheAsyncTransport();
        transport.start();
        AMFRemotingChannel channel = new AMFRemotingChannel(transport, 
            "graniteamf", new URI("http://localhost:8080/helloworld/graniteamf/amf.txt"));      
        RemoteService service = new RemoteService(channel, "helloWorldService");
        service.newInvocation("sayHello", args[0]).setTimeToLive(5, TimeUnit.SECONDS)
            .addListener(new ResultFaultIssuesResponseListener() {
            
            @Override
            public void onResult(ResultEvent event) {
                System.out.println("Result: " + event.getResult());
            }
            
            @Override
            public void onFault(FaultEvent event) {
                System.err.println("Fault: " + event.toString());
            }
            
            @Override
            public void onIssue(IssueEvent event) {
                System.err.println("Issue: " + event.toString());
            }
        }).invoke();
    }
}
        

You will also need to add a few libraries in a lib folder and add them to the build path of the project with Right Click/Build Path/Add to Builder Path:

  • httpclient-4.2.1.jar

  • httpcore-4.2.1.jar

  • httpcore-nio-4.2.1.jar

  • httpasyncclient-4.0-beta2-SNAPSHOT.jar

  • httpclient-4.2.1.jar

  • granite-client.jar

  • granite-java-client.jar

You may now run the Java application in Eclipse by right-clicking the class HelloWorldClient and Run As.../Java Application. The result should appear in the Eclipse console. You can test different results by changing the run arguments in the Eclipse Run configuration for the application.

Here are some highlights on some parts of the code and configuration:



public String HelloWorldService.sayHello(String name)
        

The HelloWorldService is a simple Java service which declares a method sayHello() that takes a String argument and returns another String.



<destination id="helloWorldService">
    <channel ref="my-graniteamf"/>
    <scope>application</scope>
    <source>org.test.HelloWorldService</source>
</destination>
        

This part of the services-config.xml defines a mapping between a destination name and the service class and its scope. This is a basic declaration for an application scoped bean that will be created by GraniteDS itself but there are other kinds of configurations that give access to beans managed by an existing container such as Spring, or that use annotations to declare the remoting-enabled classes.



<url-pattern>/graniteamf/*</url-pattern>
        

This part of web.xml defines the mapping between the target url and the GraniteDS servlet. Other kinds of configuration are also possible which use a Spring MVC dispatcher servlet or use Servlet 3 features to automatically initialize the GraniteDS servlet. /graniteamf/* is the default and recommended url mapping for GraniteDS, but any other can work.



ApacheAsyncTransport transport = new ApacheAsyncTransport();
transport.start();
AMFRemotingChannel channel = new AMFRemotingChannel(transport, "my-graniteamf", 
    new URI("http://localhost:8080/helloworld/graniteamf/amf.txt"));
RemoteService srv = new RemoteService(channel, "helloWorldService");
        

This is the initialization part of the GraniteDS Java client. It requires creating a transport (here the default transport based on the Apache asynchronous HTTP client), a remoting channel and a RemoteService whose target destination matches the destination we declared earlier in the server configuration.



srv.newInvocation("sayHello", args[0]).setTimeToLive(5, TimeUnit.SECONDS)
    .addListener(new ResultFaultIssuesResponseListener() {
                
    @Override
    public void onResult(ResultEvent event) {
        System.out.println("Result: " + event.getResult());
    }
    
    @Override
    public void onFault(FaultEvent event) {
        System.err.println("Fault: " + event.toString());
    }
    
    @Override
    public void onIssue(IssueEvent event) {
        System.err.println("Issue: " + event.toString());
    }
}).invoke();
        

This is the main client part where the RemoteService triggers a server request that will call the sayHello() method with the first argument of the main method: srv.sayHello(args[0]).

The result of this call will be displayed, when available, in the console output in the asynchronous result handler of the remote call.