Run BASIC for Windows, Mac and Linux

Tonight I am pleased to mention that we posted Run BASIC v1.0.1 beta 3 for Windows, Mac OS X, and Linux (tested on Ubuntu). This is our first ever release of software for Linux, although people have been successfully using the Windows version using Wine.

It shouldn't take more than a couple of weeks to finalize v1.0.1 and release it. If you haven't had a look at Run BASIC check out the site. Make sure to watch the videos posted there to get a complete sense of just how easy web programming can be.

Eating my own dog food

Run BASIC comes with a bunch of example programs, one of which is a wiki called runWiki. It's about two pages long and is remarkable for what it does in those two pages, including the use of the SQLite database to store pages.

One of my customers (Neal) took that wiki and added a bunch of cool stuff to it like user accounts and many more formatting tags.

Now I've decided to take Neal's version of my original runWiki and use it to host a site for a civic group in the town of Ashland, Massachusetts where I live. It went live last weekend to coincide with the annual Ashland Day faire. Check it out at http://www.weloveashland.com

It's a pretty simple site which will get more sophisticated as we go. The beautiful thing is that it acts as a vehicle for producing runWiki3. I can customize it to my hearts content since I have all the source code in BASIC, the people's language. ;-)

Free version of Run BASIC

One thing that has been lacking in our effort to promote our Run BASIC web programming system is a free version. In fact there is no time limited trial either. This has been mostly because we have been unsure what would be the best way to do it.

What we've decided on is when Run BASIC v1.0.1 is released soon for Windows, Mac and Linux we will also release a free version. This free version will be for personal use instead of being a web application server. Users of the free Run BASIC will be able to create projects and use any features of the language, but they will not be able to serve applications. This will allow them to experiment and see if Run BASIC meets their needs. If it does and hosting the application is in the cards then an upgrade to the server version is available for $59.95, or hosting service can be purchased at http://www.runbasicnet.com

Comments and suggestions are most welcome.

Gmail Multiple Sessions Alert: This account is open in 1 other location

Gmail This account is open in 1 other location"This account is open in 1 other location at..." Gmail user interface provides this message when your account is used in multiple locations simultaneously. One of the most important and interesting security feature that any web mail service would wish to provide. I suppose Gmail is the only web mail service that has this type of security feature (let us know if any other does). Users become aware of any misuse of their Gmail accounts.

Gmail is countering the number of active sessions per account in providing this information; so "open in multiple locations" means that there are multiple active session for this particular account. Gmail also provides more details about each session making it easy to track the misuser. Access Type, IP address and Date/Time are displayed as details.

Effectiveness

All these details are visible to all web sessions including misuser's session; so the effectiveness of this feature is in doubt. For example, a misuser can sign out as soon as this information is displayed in Gmail account. However a solution for this will not be simple and easy. In the meantime, these information is not displayed in a very prominent place (shown at the very bottom of the page), only the misuser will use these information rather than actual (innocent) account owner.

Improvements

Gmail Top Links BarWe are not highlighting the weaknesses by neglecting effort made in providing this feature. However, as an improvement; active sessions count can be shown at the top bar; so that all users will notice the multiple session usage. However this should be displayed only when multiple sessions are active.

Out of control!

On a Java project that I work on part time we use the Eclipse IDE, which is a power tool for Java programming. Java itself gets hard to deal with once your software gets to a certain size, and Eclipse tries to do a lot of the hard work for you. Java would be unusable without such tools.

On the flipside to this, we had been using an older version of Eclipse. Ultimately we decided to upgrade to a newer version (but not the latest) because we wanted to use Subversion instead of CVS for our source code control.

One of my colleages decided to attack the upgrade and document what was needed for everyone to use the new version. It seemed like it took him many days to figure it all out. The new version didn't look too much difference on the surface, but I kept hearing groans from him. Clearly something wasn't going well, so I went over and asked him what was the matter. His answer was simply, "I can't figure out how to do things that I used to know how to do!" The new software was getting bigger and more complicated.

There's a balance to strike when developing software. It's hard to make software easy to use while also adding new features.

Simple File Uploading Script in PHP

Simple File Uploading Script in PHP


PHP is undoubtedly the best programming language when it comes to web programming.
It gives us so many features and capabilities, a few of which we’ve discussed
already. So continuing with that, today we’ll see how we can use a few
lines of code to create a script that’d allow file uploading right from
the web browser. File upload feature is definitely useful kinds of website but
at the same time very much vulnerable to malicious attacks as well. So use it
with a LOT of precautions!


For this example, we’ll need a front-end web page that’ll accept
the file from the user and a backend script to process and store the file. Let’s
look at the codes of each:


upload.html:



<html>
<body>
<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>


Here we have a HTML form that calls the script on submission. The method of
data sending should be “POST” and there should be and
enctype as “multipart/form-data” which means we can
upload binary form data. The input type “file” opens the File Input
Box that’d let the user browse for the file. The submit button “Upload”
submits the form as usual.


upload_file.php:


<?php 
if ($_FILES["file"]["error"] > 0)
    echo 
"Error:: " $_FILES["file"]["error"] . "<br />";
else
{
    if (
file_exists($_FILES["file"]["name"]))
    {
        echo 
$_FILES["file"]["name"] . " already exists. ";
    }
    else
    {
        
move_uploaded_file($_FILES["file"]["tmp_name"], $_FILES["file"]["name"]);
        echo 
"File <b>" $_FILES["file"]["name"] . "</b> uploaded successfully!";
    }
}
?>

Just like we had POST form data in $_POST[] and GET data in $_GET[]
array same way to have files sent to script we use $_FILES[] array.




  • $_FILES["file"]["error"]: Tells
    us if there is any error in uploading. Note that “file” the
    first string index of the array is the name of the “File” input
    type from the HTML form.




  • $_FILES["file"]["tmp_name"]:
    All the files sent to any script is stores in a temporary directory by PHP,
    this tells us the location of that temporary file.




  • $_FILES["file"]["name"]:
    It tells us the name of the file on the users’ computer.




  • move_uploaded_file(): As files sent to scripts
    are just stored temporarily, we have to save it to some place, for this
    we use this PHP function. It’s first parameter is the temporary file
    location and second is the place we need to store the file and with what
    name. We are storing it to the same directory the script is in and with
    name same as on the users’ computer.




NOTE: This is just meant for example purpose and you shouldn’t have this
on your server as it is an open invitation to hackers/spammers. If you need
upload facility on your website in all the cases you should have some kind of
authentication
system
that'd only allow registered users to upload anything. you should
also accept only certain file types. you wouldn't like someone uploading/running
spamming script off your server. Would you? there may be a few other precautions
that you may need to take depending on the purpose you intend to use the script
for.


Previous Posts:


Sun suspends NetBeans IDE DVD Starter Kit distribution program

Sun has suspended their NetBeans IDE DVD Starter Kit distribution program indefinitely. Yes, you read it correctly; they have done it. So many developers used to get most of Sun (free) products through the distribution program. Students with less bandwidth (in some colleges & universities); specially users without Internet access to home computers are fond of this service as NetBeans DVDs are freely delivered to their hands at no cost.

According to NetBeans.org;
"Since August 30th, 2005, NetBeans.org has shipped more than 225,000 CDs & DVDs to developers around the world through this initiative! During this period, NetBeans has experienced explosive growth as a download, media kit, and a community. To stay ahead of this encouraging trend we are looking into ways to effectively satisfy increasing demand for NetBeans software worldwide."

For sure this service played a huge role in helping so many Java developers. Also the program is a good marketing option for NetBeans since Eclipse (the best free Java IDE) provides no such services, rather than allowing free download. Sun also has decided to follow the same; stick only for free downloads. However the Starter Kit is available for download as an ISO image. In near future may offer downloads via mirrors and bit torrent; but not sure how near that future is. Anyway we are grateful to service Sun provided us.

Finally a Blogging Platform for the Mobile Web (WAP)

Most of the time I browse internet for reading blogs, checking emails etc.
I do it on my cell phone. One day I thought why not create a mobile website
or better yet blog, and started searching around. What did I find? Well, nothing
much useful. In this big world and yet bigger web, to my disappointment, I couldn’t
find any website offering free blogs like we do on the normal (desktop) web.
Moreover, those that offered mobile websites, I just didn’t like their
service. You just have to spend so much time to just have a single page up!


What I had in my mind was a service that’d offer free blogs, let me register
it from the mobile phone, let me post from the mobile phone, in other words
a service that’d let me operate the whole thing right from the mobile
phone itself. Days passed and then, rather than me wanting these services I
thought of offering them to others instead, of course for FREE. Therefore I
took a nearly a month off and created what I wanted myself. Here it is MyWapBlog.com
(You need a mobile phone to access it. Not accessible form desktop
browsers except Opera, and FireFox with addon)


A picture is worth a thousand words, here area a few of them:


MyWapBlog.com - Homepage

MyWapBlog.com Homepage


MyWapBlog.com - Registration Page

Registration Page - You'll get your blog at your-name.mywapblog.com


MyWapBlog.com - Dashboard

After registration/logging in you'll see your dashboard like shown
above


MyWapBlog.com - User Blog

Your blog looks like this using the "Default-2" theme


MyWapBlog.com - Blog Theme Choice

You can choose between the three themes available now for your blog's layout.
More themes will be added soon.


While I’ve sorted most of the bugs that I could find in
ten-days testing period, there might (sure) still be quite a few of them. Therefore,
the only thing I’d like to ask for is to use the Feedback Form (on Dashboard
Page) a lot!


Thanks a lot for reading! Go get your Free
Wap Blog
Now!

Lazy loading vs. pre-loading beans with Spring Framework

Spring LogoSpring framework can instantiate and bind (called loading) related Java objects (called beans) according to a given configuration. An XML file can easily be used to define these bindings. Spring framework supports two different types of loading methods; lazy loading and pre-loading respectively managed by BeanFactory and ApplicationContext containers.

Lazy Loading

A bean is loaded only when an instance of that Java class is requested by any other method or a class. org.springframework.beans.factory.BeanFactory (and subclasses) container loads beans lazily. Following code snippet demonstrate lazy loading, concentrate on how "beans.xml" spring configuration file is loaded by BeanFactory container class.

BeanFactory factory = new XmlBeanFactory(
new InputStreamResource(
new FileInputStream("beans.xml"))); // 1
Employee emp = (Employee) factory.getBean("employeeBean"); // 2

Even though "beans.xml" configuration file is loaded with BeanFactory container in line number 1, none of the beans will be instantiated. Instantiation takes place only at line number 2, where bean called "employeeBean" is requested from container. Since the class is instantiated at getBean() method call, time spend to return this method will vary depending on the instantiated object.

Pre-loading

All beans are instantiated as soon as the spring configuration is loaded by a container. org.springframework.context.ApplicationContext container follows pre-loading methodology.

ApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml"); // 1
Employee emp = (Employee) context.getBean("employeeBean"); // 2

As all singleton beans are instantiated by container at line number 1, this line will take some considerable time to complete. However line number 2 will return the bean instance immediately since instances are already available inside the container.

Point to note

Decision to choose one from these two methods would depend solely on application specific requirements. Some applications need to load as soon as possible while many others would probably willing to spend more time at startup but serve client requests faster. However some of the beans defined in a configuration may only be used rarely, so instantiating such classes at start up would not be a wise decision. Similarly, some Java instances would be highly resource consuming; leading not to instantiate at start up.

Related articles
Better use <object> instead of <bean> in Spring

[Eclipse] Access restriction: Class is not accessible due to restriction on required library

"Access restriction: Class is not accessible due to restriction on required library"; error message may be shown while developing Java projects in Eclipse IDE. Error message is self-explanatory, some classes can not be loaded into the project since restriction rules are being imposed on those classes.

How to solve

This error message can be removed by changing a setting inside Eclipse IDE. Open up the dialog box shown below, using any of the following paths.
  • Windows -> Preferences -> Java -> Compiler -> Errors/Warnings
  • (Project) Properties -> Java Compiler -> Errors/Warnings
Locate the "Forbidden reference (access rules)" option under "Deprecated and restricted API" section in the dialog box. This option decides how to handle access rules defined inside Eclipse. By default it is set to "Error" which causes Eclipse to complain about references to any restricted classes. Choosing any other option (Warning or Ignore) will remove these error messages.

"Warning" or "Ignore" options will only hide the potential issue in the project, by allowing the project to use any classes ignoring predefined access rules. To completely resolve this issue, analyze the project and located the use of restricted classes and take necessary actions (either remove those references or access rules).

Chrome or Firefox - which browser to choose?

Chrome is the newest baby in browser family or the next competitor in browser war. What ever it is, Google released their browser named Chrome. But Mozilla Firefox is the most popular browser in the world right now and Google was the major supporter for Firefox. Even while supporting it, they have built their own browser free and open source. Here we are looking at the two browsers and trying to compare them to decide whether to switch to the new one or not leaving our old but fascinating friend Firefox?

Interesting features

1. One Process per each tab
Tab is not another thread running inside the browser process; there is a separate process per tab. Even if one tab crashes, the rest of the tabs will be running as nothing happened; which was not available in Firefox. This is one of the most interesting features.

2. New tab is filled with useful links
For a new tab in Firefox, you can load a predefined page, a blank page or a predefined set of page links (using an extension). But you would be much happier to see a set of links that you dealt with in recent past; Chrome comes exactly with that. The new tab will show a set of links;
  • Most visited pages
  • Recently closed
  • Recently Bookmarked
I do not think the last one will be much useful, but the other two will be pretty handy.

3. Rich Location bar
Location bar in Chrome is a combination of location bar & search bar. You can directly type a url or a search keyword, also it comes with suggestions.
Using separate location bar per each tab is also an interesting move, each tab looks like individual browser instances; while in firefox you have single location bar shared by all tabs.

4. Speed
Stephen Shankland at CNet has posted an article on speed, and it tells most of the details. However Brendan at MozillaZine has published another set of testing statistics. So we'll have to check some statistics done by an independent party to get a clear view. Anyway Chrome is starting up so fast compared to any other browser.

Some complains

Since Chrome is still in beta, this may be a good time to suggest some features or improvements. Following are some complains that we have.

1. No warning in closing
When multiple tabs are opened Firefox is used to show a warning in closing the browser, but Chrome does not and closes immediately. Since people can accidentally close the browser better to add it soon.

2. Displaying different fonts
Some of the fonts are not displayed smoothly as Firefox used to do. Above image shows how the same content is displayed in two of these browsers.

3. No XML viewer
May be it is not a must to have a XML viewer in a browser, but we are used to it. Firefox and IE both have good XML viewers, but Chrome lacks it. Similar to this Opera and Safari also do not have this feature. Many people happened to work with XML files every day and having an XML viewer in the browser is an added advantage.

4. Security issues
Chrome has exposed to a set of known security issues by using an older version of WebKit, which had already been fixed. Anyway we expect Google to fix it soon.

Main Concern

Above all of these our main concern is the lack of support for extension development. We are used to live with some great extensions with Firefox, which we are not experiencing with Chrome. Since it is still in beta version, we should wait for extension support. However no API is released for extension development, users will have to wait longer than expected to see some useful extensions. There are so many extensions that makes our lives easier and better. Few of them are;
  • NoScrip
  • Adblock
  • Gmail Manager
What are the other reasons that you are not switching to Chrome straightaway?

Designing a Simple HTML Code & Preview Tool (Online)

Designing a Simple HTML Code & Preview Tool (Online)


With online CMSs everywhere and craze of blogging like never before, we see
some sort of online HTML editors everywhere. Ever blogged or posted in some
forum? Most of them have it! These editors let you write, format, preview and
tinker with the HTML code before publishing anything. Most of them have a nice
UI to format everything much like the desktop applications like NVu, Dreamweaver
etc. these online editors also let you manually change or write HTML code
that can be previewed without leaving the page.


Well what we are going to design today is a scaled down version (say simple)
of these kinds of editors. It’d let you write (or paste) HTML code and
preview how it’d look. What it wouldn’t let you do is to format
or change anything while in the preview mode. We will be using HTML, JavaScript
and a little inline CSS.


Basic Theory


If you look at the HTML editors used by Blogger and Wordpress, they have two
modes, Code and Compose. In code mode HTML code is displayed which can also
be edited. On the other hand in compose mode, preview of the code is displayed
which can be edited/formatted using its GUI. Interesting thing here is that
both the mode displays in the same place, giving a feeling that the same code
box is changing to the Compose box.


For our purpose, we can use a HTML textarea for code view and an iframe for
preview. Iframe is the simplest way of showing HTML preview that could also
be made to work in edit mode, therefore letting us format things using the UI
and see the code in code view.


Working


From the staring both the textarea and the iframe are placed in the page. Textarea
is be styled to be visible (display: block;) and the iframe to
be invisible (display:none;). When you type in some code in the
code view (textarea) and switch to preview mode, a JavaScript function is called
that makes the textarea invisible an the iframe visible. It also places the
code (form the textarea) as HTML for the iframe, which in turn displays the
code as it’d in a browser. Again when you switch back to code view, textarea
is made visible again and the iframe invisible. If we give both the textarea
and iframe the same look, it’d give the feeling that the same box is being
used to show code as well as preview.


The button’s value is also changed to reflect which mode we are in and
clicking it would result in which view.


Code



<html>
<head>
<title>Code & Preview</title>


<script language="JavaScript" type="text/JavaScript">
//flag to store current state of view (code or preview)
var flag=1;

//var to store code forom the textarea
var val1='';

function changeMode()
{
//store code from the textarea
val1=document.form1.code.value;

//check which view we are in
if (flag==1)//code view
{
//set textarea to be invisible
//notice how style property is accessed
document.getElementById('code').style.display = "none";
document.getElementById('preview').style.display = "block";

//give the iframe the HTML code to display
//note how an iframe's properties are accessed
//is's because an iframe is a seperate window itself
document.getElementById("preview").contentWindow.document.body.innerHTML=val1;

//rename the button
document.getElementById('submit').value = "Code";

flag=2;
}
else
{
document.getElementById('preview').style.display ="none";
document.getElementById('code').style.display ="block";

document.getElementById('submit').value = "Preview";

flag=1;
}
}
</script>

</head>

<body>
<form name="form1" method="post" action="">
<p id="textb">
<iframe style="display: none" id="preview" width="600px" height="300px" scrolling="auto"></iframe>
<textarea style="display: block;width:600px; height:300px" name="code" id="code"></textarea>
</p>
<p>
<input id="submit" type="button" name="Submit" onClick="changeMode()" value="Preview">
</p>
</form>
</body>
</html>


Previous Posts:


Use "object" instead of "bean" in Spring Configuration XML

Spring configuration xml is used for defining the wiring between different object. It has the following format.

<beans>
<bean id=".." class="...">
...
</bean>
...
<beans>

Classes specified in the configuration file will be instantiated by Spring container. And those objects will be bound with each other accordingly. Any java class specified under attribute named "class" will be instantiated. There is no much limitations on the classes that can be used for this here. It does not need to be a JavaBean. It can be any POJO (plan old java object). The only requirement is that this class must be possible to instantiate.

Spring LogoSo why does this tags are named <beans> and <bean>? This seems to be misleading.

In Spring one way of binding objects is using the beaness of java classes. But that is not that only way to bind them together, constructor can be used to bind objects. So if configuration file used tags as follows, it would be more meaningful.

<objects>
<object id=".." class="...">
...
</object>
...
<objects>

Seems it is used only to express that beaness can also be used in initialization. Would you agree? May be we are not seeing the exact reason. This is completely open for discussion.

Google Web Toolkit (GWT) & Servlets - Web application tutorial

GWT LogoGoogle Web Toolkit (GWT) and Java Servlets used in one web application. This tutorial will take you though the steps of developing a simple web application with Google Web Toolkit and J2EE Servlet Technology. The application will have a servlet on server side and one web page.

Prerequisites

  • Better to be familiar with developing web applications with J2EE/Servlets
  • Knowledge on deploying a web application into Tomcat web server

System Requirements

  • JDK installed
  • Apache Tomcat web server (download, any other web server can be used)
  • GWT (download)
In brief, GWT is a framework for developing Ajax based web pages with Java. All the HTML page content will be written as Java classes and converted into a set of Javascript files. For more information on GWT, refer to official site here. http://code.google.com/webtoolkit/

Introduction

In this tutorial we will create a simple web application which has one page. When a user clicks a button, web page content will be updated without refreshing or leaving the current page. But the web page will talk to a servlet deployed in web server and update the page content. The communication between web server and browser will be invisible to the user, providing a convenient web experience. Even though this is a simple application, it represents a main concept of any advanced application implemented with GWT.

Implementation

The development work is broken down into 7 steps and each will be discussed in details.
  1. Create a java web project with GWT
  2. Data Service - server & client side
  3. Widget (component displayed on web page)
  4. Entry point
  5. Web page (html/jsp)
  6. Module XML
  7. Compile and deploy
In this document $GWT_HOME is used to denote the directory where extracted GWT framework is available.
eg: $GWT_HOME=C:\java\gwt-windows-1.4.61

1. Create a java web project with GWT

To start with, we need to create a java project. GWT comes with a script to create a java project according to the recommended project structure. It is called "applicationCreator"; applicationCreator.cmd is available inside $GWT_HOME directory.

$GWT_HOME> applicationCreator -out C:/samples/GWT-Sample 
org.kamal.hello.client.HelloWorld

For parameter named "out" you must provide the location to create the new project. Also a class name must be provided for this command. This class is called Entry point class (we'll be touching this class later).
Above command creates a project named GWT-Sample in the destination location and created project would look as follows.

GWT applicationCreator project structureIt will contain a Java class (Entry point class), a HTML page and a XML file (called Module XML). This module xml file will also be discussed later. For the time, better note the path to this file: org/kamal/hello/HelloWorld.gwt.xml.

2. Data Service - server & client side

For our application we need a service that provides data for our client side page. So we'll define this service to have only one method returning a String. This service will be provided through a servlet which is running on a server side. Generally we would write only a single servlet that extends from javax.servlet.http.HttpServlet, but in GWT we must define two interfaces inside client package (org.kamal.hello.client) along with the servlet. However these two interfaces are quite simple.

i). Service interface

The services provided by the server-side must be declared in a Service interface first. The methods declared in the Service interface will be available to the client side. It is only a simple interface which must extend com.google.gwt.user.client.rpc.RemoteService interface. We will define the service interface with only one method that returns a string.

package org.kamal.hello.client;

import com.google.gwt.user.client.rpc.RemoteService;

public interface DataService extends RemoteService {
public String getData();
}

ii). Asynchronous Service interface

Next we will define another interface called "Asynchronous interface". This interface is used to define the asynchronous feature of the service. That is when ever a call is made to this interface, the caller can expect the service to be asynchronous and the result will be available after sometime. The caller must provide a callback object to receive the resulting data. There are some important points to note.
  1. Asynchronous interface must be in the same package as the service interface
  2. This interface's name must be as <Service-Interface-Name>Async (same name with Async suffix)
  3. Add a new parameter of type com.google.gwt.user.client.rpc.AsyncCallback to parameter list of every method.
  4. All methods must have void as return type
package org.kamal.hello.client;

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface DataServiceAsync {
public void getData(AsyncCallback callback);
}

The above interface is named DataServiceAsync (using DataService + Async) and the DataService.getData() method is provided with a new parameter while having void return type.

iii). Service servlet

Now we can define the service servlet which does the actual work. This class must implement above declared DataService interface and extend the com.google.gwt.user.server.rpc.RemoteServiceServlet class.

package org.kamal.hello.server;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import java.util.*;
import org.kamal.hello.client.DataService;

public class DataServiceImpl
extends RemoteServiceServlet implements DataService {

public String getData() {
int key = (int)(Math.random()*3);
return (String)data.get(String.valueOf(key));
}

private static Map data = new HashMap();

static {
data.put("0", "Hi, This is Server");
data.put("1", "How are you?");
data.put("2", "It’s too warm here at Server");
}
}

Above class implements the getData() method of DataService interface and returns a String with simple logic. Even though we call this a servlet, no servlet specific implementation is available, so is this a servlet? Yes, it is; the super class, RemoteServiceServlet is a servlet.

iv). Servlet configuration (web.xml)

Now we have to specify the servlet in a web.xml file. (Do not worry even if you are not much familiar with web.xml, everything needed is listed below).

Create a file named web.xml inside GWT-Sample project folder with the following content.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
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_4.xsd">
<servlet>
<servlet-name>DataService</servlet-name>
<servlet-class>
org.kamal.hello.server.DataServiceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DataService</servlet-name>
<url-pattern>
/org.kamal.hello.HelloWorld/data
</url-pattern>
</servlet-mapping>
</web-app>

Here we have defined a url pattern for our above mentioned DataServiceImpl servlet. Note the way this url pattern (/org.kamal.hello.HelloWorld/data) is defined.
First part of the url pattern org.kamal.hello.HelloWorld is derived from the path to Module XML file which is org/kamal/hello/HelloWorld.gwt.xml. The rest of the url pattern can be selected arbitrarily, better to use a declarative word.

3. Widget (component displayed on web page)

Now we must create the widget that will be displayed in the web page of our web application. The widget coding is listed below.

package org.kamal.hello.client.widgets;

import com.google.gwt.core.client.*;
import com.google.gwt.user.client.rpc.*;
import com.google.gwt.user.client.ui.*;
import org.kamal.hello.client.*;

public class HelloWidget extends Composite {

public HelloWidget() {
// obtain a reference to the service
service = (DataServiceAsync) GWT.create(DataService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) service;
endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "data");

initWidget(panel);
panel.add(label, DockPanel.CENTER);
panel.add(button, DockPanel.SOUTH);

// click listener to get data from server
button.addClickListener(new ButtonClickListener());
}

private class ButtonClickListener implements ClickListener {
public void onClick(Widget sender) {
// call servlet to get data
service.getData(new AsyncCallback() {

public void onFailure(Throwable e) {
label.setText("Server call failed");
}
public void onSuccess(Object obj) {
if (obj != null) {
label.setText(obj.toString());
} else {
label.setText("Server call returned nothing");
}
}
});
}
}

private final DataServiceAsync service;
private final DockPanel panel = new DockPanel();
private final Button button = new Button("Talk");
private final Label label = new Label("Welcome, talk to server");
}

This widget contains one label and one button. It uses a reference of type DataServiceAsync to communicate with the DataServiceImpl servlet deployed on a web server. You must pay attention to the way this DataServiceAsync reference is obtained.
HelloWidget.ButtonClickListener class is there to respond to onClick() action of the button. Inside this class an implementation of AsyncCallback is used to get data from the DataServiceAsync reference and to update the label content.

4. Entry point

Entry point class was generated while creating the project at step 1 of this tutorial with the class name org.kamal.hello.client.HelloWorld. This is the class used to load the widget into the web page. Inside the onModuleLoad() method, we have accessed an element named "content"; this element must present in the web page that we are expecting to load the widget. Then the HelloWidget; the widget we created above is added into this element.

package org.kamal.hello.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import org.kamal.hello.client.widgets.HelloWidget;

public class HelloWorld implements EntryPoint {

public void onModuleLoad() {
// set widget on "content" element
RootPanel content = RootPanel.get("content");
if (content != null) {
content.add(new HelloWidget());
}
}
}

5. Web page

Following is the page that we will be using to load our HelloWidget. This page is already available inside GWT-Sample1\src\org\kamal\hello\public folder. Edit this page to have the following coding.
This page contains an element with id="content", which is used to load the newly created widget into this page. Also note that a .js file has been imported into this page. We will be generating this org.kamal.hello.HelloWorld.nocache.js file in a following step.

<html>
<head>
<title>HelloWorld</title>
<script language="javascript"
src="org.kamal.hello.HelloWorld.nocache.js">
</script>
</head>
<body>
<h1>HelloWorld</h1>
<table align="center" width="100%">
<tr>
<td id="content"></td>
</tr>
</table>
</body>
</html>

6. Module XML

This is the module configuration (module xml) file. The entry point class is specified in this module xml. This file is also autogenerated in step 1, and it is stored inside "org\kamal\hello" folder.

<module>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name="com.google.gwt.user.User" />

<!-- Specify the app entry point class. -->
<entry-point class="org.kamal.hello.client.HelloWorld" />
</module>

7. Compile and deploy

We have created all the required classes and files. Now we must generate Javascripts from above created Java classes. Then compile and deploy the project.

i). Generate Javascript from Java classes

For generating Javascript files from Java classes we will use the HelloWorld-compile.cmd, which was generated into the project folder in the step 1. You just have to run this command file without any parameters.

GWT-Sample> HelloWorld-compile.cmd

This will create a new folder named "www" inside GWT-Sample project folder, and it will contain a set of web resources including "org.kamal.hello.HelloWorld.nocache.js" file which we used in step 5.

ii). Compile classes

Now create a folder named "WEB-INF" inside "www" folder. Then create two folders named "classes" and "lib" inside this WEB-INF folder.
Now compile service related Java classes that we created up to now into this www/WEB-INF/classes folder.

GWT-Sample\src> javac -cp $GWT-HOME/gwt-user.jar 
-d ../www/WEB-INF/classes
org/kamal/hello/client/Data*.java
org/kamal/hello/server/*.java

Now copy $GWT-HOME/gwt-servlet.jar file into the www/WEB-INF/lib folder.

GWT-Sample> copy $GWT-HOME\gwt-servlet.jar www\WEB-INF\lib

Note: we use gwt-user.jar to compile while gwt-servlet.jar at deployment. (you can read the reason here).

Copy GWT-Sample/web.xml into www/WEB-INF folder.

iii). Deploy into web server


GWT web application deployed in TomcatCreate a folder named "GWT-Sample" inside $CATALINA_HOME/webapps and copy "www\org.kamal.hello.HelloWorld" and "www\WEB-INF" folders into that "GWT-Sample" folder (shown above). Now everything is completed.

Start Tomcat and try the following URL from your browser.
http://localhost:8080/GWT-Sample/org.kamal.hello.HelloWorld/HelloWorld.html

GWT HelloWorld web application outputNow you will see the web page with the label text and button as shown in the image. Play around by clicking the button to see different messages coming from the server. The web page will not be re-fetched from the web server, but only the text of the label will be refreshed.

Even though this is a pretty simple application, you can use this concept to develop advanced applications.

Check out this stream