
Just read the first blog posts (Google App Engine Blog, GR8 Conference, The Aquarium) about the announcement that Java is the next programming language supported on Google App Engine.
This is so funny, as I think just before Google released the announcement I put a question on the Google App Engine discussion group about when we can expect the new language and which language it would be. So my qusetion is answered now.
Since Google App Engine was announced I've always followed it with interest. I'm really excited/interested in the Cloud computing model so I don't have to maintain a deployment server/server park myself. Also the fact that I will just use more resources on the cloud infrastructure when my application needs is just great. I don't have create a cluster or whatever myself.
The reason I put the question on the forum yesterday was that I'm working on a small personal application I like to host on the internet somewhere in the future. Important thing is that the hosting has to be cheap when starting up. I've looked into Mor.ph but it would still cost me $31 a month to host my Java application. This does not sound expensive, buy hey I'm not a business!
In the past I hosted a couple of PHP websites using Drupal and I must say good PHP hosting is cheap and works very good. So I was already thinking of alternative scenario to develop my application in PHP, and not in Grails ;-(
I had already downloaded CakePHP and was experimenting a bit with it. I must say CakePHP is really easy to learn for Grails developers as it uses a lot of the same concepts as Grails and also RoR.
But with the annoucement of Google that Java will be supported I will be putting my PHP alternative in the fridge again. Also a very big plus that SpringSource's Groovy team has worked together with Google to make sure Groovy works well on Google App Engine. Let't hope the same thing counts for Grails one day.
Wednesday, April 8, 2009
Java support on Google App Engine
Posted by
Marcel Overdijk
at
11:06 AM
2
comments
Labels: Google App Engine, Grails, Java
Wednesday, March 18, 2009
IBM buying Sun?

Some news sites (1, 2) today are reporting that IBM is in talks to buy Sun in a deal for at least $6.5 billion.
Off course this is some interesting news and might have some impact on Java and Java related products from Sun (GlassFish, NetBeans, ...). The future will tell us.
The reason I'm blogging about this that I'm believing for years that Oracle's Larry Ellison would step up one day and buy Sun. It would make a lot of sense in my opionion. Oracle is really attached to Java and they are involved in many JSR's. With buying Sun and thus Java they would have real strong voice in which Java would be heading. They would also have their own operating system which is one the less things they don't have at the moment. You can then have a stack like Oracle Solaris, Oracle Database, Oracle WebLogic Application Server and Oracle Applications. And there is a lot more, think about MySQL!
For once and all I want to write down this prediction, so if it would happen once (and this seems not the case right now) I can tell I had predicted it ;-).
PS: If I had a chrystal ball I was bying a lotery ticket right now.
Posted by
Marcel Overdijk
at
1:06 PM
3
comments
Friday, February 15, 2008
Grails adaptive AJAX support with the Yahoo! UI Library

Grails ships out of the box with adaptive AJAX support.
By default Grails uses the Prototpe library when invoking AJAX request using the Grails remoteLink, formRemote and submitToRemote AJAX tags.
Not only is Grails providing an easy way of integrating AJAX functionality in your pages, but it also allows you to switch to another AJAX library if needed. This is what we mean with adaptive AJAX support.
One of the use cases to switch to another AJAX library is that this library offers more functionality then the default Prototype library. E.g. you want to use the Yahoo! User Interface Library (YUI) within you application for the autocomplete or calendar functionality. In this case you want the YUI library also to be used for your AJAX tags, so you only depend on YUI and not on both YUI and Prototype.
If you want easy support for YUI in your Grails application then just install the Grails Yahoo! UI Library Plugin which I released today. It downloads and installs automatically the latest YUI 2.4.1 2.5.0 distribution in your application, and registers itself to be used with the adapative AJAX tags. It also contains two helper tags to easily include additional YUI javascript and css files as well.
Note that this plugin does not provide any tags for embedding rich ui components without having to deal with javascript libraries. If you are more interested in such a plugin, have a look at the Grails RichUI Plugin. This plugin contains a set of AJAX components not limited to the YUI library.
For a personal application I want to use the YUI autocomplete and calendar functionality so I'm thinking already of a Grails YUI Widgets Plugin which can be installed on top of the YUI Plugin ...
Saturday, October 27, 2007
Amazing JetGroovy plugin

First of all I need to say that I'm a happy daily Eclipse user; Eclipse does (almost) everything I want from a Java IDE.
In the past I also used JDeveloper using Oracle's proprietary Application Development Framework (ADF) and experimented a little bit with NetBeans.
But I actually never tried IntelliJ. Maybe because the price tag of $499 and because Eclipse is working good enough for FREE.
IntelliJ IDEA 7.0 was released recently and the fully functional Beta version of the JetGroovy plugin provides excellent Groovy and Grails support.
A lot of people were very enthusiastic about this JetGroovy plugin I gave it a try this evening and I was really amazed as it worked perfectly:
Code completion/assistance
- Groovy code completion for keywords, classes, fields and methods
- Cross-resolution between Groovy and Java classes, methods and fields
- Syntax and error highlighting
- Groovy-aware refactoring
Grails application and artifact creation
- Grails applications can be created from using a wizard
- Grails artifacts (like domain classes, controllers, views etc.) can be created using a wizard
GSP support
- Groovy code completion
- Tag completion (both Grails core and custom created tags; even tags with custom namespaces are resolved ;-) !)
When developing Groovy and/or Grails projects then IntelliJ is a real recommendation.
I hope one day we will see the same functionality provided by the Groovy Eclipse plugin.
Posted by
Marcel Overdijk
at
1:09 PM
2
comments
Wednesday, October 10, 2007
Some great Groovy/Grails news this week

Some really good Groovy and Grails news this week I wanted to mention (or better copy from Graeme Rocher's Blog)
First LinkedIn, a online network of more than 14 million experienced professionals from around the world, are looking for software engineers preferably with Groovy/Grails experience.
Then big ERP software giant SAP announced that they have released a new community driven product called Composition on Rails that allows you to use their SAP NetWeaver Composition Environment to quickly prototype applications using Groovy/Grails.
And today G2One Inc - the Groovy/Grails company was announced. G2One has been founded by Graeme Rocher (Grails Project Lead), Guillaume LaForge (Groovy Project Lead) and Alex Tkachman (Former JetBrains COO) to provide consultancy, training, support and products around Groovy & Grails. Personally I think offering commercial support etc. will help adoption signifantly. And with this Groovy/Grails can be developed further. This is the same as e.g. JBoss and Spring are offering great open source software for free, but still making money to constantly evolve this free software.
Posted by
Marcel Overdijk
at
3:48 AM
0
comments
Thursday, October 4, 2007
Grails i18n templates plugin released

After my previous post about i18n aware scaffolding templates I decided to create a plugin for those templates. For documentation and installation instructions see http://www.grails.org/I18n+Templates+Plugin
Posted by
Marcel Overdijk
at
8:45 AM
1 comments
Tuesday, September 25, 2007
Grails scaffolding templates improved; i18n aware templates available for download

Despite the fact that the Grails scaffolding templates can be customized, it has always bothered me that the "editors" in the create and edit views were fixed. This meant that tr, td and input elements could not be customized. In the current RC1 development snapshot the fixed code has been moved to a new template which can be customized when installing the templates.
[Note that the templates are still limited to list, create, edit and show views]
You can now customize the way various editors should be rendered, or maybe you want a complete different editor as used in the default templates. E.g. use the fancy Yahoo! UI Calendar instead of the default Grails datePicker.
Or use fully i18n aware templates which can be downloaded here. The i18n templates are now available by a new plugin: http://www.grails.org/I18n+Templates+Plugin. To use them, install the default templates in your project by running grails install-templates. This should create a folder \src\templates\scaffolding containing the default templates. Copy the downloaded templates in this folder and Grails will use them to generate a i18n aware application.
Here are some guidelines for resolving the i18n labels and messages for your domain classes. Imagine you application consists of these 2 domain classes:
class Author {
static hasMany = [books:Book]
String name
static constraints = {
name(blank: false, maxSize: 50)
}
}
class Book {
Author author
String isbn
String title
String category
Float price
String description
static constraints = {
author()
isbn(blank: false, maxSize: 10)
title(blank: false, maxSize: 50)
category(inList: ["Fantasy", "Mystery", "Romance", "Thriller"])
price(min: 0F, max: 100F, nullable: true)
description(blank: true, maxSize: 500)
}
}
Then by default the application is generated using the labels and messages as normal.
But you can change them by adding the following entries to your messages.properties:
# General messages
home=Home
list=List
new=New
create=Create
edit=Edit
update=Update
delete=Delete
delete.confirm=Are you sure?
# Author messages
author=Author
author.plural=Authors
author.created=Author {0} created
author.updated=Author {0} updated
author.deleted=Author {0} deleted
author.not.found=Author not found with ID {0}
author.id=ID
author.books=Books
author.name=Name
# Book messages
book=Book
book.plural=Books
book.created=Book {0} created
book.updated=Book {0} updated
book.deleted=Book {0} deleted
book.not.found=Book not found with ID {0}
book.id=ID
book.author=Author
book.isbn=ISBN
book.title=Title
book.category=Category
book.category.Fantasy=Fantasy
book.category.Mystery=Mystery
book.category.Romance=Romance
book.category.Thriller=Thriller
book.price=Price
book.description=Description
Off cource these English messages would not change anything, as the values would also be used as default. But you can now translate your complete application by just adding resource bundles for that language, and translating the properties.
Note that also the list constraint (by domain.property.value) is displaying i18n labels!
If I have time this week I might create a standalone plugin with these templates. This would include the general labels already then, and maybe some other useful features.
My end goal (and I'm thinking of this since I learned about Grails) is to have a 4GL-like application generator which uses it's own DSL to generate a Grails application. Think of defining number of rows to display in list, is insert allowed, is update allowed, etc.
Posted by
Marcel Overdijk
at
12:01 PM
4
comments
Monday, September 3, 2007
Grails 1.0 on the horizon

Last week Grails 0.6 was released and the 1.0 release is coming closer every day now!
The 0.6 release contained the following key features:
- Joint Groovy/Java Compilation
- Spring Web Flow Integration
- Support for Spring scopes to allow scoped services
- Improved support for REST with automatic XML/JSON marshalling and RESTful URL mappings
- New Config DSL for configuration not possible by convention
- Refreshed scaffolding interface and branding
- Support for Sitemesh inline decorators
- Controllers can now call tag libraries as methods
- New GSP tags
- Massive improvements to speed of start-up time, unit tests and generation tools
Besides the great Spring Web Flow integration, and out-of-the-box support for rendering XML and JSON responses (formerly known as the Converters plugin), also the scaffolding views were revamped. Scaffolding now provides a professional and good looking user interface. Take a look below!
Posted by
Marcel Overdijk
at
9:45 AM
0
comments
Wednesday, August 1, 2007
Another Sexy Flex Grails Example

Here is another (quick) Flex example which uses Grails on the back-end. It contains all CRUD operations in just one screen. Just follow the steps below to see it for yourself:
- Create a new grails application:
grails create-app flexongrails - Create a new Book domain class:
grails create-domain-class Book
Open the Book domain class and replace the code with:class Book {
String isbn
String title
String author
Float price
String format
static constraints = {
isbn(maxLength:20, unique:true)
title(maxLength:50)
author(maxLength:50)
price(min:0F, max:999F, scale:2)
format(inList:["Hardcover", "Paperback", "e-Book"])
}
} - Create a new Book controller:
grails create-controller Book
Open the Book controller class and replace the code with:class BookController {
def index = { redirect(action:list, params:params) }
// the delete, save and update actions only accept POST requests
// def allowedMethods = [delete:'POST', save:'POST', update:'POST']
def list = {
response.setHeader("Cache-Control", "no-store")
def bookList = Book.list(params)
render(contentType:"text/xml") {
data {
for(i in bookList) {
book {
id(i.id)
isbn(i.isbn)
title(i.title)
author(i.author)
price(i.price)
format(i.format)
}
}
}
}
}
def save = {
def book
if(params.id) {
book = Book.get(params.id)
}
else {
book = new Book()
}
book.properties = params
book.save()
render ""
}
def delete = {
def book = Book.get(params.id)
if(book) {
book.delete()
}
render ""
}
}
What you can see here is that thelistaction return xml data which will be used by Flex. Important is setting the cache control in the response header. Thesaveaction will be used both creating as editing. - Create a new Flex project (in Flex builder) and replace the code in the main mxml file with:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="listService.send()">
<mx:HTTPService id="listService" url="http://localhost:8080/flexongrails/book/list" useProxy="false" method="GET"/>
<mx:HTTPService id="saveService" url="http://localhost:8080/flexongrails/book/save" useProxy="false" method="POST" result="listService.send()">
<mx:request xmlns="">
<id>{book_id.text}</id>
<isbn>{isbn.text}</isbn>
<title>{title.text}</title>
<author>{author.text}</author>
<price>{price.text}</price>
<format>{format.text}</format>
</mx:request>
</mx:HTTPService>
<mx:HTTPService id="deleteService" url="http://localhost:8080/flexongrails/book/delete" useProxy="false" method="POST" result="listService.send()">
<mx:request xmlns="">
<id>{dg.selectedItem.id}</id>
</mx:request>
</mx:HTTPService>
<mx:NumberFormatter id="priceFormatter" precision="2"/>
<mx:Script>
<![CDATA[
[Bindable]
private var formatArray:Array = ["Hardcover", "Paperback", "e-Book"];
private function clearForm():void {
book_id.text = "";
isbn.text = "";
title.text = "";
author.text = "";
price.text = "";
format.selectedIndex = 0;
}
private function formatPrice(item:Object, column:DataGridColumn):String {
return priceFormatter.format(item.price);
}
]]>
</mx:Script>
<mx:VDividedBox x="0" y="0" height="100%" width="100%" paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10">
<mx:Panel width="100%" height="300" layout="absolute" title="Create/Update Book">
<mx:Form x="10" y="10" width="930" height="200">
<mx:FormItem label="ID">
<mx:TextInput width="120" id="book_id" text="{dg.selectedItem.id}" enabled="false"/>
</mx:FormItem>
<mx:FormItem label="ISBN">
<mx:TextInput width="220" id="isbn" text="{dg.selectedItem.isbn}" maxChars="20"/>
</mx:FormItem>
<mx:FormItem label="Title">
<mx:TextInput width="320" id="title" text="{dg.selectedItem.title}" maxChars="50"/>
</mx:FormItem>
<mx:FormItem label="Author">
<mx:TextInput width="320" id="author" text="{dg.selectedItem.author}" maxChars="50"/>
</mx:FormItem>
<mx:FormItem label="Price">
<mx:TextInput width="120" id="price" text="{priceFormatter.format(dg.selectedItem.price)}"/>
</mx:FormItem>
<mx:FormItem label="Format" width="220">
<mx:ComboBox id="format" selectedIndex="{formatArray.indexOf(dg.selectedItem.format)}">
<mx:dataProvider>{formatArray}</mx:dataProvider>
</mx:ComboBox>
</mx:FormItem>
</mx:Form>
<mx:ControlBar horizontalAlign="right">
<mx:Button label="New" click="clearForm()"/>
<mx:Button label="Save" click="saveService.send(); clearForm()"/>
</mx:ControlBar>
</mx:Panel>
<mx:Panel width="100%" height="444" layout="absolute" title="Book List">
<mx:DataGrid x="0" y="0" width="100%" height="100%" id="dg" dataProvider="{listService.lastResult.data.book}">
<mx:columns>
<mx:DataGridColumn width="120" headerText="ID" dataField="id"/>
<mx:DataGridColumn width="220" headerText="ISBN" dataField="isbn"/>
<mx:DataGridColumn width="320" headerText="Title" dataField="title"/>
<mx:DataGridColumn width="320" headerText="Author" dataField="author"/>
<mx:DataGridColumn width="120" headerText="Price" dataField="price" labelFunction="formatPrice"/>
<mx:DataGridColumn width="220" headerText="Format" dataField="format"/>
</mx:columns>
</mx:DataGrid>
<mx:ControlBar horizontalAlign="right">
<mx:Button label="Delete" click="deleteService.send()" enabled="{dg.selectedItem != null}"/>
</mx:ControlBar>
</mx:Panel>
</mx:VDividedBox>
</mx:Application> - Run the Flex application
You now have a basic CRUD Flex application which uses Grails as back-end. The example is very basic and the Grails Book controller isn't responding back any possible validation errors; they just get absorbed. Also for a couple of row retrieving all the rows at once is no problem, but in real life it will me thousands and thousands of records, so also server side paging and ordering is needed. Well, this could be easily implemented in the Book controller (as it is basic Grails functionality) but most of the work will go in the Flex application I think...
For server-side paging/sorting a custom Flex component would be needed which remembers the current page and just submits the required paging and sorting fields to the serve-side. This is independent to Grails as it could be used by any server-side application. I guess I'm not the first one looking into this so I might find something on the internet.
Friday, July 27, 2007
Java Summer Camp in The Netherlands with Rails and Grails

This years Profict Java Summer Camp will host both Charles Nutter and Graeme Rocher to speak about JRuby and Grails.
This Java Summer Camp is hold on August 24 in The Netherlands. I will be there myself and I'm looking forward to meet other Grails users. Exciting!
If you are interested you can find more information on http://javasummercamp.nl.
Posted by
Marcel Overdijk
at
9:07 AM
0
comments
Thursday, July 26, 2007
Sexy Flexy Grails
With Flex you can create rich internet applications with highly interactive GUI's. It offers various methods for talking with server-side components to retrieve and store data. You can use simple HTTP GET/POST services, WEB services, RPC calls or Flex Data Services.
Using HTTP GET/POST or WEB services gives you the freedom to choose the server-side technology: PHP, Servlets, JSP, Ruby on Rails etc.
Mike Potter already has written a small tutorial about integrating Flex and PHP.
I will use Mike's tutorial to show you how easy it is to integrate Flex and Grails.
Prerequisites: I assume you have basic understanding of Flex and Grails and that you have installed them both already.
Where to start:
- First read Mike's tutorial about integrating Flex and PHP. After reading it you will understand that a simple PHP page is used to retrieve/return User records in XML data and to store new User records. In the next steps we will do the same, but then using Grails.
- It's time to create a new Grails application so from the command line type:
grails create-app sexyflexygrails
- Create the User domain class:
grails create-domain-class User
It's not needed to create the User table like in the PHP tutorial. Grails will automatically create the table when you run the application. - Add the Username and Emailaddress properties to the created domain class:
class User {
String username
String emailaddress
} - reate a new controller to retrieve and store data:
grails create-controller User
- Implement the needed logic in the created UserController:
When the index action is called it will check if the Username and Emailaddress parameters are in request parameters, and if so it will create a new User. In any case, the call to the index action will return all Users in the database as XML. Flex will use this XML to display the Users in a table.class UserController {
def index = {
if (params.username && params.emailaddress) {
def user = new User()
user.properties = params
user.save()
}
def userList = User.list()
render(contentType:"text/xml") {
users {
for(i in userList) {
user {
userid(i.id)
username(i.username)
emailaddress(i.emailaddress)
}
}
}
}
}
} - That's it for the server-side Grails part. Start the Grails application with:
grails run-app
- Open a browser and goto http://localhost:8080/sexyflexygrails/user. You will see no data as there is nothing in the database yet. Try adding a new User with http://localhost:8080/sexyflexygrails/user?username=MyUsername&emailaddress=MyUsername@MyCompany.com. This will create the new User in the database and will render the XML in the browser.
- Now start Flex Builder and create a new Flex project. Chooser Other/None as Server type.
- Open the automatically created main mxml file and copy in the MXML code from Mike's tutorial: http://www.adobe.com/devnet/flex/articles/flex2_php_03.html
- In the MXML code change the HTTPService url to: http://localhost:8080/sexyflexygrails/user
- Now run the Flex application and it will use Grails for retrieving and storing the data from the back-end.
In the next weeks I will have a further look at Flex, and see if I can create a small Flex CRUD application that uses Grails at the server-side. I will post my findings here, so stay tuned.
Monday, March 12, 2007
Grails Frappr Map
Recently I've created a Grails Frappr Map to see where the Grails users and committers are located. It's just nice to know where people you talk to on the mailing lists live. And maybe you will find out your neighbor is also using Grails!
Posted by
Marcel Overdijk
at
11:12 AM
0
comments
Wednesday, January 31, 2007
Grails 0.4 Released!

Grails 0.4 has been released today! You can download it from: http://grails.org/Download
Notable improvements include:
- ORM enhancements with support for more relationship types, easy transactions and criteria building, constraints to SQL schema mappings, and upgrade to Hibernate 3.2
- All-new non-invasive plugin system for writing reusable plugins for Grails applications (http://grails.org/The+Plug-in+Developers+Guide)
- Greater Spring integration thanks to a new syntax for scripting Spring (http://grails.org/Spring+Bean+Builder) and an upgrade to Spring 2.0
- A new Groovy-based build system based on Gant for easy command line scripting (http://grails.org/Command+Line+Scripting)
- Grails now ships with Groovy 1.0!
Read the full announcement at http://www.nabble.com/-groovy-user--Grails-0.4-Released!-tf3150030.html. Change log at http://jira.codehaus.org/browse/GRAILS?report=com.atlassian.jira.plugin.system.project:changelog-panel.
Posted by
Marcel Overdijk
at
11:31 AM
0
comments
Thursday, January 25, 2007
First public Grails based site
Marc Palmer has posted his experiences with developing a Grails based site for one of PepsiCo UK's well known juice brands, Copella: http://www.copellafruitjuices.co.uk
Read the full story here: http://www.nabble.com/Major-UK-brand-launches-Grails-based-site-tf3081890.html
Posted by
Marcel Overdijk
at
10:29 AM
0
comments
Thursday, January 18, 2007
Grails Templating
Since Grails 0.4 (not yet released, but downloadable as snapshot), you can customize how Grails creates/generates artifacts and scaffoldig.
The creation of artifacts like domain classes, controllers, services etc., but also the generation of the scaffolding controller and views, are now template based. As Grails developer you will notice no difference in contrast to previous version, as the the Grails distribution has default templates embedded.
However, for customizing your project needs, you can now take the advantage of customizing these templates for each application. These customization may vary from just extending a BaseController to completely customized layout in the views. Especially customizing the generated HTML in the views offers a lot of potential for developing your applications faster. Changing the same HTML code in generated views is time consuming, but with the customized templates you just do it once, and get it anywhere!
To customize the templates you will need to install the templates. Go into your project's basedir and type:
grails install-templates
This will install the templates in the src/templates folder of your project. Two kind of templates will be installed: artifact and scaffolding templates. The artifact templates are templates which will be used when creating artifacts with the create-xxx command line tools. The scaffolding templates will be used for scaffolding. There are scaffolding templates for the controller and for each view (list.gsp, create.gsp, edit.gsp, show.gsp).
After installing the templates, Grails will use these templates instead of the embedded default templates. If you later don't want to use customized templates anymore, just delete the customized templates from your project and the embedded default templates will be used again.
See also http://www.grails.org/Artifact+and+Scaffolding+Templates.
Posted by
Marcel Overdijk
at
12:00 AM
0
comments
Thursday, January 11, 2007
I'm part of the team!
In my last blog entry (ages ago already; shame on me) I pointed to a new and very interesting web application framework: Grails.
As I was playing with Grails at home I became more and more enthusiastic about it. In the meantime the popularity of Grails also increased heavily: blog entries, forum usage, screencasts, presentation at JavaPolis, the Grails book etc. Last December I started diving in the Grails source code myself and as a matter of fact I joined the Grails development team this week, and I'm really pleased with this!
Posted by
Marcel Overdijk
at
12:00 AM
0
comments
Tuesday, August 22, 2006
Great Grails Step-by-Step Tutorial
Some weeks ago I bumped against Grails. Grails is an open source web application framework inspired by Ruby on Rails. With Grails you can easily and quickly build/generate a web application using Groovy and (any) Java Technology.
In the near future I will post some of my Grails experiences here. But today I found a great Grails tutorial, written by Jason Rudolph, I really wanted to refer to: Grails + EJB Domain Models Step-by-Step.
Posted by
Marcel Overdijk
at
12:00 AM
0
comments
Friday, June 2, 2006
EJBQL query support added in JasperReports
My patch to support EJBQL queries inside JasperReports templates is included in the latest JasperReports 1.2.3 release. You can use any Java Persistence API implementation (part of JSR-220) like GlassFish/Toplink Essentials or Hibernate Entity Manager to provide data to your reports.
An example of using EJBQL in JasperReports templates is provided in the JasperReports project distribution, located in \demo\samples\ejbql. The example uses the Toplink Essentials Java Persistence API implementation from GlassFish. All necessary libraries to run the example are included in the JasperReports project distribution.
Running the example
Open a Command box and and navigate to JR_HOME\demo\samples\ejbql. Then run ant javac to compile the Java sources, ant compile to compile the JasperReports template files, ant fill to fill the compiled report design with data, and ant view to launch the report viewer to preview the report.
C:\Java Libs>cd jasperreports-1.2.3\demo\samples\ejbql
C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql>ant javacBuildfile:
build.xml
javac:
[mkdir] Created dir: C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\build\classes
[javac] Compiling 5 source files to C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\build\classes
[javac] Note: C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\EjbqlApp.java uses unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[copy] Copying 1 file to C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\build\classes
[copy] Copying 1 file to C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\build
BUILD SUCCESSFUL
Total time: 2 seconds
C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql>ant compileBuildfile:
build.xml
compile:
[jrc] Compiling 3 report design files.
[jrc] File : C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\JRMDbVariaSubreport.jrxml ... OK.
[jrc] File : C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\JRMDbCastSubreport.jrxml ... OK.
[jrc] File : C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\JRMDbReport.jrxml ... OK.
BUILD SUCCESSFUL
Total time: 3 seconds
C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql>ant fillBuildfile:
build.xml
fill:
[java] [TopLink Info]: 2006.06.02 08:55:20.906--ServerSession(30533424)--TopLink, version: Oracle TopLink Essentials - 2006.4 (Build 060412)
[java] [TopLink Info]: 2006.06.02 08:55:21.281--ServerSession(30533424)--file:/C:/Java%20Libs/jasperreports-1.2.3/demo/samples/ejbql/build/classes-pu1 login successful
[java] Filling time : 2125
[java] [TopLink Info]: 2006.06.02 08:55:23.015--ServerSession(30533424)--file:/C:/Java%20Libs/jasperreports-1.2.3/demo/samples/ejbql/build/classes-pu1 logout successful
BUILD SUCCESSFUL
Total time: 4 seconds
C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql>ant viewBuildfile:
build.xml
view:
BUILD SUCCESSFULTotal time: 4 seconds
Understanding the code
The ant fill target does the filling of the report by quering the HSQDB using the Java Persistence API. In the JRMDbReport.jrxml report template the following queryString was defined:
<queryString language="ejbql">
<![CDATA[
SELECT m
FROM Movie m
WHERE m.releaseDate BETWEEN $P{DateFrom} AND $P{DateTo}
ORDER BY $P!{OrderClause}]]>
</queryString>
By setting the language="ejbql" attribute, the JasperReports engine will use the Java Persistence API to retrieve the data. When filling the report an EnitiyManager instance need to be provided to the JasperReports engine. This is done in the main \demo\samples\ejbql\EjbqlApp.java class:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu1", new HashMap());
EntityManager em = emf.createEntityManager();
Map parameters = new HashMap();
parameters.put(JRJpaQueryExecuterFactory.PARAMETER_JPA_ENTITY_MANAGER, em);
JasperFillManager.fillReportToFile(fileName, parameters);
Note that this is only the part of the code to provide the EntityManager. Take a look at the \demo\samples\ejbql\EjbqlApp.java class for the complete code of the example.
The actual connection information to connect to the database is stored in the \demo\samples\ejbql\META-INF\persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="pu1">
<!-- Provider class name is required in Java SE -->
<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
<!-- All persistence classes must be listed -->
<class>Person</class>
<class>Movie</class>
<class>Cast</class>
<class>Varia</class>
<properties>
<!-- Provider-specific connection properties -->
<property name="toplink.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
<property name="toplink.jdbc.url" value="jdbc:hsqldb:db"/>
<property name="toplink.jdbc.user" value="sa"/>
<property name="toplink.jdbc.password" value=""/>
<!-- Provider-specific settings -->
<property name="toplink.logging.level" value="DEBUG"/>
<property name="toplink.platform.class.name" value="oracle.toplink.essentials.platform.database.HSQLPlatform"/>
</properties> </persistence-unit></persistence>
To read more about the EJBQL support in JasperReports, for example how to specify Query Hints, take a look at the JasperReports API documentation of the JRJpaQueryExecuter class.
Posted by
Marcel Overdijk
at
12:00 AM
0
comments
Labels: JasperReports, Java
Thursday, May 25, 2006
Using Facelets in NetBeans 5.5 (beta)
Although NetBeans 5.5 beta has no direct support for Facelets (yet?), you can successfully develop JSF Facelets applications with it, and take advantage of NetBeans' Java EE 5 platform support and other cool things.
In this this tutorial I will create a new Web Application in NetBeans 5.5 beta, based on the NumberGuess example included in the Facelets distribution. This tutorial assumes that you have basic JSF, Facelets and NetBeans knowledge. Before starting make sure you have the following in place:
- Java EE 5 SDK, Sun Java System Application Server PE 9 or GlassFish installed.
- NetBeans 5.5 (beta) installed.
- The installed Java EE 5 Server registered in NetBeans.
- Unpackaged distribution of Facelets (in this tutorial I used Facelets 1.1.4).
The NumberGuess example is a simple application consisting of a couple of JSF pages and navigation rules and a single JSF managed bean. Follow the steps below to set up the NumberGuess project in NetBeans and deploy and run it from within the IDE.
- Register the Facelets library in NetBeans (Tools --> Library Manager). Create a New Library containing the jsf-facelets.jar from the Facelets distribution.
- Create a new Web Application project. Choose as Project Name numberguess (make sure the context path is also set to numberguess) and select the Java EE 5 server you installed as Server. Select Java Server Faces in the Frameworks step. Click Finish to create the project.
- NetBeans will automatically create an index.jsp and welcomeJSF.jsp. Delete both files as we will not be using JSP pages, but xhtml formatted JSF pages.
- Add the Facelets library to your project (Project Properties --> Libraries --> Add Library).
- Copy the tutorial directory (containing the managed bean class) from \facelets-1.1.4\demo\numberguess\src\ to your projects \src\java\ directory. NetBeans will refresh your project content automatically.
- Also copy all files from \facelets-1.1.4\demo\numberguess\web\ to your projects \web\ directory. Do NOT copy the \WEB-INF\ directory.
- Open your projects web.xml and add the folowing:
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
Next, change the the Faces Servlet url pattern from /faces/* to *.jsf (next time you can do this when creating the project).
Also completely remove the welcome file list configuration which was pointing to the deleted index.jsp file. - Open your projects faces-config.xml and add the folowing:
<application>
<view-handler>
com.sun.facelets.FaceletViewHandler
</view-handler>
</application>
<!-- our NumberBean we created before -->
<managed-bean>
<managed-bean-name>NumberBean</managed-bean-name>
<managed-bean-class>tutorial.NumberBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>min</property-name>
<value>1</value>
</managed-property>
<managed-property>
<property-name>max</property-name>
<value>10</value>
</managed-property>
</managed-bean>
<!-- going from guess.xhtml to response.xhtml -->
<navigation-rule>
<from-view-id>/guess.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/response.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<!-- going from response.xhtml to guess.xhtml -->
<navigation-rule>
<from-view-id>/response.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/guess.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
The most important part is to configure the FaceletViewHandler to use Facelets as view technology. The other parts are just 'normal' JSF managed beans and navigation rules which you would also need without using Facelets. - Deploy and Run your project.
Posted by
Marcel Overdijk
at
12:00 AM
0
comments
Tuesday, April 18, 2006
Java Persistence API kickstart example
The new Java Persistence API (JSR 220) - the API for management of persistence and object/relational mapping - is comming your way! Finally persistence gets standardised. The Java Persistence API, or simply JPA, is required to be supported by any Java EE 5 implementation (as part of EJB 3.0), but can also be used in stand-alone Java SE.
I've set up a simple kickstart example which can be used as starting point to persist objects and run EJBQL queries. Start experimenting yourself today! You can add your own Java objects to the example and use them to persist or retrieve data.
To keep things simple we will use the stand-alone JPA implementation of GlassFish, Toplink Essentials, in Java SE (JDK 5 required) and as database we use an embedded HSQLDB database.
- Let's get started by downloading the GlassFish JPA implementation from: https://glassfish.dev.java.net/downloads/persistence/JavaPersistence.html (for this example I used build 44). You need to install/unpackage the downloaded jar as described on the download page: java -jar filename.jar. A directory will be created containing the needed jar files. Next, download HSQLDB from: http://www.hsqldb.org.
- Create a project environment (e.g. using Eclipse) and make sure toplink-essentials.jar, toplink-essentials-agent.jar and hsqldb.jar are on the classpath.
- Next, create your first entity class:
import javax.persistence.Entity;import javax.persistence.Id;
@Entity
public class Cat {
private String id;
private String name;
private char sex;
private float weight;
public Cat() {
}
public Cat(String id, String name, char sex, float weight) {
this.id = id;
this.name = name;
this.sex = sex;
this.weight = weight;
}
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
} - Create a META-INF directory on your classpath and add the file persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
Because we are running HSQLDB in memory and have set ddl-generation to "create-tables" we don't have to install a database and even don't have to create the Cat table. Toplink Essentials will create the table automatically.
<persistence-unit name="example">
<!-- Provider class name is required in Java SE -->
<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
<!-- All persistence classes must be listed -->
<class>Cat</class>
<properties>
<!-- Provider-specific connection properties -->
<property name="toplink.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
<property name="toplink.jdbc.url" value="jdbc:hsqldb:mem:."/>
<property name="toplink.jdbc.user" value="sa"/>
<property name="toplink.jdbc.password" value=""/>
<!-- Provider-specific settings -->
<property name="toplink.ddl-generation" value="create-tables"/>
<!-- other values are: drop-and-create-tablesnone -->
<property name="toplink.logging.level" value="DEBUG"/>
<property name="toplink.platform.class.name" value="oracle.toplink.essentials.platform.database.HSQLPlatform"/>
</properties>
</persistence-unit>
</persistence> - Create a simple Example class in which we will use the Java Persistence API:
import java.util.List;
First we persist 2 Cat instances and later we retrieve them back againg using an EJBQL query.
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class Example {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("example");
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
Cat princess = new Cat("1", "Princess", 'F', 7.4f);
Cat blackie = new Cat("2", "Blackie", 'M', 7.6f);
em.persist(princess);
em.persist(blackie);
em.getTransaction().commit();
List<Cat> cats = em.createQuery("SELECT c FROM Cat c").getResultList();
for (Cat c : cats) {
System.out.println(c.getName());
}
} catch(Exception ex) {
em.getTransaction().rollback();
} finally {
em.close();
}
}
} - Now run the Example class. The result should be something like below. This means you are successfully using the Java Persistence API!
[TopLink Info]: 2006.04.18 08:54:44.734--ServerSession(9800632)--TopLink, version: Oracle TopLink Essentials - 2006.4 (Build 060412)
[TopLink Info]: 2006.04.18 08:54:45.093--ServerSession(9800632)--file:/C:/Projects/workspace/jpa_example-example login successful
Princess
Blackie
Next steps: create your own Java objects, list them in the persistence.xml and start expirementing with them by persisting them and retrieving them using EJBQL queries. Note that when you run the example new tables are created automatically for your new Java objects.
Posted by
Marcel Overdijk
at
12:00 AM
6
comments












