Thursday, June 01, 2006

Trivial GWT Example

Editor's note 5/24/07: As you probably know, Adam and I just finished writing GWT in Action, a Manning title. Last week we were asked two pick two chapters that would be released for free. One of those, chapter 10, covers the GWT-RPC mechanism in some detail. Seeing that this entry is the most popular on the site, that was probably a good choice. So read the entry first, and if you still need to know more, go download chapter 10 from the GWT in Action book page. As always, feedback is welcome.

I was asked for a trivial RPC example for GWT by Plasante, and here it is.

File Structure


./org/hanson/gwt/MyApplication.gwt.xml
./org/hanson/gwt/public/MyApplication.html
./org/hanson/gwt/client/MyApplication.java
./org/hanson/gwt/client/MyService.java
./org/hanson/gwt/client/MyServiceAsync.java
./org/hanson/gwt/server/MyServiceImpl.java

At the root of the project is MyApplication.gwt.xml, which is the config file that defines any GWT project. I don't want to get into what each tag is used for, as I leave that to the GWT documentation. I do want to point out though that we defined a <servlet>, which is the server-side class for our RPC service.


<module>
<inherits name='com.google.gwt.user.User'/>
<entry-point class='org.hanson.gwt.client.MyApplication'/>
<servlet path="/myService" class="org.hanson.gwt.server.MyServiceImpl"/>
</module>

Under the public folder is the HTML file that will be used primarily for testing in "hosted" mode. This is a special mode used for testing GWT applications.


<html>
<head>
<title>Wrapper HTML for MyApplication</title>
<meta name='gwt:module' content='org.hanson.gwt.MyApplication' />
</head>
<body>
<script language="javascript" src="gwt.js"></script>
</body>
</html>

The three files in the "client" package are the files that are converted to JavaScript by GWT. This is the default place to put these files, but you can configure a different package to hold these.

The first file is our "main" application that is executed when the HTML page loads the JavaScript file, and the other two are interfaces (stubs) to the remote code.

Lets look at the interfaces first. The first one, which we called MyService is the interface that is implemented by the server-side code. This is a sample, so I created a very simple interface with only a single method.


// ./org/hanson/gwt/client/MyService.java

package org.hanson.gwt.client;

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

public interface MyService extends RemoteService
{
public String myMethod (String s);
}

The second interface is used for the client-side code. The name of the interface MUST be the same as the server-side interface with "Async" appended. It must implement all of the methods in the server-side interface, but all of the methods MUST also take an additional parameter, which is an AsyncCallback object.


// ./org/hanson/gwt/client/MyServiceAsync.java

package org.hanson.gwt.client;

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

public interface MyServiceAsync
{
public void myMethod(String s, AsyncCallback callback);
}

Notice that both interfaces are idential except for that additional parameter, and return type. I have highlighted that second part because I usually just copy the code from the first interface to the second, and it is easy to miss this small point.

Now, this is how you use it from the client application. First you create an AsyncCallback object by using the GWT.create() method. Note that this method takes the server-side interface as an argument, and will return an object that uses the client-side interface.

The object returned from the create() call also implements the ServiceDefTarget interface. We cast it to this interface, and set the serviceEntryPoint, which is the URL of the server-side code. We defined this location in the project configuration file with the <servler> tag.

Next we need to create an object instance that implements the AsyncCallback interface. Here we create an anonymous class for this. Calling server-side code happens asynchronously, meaning the code won't wait for a response (i.e. block). That is why we need to create this object. This object will handle the result when it makes it's way back fo the browser. We need to write code to handle both success and error conditions.

The last step is to actually call the server-side code. We do this by using the MyServiceAsync instance that we created, passing it our argument(s) as well as the AsyncCallback object to handle the result.


// ./org/hanson/gwt/client/MyApplication.java

package org.hanson.gwt.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;

/**
* Entry point classes define onModuleLoad().
*/
public class MyApplication implements EntryPoint
{

public void onModuleLoad ()
{
// define the service you want to call
MyServiceAsync svc = (MyServiceAsync) GWT.create(MyService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) svc;
endpoint.setServiceEntryPoint("/myService");

// define a handler for what to do when the
// service returns a result
AsyncCallback callback = new AsyncCallback()
{
public void onSuccess (Object result)
{
RootPanel.get().add(new HTML(result.toString()));
}

public void onFailure (Throwable ex)
{
RootPanel.get().add(new HTML(ex.toString()));
}
};

// execute the service
svc.myMethod("Do Stuff", callback);
}
}

Here is what the server-side code looks like. It just returns a simple String. The two things that are important to note is that the code does NOT live in the "client" package. It can not live there, the "client" package is for client-side only code.

We can use these classes on the server-side though. The difference is that we are actually using the Java versions, not the JavaScript versions of these classes and interfaces. In face we MUST implement the server-side interface, but becuase this interface is references in client-side code it MUST be in the "client" package.

Confusing? I hope not. Here is the short version:

  1. Server side code can go anywhere.
  2. Client side code must be in the "client" package (or sub-package).
  3. All code in the "client" package must be able to be converted to javaScript



// ./org/hanson/gwt/server/MyServiceImpl.java

package org.hanson.gwt.server;

import org.hanson.gwt.client.MyService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class MyServiceImpl extends RemoteServiceServlet implements MyService
{
public String myMethod (String s)
{
return "You sent us '" + s + "'";
}
}

Comments welcome.

157 comments:

plasante said...

Thanks a lot Robert.

I tried to follow the DynaTable example provided in the GWT SDK but it was too confusing.

Cheerio.

Pierre Lasante.

Anonymous said...

Hi Robert, I like your example but got stuck here when running it in hosted mode: com.google.gwt.user.client.rpc.InvocationException: Unable to find/load mapped servlet class.

Looks like MyServiceImpl.java does not get compiled or something. Any idea where I should look?

Thanks!

Robert Hanson said...

Hmmm...

Verify that the script that starts the GWT shell app includes path to the compiled code in the classpath (usually bin in Eclipse).

And double check that in you *.gwt.xml file you have a "servlet" tag, and it points to the right class name.

Anonymous said...

Strange, it looks ok. Would it be possible you zip your files and email it to me? robodos at gmail.com

Thanks a lot!

Anonymous said...

Robert -

I had a similar problem. I copied and used your source as you posted it (including the filenames). I ran shell command to run the application in host mode in the directory that includes MyApplication.gwt.xml (../../../MyApplication-shell.cmd) and I get this error: "Unable to instantiate 'org.hansen.gwt.server.MyServiceImpl'. Unable to dispatch request."

Any suggestions?

Peter

Anonymous said...

I figured it out. The servlet was not getting compiled into the /bin directory. I assumed this was being done automatically by the GWT-provided application shell file. Sorry for the original post.

Peter

Robert Hanson said...

Glad to hear that you figured it out.

Oliver George said...

Nice work, good clean example. Thanks.

Ram said...

Robert,

Thanks for a nice example. It works in the gwt host mode.

But, I would like to make the same to a web application.

could you please explain with a simple example on "how to create a web application using the same", where to register our rpc service , and different config stuffs?

Thanks
Ram

Robert Hanson said...

Ram, I will add it to my list of things to do, but it will probably be a little while. I just got back from vacation and have a lot of catching up to do.

Anonymous said...

I think there is an error in the MyServiceAsync. I believe that it, as well as MyService, needs to extend Remote Service if you want your server-side code to be able to use additional classes.

Also, I cannot get my version of this example to work in Web mode.

Robert Hanson said...

The MyServiceAsync interface does not need to implement the RemoteService interface.

See the RPC plumbing diagram. It shows that the "YourServiceAsync" doesn't implement any interface.

> Also, I cannot get my version of
> this example to work in Web mode.

It should work as described. If there are any error messages, that would be helpful.

Anonymous said...

Robert, you are correct. I'm wrong.

I saw that on the GWT Forum and apparently saw what I wanted to see when I attempted to confirm it in DynaTable. I must have made another change at the same time that accounted for the improved behavior. I'll get back to you when I've got story straight.

Meanwhile I apologice for the inconvenience; your very nice example was the key to my getting started. Thanks!

Anonymous said...

Robert,
In order to run this example, I need tomcat (or servlet container)?
Where run the servlet??

Robert Hanson said...

> I need tomcat (or servlet container)?

Yes, but GWT ships with Tomcat, so there is nothing to install. When you are running it in hosted mode all you need to do is click the "Compile and Run" button. This actually kicks off an instance of Tomcat.

Sergey said...

Hi Robert, I like your example. I create similar application and it successfuly run us shell.cmd utilite.
But when i push button "compile/browse" what try this message
"The development shell servlet received a request for '63EB3EFF0BC53B224C1F918C9FB3E36B.cache.html' in module 'com.google.gwt.sample.test.Test'"
Resource not found: "D:\Java\Projects\GWTTest\www\com.google.gwt.sample.test.Test\63EB3EFF0BC53B224C1F918C9FB3E36B.cache.html"
You can help me.

Robert Hanson said...

Sergey, did you check to see if that file exists? These files are the JavaScript files built for each specific browser, and the name will change every time you recompile (or most of the time).

Perhaps the issue is that your browser has cached an old page, and is still looking for an old version of the file. I typically get this when I am working with IE. My suggestion is that you close your IE browser prior to clicking this button so that it is forced to restart, and reload the new page.

If that doesn't do it, you might want to ask on the dev list as no other suggestions come to mind.

Sergey said...

Hu Robert.
I'am write you letter yesterday.
I'am attempt deployment project in IDEA 5.1 with Tomcat 4.0.4-b3, but server side don't work.
Please if you no complicated see part my code in page http://groups.google.com/group/Google-Web-Toolkit/browse_frm/thread/0c2e9f2c4a9cb058/#.

My structure exploded:
exploded/com.google.gwt.sample.test.Test - with compiled gwt client side code
exploded/WEB-INF
exploded\WEB-INF\classes\com\google\gwt\sample\test\server\TreeShow.class - contain servlet (server part GWT)
exploded\WEB-INF\lib\gwt-dev-windows.jar
exploded\WEB-INF\lib\gwt-user.jar
exploded\WEB-INF\web.xml

Please help me

Robert Hanson said...

Sergey, I haven't done much in the way of deploying the code outside of the GWT shell, so I might be the wrong person to ask at this time.

The only thing that I see might be an issue is that you are using an unmodified gwt-user.jar file. Inside the get-user.jar file is a javax.servlet.http package. The issue is that this code will already exist in your app server, so you need to remove this code from the jar for deployment. There have been several posts about this, and it is classified as a bug to be fixed in a later version.

Besides that, i don't have any other ideas.

naren8642 said...

Thank you for this article. It helped me much better than the sample in the GWT not only in that you have more descriptions but also that I was able to get the code working. Do you have any insights you could share on the lines where you actually create an instance of the async callback.

// define the service you want to call
MyServiceAsync svc =
(MyServiceAsync) GWT.create(MyService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) svc;
endpoint.setServiceEntryPoint("/myService");

Seems like you might not always want to call all of these together. Where would that be true?

Naren

Sergey said...

Hi Robert.
It's now Sergey.
Big thank you consultation.
I delete packajes javax from gwt-dev-windows.jar and gwt-user.jar files and my example start work rpc call in deplyment mode with appache.
Thank you.

Anonymous said...

Excellent tutorial :)

Anonymous said...

Hi Robert,
I read the tutorial in your blog, was excellent.

Cud you help in making test case using GWTTestCase class.

I made the example as provided in GWT site. It is ok. but the assertion is not for my use. Can u tell me how should i test my widgets in the test case.

Secondly can i call the Services through RPC in my widgets..

I m help less please help me

Please give me any example if you can. Thanks

Anonymous said...

Hi, I tried to use the example and it works. My question is: if I want to call 2 or 3 different methos with RPC how can I do it?
Have I to istanziate another
AsyncCallback object?
Thanks a lot in advance

Anonymous said...

as other have mentioned i am getting

com.google.gwt.user.client.rpc.InvocationException
in the hosted mode.
There is no bin directory and I am not using Eclipse. There is only www directory which is created by the compile script.
Ne ideas ?

Robert Hanson said...

Anonymous, I wouldn't want to guess without additional information. I also don't have as much time as I would like to field questions like these, so I suggest that you check out the GWT dev forum. Try doing a search for your specific problem first, and if you don't find anything, than post the specifics to the group including GWT version.

http://groups.google.com/group/Google-Web-Toolkit

Benny said...

Hi Robert
I made a similar application and it's working fine in the Eclipse mode
but after I compile it with the GWT shell command MyApplication-compile.cmd , it builds only the client side application and it doesn't find the server.


On the html page it's writes:
com.google.gwt.user.client.rpc.InvocationException: Unable to initiate the asynchronous service invocation -- check the network connection.


Forthermore I want to know if it possible to make the Servlet side (the Impl file) on a different project that hasn't been built by the GWT, and if so how to configure it?

Anonymous said...

Hi, very nice work, good explicative example.
I have a problem: when I try host mode the compiler answer to me whit follow error message:
[ERROR] Unable to find 'myService.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?

Can anyone help me?

more thanks

Raghu Kasturi said...

Hi,

I have tried the following link it looks good.

Try it out.

http://www.javapassion.com/handsonlabs/ajaxgwtintro/#Exercise_4

Best Regards,
krk

Anonymous said...

Thank You! This is exactly what I needed!

Anonymous said...

Thank you! This is exactly what I needed!

Anonymous said...

hI all!

I have modified the kitchensink example to put this example into it... but how I bind this form when I recieved a message from eclipse that I cannot convert it to Widget?
Is something like this:

1. I put the files into com.client.other
2. then I create a com.server I put the servlet
3. when I trying to bind it to
fTabs.add(crear(), "Crear");
^

I cannot put the class like Widget.

How can I put it there?

Anonymous said...

Very nice example. Now I can implement similar functionality into my real application. Excellent.

Thanks much!

Anonymous said...

Hi all,

you need to *compile* the servlet otherwyse it will not work.
I dont use eclipse just a editor and command line:

This is what i did:

a) install ant
b) run projectcreator -ant projectname
c) run ant -f projectname.ant.xml

enjoy !

william said...

Good tutorial but I got warning on GWT 1.1.10
[WARN] Use of deprecated hosted mode servlet path mapping

suggest change
endpoint.setServiceEntryPoint("/myService");

to
String moduleRelativeURL = GWT.getModuleBaseURL() + "myService";

endpoint.setServiceEntryPoint(moduleRelativeURL);

Anonymous said...

I had trouble getting this to work right even though it looked so simple on the GWT website. After reading your clear example, I figured out that that the Async callback method is not supposed to return anything (duh). Thanks for the great example.

Anonymous said...

Hi all,

I am evaluating AJAX and I have a simple question.
If I write this example by hand-coded(without gwt), first I implement a servlet to leverage server side business logic after that I create an xmlhttprequest object in client side using java script and set the url of the object to my servlet mapping url.Finally I register an event for any widget elements to send a request.What is the difference between these two ways?Why should I use gwt?I know gwt has advantages such as auto generated java script and debug capability but can I use it for all html elements?I am using open source frameworks like struts,jsf and I would like to integrate them with AJAX in client side.
thanks a lot

Robert Hanson said...

> Why should I use gwt?

First, an example:
http://gpokr.com/

Java for many of us is just easier than JS. If you use an IDE as a productivity tool, GWT provides tools that just aren't available in the JS world. Then there is the code compression, widgets, 3rd party libraries, thriving community, etc. There are lots of reasons to use GWT.

...But to be fair, if all I needed to do was a simple XMLHttpRequest call, coding the few lines of JS would probably make sense. In general the larger the app the advantage you get from using GWT.

> ...but can I use it for all
> html elements?

When you use GWT you don't need to only use GWT. You can mix HTML and other HS libraries with GWT. As for "all HTML", yes, you can create your own components that map to any specific HTML element.

> I would like to integrate them
> (struts, jsf) with AJAX in client
> side.

GWT has a FormPanel which can submit to a Struts action (or anything else), then let you handle the result on the client side. This seems to be a typical case for interaction with Struts.

As for JSF integration, check out the G4jsf project.

If you have a specific question, you might want to search the GWT DEV list. There has been lots of discussion about integration. Just search for "Struts" for example, and see what people had to say about it.

Anonymous said...

Robert,
thanks a lot for your informative answer.

regards

Anonymous said...

Hello
It looks a simple and nice example. But I have problem in running it in host mode.when I try it there is an error:
[ERROR] Unable to find 'myService.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?

Please help

Robert Hanson said...

> [ERROR] Unable to find 'myService.gwt.xml'

What is happening is that the GWT shell is seeing the RPC request for myService, but it isn't recognizing that there is a servlet in the config for that path... so it instead assumes that it needs to load a module by that name.

I have have seen this a lot, but for some reason my brain is failing me today and I can't recall the fix.

One suggestion might be to include the additional path info from the GWT.getModuleBaseURL().

Change this:
endpoint.setServiceEntryPoint("/myService");

To this:
String moduleRelativeURL = GWT.getModuleBaseURL() + "myService";

endpoint.setServiceEntryPoint(moduleRelativeURL);

Hopefully that will resolve it.

ab said...

Hello Robert
Thank you for your reply.
I already resolved the problem. Actually it was my mistake. what i was trying to do was replace your example in existing project and edit the ---compile.cmd and ---shell.cmd. and Use ...shell.cmd to run it in hosted mode which was wrong. So I created a new project and application for eclipse with the same file structure as you have and run it in Eclipse . Now it works perfectly in hosted mode.
Again I am stacked while running it in deployed mode in Apache tomcat.I already installed Apache,configured and tested it for simple examples. And then when I try it for this example it does not work. the file structure I ued is the same as the one Surgey used and mensioned in this group discussion. So any help on how to resolve this problem.
Surgey could you please drop me few lines since you already did it.
By the way Robert I managed to understand many things from your example in very short time. Thanks a lot again.
waiting for reply...
Ab

Robert Hanson said...

I assume it is a servlet mapping problem. Your web.xml should look something like this.

<servlet>
<servlet-name>service</servlet-name>
<servlet-class>org.hanson.gwt.server.MyServiceImpl</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>service</servlet-name>
<url-pattern>/myService</url-pattern>
</servlet-mapping>


Then you may need to alter the endpoint URL in the app. The above mapping for /myService is relative to the URL for the app. So if you have your app serving from http://localhost/rpc-test, then the endpoint URL in the app should point to /rpc-test/myService.

On the other hand if you used GWT.getModuleBaseURL(), this will return the path to the nocache.html files... so if your app is in /foo/bar/, then this will be the return value of GWT.getModuleBaseURL().

And lastly, some people have copied the web.xml that is created when you run the hosted-mode browser. You can't use this web.xml. It uses the a shell servlet that is only meant to be used in hosted mode.

As for debugging, the easiest way is to have the app hit the server, then check the server logs to see what URL was being requested. ...If the app doesn't request any URL from the server, well, then you have other problems.

ab said...

Hi Robert
Lots of thanks . Now it is working.Your example is excellent and your consultation is fast and to the point.Now I am going to develop my own application ,May be I will write about it .
Thanks
ab

Ethan said...

I really appreciate your work. This was an excellent tutorial. I would like to make one small suggestion.

You wrote:

"Notice that both interfaces are idential except for that additional parameter."

There actually is one more difference. I would write:

"Notice that both interfaces are identical except for that additional parameter and the return type.

The bold text would have saved me 15 minutes. :)

Robert Hanson said...

> The bold text would have
> saved me 15 minutes. :)

I know the feeling... I can remember at least two times when I forgot that, and sat there scratching my head for a bit. If I recall, the error message wasn't too helpful in pointing me to the problem.

In any case, I will make the change.

akeimou said...

i too copied and got it to work in hosted mode. then spent close to a day to get it to run in tomcat. it was something really basic. i deployed in tomcat manager and kept clicking on the link MyApp in the list of deployed apps to run it and it kept saying resource not found. well, it's because it's looking for MyApp/index.html whereas the hosted mode automatically went for MyApp/MyApp.html. (shame on me)

do you usually just copy MyApp.html into index.html in the build or can the filename be entered as parameter to applicationCreator?

looking forward to your book,

--meg

Robert Hanson said...

> do you usually just copy MyApp.html
> into index.html in the build or can
> the filename be entered as
> parameter to applicationCreator?

Yes, you can just rename the file... as long as you have the web.xml set up properly. One mistake I have seen a few times is where the production web.xml uses the GWTt shell servlet instead of the servlet that you created.

> looking forward to your book

Me too... it has been a very long process. It basically became a second job for 5 months or so.

In any case, the book has a half of a chapter about deploying a GWT app.

Rishi said...

I am trying out RPC and facing the same issue that others have faced before, "Unable to find/load mapped servlet class 'com.ria.msde.server.OrderServiceImpl'
unable to dispatch request".

I understand that peter found the issue and the problem was the servlet was not getting compiled at all and put in the bin folder.

In my case I am running shell.cmd that brings up the application. Can somebody please let me know what additional step I need to do to compile the servlets.

Robert Hanson said...

If you aren't using an IDE that will do this, you can either use a build tool like Ant or Maven... or just use the Java compiler at the command line.

Note... all of this would appear on one line at the command prompt.

javac
-classpath 'gwt-user.jar;gwt-dev-windows.jar'
-sourcepath src
-d bin/
[filelist]

For the -classpath you will need to alter it to point to your gwt-user and get-dev jar.

You will need to create the output directory bin/ before running this.

For the [filelist] you need to provide the path to each Java source file that you want compiled. On Linux/Cygwin/Unix you can use `find . -name \*.java` to do that for you.

I hope that helps.

Rishi said...

Thanks a lot Robert. I created the bin folder and compiled the java files under bin.
I am able to make a RPC call now.
I am creating a small demo application using GWT, will keep you guys updated as to how it goes.
Thanks again Robert.

kenlars99 said...

I wrote a build.xml and web.xml that can be used to deploy the DynaTable example to tomcat. See my blog entry on it

Vackar said...

Hi,

I tried to use the examaple code but I get this error:

Deferred binding failed for 'com.remotehomesecurity.webfrontend.client.IDirectorySearcher'; expect subsequent failures

Do you have any idea what's causing it and how I can fix it?

Thanks,
Vackar

Robert Hanson said...

Vackar, I am not entirely sure why you are getting the error, but I have a string feeling that I need to rewrite this article. The two problems with the article is that the steps aren't bulletproof, and second it should use the new RequestBuilder.

No promises, but I will try to get a new article out soon and link to it from this one.

Anonymous said...

Hi,
I succesfully created the rpc server side (tomcat server) and compiled the client-side (locally stored) and it works fine. Thank you very much..
I still have a question.. is it possible to make a google desktop gadget from this compiled code (java script) ? I tried but did not succeed.

Robert Hanson said...

> is it possible to make a
> google desktop gadget

I am not familiar with that technology, so I can't say for sure. My guess would be yes though, since GWT can interface with external JS code by using JSNI.

Anonymous said...

Thank you for your response. Actually, I did not succeed for 2 main reasons:
- the google desktop bar do not provide the same environment than a basic web browser, thus some objects like "document" or "window" in the generated gwt.js are not supported..
- moreover, to load the gwt.js file, the .html document need an appropriate "meta" tag that can not be added the xml specification of a google desktop gadget..

I needed the gwt rpc functions to be integrated to a google desktop gadget, finally I try make it with a dll.

Shadab said...

Hi,
I am trying to use Kitchen-Sink example in hosted mode.As soon as I executed KitchenSink-Shell,I got the warning WARNING: Prefs file removed in background ~/.java/.userPrefs/com/google/gwt/dev/shell/prefs.xml and
the hosted browser is trying to connect some www.localhost.com.When I allowed it to do so I go the error " www.localhost.com could not be found. Please check the name and try again. "
The console contained this error
[WARN] Confirmation was required to visit untrusted URL: 'http://www.localhost.com:8888/com.google.gwt.sample.kitchensink.KitchenSink/KitchenSink.html
[WARN] reason: http://www.localhost.com:8888/com.google.gwt.sample.kitchensink.KitchenSink/KitchenSink.html is not in the whitelist
[WARN] To fix: add regex matching URL to -whitelist command line argument
[WARN] Example: -whitelist=" ^http[:][/][/]www[.]localhost[.]com[:]8888"

Then I edited www.localhost.com to localhost still it didnt work.So I made it 127.0.0.1 Then it worked.But when I typed http://127.0.0.1:8888/com.google.gwt.sample.kitchensink/KitchenSink.html
I got Cannot find resource 'KitchenSink.html' in the public path of module 'com.google.gwt.sample.kitchensink' in hosted browser and got the following message in the console
[TRACE] The development shell servlet received a request for 'KitchenSink.html' in module 'com.google.gwt.sample.kitchensink'
[ERROR] Unable to find 'com/google/gwt/sample/kitchensink.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?

Please help me to get out of this problem
Thanks and Regards,
Shadab.

Robert Hanson said...

I suggest asking this on the developers forum. I don't have any immediate answer. http://groups.google.com/group/Google-Web-Toolkit

Bugsfunny said...

I also tried to implement the RPC example. It does work ok. I implemented the service and serviceAsync files as in the example and created a serviceImpl in my server dir:

client/listService.java
client/listServiceAsync.java
server/listServiceImpl.java

Now I wanted to extend this example by using three different serviceImpl files, which return different data:

server/List1ServiceImpl.java
server/List2ServiceImpl.java
server/List3ServiceImpl.java

and appended the servlets to the gwt.xml file:

< servlet path='/list1' class='com.company.server.List1ServiceImpl'/>
< servlet path='/list2' class='com.company.server.List2ServiceImpl'/>
< servlet path='/list3' class='com.company.server.List3ServiceImpl'/>

I also added a parameter to the ListDataProvider for the module name. Now every time I got the following error:

Unable to find/load mappet servlet class 'com.company.server.List2ServiceImpl'

The first list does work and is retrieved perfect, but when the second is retrieved, this error appears, and probable also when I try to load the third list. If I change the second and third list in the gwt.xml file to com.company.server.List1ServiceImpl it does work (although it retrieves the wrong lists, but thats because it uses the other servlet).

It both occurs in the shell and in the browser. The bin-dir also contains the three class files for the list.

Anyone an idea?

Robert Hanson said...

Bugsfunny, it sounds like you did everything right, especially when you verified that the compiled class files for the other two services were there.

So... I assuming the classpath is correct. Perhaps your code in service #2 references some class in a jar file that isn't in your classpath? For example, if #2 is using Hibernate (or whatever), perhaps that jar wasn't added to the classpath.

Beyond that, I don't have any ideas for you. You also might want to post to the GWT dev list (http://groups.google.com/group/Google-Web-Toolkit). There are 4,000 pairs of eyes on that list, so I would hope that you would get more ideas than you would here.

Bugsfunny said...

I already found out what the problem was.

The idea of the three lists was to let the content of the second list depend on the selected value in the first list and the third list depending on the second list.

Therefore I added a parameter to the List2ServiceImpl constructor function (and also for List3). This caused the error. I removed the parameter and it works.

Still I want to be able to provide the service with some information (about the selected values in the list, it depends on). Can you give me a clue how I can do that?

Thanks for your fast respond on my previous question.

Robert Hanson said...

> Still I want to be able to provide
> the service with some information
> (about the selected values in the
> list, it depends on).

You need to pass that information as parameters to the remote method call.

It sounds like you almost want to store state for each user on the server. You *can't* use instance vars for this because ALL users will use the same service instance because it is just a servlet.

You can though use the user session to store data. You can get the HTTPSession object from calling getThreadLocalRequest().getSession(), then call setAttribute() and getAttribute().

Bugsfunny said...

Thanks Robert. Using the session works fine for me.

Now I got another problem, which I read about over and over again, but can't find a solution.

It's the following problem:

I tried to add GWT to my existing J2EE project in WSAD (Eclipse). I added the jars, added the example of Kenlars99 (some posts above). When it tries to compile I get the error UnsupportedClassVersionError for the GWTCompiler. I use j2sdk1.4.2_08. I read that I had to use at least 1.4, so this can't be the problem. Also because I can compile it with the shell-command.

I tried to fix this problem a few days ago and retried it now, but it gives me headaches, since I don't know where to look anymore.

Got an idea?

Robert Hanson said...

Bugsfunny, nope, I have no idea... assuming that you are actually using Java 1.4.

Take a look at this post on the dev list where someone had this same error, and found that unknown to them that they had an old installation of Java 1.3 on their system.

http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/fa74f96829b19e25

So I would double check that you are actually using 1.4.

Flavio P. said...

Great Troubleshotting guide!!!!

I was desperate because in hosted mode when I was trying to launch my Servlet I was receiving the boring Exception relative to the ClassLoading of the class!
As you told (fortunately!!) the problem was that I was using JBuilder default output classes directory that put all compiled sources in the classes directory for default instead the bin one required by GWT!!

Another problem was that I didn't sign the methods of the Async interface as returning null!

THANKS A LOT!!

Teal Wren said...

Thanks for an excellent tutorial!

Will said...

I usually don't leave comments but since your simple tutorial helped me fixed my problem, I have to :)
I got a message : "[WARN] Resource not found: trainingDB"
I missed "{servlet path="/trainingDB" class="com.cognex.VSF.trainingDB.server.TrainingDBServiceImpl"/\}
(replace {} by <>)

Anonymous said...

Hi ,

I'm facing a problem very similar to the one posted earlier.

This is what I get when I run the html file in my browser (web mode). "Unable to initiate the asynchronous service invocation -- check the network connection."

The application runs fine from Eclipse or in hosted mode.

If anyone can point me to some corrective action, that would be great.

Thanks,
Sangeeta

Robert Hanson said...

I don't recall ever seeing that specific message before. If you haven't already done so, I recommend posting your issue to the dev group.
http://groups.google.com/group/Google-Web-Toolkit

Anonymous said...

Thanks Robert for your prompt response. I visited the GWT forum and found similar posts there but no useful response. Anyway, there is a post on your site from a Benny with the exact problem as mine. Wonder what he did!

Thanks,
Sangeeta

joseph said...

I was getting a NullPointerException for the longest time. (I opened in Hosted Mode and got a 500 server error).

To fix the problem, I had to change:
<servlet path="/myService" class="com.domain.server.myServiceImpl">

to have the /> at the end like it should.

Very annoying to debug and I couldn't find any forums going over the problem. :(. So I figured that I would post it here in case someone else has the same problem.

Rishi said...

Did anybody else run into the following issue? I am getting the same error with the example.


Hi,

I tried to use the examaple code but I get this error:

Deferred binding failed for 'com.remotehomesecurity.webfrontend.client.IDirectorySearcher'; expect subsequent failures

Do you have any idea what's causing it and how I can fix it?

Thanks,
Vackar

Rishi said...

Figured out! The reason for the error (atleast in my case) was the fact that the async interface had a typo. I named the interface MyServiceasyn rather than "MyServiceAsync". Not the capital "A" in "Async".

Robert Hanson said...

> Figured out!

Good to hear.

Poor error messages have been a problem with GWT. Hopefully they will get better over time.

Suresh said...

Hi Robert,

Thanks for the example. I'm able to create a simple RPC. The steps outlined here were very clear.

Anonymous said...

hi robert

great tutorial but i have a problem. everything works fine in hosted mode but when i upload to the web i get the invocationexception and the onFailiure() method of the AsynCallback object runs. Any ideas?

.clicky

Robert Hanson said...

Hi Clicky. No, I have no immediate ideas. It is probably some small error... it always is. I have found in general that GWT's error messages for RPC are pretty bad, making it difficult to debug.

One of the most common mistakes is in the async interface. Make sure that all of the methods return void, and that the method takes the same args as the main interface plus the callback.

If you are still stuck, you might want to try again from the beginning. Sometimes that is the easiest way when you start out with GWT-RPC, until you get used to all of the parts.

If all else fails, try posting your actual code to the GWT-Developers (http://groups.google.com/group/Google-Web-Toolkit) list. Maybe a few thousand eyes can spot the problem. If you haven't used the developers list, it can be very helpful, just as long as you don't post questions that could be answered by the documentation.

Anonymous said...

hey

so i narrowed my problem down further. it works in web mode when i access it through localhost but if i simply run the html file from windows explorer, i get the same error. is there anything special that needs to be isntalled on the server like a container or something?

.clicky

Robert Hanson said...

> is there anything special that
> needs to be isntalled on the server
> like a container or something?

You do need a Java servlet container, if that is what you mean. Apache Tomcat is one of the most popular ones.

Anonymous said...

Thanks a 100.000 times for this tutorial. You helped me alot!

Magnus

geccg said...

Robert, this was an awesome RPC example. I think its the best one out there on the web. I just bought your GWT in Action book and look forward to getting more knowledge on this stuff. Thanks to you and Adam Tacy.

geccg

Anonymous said...

Hi,

Thanks for the tutorial. I'm new to GWT and maybe I jumped too quickly into RPC, but I was trying to add your example (with changed names) to an existing Eclipse module completely manually and I'm getting the follwing exception. Any idea on what I'm missing?

[ERROR] Unable to load module entry point class com.fb.gwt.client.Calculator (see associated exception for details)
java.lang.RuntimeException: Deferred binding failed for 'com.fb.gwt.client.CalculatorServiceAsync' (did you forget to inherit a required module?)
at com.google.gwt.dev.shell.JavaScriptHost.rebindAndCreate(JavaScriptHost.java:157)
at com.google.gwt.dev.shell.ShellGWT.create(ShellGWT.java:24)
at com.google.gwt.core.client.GWT.create(transient source for com.google.gwt.core.client.GWT:47)
at com.fb.gwt.client.Calculator.onModuleLoad(Calculator.java:13)
at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:342)
at com.google.gwt.dev.shell.BrowserWidget.attachModuleSpace(BrowserWidget.java:326)
at com.google.gwt.dev.shell.ie.BrowserWidgetIE6.access$200(BrowserWidgetIE6.java:36)
at com.google.gwt.dev.shell.ie.BrowserWidgetIE6$External.gwtOnLoad(BrowserWidgetIE6.java:70)
at com.google.gwt.dev.shell.ie.BrowserWidgetIE6$External.invoke(BrowserWidgetIE6.java:125)
at com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:293)
Caused by: com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
at com.google.gwt.dev.shell.ModuleSpace.rebindAndCreate(ModuleSpace.java:415)
at com.google.gwt.dev.shell.JavaScriptHost.rebindAndCreate(JavaScriptHost.java:153)
at com.google.gwt.dev.shell.ShellGWT.create(ShellGWT.java:24)
at com.google.gwt.core.client.GWT.create(transient source for com.google.gwt.core.client.GWT:47)
at com.fb.gwt.client.Calculator.onModuleLoad(Calculator.java:13)
at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:342)
at com.google.gwt.dev.shell.BrowserWidget.attachModuleSpace(BrowserWidget.java:326)
at com.google.gwt.dev.shell.ie.BrowserWidgetIE6.access$200(BrowserWidgetIE6.java:36)
at com.google.gwt.dev.shell.ie.BrowserWidgetIE6$External.gwtOnLoad(BrowserWidgetIE6.java:70)
at com.google.gwt.dev.shell.ie.BrowserWidgetIE6$External.invoke(BrowserWidgetIE6.java:125)
at com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:293)

Robert Hanson said...

Hi Anonymous,

You might want to start from scratch, and get the example running as-is. It is *very* common to run into issue like this until you have done it a few times. Everything has to be just right to get it to work, and in this case the error message isn't helping all that much.

Some common mistakes:

* The CalculatorServiceAsync has methods with return values. This is *wrong*, all methods need to return void.

* The CalculatorService interface doesn't extend the RemoteService interface.

* The methods in the CalculatorServiceAsync interface are missing the final argument of AsyncCallback.

* The methods on the two interfaced, CalculatorService and CalculatorServiceAsync, don't match up exactly (other than the return value and AsyncCallback argument)

Anonymous said...

Hi all,

I have a problem that the Impl class cannot be instantiated in the server, one user said:

"I figured it out. The servlet was not getting compiled into the /bin directory. I assumed this was being done automatically by the GWT-provided application shell file. Sorry for the original post. "

I think that I'm having the same problem. Could you please help me to fix this problem?

Thanks a lot for your help,
Marcelo.

Robert Hanson said...

Hi Marcelo.

Did you confirm that all server-side code was compiled, and that it is in the classpath? The classpath is defined in script (or command) you used to start the hosted browser.

Anonymous said...

Hi Robert,

Thanks for your answer.

I get the .class file under the server directory, but I didn't change anything in the scrip (xxx-shell).

I'll check that and let you know.

Thanks,
Marcelo.

prady said...


prady said...


hi Robert

I was developing a webppalication in GWT.now am done with the
application which i wanted to do. (like if i click a button load it
will load values from the datbase into listboxes & then if i select
some values in the lists & submitt(button) i can see the values in a
TextArea).

since am working in eclipse i had given the mysql jdbc connector/
driver in the build path. so am able to c the output while running
through eclipse in the hosted mode... it wanst working while executing
{project}.shell file....separately.. then i edited the {project}.shell
file & included jdbc driver then it was working.

but there was a problem with the {project}.compile bat file. it is not
loading values if i run the html file generated. (in the web mode).
i guess the problem is with these jdbc driver is that so... .
i hav also creaed WEB-INF\lib\ inside www folder... & included servlet
jar & my source jar file....
done with the web.xml file with servlet mapping...

by the way
then i want to deploy this on a Apache Tomcat server. , i hav included
the folder in the webapps\root directory
am able to get the GUI client side view.... but values are not being
loaded ..from databse...

this is the error:while deployin on tomcat server....
if i open...
http://localhost:8080/.... /...html

i hav one more doubt like will there be any clash beacause of this localhost port... coz GWT connects to HTTP port 8888 by default... any ways.
...cud you help me regarding this...

ERROR:


this last line is because of the getStackTrace...

Thanx

prady

prady said...

Servlet guiService is not available
description
The requested resource (Servlet guiService
is not available) is not available.

** Actually am unable to include the error part in my prev comment beacuse of some upaoding probelm...(since he error part contains some html coding & stuff.. now the above lines are some part of the error.... hope therz some probelm with servlet...could u please hep me in this regard..

Robert Hanson said...

Prady, I have to admit, you lost me bit there.

It sounds like your problem is that you are deploying you app to Tomcat, and it isn't working.

You need to debug this like any other web app. Is the GWT app hitting the right URL? You can check the server logs for that. Are you using Log4J on the server to print out debugging statements? How about the server error logs?

I am focusing on the server because if the interface works in hosted mode then the problem is likely in the configuration of the app on the server.

prady said...


Hi Robert

i figured out the error... that was the error with the folder name which i deployed on tomcat server inside webapps

i had put the folder (org.sampe.gui) generated by {}.compile bat file inside /www/

so there was a clash with this folder name (org.sampe.gui) ..

i put a folder guisample/ under webapps/ & i included the contents of org.sample.gui under that... & WEB-INF & stuff

now its perfectly working..
i think the error wud hav occured becoz of the servlet mapping in web.xml file...

ny ways thanx for ur reply
--
prady

Anonymous said...

Thank you again and again.

minku said...

Hi Robert
I am devloping a project on GWT. I inserted a google gadget i.e. calculator in my application by using URL of it inside a Frame class.Now i want to communicate with calculator via my GWT application means i have some textboxes and labels, i want to pass the value inside textboxes and sum of these values,i want to calculate with the help of calculator.simply u say that how can i pass the value in calculator through my GWT application. the calculator i am using i got it from google API...

If it is possible send me the exact code of it.

karunjay

minku said...

my email id is anand.karunjay@gmail.com

Robert Hanson said...

> If it is possible send me the exact code of it.

Nope, not possible. I know nothing about the API you mentioned.

In GWT you will want to use the JSNI interface that allows you to include native JavaScript in your GWT app. You would use JSNI to write some custom JavaScript that could talk to the calculator widget using it's API.

The JSNI docs are here:
http://code.google.com/webtoolkit/documentation/com.google.gwt.doc.DeveloperGuide.JavaScriptNativeInterface.html

Robert Hanson said...

Reposting link to JSNI docs as a hyperlink:

Google JSNI Docs

marwan said...

Hello Robert,

And thank you for your book and user group. Very helpful!

I have a little architectural problem that I'd like to submit to your attention, and hope that you'll be able to help.

Server-side, my implementation manages and stores, for each client, some kind of "conversation state" information. That "conversation state" information transits back and forth between the server and the client within the HTTP response & HTTP Request headers.

Using a com.google.gwt.http.client.RequestBuilder , I can easily access those headers. They are available to the client.

Now, for an RPC call (com.google.gwt.user.client.rpc.RemoteService) , I can't get access to those headers. Google made it so, that all the low-level details are hidden and unavailable to the client.

Do you have any idea on how I could achieve this? Any way to get to those headers when in an RPC call?

Thank you for your time and best Regards,

Marwan SINGER

Robert Hanson said...

I have a few ideas Marwan.

1. Mention it on the GWT-Contrib list. See if anyone there thinks that it should be added to the GWT-RPC classes. Perhaps suggest an API that you think would work well.

2. You could modify the GWT code base to do what you need it to do. This creates a problem when you upgrade though.

3. Pass the conversation state as part of the message back to the server. You can do this unobtrusively by creating a new wrapping class, and having that class wraps both the return object plus your message. Your client side code then reads the message, strips off the the wrapping class. This is likely the easiest option.

4. Don't use GWT-RPC, use REST instead. This might not be an option for you since you would need to (de)serialize the data yourself.

Mark Kenneth said...

Hi Robert,

I am new to GWT and eclipse but am grasping the concepts for quite a while now.

I am creating an currently application using gwt. I would want to create a simple authentication page, where i will be linking it with apache jackrabbit just like the 1st hop example,.. Can you please guide me on how can i implement this first hop with gwt,.. (authentication page sample)

heres the link for the first hop:
http://jackrabbit.apache.org/doc/firststeps.html

I hope you get my question.

Thank you for your time. I hope to hear from you soon thanks



Mark Kenneth RaƱosa

Robert Hanson said...

Hi Mark,

I have no experience with JackRabbit other than playing with it during a few minutes of down time.

> I would want to create a simple authentication page

That is easy enough. Take a look at the GWT docs for TextBox, PasswordTextBox, and Button. Use those to create a login for for the user.

From there you need to add a ClickListener to the Button to trigger the authentication. The listener will need to send the data to the server in some manner. You can use either GWT-RPC (like this article) or via the RequestBuilder class.

Once you get that far, all is left is to implement the authentication on the server. How you do that depends on the transport mechanism you chose and what server-side technologies you have chosen. This could be a servlet, JSP, Spring controller, Struts controller, etc. There is no wrong answer here.

Besides logging in, the server side needs to return some value to the client so that it is aware of the outcome. If you use RequestBuilder (perhaps the easier solution), a single word response like "OK" or "FAIL" is enough. The client would receive this result and act accordingly, like showing the user a message indicating the result.

I hope that helps.

Titty said...

Hi all.

I need a help
I included a jar file for GWTDatePicker into my eclipse project.Then I import
"com.google.code.p.gwtchismes.client.GWTCDatePicker"
there is no complile error
but I could,ny run the program It displays a "failed to load module" error. what is the problem

Robert Hanson said...

You should probably ask that question on the GWT forum, http://groups.google.com/group/Google-Web-Toolkit. I would suggest though that you provide more information. The info you gave is the equivalent of you saying "my car isn't starting, what is the problem?". For all we know you just forgot to buy gas.

Anonymous said...

Hi Robert,

PNGImage pngImage = new PNGImage("verify.png");

Now verify.png is server side mapping to generate different png file per request.

It works perfectly fine with IE but firefox doesn't update new image but shows old one.

in GWT I do the following

HorizontalPanel hpanel = new Hor..Panel();
hpanel.add(pngImage);
rootPanel.get("verifyImage").add(hpanel);

When I want to show new image on click event of another button
hpanel.remove(pngImage);
pngImage = new PNGImage("verify.png");
hpanel.add(pngImage);
rootPanel.get("verifyImage").add(hpanel);

everything works great in IE but Firefox doesn't update new png image. any pointer...

also servlet response has all kind of header set saying no-cache, expire =0 etc...

Thanks for your widget library..
Ken

Anonymous said...

yes I also set width and height for PNGImage otherwise it won't compile..

Thanks,
Ken

Robert Hanson said...

Hi Ken,

The PNGImage requires a width and height because of how it works. On IE it renders as a background image or a div. This is required for the alpha channel of the PNG to work in IE.

I can't do much with the browser caching the image, so the best way I think would be to add a random number to the querystring for the image. I often use this in practice with banners from advertising industries and calls to the server from flash movies.

So instead of "foo.png" you would use "foo.png?rand=1847562", where rand changes for each request.

Something like this should do the trick.

long double = Math.random();
pngImage = new PNGImage("verify.png?rand=" + rand);

Anonymous said...

Thanks for suggestion.

I have pre-define 20 url in web.xml since you can't change servlet mapping in tomcat programmatically. This solution works on all browser but upto 20 new images after that it rolls to first one..

Thanks,
Ken

Riaz said...

Hey Robert,
It's really wonderful to see my app working... with this beautiful post. I was successfully able to run the webapp by creating a new project by going step by step thru the guide on GWT site. The problem came when i tried to integrate it in struts (1.x) webapp. I did not find much to read on it. Here is what I did to integrate GWT in struts:
1. Compile the project as mentioned on GWT site.
2. copy the js generated to a separate folder 'gwt' under WebContent.
3. update the js src path in gwt.js and all.

When the page loads, i get a message saying unable to get data from server. It is 'onFailure' method message. How do I fix it?

Robert Hanson said...

Ken, I think you missed the point here. You aren't creating new servlet targets, you are just altering the request params. The browser will consider a change in request params a different page, although your server should consider it the same page with different arguments.

Robert Hanson said...

> i tried to integrate it in struts...
> 1. Compile the project...
> 2. copy the js generated...
> 3. update the js src path in
> gwt.js and all.
>
> When the page loads, i get a
> message saying unable to get data
> from server. It is 'onFailure'
> method message. How do I fix it?

Riaz, that really is really vague description of the problem. First of all, if you are using Struts, then you aren't using GWT-RPC (the topic of this post). Second, the gwt.js file should never be modified, and for that matter is not even used in GWT 1.4, it has been deprecated.

That being said, I need to assume that you are using GWT 1.3 with RequestBuilder. You should start by using the Firebox add-on FireBug, and make sure your app is hitting the right URL. Then use FireBug to inspect the contents of the request payload, that is always helpful.

If that doesn't work you should post a detailed question on the gwt-dev list, specifying what you are actually trying to do, why you need to do it this way, perhaps with code snippets, a list of what you tried, and a list of all of the symptoms. http://groups.google.com/group/Google-Web-Toolkit.

Good luck.

Riaz said...

Hey Robert,
Excuse me for that unhelpful description. I have figured out the problem. It was because of incorrect source path that I was using.
Another thing is, if gwt.js is not being used then why is it being generated. I had to edit gwt.js as I was copying the com.mycompany.xx... generated under www folder to gwt folder under 'WebContent' directory. So the structure is like this: 'WebContent/gwt/com.mycompany.xx...'. Changing gwt.js to the correct path helped to load the script in my own pages. How do i do this if I dont have to use gwt.js? What is the wokaround in GWT 1.4? Please help...

Robert Hanson said...

Riaz,

Where to start...

> if gwt.js is not being used then
> why is it being generated.

For backwards compatibility. With GWT 1.3 you use a meta tag and gwt.sj to load the module... with GWT 1.4 you simply point to the JS file instead of the gwt.js, and the meta tag is no longer used.

> I had to edit gwt.js as I was
> copying the com.mycompany.xx...
> generated under www folder to
> gwt folder under 'WebContent'
> directory.

If you had bought GWT in Action you would have known why you didn't need to do that, there is a half-chapter dedicated to deployment :)

In GWT 1.3 you can use the meta tag to point to the module if it isn't in the default location. No need to edit the gwt.js.

On the other hand, like I said, that is deprecated. So you should update your HTML to load the file the GWT 1.4 way instead.

Here is an example of loading my "Foo" project in GWT 1.4. Just a single script tag.

<script language='javascript' src='org.test.Foo.nocache.js'></script>

Ken said...

Hi Robert,
One more question about HTML and GWT relation. I have gone through you book and found good tips about UI side but I have something specific so here it is.
As most of the developer sucks in CSS I am in the same position where CSS isn't my strong point. So we have complete GWT base interface and later on designer provide HTML/CSS base interface do you see any problem in converting HTML/CSS base to pure GWT base. Does HTML CSS can be used as is for pure GWT interface or you need to make some
changes?
Also any limitation in converting HTML/CSS base interface to pure GWT?
We don't have UI designer right now but developing application using HTML and doing something like this


html
define module file name i.e. com.company.module-nocache.js file

table
tr-td id="companyname" -td-tr
/table
/html

Now in Java code get this by

rootPanel.get("companyname").add(new TextBox())

I know it will be nasty job to do it for 10-15 HTML files and also
create mostly each module per HTML. I might use one module in multiple
HTML file but it will be loaded repeatedly with every HTML file.

In this direction it will be hand picking and replacing all HTML
elements with GWT but you are not redoing what designer has
provided in case you implement pure GWT.

Let say you design entire interface in pure GWT and later on designer
come into your project and provide HTML/CSS base interface then you
have to redo your entire GWT base interface accordingly. In that case
do you think we will have some problem with CSS??

I might be repeating same point here just to make sure you get the
picture where designer is working separately.

Thanks,
Ken

Robert Hanson said...

Ken,

> do you see any problem in
> converting HTML/CSS base to pure
> GWT base

No. Other than the time it takes the designer to learn the CSS rule names it is just CSS.

> Also any limitation in converting
> HTML/CSS base interface to pure GWT?

It depends on the project, but probably not.

> We don't have UI designer

Then you might want to use the default CSS for GWT 1.5 for now.

http://groups.google.com/group/Google-Web-Toolkit-Contributors/browse_thread/thread/d6cbd616a4042c72

However you do it, the designer needs to be aware that you are using GWT, and know that you will need to create components out of it.

Ken said...

Thanks Robert

Sivasankari said...

hi,
Can we store the user input from a page created by gwt toolkit using json. Can any one tried? if so pls give sample code or links to develop
thanks in advance,
Siva

rajesshmca said...

Hi sir,

This is rajesh

i am new for GWT,EClipse and Derby database

i need a small examples using these

it will be very useful for me sir

plz help me as soon as posible

Robert Hanson said...

Rajesh,

Derby is just a database engine, so I would assume you would just use JDBC. I have never used Derby before, I tend to use other engines.

rajkumar_12 said...

Wonderful example, very useful. I was able to get it working except for few of my mistakes. Very simple and easy to understand. I can now build a realistic application based on this beautiful simple example. Many Thanks! to Robert.

Anonymous said...

Hi Robert,
Thanks for your help on Image change example i.e. (("verify.png?rand"+rand). It is working great.
I have used your API org.gwtwidgets.client.util.Location and greated GWT application page driven like JSP or PHP. You know in PHP or JSP they have home.php or login.php or register.php. I was able to do same with GWT keeping on thick module for entire application but distributed per page i.e. home.html or register.html or login.html or forgotpwd.html using your API.

Thanks a lot,
\Ken

Anonymous said...

Robert,

We are building a portalet and it may contain multiple widgets. For each new widget down the road, we have to build a new "MyServiceImpl" and add it in web.xml. We also end up with many servlets reside in the server's memory. Is there a way to use only one spring/struts controller instead of servlets in this case?

Thanks!

Robert Hanson said...

> Is there a way to use only one
> spring/struts controller instead
> of servlets in this case?

Yes, but that doesn't lessen the number of classes in memory.. in fact it probably means more. Each Spring or Struts controller is just like a servlet... it is just another class in memory. And both the Spring and Struts dispathers need to do the same sort of dispatching that the servlet engine would do.

So as far as memory consumption/performance goes, it doesn't really matter which you use. The only real difference is the technology, which can be substantial. For instance, if you use Struts, then you can't use GWT-RPC... but if you use Spring you can, but only if you use something like the GWT-SL (http://gwt-widget.sourceforge.net) to hook the two together.

gcstang said...

Excellent tutorial. Works great.

Thank you,

TTB Software said...

does this work with gwt1.5M1 ? I'm getting IncompatibleRemoteServiceException?

Robert Hanson said...

Yes, it should all work. Are you perhaps using a different version of GWT's server.jar on the server? The server jar needs to match the version that you compiled the app with.

Anonymous said...

Hy... I'm trying to deploy this aplication within an ear or war... i have 3 problems:
1. when i call svc.myMethod i get this in the browser (not using hosted mode):
com.google.gwt.user.client.rpc.InvocationException: //OK[1,["You\x20sent\x20us\x20'Some\x20Stuff'"],0,3]
it sends OK and Exception ???

2. i tried to use a servlet from another servlet in another ear/war arhive and i also get the IncompatibleRemoteServiceException, but i used the same gwt jars (1.2.22) copied in the project folder
3. if i use the 1.4.61 gwt jars it wont compile the js and html (i can't see an exception there because i use browser mode)
Can anyone help pls?

Andrew.

Robert Hanson said...

Anonymous, you will have better luck if you post your questions on the GWT forum. There are 10,000+ helping hands, and it is likely that someone will know of the top of their head what the issue is.

http://groups.google.com/group/Google-Web-Toolkit

> but i used the same gwt jars
> (1.2.22) copied in the project folder

JarS? There should only be one jar in production, the gwt-servlet.jar. I am not sure when that was introduced though, it may not have been until 1.3. The gwt-user.jar has servlet classes that could cause problems with some containers.

> if i use the 1.4.61 gwt jars it
> wont compile the js and html

The API did change a bit in 1.4, so maybe that is one of the issues you are seeing. Assuming you are using an IDE, these API changes are pretty easy to spot.

Anonymous said...

Analyzing source in module 'com.viplane.RealEstate'
[ERROR] Errors in 'jar:file:/F:/software/gwt-widgets-0.1.5/gwt-widgets-0.1.5.jar!/org/gwtwidgets/client/ui/gsearch/GResult.java'
[ERROR] Line 32: JavaScriptObject classes cannot have fields
For additional info see: file:/F:/software/gwt-windows-1.5.2/doc/helpInfo/jsoRestrictions.html


======================

I got above error while using API with GWT1.5 M2 and remove org/gwtwidgets/client/ui/gsearch

directory since I was not using that part and now it is working so you have to take out fields from classes in gsearch.. (you know better).

Thank you

Robert Hanson said...

I'll have to check it out. I have not had a chance to test it too much with the 1.5 release.

Of course, if you happen to have a patch, that would be helpful.

Anonymous said...

Hi Robert,
I am trying to combine my two
(com.companyname.project1 and com.companyname.project2)GWT projects into single (com.companyname.main)GWT project.For that,i put all the source files,html files and xml files into my newly created GWT project at their respective places.Then complied both of them and made sure that com.companyname.project1 and com.companyname.project2 are placed into www/com.companyname.main directory,so that i can access project1.html and project2.html pages when user clicks on respective buttons.

My client code is all good. But when i try to access my server code of project1 through RPC,it gives me error, which is "Resource not found: customer". However i have already included servlet path into my project1.gwt.xml....

It is...
servlet path='/customer' class='com.companyname.server.CustomerSearchServiceImpl'


Any idea whats wrong in here?

Eagerly waiting for appropriate solution...

Thanks!!!!

Ketki said...

Hi Robert,
I am trying to combine my two
(com.companyname.project1 and com.companyname.project2)GWT projects into single (com.companyname.main)GWT project.For that,i put all the source files,html files and xml files into my newly created GWT project at their respective places.Then complied both of them and made sure that com.companyname.project1 and com.companyname.project2 are placed into www/com.companyname.main directory,so that i can access project1.html and project2.html pages when user clicks on respective buttons.

My client code is all good. But when i try to access my server code of project1 through RPC,it gives me error, which is "Resource not found: customer". However i have already included servlet path into my project1.gwt.xml....

It is...
servlet path='/customer' class='com.companyname.server.CustomerSearchServiceImpl'


Any idea whats wrong in here?

Eagerly waiting for appropriate solution...

Thanks!!!!

Mary G said...

Hi Robert, I'm begginer in GWT. I have tested some tutorial examples (including your book, it's very helpful), I have made with Eclipse. I want to create applications implementing rpc, my choice is RequestBuilder; however I don't understand how to implement it on my project, on wich files must be it. Can you help me?, Can you explain me step by step? or Can you give me any complete reference in wich I might find an practice-example and detailed?

Well, I'll wait your response, I'll thank you much, see you soon.

Robert Hanson said...

Ketki, no immediate solution comes to mind, and I unfortunately don't have the time to fire up the IDE and do some investigation. I suggest posting to the dev forum. With 10,000+ GWT developers there, it is likely that someone has seen this before... but if not I am sure that someone can help you.
http://groups.google.com/group/Google-Web-Toolkit

Cheers.

Robert Hanson said...

Mary G, there is a whole chapter or so in the book on that. Should be ch 11 and 12 I think.

You would use RequestBuilder if you wanted to access arbitrary URLs on the server. The URL might be for a static XML file, text file, or PHP/Ruby/Perl script. The JSON chapter in the book shows how you would use RequestBuilder to hit a script on the server (Perl, Ruby, and Java examples provided). There is also an example of using RequestBuilder to access an XML file (and then parse it).

Anonymous said...

Do you have any examples where a collection is used with the typeargs? The book shows how to set up a collection but how to use it. Thanks.

Robert Hanson said...

> Do you have any examples where a
> collection is used with the typeargs?

You mean like this?

@gwt.typeArgs <java.lang.String>

That marks the field as being a Collection of Strings.

smartsr said...

Hi Robert !
I'm a new user of gwt ;-) and I want to know (perhaps by a small example) how to make an uploading of a .xml file.
I have to connect to an external url, get the file. xml and to parse the xml files.
I tried to do with a HTTPRequest but give me error!
thanks very much!

Robert Hanson said...

Hi smartsr. You have the steps right, that is how you do it. If you haven't already done so, you should post your question on the GWT Dev forum, along with a lot more detail, like the exact error you are getting and a small code example.
http://groups.google.com/group/Google-Web-Toolkit

Anonymous said...

There is a good article on GWT and good elaboration on JSNI http://xblog.chiradip.com/2008/01/weekend-with-gtw-and-javascript.html

Mary G said...

Hello again Robert!

I have tried to work with RequestBuilder; I have imported a project on Eclipse, I'm working with Tomcat v6.0; I don't see troubles on compile-time, however on run-time, there a message: "unable to find the resource: [name of my servlet] ". Why?, I don't understand!. I believe that I'm don't entering the correct url in builder RequestBuilder, any suggestion please soon!.

Robert Hanson said...

Mary, if you aren't already running Firefox 2 (not 3) with the Firebug plugin, start there. Firebug is a standard tool used by a lot of web developers. One of the features of the tool is to show you all requests initiated by the browser and the result from the server.

The reason I mention that tool is because it sounds like you don't know if the request is being made at all, or if it is requesting the wrong URL, or if the returned data is bad. Firebug will help you sort all of that out.

If you really don't want to use Firebug (hard to imagine and not recommended), you could always use a network sniffer. These are harder to use than Firebug, but some in handy every once in awhile. I use WireShark.

In my experience I start with Firebug, but if the problem only exists in IE or is some other issue that Firebug can't detect, then I fall back on WireShark.

That being said, the usual cause is that the URL is not correct. Sometimes it is the servlet mapping, other times it is the GWT code. In both cases Firebug is invaluable.

oygan said...

Hi
I am very new at trying to use extJS+GWT to write a webapplication.

I am using GWT1.5 and eclipse.

App.gwt.xml contain mapping:
..servlet path="/storageservice" class="demo.app.server.StorageServiceImpl"/..

I have the following problem:
[ERROR] Unable to instantiate 'demo.app.server.StorageServiceImpl'
java.lang.ClassNotFoundException: demo.app.server.StorageServiceImpl at ...GWTShellServlet.tryGetOrLoadServlet(..)
at ...GWTShellServlet.service(..)
at ...service(HttpServlet.java:802)

All help is much appreciated Thanks

Robert Hanson said...

oygan, double check you classpath, the problem is surely there. Just a wild guess, but for servlets they MUST be pre-compiled, and the .class file MUST be in the classpath. It is not sufficient to only have the .java file in the classpath.

Adriano said...

Hi Robert, i am with a problems. I create a project with projectcrator, application with applicationcreator. OK. After, I followed a steps in your blog and my project is compiled sucessfully. BUT when I test in browser (firefox) a error message is showed to me. My service implemented is ot found. I included this service in xml file in root project folder. Please help me. Thanks.

Geethan said...

Hi, Thanks for sharing this.

I found the following tutorial also useful in developing a GWT app with servlets. It goes end-to-end for a newbie.

http://lkamal.blogspot.com/2008/09/java-gwt-servlets-web-app-tutorial.html

Cheers,
Geethan

Robert Hanson said...

Adriano,

First, you will get much more help if you post your questions on the GWT-Dev forum http://groups.google.com/group/Google-Web-Toolkit)

Second, you were not clear on how the servlet was deployed. Are you running the hosted browser or a servlet container? If it runs in the hosted browser, then it should work just fine when you click the "Compile/Browse" button. If you have deployed the app to Tomcat, then you should probably install the Firebug plugin for FF and verify that the browser is hitting the right URL.

Surendra said...

Hi there,
I see that you had managed to integrate GWT with Struts. I have a question on this though. For now I'm trying to do a simple integration where when from one page, when I click a link, an Action is performed and the resulting page, shall contain the GWT code for logic on that page. Since I wrote the page using GWT (a simple page with one Label in it) after the Struts action forwards me to this page, the javascript isn't automatically invoked. however when i go to the url of the GWT page directly, the javascript gets automatically executed. I know that the page is being retrieved because the title of the page and the source code all show the HTML we write in the GWT page. Any ideas on how to change this. Having a redirect is not an option because I'm using tiles and need the request context information to generate the tiles content.

Robert Hanson said...

Surendra, my guess is that the Struts-hit URL is a different than the direct-hit URL... and what is likely happening is that the JS code isn't getting loaded because your path is incorrect.

If you use Firefox (all web developers should), you can use the Firebug plugin to see what files is getting loaded and which aren't.

If you find that the JS file is being loaded, then check the contents of it. I had an issue once where the file looked like it was being loaded, but was actually being modified by a security filter I had in place.

gwt sample said...

sample project using gwt
http://gwt-sample-project.blogspot.com

santu said...

hi Robert

this is santosh,
i got a job on java platform, so here im working on eclipse environment
also im using GOOGLE WEB TOOLKIT ..

but im facing difficulty in understanding the concept of GWT.

gimme the guidelines how to start my carrer in GWT ... plsss

so pls wil u suggest me the best GWT book


im ready to pay for tat !!!!

Robert Hanson said...

If you buy a book, make sure that it covers GWT 2.x. GWT in Action does not currently fall into that category, but we are working on a second edition. As long as you already know Java it should be easy enough. ...And if you don't know Java, you should get an introductory book and at least learn the basics.

ashwini said...

Hi Robert..
I am new to GWT, as I tried to run a program i'm getting this error, i tried to debug but could'n...the error is ,,Unable to find 'com/anrc/nco/guiapp/client/NcoGUI.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?

what is the cause for it..??

Robert Hanson said...

@ashwini my number one suggestion would be to use Eclipse along with the Google Plugin for Eclipse (http://code.google.com/webtoolkit/download.html). I would do this even if you aren't currently an Eclipse user.

With that you can go to use the Web Application Project wizard to create a working sample project (including GWT-RPC).

GWT 2.0 uses a layout different from this article and GWT 2.0 now makes use of annotations, so expect some differences from this article (although the concepts have not changed).

The sample app the Google Eclipse Plugin creates is ok if you want a sample, but if you want a fresh project ends up being a lot of junk. So you might also want to install the GWT Designer plugin for Eclipse (same download page as the other one). It has a slick GUI designer, but even without that it has it's own new project wizards that don't create a lot of unnecessary files.

Good luck.

Yuriy said...

Problem: Loading modules src.main.java.com.google.gwt.sample.expenses.Expenses [ERROR] Unable to find 'src/main/java/com/google/gwt/sample/expenses/Expenses.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source? [ERROR] shell failed in doStartup method

Solution:
http://stackoverflow.com/questions/7401081/gwt-compiler-cant-find-gwt-xml

Comment:
Delete ald run configuration and create new.

Anonymous said...

Thanks...this was helpful..for understanding the flow..

mostafa kamal said...

com.google.gwt.user.client.rpc.StatusCodeException: 404
HTTP ERROR 404

Problem accessing /myapplication/myService. Reason:

NOT_FOUND

Robert Hanson said...

This is a very old post ... it may need some tweaking due to changes.

Did you check out the Chapter 10 from GWT in Action (v1)?

http://www.manning-source.com/books/hanson/sample-ch10_GWTiA.pdf

That is newer than this article and more complete, but it is still a few years old now.