My favorites | Sign in
Project Home Wiki Issues Source
Search
for
GWTGrailsTutorial  

Featured
Updated Nov 16, 2009 by jan.ehrhardt

A tutorial showing how do develop a Grails application with a GWT UI.

Google Group

There's a Google Group (http://groups.google.com/group/grails-gwt) for discussion and help around Grails and GWT. Please ask your questions there instead of writing comments below.

Prepare your system

The first step is to set up your system for running Grails and the GWT. You will also need to create a new Grails application with the command

grails create-app GwtTutorial

Installing the Grails GWT plugin with the command

grails install-plugin gwt

is required too.

This tutorial uses Grails 1.0.3, GWT 1.4 and GWT plugin 0.2.4. It will be upgraded in the future to new versions, if available. General information on Grail GWT plugin can be found here: http://grails.org/GWT+Plugin.

You can even check out the code from Mercurial repository with

hg clone -r 1.0.0 http://derjanandhisblog.googlecode.com/hg GwtGrailsTutorial

or browse the code online http://code.google.com/p/derjanandhisblog/source/browse?r=1.0.0#hg/GwtTutorial. Of cause the code is free and thus you can use it.

Creating your domain model

We want create a book store application and our domain model needs two domain classes Book and Author. You should know, how to create domain classes in Grails, else read the User-Guide.

Edit them like the following:

Book:

class Book {
	
	String title
	
	static belongsTo = [author: Author]

}

Author:

class Author {
	
	String firstName
	String lastName
	
	static hasMany = [books: Book]
	
	static constraints = {
		books(nullable: true)
	}

}

These model is very simple, but contains some of the cool features Grails offers. A Book belongs to an Author and an Author can have more than one Book, but can also have no Books, if he is just writing his first. We should also have some default data in our database during development so you should edit the BootStrap.groovy file like this:

BootStrap:

class BootStrap {

     def init = { servletContext ->
     	
     	def author1 = new Author(firstName: "Jan", lastName: "Ehrhardt")
     	def book1 = new Book(title: "GwtTutorial")
     	author1.addToBooks(book1)
     	
     	author1.save()
     	
     }
     def destroy = {
     }
} 

Ok, this isn't a real book, but it's just for development ;-)

Creating a service for GWT client

After having a domain model and some development data, we will need a middle tire. Unlike a classic Grails application, we don't need controllers and GSP views. The GWT brings all this stuff to the richer GWT client, which runs in the browser. Thus we only need a service, which gets our data from the database and brings it to the browser using GWT RPC mechanism. For this we need to put a static property called "expose" to our service and the GWT plugin will start to create automatically the Java interfaces needed by the GWT client to access the service. Another problem is, that the GWT allows us to create a client application, which has a design according to MVC-Pattern, thus it would be great, if we could serialize our domain model directly and reuse it as a model in the GWT client. Unfortunately, this isn't possible yet. But a cool way to solve this problem is using JSON. GWT provides client side support for JSON and Grails provides server side support for domain serialzation to JSON. So we can use a JSON based model in client and use domain class serialization on the server. Our BookService should look like this:

BookService:

class BookService {

    boolean transactional = true

    static expose = ["gwt:org.grails.gwttutorial.client"]
    
    String getAuthor(int id) {
    	def author = Author.get(id)
    	return author.encodeAsJSON()
    }
    
}

You can see, that the "expose" property points the GWT plugin to "org.grails.gwttutorial.client", which is the the package, where the service interfaces shall be placed, when the plugin generates them. Currently, we didn't create it, but soon we'll. There is just one method so far, which does nothing else than getting an Author from the database and sending it to the client, encoded as JSON. The method for encoding is provided by Grails as a standard.

The GWT client

For creating our client, you should run the following commands:

grails create-gwt-module org.grails.gwttutorial.Application
grails create-gwt-page bookStore/index.gsp org.grails.gwttutorial.Application

The second one will prompt you, if you want to create the Controller BookStore. You should accept this by typing "y" and don't care any longer about this (this controller is needed, to return the GSP, we just create him, nothing else). Now edit the bookStore/index.gsp page:

index.gsp:

<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
  		<title>Book Store</title>
  		<script type="text/javascript" src="${createLinkTo(dir: 'gwt/org.grails.gwttutorial.Application', file: 'org.grails.gwttutorial.Application.nocache.js')}"></script>
	</head>
	<body>
  		<iframe id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
  		<div id="bookStoreContainer"></div>
	</body>
</html>

Than open the file org.grails.gwttutorial.Application.gwt.xml in the src/java directory and edit it like this:

Application.gwt.xml:

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

    <!-- Inherit the client side JSON handling. -->
    <inherits name='com.google.gwt.json.JSON'/>
        
    <!-- Specify the module entry point class. -->
    <entry-point class="org.grails.gwttutorial.client.Application"/>
</module>

This brings the JSON modul to our GWT client (If you're using Eclipse, you shall additionally put your GWT_HOME directory to the projects classpath, else you'll get some trouble with the Java editor). Further more copy the gwt-user.jar from GWT_HOME to the lib directory of your Grails project. This is a good moment for running our app first time ("grails run-app" command ;-)). While starting the GWT plugin hooks into the build process and generates the service interfaces, we'll need for RPC calls (and for the Eclipse editor, during editing of the Application.java). If everythig works, let's start creating the client. Currently it shouldn't be a real store. It only shows the one existing Author from the database in a tree view ;-), but hopefully the next version of the sample application will do more. Here is the code:

Application.java

public class Application implements EntryPoint {
        
    private BookServiceAsync bookService;
        
    private Tree tree;
        
    public void onModuleLoad() {
        
        tree = new Tree();
        
        bookService = (BookServiceAsync) GWT.create(BookService.class);
        ServiceDefTarget endpoint = (ServiceDefTarget) bookService;
        String moduleRelativeUrl = GWT.getModuleBaseURL() + "rpc";
        endpoint.setServiceEntryPoint(moduleRelativeUrl);
        
        bookService.getAuthor(1, new AsyncCallback() {

                        public void onFailure(Throwable arg0) {
                                
                        }

                        public void onSuccess(Object author) {
                                
                                JSONValue value = JSONParser.parse((String)author);
                                tree.removeItems();
                                tree.setVisible(true);
                                TreeItem item = tree.addItem("Response");
                                addChildren(item, value);
                                
                        }
                
        });
        
        RootPanel panel = RootPanel.get("bookStoreContainer");
        if(panel != null) {
                panel.add(tree);
        }
        
    }
    
    private void addChildren(TreeItem treeItem, JSONValue jsonValue) {
        JSONArray jsonArray;
        JSONObject jsonObject;
        JSONString jsonString;

        if ((jsonArray = jsonValue.isArray()) != null) {
          for (int i = 0; i < jsonArray.size(); ++i) {
            TreeItem child = treeItem.addItem(getChildText("[" + Integer.toString(i) + "]"));
            addChildren(child, jsonArray.get(i));
          }
        } else if ((jsonObject = jsonValue.isObject()) != null) {
          Set keys = jsonObject.keySet();
          for (Iterator iter = keys.iterator(); iter.hasNext();) {
            String key = (String) iter.next();
            TreeItem child = treeItem.addItem(getChildText(key));
            addChildren(child, jsonObject.get(key));
          }
        } else if ((jsonString = jsonValue.isString()) != null) {
          treeItem.addItem(jsonString.stringValue());
        } else {
          treeItem.addItem(getChildText(jsonValue.toString()));
        }
        }
    
    private String getChildText(String text) {
        return "<span style='white-space:normal'>" + text + "</span>";
    }
    
}

So what is this code doing? Well, nothing else, the creating a Tree, hookink the Tree into the page, calling our RPC method for the Author with id 1, parsing the result with a JSON parser and putting the values into the Tree. That's all. Now start the Grails application again and run the command:

grails run-gwt-client

This should open the GWT client and allows you to see the result. Another command

grails compile-gwt-modules

will compile your GWT code to JavaScript. This allows you to see it in a real browser (not Firefox 3 RC2 on my Mac but maybee on yours).

Additional notes

This is just a very basic tutorial and hopefully it will be extended in the next weeks and months and when new releases are available and so on. If you want to be informed about new versions, start reading my blog http://derjanandhisblog.blogspot.com, where updates will be announced.

License

The content of this page is under a Creative-Commons-License, so reuse it :-)

Comment by goo...@theavspot.com, Jun 18, 2008

Thanks

Comment by dchi...@gmail.com, Jun 27, 2008

Good tutorial. Thanks!

Comment by george.b...@gmail.com, Jul 4, 2008

I went this tutorial, but when i'm running, i receive this follow error: ERROR? Unable to find 'GwtTutorial?.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?

my gwt version is 1.4.x

tks

Comment by tuomas.k...@gmail.com, Jul 12, 2008

Thanks about your tutorial, it helps a lot!

With jdk 6/gwt 1.4.x (latest)/grails 1.0.3 works fine, except that books did not load at all within the tree. Until I changed little bit the service code to get all sended to the browser:

1. option, when you will send all books of an author:

import grails.converters.JSON class BookService? {

boolean transactional = true static expose = ["gwt:org.grails.gwttutorial.client"] String getAuthor(int id) {
def author = Author.get(id) author.books?.size() //def value = author as JSON // grails.converters.deep.JSON println value // to show what is an output return value // author.encodeAsJSON()
} def test(p) { }
}

2. option, when you will send only keys of books:

class Book {

String title
static belongsTo = [author: Author] static fetchMode = [author:"eager"]
}

class Author {

String firstName String lastName static hasMany = [books: Book] static constraints = {
books(nullable: true)
} static fetchMode = [books:"eager"]
}

class BookService? {

boolean transactional = true static expose = ["gwt:org.grails.gwttutorial.client"] String getAuthor(int id) {
def author = Author.get(id)
//author.books?.size() def value = author as JSON // grails.converters.deep.JSON println value // to show what is an output return value // author.encodeAsJSON()
} ...
}

Tk

Comment by Benjamin...@gmail.com, Aug 6, 2008

Missing lines at the begin of Application.java:

package org.grails.gwttutorial.client;

import com.google.gwt.core.client.;

import com.google.gwt.user.client.ui.;

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

import com.google.gwt.json.client.;

import java.util.HashSet?;

import java.util.Set;

import java.util.Iterator;

Comment by unebelle...@gmail.com, Aug 12, 2008

Here are the three commands you need at the beginning of this tutorial, be careful to the case of each parameter:

grails create-domain-class Author
grails create-domain-class Book
grails create-service book
Comment by zhqren@gmail.com, Aug 28, 2008

It's no easy.

Comment by elsch...@gmail.com, Sep 2, 2008

In case you are running into some kind of

'Exception while dispatching incoming RPC call javax.servlet.ServletException?: Content-Type must be 'text/x-gwt-rpc'' or ' Exception while dispatching incoming RPC call javax.servlet.ServletException?: Content-Type must be 'text/plain''

Exception - this is because you have different GWT versions on your machine the changed the content-type to 'text/x-get-rpc' in version 1.5 so depending on the message you either want to upgrade your gwt installation or the grails gwtlib.

Comment by chu...@gmail.com, Sep 23, 2008

I just verbatim the instruction above. And for some reason I am getting errors on BookServiceAsync? which I know I didn't create. So is there some assumption that GWT or Grails will create certain classes for you that is Async? I know the definition and syntax for grails works, just the portion where JSON is brought in is where things got confusing.

Comment by casey.wa...@gmail.com, Oct 28, 2008

I keep getting the following error:

com.google.gwt.user.server.rpc.UnexpectedException?: Service method 'public abstract java.lang.String org.grails.gwttutorial.client.BookService?.getAuthor(java.lang.Integer)' threw an unexpected exception: groovy.lang.MissingMethodException?: No signature of method: BookService?.getAuthor() is applicable for argument types: (java.lang.Integer) values: {1}

Any help would be great.

CW

Comment by mittipro...@gmail.com, Jan 7, 2009

I wonder what exactly you mean by:

"if we could serialize our domain model directly and reuse it as a model in the GWT client."

Comment by mittipro...@gmail.com, Jan 7, 2009

one tiny spelling mistake:

"middle tire"

in an otherwise nice tutorial.

Thanks !

Comment by john.san...@gmail.com, Jan 30, 2009

Thanks for this tutorial. People with little experience in Grails might take advantage of this document. ;-)

Comment by RussianS...@gmail.com, Feb 11, 2009

Just a few comments because it wasn't too clear:

After you create groovy service, run 'grails run-app', and the compiler will create Java versions of BookService? and BookServiceAsync? for you. Then you can update Application class using BookService? & BookServiceAsync? classes as they will be generated in the src/java folder of your Grails projet.

Comment by brian.bo...@paraware.com, Mar 17, 2009

Jan, does this tutorial really work?? I've tried going through it and I noticed that the instructions are different from the code here: http://code.google.com/p/derjanandhisblog/source/browse/trunk/GwtTutorial/src/java/org/grails/gwttutorial/client/BookService.java?r=15

e.g. The BookService? is a java class in SVN, but it's a Groovy class in the tutorial above. The BookServiceAsync? isn't created anywhere up above, but it's in SVN.

I tried including the code from SVN and running it and received:

C:\work\workspace\GwtTutorial?>grails run-gwt-client Welcome to Grails 1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: c:\grails-1.1

Base Directory: C:\work\workspace\GwtTutorial? Running script C:\Documents and Settings\BBonner\.grails\1.1\projects\GwtTutoria? l\plugins\gwt-0.3-SNAPSHOT\scripts\RunGwtClient?.groovy Environment set to development Warning, target causing name overwriting of name default

java? WARNING: 'com.google.gwt.dev.GWTShell' is deprecated and will be rem
oved in a future release.
java? Use 'com.google.gwt.dev.HostedMode?' instead.
C:\work\workspace\GwtTutorial?>grails run-gwt-client Welcome to Grails 1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: c:\grails-1.1

Base Directory: C:\work\workspace\GwtTutorial? Running script C:\Documents and Settings\BBonner\.grails\1.1\projects\GwtTutoria? l\plugins\gwt-0.3-SNAPSHOT\scripts\RunGwtClient?.groovy Environment set to development Warning, target causing name overwriting of name default

java? WARNING: 'com.google.gwt.dev.GWTShell' is deprecated and will be rem
oved in a future release.
java? Use 'com.google.gwt.dev.HostedMode?' instead.

Any thoughts???

Comment by jay.k...@gmail.com, Mar 22, 2009

Good tutorial, only a little outdated by now it feels. I'm trying to get this running on my macbook with the following setup:

java 1.5.0_16 gwt mac-1.5.3 grails 1.1 grails gwt plugin 0.3-snapshot

Everything seems to be working fine but when I run the app nothing is rendered on http://localhost:8080/GwtTutorial/bookStore/index except for the grails logo. I actually have a feeling like my GWT java code actually doesn't execute because when trying to debug it in Eclipse it never stops at my breakpoints.

I have a feeling like I'm close but something conflicts in my setup. Another hint is that when I'm running "grails compile-gwt-modules" to generate javascript I get the following stack trace:

     [echo] Compiling GWT modules
     [echo] Module: org.grails.gwttutorial.Application
     [java] Compiling module org.grails.gwttutorial.Application
     [java] Scanning for additional dependencies: file:/Users/username/dev/grails/GwtTutorial/src/java/org/grails/gwttutorial/client/Application.java
     [java]    Computing all possible rebind results for 'org.grails.gwttutorial.client.BookService'
     [java]       Rebinding org.grails.gwttutorial.client.BookService
     [java]          Invoking <generate-with class='com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator'/>
     [java]             Generating client proxy for remote service interface 'org.grails.gwttutorial.client.BookService'
     [java]                Analyzing 'org.grails.gwttutorial.client.BookService' for serializable types
     [java]                   Analyzing methods:
     [java]                      public abstract java.lang.Object super$1$clone()
     [java]                         Return type: java.lang.Object
     [java]                            java.lang.Object
     [java]                               [ERROR] In order to produce smaller client-side code, 'Object' is not allowed; consider using a more specific type
     [java]                      public abstract java.lang.Class super$1$getClass()
     [java]                         Return type: java.lang.Class
     [java]                            java.lang.Class
     [java]                               [ERROR] Type 'java.lang.Class' was not serializable and has no concrete serializable subtypes
     [java] [ERROR] Errors in 'file:/Users/username/dev/grails/GwtTutorial/src/java/org/grails/gwttutorial/client/Application.java'
     [java]    [ERROR] Line 29:  Failed to resolve 'org.grails.gwttutorial.client.BookService' via deferred binding
     [java] [ERROR] Cannot proceed due to previous errors
     [java] [ERROR] Build failed
     [java] Java Result: 1

Anybody out there who can point me in the right direction?

Comment by m.c...@gmx.net, Mar 30, 2009

I ran into the same issue as jay.kirc - anyone an idea how to solve that?

Comment by aless...@gmail.com, Apr 2, 2009

@Jay.kirc, m.c...@gmx.net Hi, the issue is caused by some of the methods the plugin creates during client-side service stub generation. If you examine BookService? you'll find a bunch of "super$xxxx$nnn" that are generated through reflection and can be safely deleted (you'll lose plugin auto-synchronization, but...)

HTH, Alessio

Comment by der...@gmail.com, Apr 3, 2009

Wow, thanks Ale that really worked. I hadn't seen that generated code in my eclipse, or I would've tried. Anyway, i guess the only two methods that you really need to delete are clone() and getClass() inherited from Object, since they return something other than void.

But, there has to be a better way to do this, since this is going to happen with any class generated since they all inherit from Object. Can't the stubGen just ignore those two methods from Obj? I don't wanna loose auto-sync for all classes in my complete project just because of this...

Comment by der...@gmail.com, Apr 3, 2009

So, it seems that the problem lies in this one line: boolean transactional = true And since, at least according to the grails docu, services are transactional by default, do we really need that there?

I introduced that to the other sample project that I found and had worked (http://www.spenceruresk.com/2008/06/15/grails-gwt-with-gwt-ext-googlemaps-maxmind-sample-application/) and recompiled which then added all the super1$xx$nn functions to the code. Lost my auto-sync with that, too, but oh well...

Comment by jay.k...@gmail.com, Apr 4, 2009

@alessios Sweet, thanks so much man! I already tried removing the 2 methods working with Object directly but that apparently wasn't enough. After your hint I removed all the super invocations and it's working like a charm! Awesome!

Comment by alanole...@gmail.com, Apr 8, 2009

@mittiprovence

If this pluging was combined with features from Gilead (used to be Hibernate4GWT) http://noon.gilead.free.fr/gilead/ it would be extreemly powerful as the domain objects (which typically come across implementing Serializable) can be transparently converted to GWT friendly objects...

Comment by mslimo...@gmail.com, Apr 10, 2009

How would I add another module? In this case, I want to use "Google AJAX Search library for GWT" from my main module. In my main gwt.xml, I've included an <inherits...> statement for the module that I want to add.

But when I do grails compile-gwt-modules, I get an exception: ERROR? Unable to find 'com/google/gwt/search/Search.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?

So, how do I add the jar to my classpath for compiling?

I did copy it to the /lib directory. But that didn't help.

Comment by mslimo...@gmail.com, Apr 10, 2009

Found an answer to my classpath question above.

The jar (gwt-search.jar, in my case) needs to be in lib/gwt/

Comment by sphinxdw...@gmail.com, Apr 29, 2009

@jay.kirc But it report: Resource not found: rpc; (could a file be missing from the public path or a <servlet> tag misconfigured in module net.openonlinejudge.web.gwt.Admin.gwt.xml ?)

Comment by RichardH...@gmail.com, May 18, 2009

It seems you left off a step. You forgot to mention generating the async interface, namely,

generate-gwt-rpc

Comment by timoblec...@gmail.com, Jul 24, 2009

Great Tutorial. I still have a problem with the gwt-user.jar - where do i have to place it, so that the gwt client finds it. I wanted to look at the Repository (http://code.google.com/p/derjanandhisblog/source/browse) - but i m only getting 404 s and the message "No files in this directory." Thanks for your help in advance. Bye

Comment by project member jan.ehrhardt, Jul 24, 2009

The source code should be available again.

Comment by iamjohnw...@gmail.com, Jul 26, 2009

I get an error installing the plugin:

Welcome to Grails 1.1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: /opt/grails-1.1.1

Base Directory: /Users/jwalsh/Dev/hnny/nb/Enrollment Running script /opt/grails-1.1.1/scripts/InstallPlugin?.groovy Environment set to development Reading remote plugin list ... Reading remote plugin list ...

get? Getting: http://plugins.grails.org/grails-gwt/tags/RELEASE_0_4-SNAPSHOT/grails-gwt-0.4-SNAPSHOT.zip get? To: /Users/jwalsh/.grails/1.1.1/plugins/grails-gwt-0.4-SNAPSHOT.zip get? local file date : Fri Jul 24 05:53:07 EDT 2009 get? Not modified - so not downloaded
copy? Copying 1 file to /Users/jwalsh/.grails/1.1.1/projects/Enrollment/plugins
Installing plug-in gwt-0.4-SNAPSHOT
mkdir? Created dir: /Users/jwalsh/.grails/1.1.1/projects/Enrollment/plugins/gwt-0.4-SNAPSHOT unzip? Expanding: /Users/jwalsh/.grails/1.1.1/plugins/grails-gwt-0.4-SNAPSHOT.zip into /Users/jwalsh/.grails/1.1.1/projects/Enrollment/plugins/gwt-0.4-SNAPSHOT
Executing gwt-0.4-SNAPSHOT plugin post-install script ...
mkdir? Created dir: /Users/jwalsh/Dev/hnny/nb/Enrollment/web-app/gwt
Plugin gwt-0.4-SNAPSHOT installed Plug-in provides the following new scripts:
grails clean-gwt-modules grails compile-gwt-modules grails compile-i18n grails create-gwt-module grails create-gwt-page grails generate-gwt-rpc grails run-gwt-client Found events script in plugin gwt java.lang.NullPointerException?
at java.io.File.<init>(File.java:194) at GwtInternal?_groovy.run(GwtInternal?_groovy:43) at GwtInternal?_groovy$run.call(Unknown Source) at PackagePlugins?_groovy$run.call(Unknown Source) at Events.run(Events.groovy:1) at PluginDependencies?_groovy$run_closure26.doCall(PluginDependencies?_groovy:964) at PluginDependencies?_groovy$run_closure26.call(PluginDependencies?_groovy) at GrailsPlugins?_groovy.completePluginInstall(GrailsPlugins?_groovy:80) at GrailsPlugins?_groovy.this$4$completePluginInstall(GrailsPlugins?_groovy) at GrailsPlugins?_groovy$this$4$completePluginInstall.callCurrent(Unknown Source) at GrailsPlugins?_groovy.withPluginInstall(GrailsPlugins?_groovy:68) at GrailsPlugins?_groovy.this$4$withPluginInstall(GrailsPlugins?_groovy) at GrailsPlugins?_groovy$run_closure4.doCall(GrailsPlugins?_groovy:60) at GrailsPlugins?_groovy$run_closure4.call(GrailsPlugins?_groovy) at GrailsPlugins?_groovy$run_closure5.doCall(GrailsPlugins?_groovy:110) at gant.Gant$dispatch_closure4.doCall(Gant.groovy:324) at gant.Gant$dispatch_closure6.doCall(Gant.groovy:334) at gant.Gant$dispatch_closure6.doCall(Gant.groovy) at gant.Gant.withBuildListeners(Gant.groovy:344) at gant.Gant.this$2$withBuildListeners(Gant.groovy) at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source) at gant.Gant.dispatch(Gant.groovy:334) at gant.Gant.this$2$dispatch(Gant.groovy) at gant.Gant.invokeMethod(Gant.groovy) at gant.Gant.processTargets(Gant.groovy:495) at gant.Gant.processTargets(Gant.groovy:480)
Error loading event script from file [/Users/jwalsh/.grails/1.1.1/projects/Enrollment/plugins/gwt-0.4-SNAPSHOT/scripts/Events.groovy] null

Any ideas?

Comment by omsrob...@gmail.com, Aug 5, 2009

I am trying to understand how Grails handles GWT-RPC services in more depth.

The most important question I have is: What does the "static expose" do exactly? Is it the name of the service implementation class or the interface?

Additionally:

Under $MY_GRAILS_APP/grails-app, there is a services directory. I can put the IMPLEMENTATION of my GWT-RPC services there in either Groovy or Java, right? Can I put those classes in a package? Can I freely mix and match Groovy/Java?

Then under $MY_GRAILS_APP/src, there are three directories: groovy, gwt and java. The "service" interface and the "async" interface go under which directory? Can I put them in a package? It seems that the server code has to share these with the client code. What are the rules around that?

Are some of these interfaces automatically generated?

Comment by p.ledbr...@gmail.com, Sep 2, 2009

@omsrobert "static expose = 'gwt' " simply marks a service as accessible via GWT-RPC. The service itself should implement the client-side service interface (not the async one). You can also append a package after 'gwt', for example 'gwt:org.example.client'. The package just tells the plugin which package the generated service interfaces should go in.

Note that the interface generation is no longer automatic. You need to call "grails generate-gwt-rpc".

The service implementation should be Groovy if it goes in the "grails-app/services" directory. You can put it in a package, and that is definitely recommended. Java code should only go under "src/java".

The service interfaces (async included) go under "src/java". The module and client-only code, i.e. the UI stuff, go under "src/gwt". Anything shared between the server and client should go under "src/java". Any classes can be put in a package.

Comment by project member jan.ehrhardt, Sep 2, 2009

Currently I'm rewriting the tutorial. More on this soon.

Comment by alphat...@gmail.com, Sep 30, 2009

Note: after creating the BookService? (with GWT Application.java still empty), you must run:

$ grails generate-gwt-rpc

Otherwise BookServiceAsync? and stubs will not be created

Comment by dennis.b...@gmail.com, Nov 1, 2009

Was wondering if anyone got the 0.4.1 gwt-plugin working with GWT 1.71 on Snow Leopard? I get: Starting the GWT hosted mode client. ...

java? You must use a 32-bit Java runtime to run GWT Hosted Mode. java? Leopard: Use the Java 1.5 runtime. java? Snow Leopard: Use the Java 1.6 runtime and add the -d32 flag. java? Java Result: 1
Was not sure where to add the flag for the plug-in?

Thanks!

Comment by victor.b...@gmail.com, Nov 18, 2009

Could you confirm this plugin really work ? {gwt-windows-1.7.1 + grails 1.1.1 + gwt 0.4.1} I spend hour on Linux or Windows to tests it. In the past, it was working fine. I've done the tutorial several times but it doesn't work at all. Please, could you update your code in the repository.

Thanks

Comment by project member jan.ehrhardt, Nov 18, 2009

I'm currently rewriting the tutorial. The code for the new version has been moved to github (http://github.com/derjan1982/grails-gwt-tutorial). The code there runs with GWT 1.7.1 (Mac), Grails 1.1.1 and a current snapshot of the plugin. Since the new version makes use of some 0.5 features of the plugin, it won't be tested with 0.4.1. I hope the next version will be release soon. There is also a Google Group for GWT / Grails topics, which should be your prefered way to ask such questions (http://groups.google.com/group/grails-gwt).

Comment by jvm...@gmail.com, Nov 19, 2009

I'm little bit confuse because I've strange settings path error in my Window bug. if you're interested, I could provide you an example of GWT plugin usage. As soon as, my job has been done. Thanks you for your answer, nice job. (same account as victor.benarbia)

Comment by likwong...@gmail.com, Dec 14, 2009

"java? You must use a 32-bit Java runtime to run GWT Hosted Mode. java? Leopard: Use the Java 1.5 runtime. java? Snow Leopard: Use the Java 1.6 runtime and add the -d32 flag. java? Java Result: 1"

An issue have been logged for this: http://jira.codehaus.org/browse/GRAILSPLUGINS-1679

I simply modify the /scripts/GwtInternal?.groovy to add the -d32 flag myself as a work around at the moment.

Comment by kumar.je...@gmail.com, Jan 5, 2012

I followed all the steps in your article. But the application is not running in hosted mode. I need to run the grails compile-gwt-modules then run the gwt-client command to see the result. Is the plugin updated for grails 2.0 and gwt2.4.

Comment by jonrowla...@gmail.com, Feb 12, 2012

Thanks for this guide. It helped me get started using grails 2.0 and gwt 2.4.


Sign in to add a comment
Powered by Google Project Hosting