Let's have a look at what makes mixture of Grails and Vaadin so great tool that one should use it.
Vaadin - first of all, this is awesome framework combining server and client side approach. We can make RIA just in plain Java without touching JavaScript, HTML or CSS. This is nice showcase. If you want to, you can add there your HTML, CSS or JavaScript and change default look & feel and behavior.
Grails - another framework which is setting quite high standarts for development of Java based applications. Grails gives us:
- Command line scripting environment built on the Groovy-powered Gant
- Object Relational Mapping layer built on Hibernate (GORM)
- View layer in Groovy Server Pages
- Controller layer built on Spring MVC
- Embedded Tomcat container which is configured for on the fly reloading
- Dependency injection with the inbuilt Spring container
- Support for internationalization (i18n) built on Spring's core MessageSource concept
- Transactional service layer built on Spring's transaction abstraction
We don't need these two features of Grails - "View layer in Groovy Server Pages" and "Controller layer built on Spring MVC" when using Vaadin. Both of these features are replaced by Vaadin components and listener pattern.
Let's have a look at how the remaining features are used together with Vaadin and how to benefit from that.
Let's have a look at how the remaining features are used together with Vaadin and how to benefit from that.
Command line (Gant)
This is awesome, we can...
- run application or tests in different environments simply just by typing dev run-app or test run-app or test test-app. So we can use different databases, test data or whatever we want to in certain stages of development process.
- make a production package with the following command prod run-app
Tomcat
Well, we just change a code, save the files, refresh a page and that is it. No server restarts needed. We can see the changes immediately.
Also, tomcat is provided as a grails plugin. So when we want to upgrade a new version of tomcat, we just upgrade the plugin and the compatibility with grails comes really easily.
Internationalization
There is i18n() method available in all Vaadin classes which makes localization pretty easy. We just type i18n("app.title") in your Vaadin code.
Then you should create a record in i18n properties files.
And we are done. Just start the application by typing dev run-app into the command line or refresh the page in case your application is already running.
If the message doesn't exist the key in square brackets is returned (e.g. [app.title]). It is pretty useful when you don't want to make localizations immediately when producing a code.
GORM (Grails ORM)
I have mentioned how to setup working Grails & Vaadin application with access to database in this post. We can use all the GORM features without limitations.
Transactional service layer (Services)
What is this service layer about? Grails services should contain logic of the application, which means that the logic should not be placed in Vaadin code (e.g. listeners). We also get transactional behavior inside our services. Grails services are providing quite many features, please study that from official tutorial.
It is as easy as to create a persistent domain class. Let's just create a service for a user (called helloworld.UserService).
It might happen that we don't see services folder in eclipse. If that is the case, we have to add it...
Let's implement our new service:
It is as easy as to create a persistent domain class. Let's just create a service for a user (called helloworld.UserService).
It might happen that we don't see services folder in eclipse. If that is the case, we have to add it...
Let's implement our new service:
class UserService {
static transactional = true
void update(User user) {
// TODO: ... implement the logic ...
user.save(flush:true, failOnError:true)
}
}
So, everything is ready and we can get and use the service in Vaadin code. Let's rename all the users to Joshua.
class HelloWorldApplication extends Application {
@Override
public void init() {
Window w = new Window("Hello world!")
w.addComponent(new Label(i18n("app.title")))
List<User> users = User.list()
for(User u : users) {
u.name = "Joshua"
getBean(UserService).update(u)
w.addComponent(new Label(u.getName()))
}
setMainWindow(w)
}
}
Dependency injection
There is a special method getBean() provided by Grails Vaadin plugin. This method is accessible in all the Vaadin classes (assuming they are located in grails-app/vaadin).
getBean() method gets a dependency from the Spring ApplicationContext. Obtaining the references is extremely fast and serialization-safe because the references are cached and Spring takes care abou that.
Well, how to use it in practice? We have to call getBean() always when we want to get a service. This approach is going to avoid strong references to usually stateless service implementations.
Hi there,
ReplyDeleteThanks for creating the great plugin and writing the great post.
Did the plugin support dependency injection instead of using getBean() like the following code:
class HelloWorldApplication extends Application {
def userService
@Override
public void init() {
Window w = new Window("Hello world!")
w.addComponent(new Label(i18n("app.title")))
List users = User.list()
for(User u : users) {
u.name = "Joshua"
userService.update(u)
w.addComponent(new Label(u.getName()))
}
setMainWindow(w)
}
}
Hi,
ReplyDeleteplease go to: http://grails.org/plugin/vaadin and read chapter Spring Dependencies. Most interesting part is called "Reason 2". You will learn how and mainly why service dependencies work via getBean method.
Ondra.
Hi Ondra,
ReplyDeleteThanks for quick response.
Did you come across Spring Stuff add-on at https://vaadin.com/directory#addon/spring-stuff ?
I not sure whether it solved the issues you mentioned in "Reason 2" though.
Cheers,
Chee Kin
Hi,
ReplyDeletewhen I use getBean() in my Vaadin class (i.e. IndexApplication) it is fine until I change something in class which consist getBean() call then when I refresh my page I get this error (this below) (in vaadin classes where there is no getBean() i can make changes in code and refresh page without errors)
THIS ERROR:
Class
groovy.lang.MissingMethodException
Message
No signature of method: IndexApplication.getBean() is applicable for argument types: (java.lang.Class) values: [class rpgApp.SecurityService] Possible solutions: getClass(), getTheme(), getURL(), getUser(), getAt(java.lang.String)
Hi,
ReplyDelete@Marek, yes, this happens and it is reported here: http://jira.grails.org/browse/GPVAADIN-14
@Lim, thanks for recommendation, I will check that.
Thanks Ondrej (Diky Ondreji) for great tutorial. I have a Grails application that I would like to convert to Vaadin/Grails application with your great Grails Vaadin plugin.
ReplyDeleteThe application uses Spring Security plugin http://grails.org/plugin/spring-security-core. Do you have any advise/recommendation how to integrate Spring Security and Vaadin authentication https://vaadin.com/wiki/-/wiki/Main/Authenticating+Vaadin-based+applications.
And if I can be bold enough ;-) and ask for tutorial, Part III with authentication example ;-).
Thanks for your great work!
Diky moc za vyborny plugin!
Lubos Pochman
Lubos, I can make tutorial how I authenticate grails/vaadin applications. I added that to my todo list.
ReplyDelete