# Creating a Hello World Service

With webOS 2.0, third party developers can now "roll their own" JavaScript services for access on Palm's public message bus. Besides powering the new Synergy APIs, JavaScript services strengthen webOS's support for background processing and add new capabilities such as low-level networking, filesystem access, and binary data processing.

The following five-step procedure shows the reader how to create and install a package containing a Hello World JavaScript service (`com.palm.helloworld.service`) and JavaScript application to access it on Palm's message bus. Currently, a service must be installed with an accompanying JavaScript app, though this can just be a stub.

Like all Hello World-type implementations, the intention is to strip the process down to a bare minimum, clearly showing what is involved and establishing a base for further development.

This procedure shows you how to do the following:

- Create a directory structure for your service.

- Create the configuration files and JavaScript for your service and its commands.

- Set a flag to make your service available on the public bus.

- Set the time your service remains active without being called.

- Use Palm command-line tools to package, install and launch your service and the JavaScript app that calls it.

- Call a service from a JavaScript app and see its response.

This article assumes that the reader has had some experience creating Mojo apps.

In this section:

- Prerequisites
- To Create a Hello World Service
- Debugging
- Troubleshooting

## Prerequisites

- Your development PC should have the webOS 2.0 SDK installed.

- If you are using a Palm device instead of the Palm Emulator, then:

  - The device should have webOS 2.0 or higher installed.

  - You should have a USB cord to connect the device to your devlopment PC.

  - The device should be charged and prepared.

  - You need a mechanism for logging into your device.

    The Tools section describes various mechanisms for doing this. Other options include using `novaterm` on the Mac. On my Windows PC, I used `putty` (installed with the PDK) to launch a shell and log in to the device. See the Tools section for more information on using these utilities.

## To Create a Hello World Service

1. Create a folder for your app and service.

   For example: `C:\SampleService`

2. Create package, application and service subdirectories.

   You are going to need three subdirectories: one for the app, one for the service, and one for the package.

   Open a command prompt, go to C:, and generate your skeleton app that is going to call the service:

   >     C:\SampleService> palm-generate sampleservice.application

   Manually create the following two subdirectories:

   >     C:\SampleService\sampleservice.package
   >     C:\SampleService\sampleservice.service

   Currently, `palm-generate` is not set up to create these directories.

   You should now have a directory structure that looks like this:

   >     C:\SampleService\
   >               \sampleservice.application
   >               \sampleservice.package
   >               \sampleservice.service

   Note that you are free to use whatever naming convention you like for your directories.

3. Create or modify the following package and service sub-directory files:

   - `\sampleservice.package\`

     - `packageinfo.json`—Defines the package ID, app, services, icon, and template data for the service and app package.

   - `\sampleservice.service\`

     - `sources.json`—The equivalent to that for Mojo apps: it declares what source files should be loaded into the current service.

     - `services.json`—Defines what commands the service provides on Palm bus.

       The `"public: true"` property indicates that the service is accessible on the public bus. The default is `false`. Note that this is done on a per-command basis; you can choose to make some commands public and some not.

       The `"activityTimeout"` property determines how long, in seconds, the service remains running without being activated.

     - `HelloCommandAssistant.js`—Defines a single command assistant to execute the "hello" command.

       As with Mojo apps, each command consists of a controller and an assistant. The service framework provides the controller framework and manages common aspects of command execution. The service provides the assistant and manages specific aspects of command execution. The assistant is executed via the run method and returns an object containing a single `reply` property. This is constructed from the incoming `name` argument.

       Note that the assistant must return a Future, an object used for async processing that is part of Palm's Foundation libraries. See the Foundations documentation for more information.

       Note: The service ID must begin with the app ID and end in ".service". For example (this service):

       App ID : com.palm.helloworld Service ID : com.palm.helloworld.service

   File | Contents
   --- | ---
   packageinfo.json |
       {
         "id": "com.palm.helloworld",
         "package_format_version": 2,
         "loc_name": "Palm Service Hello World Demo",
         "version": "1.0.0",
         "icon": "icon.png",
         "miniicon": "icon.png",
         "vendor": "Palm",
         "vendorurl": "palm.com",
         "app": "com.palm.helloworld",
         "services": ["com.palm.helloworld.service"]
       }
   services.json |
       {
       "id": "com.palm.helloworld.service",
       "description": "Hello World Demo Service",
       "activityTimeout" : 30,
       "services": [{
           "name": "com.palm.helloworld.service",
           "description": "helloworld example",
           "commands": [{
               "name" : "hello",
               "assistant" : "HelloCommandAssistant",
               "public" : true
               }]
            }]
       }
   sources.json |
       [{
           "library": {
               "name": "foundations",
               "version" : "1.0"
             }
       },
       {
           "source": "HelloCommandAssistant.js"
       }]
   HelloCommandAssistant.js |
       var HelloCommandAssistant = function() {
       }

       HelloCommandAssistant.prototype.run = function(future) {
           console.log("***************Hello "+ this.controller.args.name);
           future.result = {reply: "Hello " + this.controller.args.name + "!"};
       }

4. Create or modify the following application files.

   These files and their contents should be familiar to Mojo app developers.

   File | Contents
   --- | ---
   appinfo.json |
       {
           "id": "com.palm.helloworld",
           "version": "1.0.0",
           "vendor": "Palm",
           "type": "web",
           "main": "index.html",
           "title": "Sample Service Call",
           "icon": "icon.png"
       }
   sources.json |
       [
           {
               "source": "app/assistants/stage-assistant.js"
           },
           {
               "scenes": "main",
               "source": "app/assistants/main-assistant.js"
           }
       ]
       app\
           assistants\
               main-assistant.js
       function MainAssistant() {};

       MainAssistant.prototype.setup = function() {
           this.debugContainer = this.controller.get("debugOutput");
           this.logOutputNum = 0;
       };

       MainAssistant.prototype.activate = function(event) {
           var that = this;
           this.logInfo("Setup");

           // Call the Hello World service using standard Palm serviceRequest
           this.controller.serviceRequest("palm://com.palm.helloworld.service", {
               method: "hello",
               parameters: {"name": "World"},
               onSuccess:this.serviceSuccess.bind(this),
               onFailure:this.serviceFailure.bind(this)
           });
       };

       MainAssistant.prototype.serviceSuccess = function(successData){
           this.logInfo("Success Data: " + JSON.stringify(successData.reply));
       }
       MainAssistant.prototype.serviceFailure = function(failData){
           this.logInfo("Fail Data:" + JSON.stringify(failData));
       }

       MainAssistant.prototype.deactivate = function(event) {};

       MainAssistant.prototype.cleanup = function(event) {};

       MainAssistant.prototype.logInfo = function(logText) {
           this.debugContainer.innerHTML = (this.logOutputNum++) + ": " + logText + "
       " + this.debugContainer.innerHTML;
       };
       app\
           assistants\
               stage-assistant.js
       function StageAssistant() {
       }

       StageAssistant.prototype.setup = function() {
           this.controller.pushScene("main");
       }
       app\
           views\
               main\
                   main-scene.html
       <div>
       Status:

       </div>
       <div id="debugOutput">
       </div>

5. Package, install and launch the Hello World service.

   At a command line prompt, enter the following commands:

   >     c:\SampleService> palm-package sampleservice.application sampleservice.service sampleservice.package
   >     c:\SampleService> palm-install -r com.palm.helloworld
   >     c:\SampleService> palm-install com.palm.helloworld_1.0.0_all.ipk
   >     c:\SampleService> palm-launch com.palm.helloworld

   You should see the following screen on your device or emulator:

## Debugging

### To open a shell and log in to the device

1. Open a command prompt.

2. On Windows type:

   >     putty -P 10022 root@localhost

3. On Mac OS X:

   >     ssh -p 10022 root@localhost

4. Press "Enter" at the password prompt.

### To open a shell and log in to the Emulator

1. Open a command prompt.

2. On Windows type:

   >     putty -P 5522 localhost

3. On Mac OS X:

   >     ssh -p 5522 localhost

4. Enter "root" at the login prompt.

5. Press "Enter" at the password prompt.

### To see your installed service on the device/emulator

1. Open a device/emulator shell.

2. Go to `/media/cryptofs/apps/usr/palm/services` and list ('ls') the files there.

   You should see an entry for `com.palm.helloworld.service`.

### To invoke the service from a shell

You can use a 'luna-send' command to call your service:

>     /media/cryptofs/apps/usr/palm/services# luna-send -n 1  palm://com.palm.helloworld.service/hello '{"name":"world"}'

You should see the following response:

>     {"reply":"Hello world!","returnValue":true}

The framework automatically sets `returnValue` to `true` because a result was returned.

### To manually start a service

You can use `run-js-service` to start your service:

>     /media/cryptofs/apps/usr/palm/services# run-js-service com.palm.helloworld.service

The `"activityTimeout"` field in `"services.json"` determines how long the service stays active without being called.

### To monitor console messages in realtime

- Open a shell and run:

  >     tail -f /var/log/messages

  The "-f" option causes tail to display the last 10 lines of messages and append new lines to the display as they are added.

- To show output for just your app:

  >     tail -f /var/log/messages | grep <packageid>

## Troubleshooting

You will see a screen similar to this:

if, in `\sampleservice.service\services.json`, you did not set the `public` flag to `true`. If `false` (the default), the service cannot be accessed on the public bus.