2 weeks earlier than expected my second son is born: Scott. He and mums are doing very well!
PS: Is it just coincidence that he was born during SpringOne 2GX at the day official Grails support was announced for SpringSource Tool Suite/Eclipse?
Wednesday, October 21, 2009
Scott is born
Posted by Marcel Overdijk at 9:27 PM 7 comments
Labels: Scott
Tuesday, October 13, 2009
Even more useful: ConfigObjectFactoryBean for Spring
Last week I blogged about a ConfigSlurperPlaceholderConfigurer for Spring. I've now come up with something more useful: a ConfigObjectFactoryBean for Spring!
It just creates a Groovy ConfigObject from the specified arguments (config file locations, environment and default environment).
It's more useful because you can use it to populate Spring's standard PropertyPlaceholderConfigurer and even expose the config properties map as a servlet context attribute using the ServletContextAttributeExporter. To populate the PropertyPlaceholderConfigurer and ServletContextAttributeExporter classes with appropriate beans derived from the ConfigObject (resp, java.util.Properties and java.util.Map), the factory-bean and factory-method attributes of the bean definition are used.
Source code of ConfigObjectFactoryBean can be found below. It includes extensive javadoc with example how to configure it in combination with the PropertyPlaceholderConfigurer and ServletContextAttributeExporter.
import groovy.util.ConfigObject;
import groovy.util.ConfigSlurper;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
/**
* {@link org.springframework.beans.factory.FactoryBean} that exposes a
* {@link groovy.util.ConfigObject} object loaded using a Groovy
* {@link groovy.util.ConfigSlurper}.
*
* Supports the concept of per environment configuration via "environment"
* and "defaultEnvironment" properties. The "environment" property will be
* typically set using a system property.
*
* Can be used in combination with a
* {@link org.springframework.beans.factory.config.PropertyPlaceholderConfigurer}
* as demonstrated in the example below.
*
* Example XML context definition:
*
* <bean id="configObject" class="com.footdex.beans.factory.config.ConfigObjectFactoryBean">
* <property name="targetClass" value="javax.persistence.Persistence" />
* <property name="targetClass" value="javax.persistence.Persistence" />
* <bean>
*
* <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
* <property name="properties">
* <bean factory-bean="configObject" factory-method="toProperties" />
* </property>
* </bean>
*
* <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
* <property name="driverClassName"><value>${dataSource.driverClassName}</value></property>
* <property name="url"><value>${dataSource.url}</value></property>
* <property name="username"><value>${dataSource.username}</value></property>
* <property name="password"><value>${dataSource.password}</value></property>
* </bean>
*
* Example config.groovy:
*
* dataSource {
* driverClassName = "org.hsqldb.jdbcDriver"
* username = "sa"
* password = ""
* }
* environments {
* development {
* dataSource {
* url = "jdbc:hsqldb:mem:devDB"
* }
* }
* test {
* dataSource {
* url = "jdbc:hsqldb:mem:testDb"
* }
* }
* production {
* dataSource {
* url = "jdbc:hsqldb:file:prodDb;shutdown=true"
* password = "secret"
* }
* }
* }
*
* {@link groovy.util.ConfigObject} properties can be exposed as servlet
* context attribute easily:
*
* <bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
* <property name="attributes">
* <map>
* <entry key="configProperty">
* <bean factory-bean="configObject" factory-method="flatten" />
* </entry>
* </map>
* </property>
* </bean>
*
* And than can be accessed in jsp's like ${configProperty["sample.foo"]}.
*
* @author Marcel Overdijk
* @see #setEnvironment
* @see #setDefaultEnvironment
* @see #setLocations
* @see groovy.util.ConfigObject
* @see groovy.util.ConfigSlurper
*/
public class ConfigObjectFactoryBean implements FactoryBean, InitializingBean {
private String environment;
private String defaultEnvironment;
private Resource[] locations;
private ConfigObject config;
private String getEnvironment() {
if (this.environment == null || this.environment.trim().length() == 0) {
return this.defaultEnvironment;
}
else {
return this.environment;
}
}
public void setEnvironment(String environment) {
this.environment = environment;
}
public void setDefaultEnvironment(String defaultEnvironment) {
this.defaultEnvironment = defaultEnvironment;
}
public void setLocation(Resource location) {
this.locations = new Resource[] { location };
}
public void setLocations(Resource[] locations) {
this.locations = locations;
}
@PostConstruct
public void yeah() {
System.out.println("yeah!");
}
@Override
public void afterPropertiesSet() throws Exception {
config = new ConfigObject();
ConfigSlurper configSlurper = new ConfigSlurper(getEnvironment());
for (Resource location : locations) {
config.merge(configSlurper.parse(location.getURL()));
}
}
@Override
public Object getObject() throws Exception {
return this.config;
}
@Override
public Class getObjectType() {
return ConfigObject.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
Posted by Marcel Overdijk at 1:24 PM 2 comments
Labels: ConfigObject, Groovy, Spring
Determining runtime environment on Google App Engine
Google recommends to determine the runtime environment of a Google App Engine application using ServletContext.getServerInfo(). In development this will be "Google App Engine Development/x.x.x" and in production it will be "Google App Engine/x.x.x".
But in some places, like Service classes, you might not have a access to the ServletContext object. Easiest way to work around this is to create a ServletContextListener which determines the environment and then stores it in a System property. The System property can be accesses from any place. You can of course also write a (static) Environment.get() utility class which return the System property.
Below you can find an example implementation of such a ServletContextListener to determine the runtime environment. As you can read the javadocs you can also use other environments then development and production. To start the application in test mode, just add a VM argument when you start your application using "-Druntime.environment=test".
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* Simple listener to set the App Engine runtime environment via a system property.
*
* Example web.xnl definition:
*
* <listener>
* <listener-class>com.footdex.web.listener.RuntimeEnvironmentConfigurerListener</listener-class>
* </listener>
*
* The runtime environment can then be accessed from any place (without reference to
* ServletContext) via System.getProperty(RuntimeEnvironmentConfigurerListener.KEY).
*
* In case a system property is already set for the RuntimeEnvironmentConfigurerListener.KEY,
* the system property will not be overridden. This allows to startup the application
* in a custom environment other than development or production. This can be done typically
* using a VM argument like "-Druntime.environment=test".
*
* @author Marcel Overdijk
*/
public class RuntimeEnvironmentConfigurerListener implements ServletContextListener {
public static final String KEY = "runtime.environment";
public static final String DEVELOPMENT = "development";
public static final String PRODUCTION = "production";
@Override
public void contextInitialized(ServletContextEvent event) {
if (System.getProperty(KEY) == null) {
String serverInfo = event.getServletContext().getServerInfo();
// ServletContext.getServerInfo() will return "Google App Engine Development/x.x.x"
// when run locally, and "Google App Engine/x.x.x" otherwise.
if (serverInfo.contains("Development")) {
System.setProperty(KEY, DEVELOPMENT);
}
else {
System.setProperty(KEY, PRODUCTION);
}
}
}
@Override
public void contextDestroyed(ServletContextEvent event) {
}
}
Posted by Marcel Overdijk at 12:58 PM 1 comments
Labels: GAE, Google App Engine
Wednesday, October 7, 2009
ConfigSlurperPlaceholderConfigurer for Spring
Lately I'm working on Spring 3.0 hobby project in my spare time. Frequent readers of my blog or followers me on Twitter might think: Why plain Spring and not just Grails? So let me explain that first:
- I love Grails (and Groovy), and if I could make the decision I would use it on every project! But...
- I want to host my hobby project cheap, and even Amazon EC2/AWS is to expensive currently. So I decided to host my application on Google App Engine. And to be honest, Grails support for GAE is just alpha/beta state in my opinion (I hope it will change one day). So Grails was not an option.
- I've been coding Groovy and Grails for a while now and also doing commercial projects. But I have the feeling my basic Java and Spring knowledge might become a little bit rusty. And to face the facts, there is a change that one of my next clients will not use Groovy/Grails, but just Java and one of the 1,000,000 Java frameworks outhere. So with my hobby project I will be up to date with the latest Java and Spring 3.0 expertise!
But let's get back to the title of this post: ConfigSlurperPlaceholderConfigurer for Spring. In my hobby project I needed the concept of per environment configuration. Yes, in Grails you have it out-of-the-box but in Spring not.
I searched the web and found some interesting thoughts:
- RuntimeEnvironmentPropertiesConfigurer - A subclass of PropertyPlaceholderConfigurer which uses a specific config file based on a system property
- Configleon - Also an interesting mini framework for per environment configs
- GroovyPlaceholderConfigurer - A subclass of PropertyPlaceholderConfigurer which uses a Groovy ConfigSlurper
What I like about Grails' concept of per environment configuration is that you can define global config properties and just override them in a specific environment if needed. So if 90% of my properties are the same for each environment I don't need to specify them for all environment but just once.
This concept was not supported by the RuntimeEnvironmentPropertiesConfigurer, and also not by the GroovyPlaceholderConfigurer. I know the GroovyPlaceholderConfigurer uses a Groovy ConfigSlurper and this does support per environment configuration (Grails uses it!). So I decided to create a proper ConfigSlurperPlaceholderConfigurer which also supports different environments using a system property. At the end this is how my Spring config now looks:
Example XML context definition:
<bean class="org.springframework.beans.factory.config.ConfigSlurperPlaceholderConfigurer">
<property name="environment" value="#{systemProperties['runtime.environment']}" />
<property name="defaultEnvironment" value="production" />
<property name="location" value="/WEB-INF/config.groovy" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>${dataSource.driverClassName}</value></property>
<property name="url"><value>${dataSource.url}</value></property>
<property name="username"><value>${dataSource.username}</value></property>
<property name="password"><value>${dataSource.password}</value></property>
</bean>
Example config.groovy:
dataSource {
driverClassName = "org.hsqldb.jdbcDriver"
username = "sa"
password = ""
}
environments {
development {
dataSource {
url = "jdbc:hsqldb:mem:devDB"
}
}
test {
dataSource {
url = "jdbc:hsqldb:mem:testDb"
}
}
production {
dataSource {
url = "jdbc:hsqldb:file:prodDb;shutdown=true"
password = "secret"
}
}
}
I created a new issue in Spring JIRA to add this to core. If you are interested you can vote for the issue. It also contains the source code if you want to use it in your own project.
Posted by Marcel Overdijk at 12:51 PM 7 comments
Labels: Google App Engine, Grails, Groovy, Spring
Thursday, August 20, 2009
Grails on Cloud Foundry: Step by Step
After being acquired themselves last week, SpringSource has now announced acquiring Cloud Foundry. Currently Cloud Foundry only supports Amazon AWS/EC2 but in the future also VMware vSphere will be supported (surprising isn't it?).
This evening I experimented with Cloud Foundry and have uploaded a simple Grails application to the SpringSource Cloud Foundry Enterprise Java Cloud. I like to share my experiences with this step by step guide.
- Sign up for Cloud Foundry at https://www.cloudfoundry.com/cfapp/reg.html?_flowId=register-flow.
- Sign up for Amazon AWS at http://www.amazon.com/gp/aws/registration/registration-form.html.
- Create an EC2 keypair using the AWS Management Console or ElasticFox FireFox plugin. For detailed info and screenshots check Chris Richardson's blog post about this subject.
- Enable SSH using the AWS Management Console or ElasticFox. See Security Groups section. Again, for more info check Chris Richardson's blog post about this subject.
- Also enable HTTP access on port 80. If you forget this you won't be able to access your application in the cloud. I searched more than a hour for this...
- Change DataSource.groovy:
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop','update'
driverClassName = "com.mysql.jdbc.Driver"
username = "book"
password = "book"
url = "jdbc:mysql://${System.getProperty("dbHostName", "localhost")}/book"
}
}
}
Change the username, password and database name (in url property). You will need to enter these credentials in Cloud Foundry later.
The "dbHostName" property is specific for Cloud Foundry as explained in Cloud Foundry Getting Started. - Download the MySQL Connector/J jar and add it to your project's lib folder.
- After changing DataSource.groovy and adding the MySQL jar build a Grails war file using
grails war
. - Login to Cloud Foundry at http://www.cloudfoundry.com/. Don't use IE7! Be warned.
- Navigate to the applications tab and upload you war file. Important things to enter are the application name, the war file to upload, context name and the database section. Leave the rest as is.
- After your application is uploaded it's time to deploy it. Click the application's deploy button. In the next screen just enter a deployment name and leave the rest as is. Now hit the Launch button.
- This will take some time, but it's worth it ;-)
- After lauching your application click to view the deployment details. There is a Go To Home Page link to access your application!
Note: If you are using Google Chrome you won't see the link... That's why my first deployment 'failed' (and a hour gone) as I didn't know how to access it. As IE7 doesn't work either I guess Cloud Foundry only supports FireFox currently (I don't mind about IE, but I would be happy with Chrome).
To be honest Cloud Foundry has some rough edges in terms of documentation and tooling support but at the end I'm very happy how simple it is to deploy a Grails application. No Apache, Tomcat or MySQL setup anymore. This is the future!
Now only pricing should be more affordable. $79,20 p/month (Amazon AWS) for a toy project/application is a little bit high.
Posted by Marcel Overdijk at 1:46 PM 17 comments
Labels: Amazon, Coud Foundry, EC2, Grails, SprigSource
Monday, August 10, 2009
Will Rod Johnson be the next Marc Fleury?
Yesterday VMware announced it is going to acquire SpringSource for around $420 million. They expect the deal to be closed in Q3 2009. This means not only acquiring the Spring framework, but also Groovy, Grails, SpringSource tc Server (Apache Tomcat), SpringSource dm Server, Roo, etc.
As a Java developer I'm making use of a lot of SpringSource products (Spring framework, Groovy, Grails) so I'm wondering what this will mean for us. The VMware blog stated that the Spring framework (and I assume the same counts for the other products) will stay open and that Rod Johnson will continue to lead SpringSource. Let's hope Rod will not go on a "Paternity Leave" like Marc Fleury did ;-)
I think a lot of attention will go to cloud computing. Both the VMware blog and SpringSource Team Blog speak a lot about it. To quote Rod Johnson: "Working together with VMware we plan on creating a single, integrated, build-run-manage solution for the data center, private clouds, and public clouds". Also Graeme Rocher (Head of Grails Development - SpringSource) tweeted that we can expect exciting developments around Grails + Cloud coming in the not too distant future.
The VMware SpringSource acquisition also means my latest prophecy that Oracle will buy SpringSource someday needs a slight change... I think Oracle will buy VMware someday.
Posted by Marcel Overdijk at 11:28 PM 1 comments
Labels: Grails, Groovy, Oracle, Spring, SpringSource, VMware
Grails w/ Dojo enabled forms
Didn't touched my Blogger account for almost a month now and I think regular tweeting is not good for the number of entries on your blog... But twitter is limited to 140 characters and I needed a little bit more this time.
While playing with Spring Roo the other day I noticed Roo is using Dojo - and to be more specific Dijit Forms - to enhance plain htlm input fields with javascript. For example Number fields are decorated with a Dojo dijit.form.NumberTextBox; what this means is that the user can only enter digits and no text. The lack of this feature with plain html inputs is a problem that has always bothered me when developing 'business' web applications.
So I dived into the magic of Dojo and it's Dijit form controls last week, and it does not only validate values using javascript, but it also contains nice widgets.
During the weekend I decided to create a small Grails application to leverage all Dijit form controls using a tag library. The following Dijit enabled form controls are available in this tag library:
- actionSubmit
- checkBox
- currencyTextBox
- comboBox (note: do not confuse this one with a filteringSelect)
- dateTextBox
- editor
- filteringSelect
- form
- multiSelect
- numberTextBox
- numberSpinner
- passwordTextBox
- radioButton
- radioGroup
- simpleTextarea
- submitButton
- textarea
- textBox
- validationTextBox
Example screenshots:
The complete application code and a little bit more information can be found at: http://code.google.com/p/grails-snippets/wiki/DojoForm. I will use this repository to share more Grails snippets in the future.
Posted by Marcel Overdijk at 3:07 AM 6 comments
Wednesday, July 22, 2009
Spring Roo vs Grails generated controllers
As I already tweeted earlier today I was trying out Spring Roo 1.0.0.RC1 as it was released today.
After playing a couple of hours with Roo I must say really like Roo using AspectJ inter-type declarations (ITDs). For example Roo will automaitcally generate id and version fields and getters and setters for your persistent fields in your domain class. Roo generates these at development time in separate AspectJ .aj files. As a developer you won't touch them as Roo will manage and update them automatically as you add fields etc. to domain classes. The great thing is the generated code will not interfere with your custom code and you don't have to be scared you custom or overwritten methods are overwritten by Roo again. During compilation all .aj files belonging to the Java class are compiled into just 1 .class file.
What I really liked is that when you are developing in SpringSource Tool Suite (based on Eclipse) code completion works also for methods contained in the AspectJ .aj files. So also debugging your code is a real breech as you can step through the methods generated by Roo easily.
Roo also contains scaffolding. However as a long term Grails user I got scared when I saw the controller code generated by Roo. See the example below:
Roo generated controller code:
@org.springframework.web.bind.annotation.RequestMapping(value = "/nation", method = org.springframework.web.bind.annotation.RequestMethod.GET)
public java.lang.String NationController.list(org.springframework.ui.ModelMap modelMap) {
modelMap.addAttribute("nations", com.footdex.domain.Nation.findAllNations());
return "nation/list";
}
Grails generated controller code:
def list = {
params.max = Math.min(params.max ? params.max.toInteger() : 10, 100)
[nationList: Nation.list(params), nationTotal: Nation.count()]
}
OK, the Roo generated code could look better if we remove all the package information before the classes:
@RequestMapping(value = "/nation", method = RequestMethod.GET)
public String list(ModelMap modelMap) {
modelMap.addAttribute("nations", Nation.findAllNations());
return "nation/list";
}
But then we should also just create the same functionality in the Grails controller (without paging):
def list = {
[nationList: Nation.list()]
}
So which one do you prefer?
I really think Spring Roo will have a great future. The use of ITDs for generated code and it's support in SpringSource Tool Suite will really aid adoption. Also in case Grails is not allowed within your company, Roo could really help you to get more productive.
As I expressed already in my example I really like Grails/Groovy effectiveness and readiness of code. Also the deep level of code by convention empowered by Grails is unbeatable.
With Grails and Roo, SpringSource has 2 remarkable frameworks in it's portfolio. Let them be as innovative as always and we as developers are the winners!
Posted by Marcel Overdijk at 7:36 AM 8 comments
Thursday, July 9, 2009
2nd NLGUG Meetup
Yesterday was the 2nd NLGUG (Dutch Groovy and Grails User Group) meetup in Baarn (close to Amsterdam).
As I live in the south of The Netherlands (close to Maastricht) attenting the meetup meant a 2-hour drive home. So at 00.10 I arrived home, tired, but it was worth it!
The meetup was organized by Erik Pragt and was hold at the VX Company headquarters. We really need to meetup up at Valid's new V-Tower at Eindhoven Flight Forum one day! Perhaps somewhere in October or November when we are settled in.
I must admit that I was not really attracted by the subject: iWebKit
But Sebastien Blanc's workshop turned out to be really fun and impressive!
After a short presentation we did a workshop by building our own Twitter client for the iPhone. And guess what it even worked and looked nice on my Android phone. Now iWebKit only need to support native Android look and feel (feature request?).
We used the Grails iWebKit Plugin (developed by Sebastien himself) and the Twitter Plugin and it's so impressive and cool to see that with a couple lines of code you can build a Twitter client for your mobile. Sebastien promised to put the workshop online so the rest of the world can try it to.
I guess there were around 15 attendees and it's really great to see how enthousiastic they are. Grails also lives in The Netherlands! Hope next time there will be even more people. Check out some photo's of the meetup.
Tuesday, July 7, 2009
Grails Google Analytics Plugin
As Marc Palmer already mentioned it's important for the community to download and test Grails 1.2-M1.
I've already started with 1.2-SNAPSHOT builds for my home project but also decided to write a simple Google Analytics plugin and test the plugin development parts of Grails 1.2-M1. Again, it is a very simple plugin but found no blocking issues so far.
About the plugin: It includes a simple tag to embed the Google Analytics tracking code in your views/layouts. Just add <ga:trackPageview />
just before your closing </body>
tag and add your Web Property ID to Config.groovy:
// grails google analytics plugin configuration
google.analytics.webPropertyID = "UA-xxxxxx-x"
By default only running your Grails application in production mode the Google Analytics tracking code will be outputted. This makes sense as you don't want to mix development or testing page hits with the ones from production. However if you need you can explicitly enable/disable Google Analytics or use different Web Property ID's per environment. See http://www.grails.org/plugin/google-analytics for details.
Posted by Marcel Overdijk at 6:19 AM 0 comments
Labels: Google Analytics, Grails
Wednesday, June 17, 2009
Tweeting now
I believe I created a Twitter account somewhere last year but never used it. But from now on I will try tweeting on a regular basis. You can follow me on http://twitter.com/marceloverdijk.
Screenshot from groovytweets.org
Posted by Marcel Overdijk at 2:08 PM 0 comments
Labels: Twitter
Sunday, June 14, 2009
Google App Engine Datastore doubts
I have been looking into Google App Engine since the beginning. I played a little bit with it using Python and Django but never did some serious work. As GAE/J was released back in April I decided to have a serious look by building a real application.
I mean the GAE promise is everything I need: easy to build, easy to maintain, easy to scale and I can run it on Google's infrastructure. And when my application won't be the next Twitter, most likely it will cost me nothing to host it as Google offers enough free quotas for medium and small application. I should also mention that now Grails also runs on GAE (using the App Engine plugin) my life couldn't get easier, but...
The only thing GAE does not offer is a relational datastore. GAE's Datastore, based on BigTable, is a hierarchical, schema-less, non-relational datastore.
One of the nice things relational databases support are the aggregate functions like count, sum, avg etc. If you are using GAE you must "Shift processing from reads to writes" as mentioned in The Softer Side Of Schemas - Mapping Java Persistence Standards To the Google App Engine Datastore presented at Google I/O. In practice this means that when inserting or updating a record you must calculate and store the count, sum, avg, etc. values of the whole table. But what if you have many conditional groupings? Let's take an example:
@Entity
class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
String id;
String name;
//Date birthdate;
Integer age;
String address;
String city;
String postalCode;
}
Now imagine I want to be able to (1) get the total number of persons and (2) the average age. Everytime I would create, update or delete a person I should calculate both and store them. Not a big deal, but in my opinion already to much hassle.
But then I also want these values per city... So for each city I should store these values. Next I want them also per postalCode or a specific range of the postalCode. You see where I'm going to? Every create, update or delete of a person would result in a lot of caluculation and storing values.
And then worse, my agile product owner comes in and want to add a boolean indicating a person is a male or not. And guess what, number of persons and average age should additionally be calculated also for this male/female indicator, and to make it worse also in combination with city and postalCode...
I truly believe GAE's Datastore is suitable for many applications don't needing features part of most relational databases. But if you need aggregate queries or common SQL functions (both most likely needed when you are trying to get some analytical data) you should really think twice.
I hope one day GAE's current Datastore will support aggregate functions or additionally a relational datastore will be provided. Then I think GAE would be my preferred Cloud platform.
Posted by Marcel Overdijk at 4:24 AM 20 comments
Labels: GAE, Google, Google App Engine
Monday, June 8, 2009
Microsoft finally seeing the light ;-)
Microsoft is finally seeing the light!! Watch the video below to see Ted Neward demonstrate the new JDBC 4 driver for Microsoft SQL Server at the Microsoft booth at JavaOne.
Funny thing is Ted is using Grails and also a MacBook.
Posted by Marcel Overdijk at 11:44 PM 1 comments
Which hosting party to choose?
For some personal project I'm currently looking for a hosting party.
I started very open minded to use whatever technology to build the web application from Grails, Spring Roo, Ruby on Rails to CakePHP or even Drupal.
I don't have that many requirements:
- Hosting party should be a respected company
- Ability to scale out easily
- Offer Subversion service to manage my application sources
- And (very important for my own wallet!) it should be affordable
I've looked into Google App Engine but for now I have decided not to go that direction. Main reason is the lack of a relational database.
For now I decided to go for a Grails or Ruby on Rails solution. I never developed a full Ruby on Rails application (except reading/trying some tutorials in the past) but maybe this is the time to give it a try... It's never bad to learn a new language and I think I will pick it up very quickly as it's concepts are very similar to Grails. I still need to think about this and will decide later which of the two I will use.
Based on hosting experiences within the Grails community I already made a shortlist of hosting parties and contacted them already with some question. This is my shortlist so far:
- eApps - e.g. Jan Sokol of grailstutorials.com is using this and is very happy about it
- Rackspace - there Cloud Server plans look great
- RimuHosting - also get good credits within the Grails community
I have some time to make a decision so any comments are appreciated.
Posted by Marcel Overdijk at 12:32 PM 10 comments
Thursday, May 28, 2009
Spring Roo coming alive
Spring Roo was announced just recently at JavaOne, and after the first alpha releases it's now time for M1.
If you are interested in this new "code generating" / productivity framework led by SpringSource you defintely have to read this introduction and example by project lead Ben Alex. Currently there is not much documentation available but this will change in the near future.
Similar to Grails, Roo wil have a plugin architecture using "add-ons". Looks like I've published the first community add-on - integrating SiteMesh - myself according to Ben's blog. Follow the steps below to try out the SiteMesh add-on:
- Follow the Roo installation instructions from Ben Alex's getting started blog post
- Download spring-roo-addon-sitemesh-1.0.0.M1.jar from http://jira.springframework.org/browse/ROO-41
- Copy spring-roo-addon-sitemesh-1.0.0.M1.jar to ROO_HOME\dist
- Start Roo and create a project as described in Ben's blog post
- After creating the project install SiteMesh to your project. Type 'ins' and press tab. Roo's shell will already display the availability of the install sitemesh command. Finish the command 'install sitemesh'
- That's it. The Maven pom file is updated so it contains the SiteMesh dependency. The SiteMesh filter and filter-mapping are added to web.xml. And default sitemesh.xml, decorators.xml and main.jsp files are created within your project.
- Open webapp\decorators\main.jsp to change your main layout and continue your project creating persistent classes, controllers, views etc.
It's really easy to create add-ons. If you are interested in creating your own add-ons have a look at the sources of the SiteMesh add-on or see the Roo core add-ons using Fisheye or SVN.
I think Spring Roo will have a bright future as it is led by SpringSource and primary uses best practices and boosts developer productivity. For companies/developers already using the Spring framework, Roo will be an easy and natural next step. This is a real strong point for Roo. Also integration with the SpringSource Tool Suite integration since day one will have huge benefits.
As a long time Grails adept I'm wondering how SpringSource will position both frameworks in the future. At least we have another choice for productivity again.
Posted by Marcel Overdijk at 10:59 AM 0 comments
Monday, April 20, 2009
The prophecy has come true! SpringSource next?
This aftenoon I received an e-mail from an old colleague that the Prophecy has come true (he was calling me Morpheus ;-): Oracle announced it entered into an agreement to acquire Sun.
Cool that just 1 month ago I finally blogged about this! I was thinking about this for years. I guess Mr. Larry Ellison had finally found my personal blog then ;-)
But seriously, what will this merger mean for us Java developers and for IT industry in general? In the past Oracle and Sun were very complementary, but the last years they became competitors also. Think about Sun acquiring MySQL and Oracle acquiring BEA Systems (including it's J2EE BEA WebLogic application server).
I guess Oracle will try to keep Java adopted as much as possible (it's in their own interest), but I don't think this will count for MySQL and GlassFish. I guess we will see a lot of other products being merged in the future, like NetBeans and JDeveloper. Time will tell, but it will definitely have some impact!
I will end with some new prophecies:
- Within 2 years Grails will be the leading platform for Java web development.
- Groovy will be the most dominant dynamic language on the JVM (Uhhhh, actually I don't think this is a prophecy but reality already).
- By 2012 a lot of Java developers are using Groovy without even knowing they are actually using Groovy.
- Someday Oracle will buy SpringSource.
- Very soon there will be a nice Groovy module for easily developing small Google App Engine applications.
Posted by Marcel Overdijk at 11:26 AM 5 comments
Wednesday, April 8, 2009
Java support on Google App Engine
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.
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
Thursday, March 12, 2009
Grails Tip of the Day: Always use packages
First of all I must say I'm lazy and I don't like overhead... That's also the reason why I don't use packages for Grails domain classes. Most Grails applications I've build so far consist of no more then 20 domain classes, so I had never the need to separate them in packages. In fact I like to have them in the top folder; no overhead of subfolders.
As Grails 1.1 was released I decided to restart Grails on Sakila. I recreated the domain classes including a "Category" domain class. I generated the default Controller and Views without problems and started the application. When browsing to the list page of the Category domain class I got (GRAILS-4233):
Welcome to Grails 1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\Grails\grails-1.1
Base Directory: D:\Grails\projects\grails-on-sakila
Running script D:\Grails\grails-1.1\scripts\RunApp.groovy
Environment set to development
[groovyc] Compiling 2 source files to D:\Users\moverdijk\.grails\1.1\projects\grails-on-sakila\classes
[groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, D:\Grails\projects\grails-on-sakila\grails-app\controllers\CategoryController.groovy: 40: You cannot create an instance from the abstract interface 'groovy.lang.Category'.
[groovyc] @ line 40, column 32.
[groovyc] def categoryInstance = new Category()
[groovyc] ^
[groovyc] D:\Grails\projects\grails-on-sakila\grails-app\controllers\CategoryController.groovy: 46: You cannot create an instance from the abstract interface 'groovy.lang.Category'.
[groovyc] @ line 46, column 32.
[groovyc] def categoryInstance = new Category(params)
[groovyc] ^
[groovyc] D:\Grails\projects\grails-on-sakila\grails-app\controllers\CategoryController.groovy: 40: You cannot create an instance from the abstract interface 'groovy.lang.Category'.
[groovyc] @ line 40, column 32.
[groovyc] def categoryInstance = new Category()
[groovyc] ^
[groovyc] D:\Grails\projects\grails-on-sakila\grails-app\controllers\CategoryController.groovy: 46: You cannot create an instance from the abstract interface 'groovy.lang.Category'.
[groovyc] @ line 46, column 32.
[groovyc] def categoryInstance = new Category(params)
[groovyc] ^
[groovyc] D:\Grails\projects\grails-on-sakila\grails-app\controllers\CategoryController.groovy: 40: You cannot create an instance from the abstract interface 'groovy.lang.Category'.
[groovyc] @ line 40, column 32.
[groovyc] def categoryInstance = new Category()
[groovyc] ^
[groovyc] D:\Grails\projects\grails-on-sakila\grails-app\controllers\CategoryController.groovy: 46: You cannot create an instance from the abstract interface 'groovy.lang.Category'.
[groovyc] @ line 46, column 32.
[groovyc] def categoryInstance = new Category(params)
[groovyc] ^
[groovyc]
[groovyc] 6 errors
Compilation error: Compilation Failed
First thing I thought I made some mistake but this wasn't the case. The problem is that Groovy resolves the Category class to groovy.lang.Category and not to my Grails domain class. This means if you have domain classes with the same name as a class in groovy.lang and don't use packages you will get into troubles.
So from now on I will create/put my Grails artifacts in a package, which is a good practice anyway. When running the Grails command line scripts to create artifacts you can specify the package so Grails automatically creates the package structure: e.g.:
grails create-domain-class org.company.Book
PS: I you want to read more about Groovy Categories have a look at the Groovy User Guide.
Posted by Marcel Overdijk at 3:01 PM 12 comments
Tuesday, March 10, 2009
Grails 1.1 I18n Templates and Message Digest Plugin Released
Grails 1.1 was released just a couple of hours ago but I like to announce the availability of the updated I18n Templates Plugin already. Check out the link for more details.
Besides the I18n Templates Plugin I also released another new Message Digest Plugin this evening. This simple plugin provides message digest codecs (currently SHA1 and SHA1Hex) to encode strings easily:
"some string".encodeAsSHA1Hex()
To be honest I think I've "stolen" these codecs from Marc Palmer some time ago... I was working on some home project in which I needed them again so it was time to make a plugin out of it, so everyone can benefit from it. The plugin currently only supports SHA1 and SHA1Hex codecs but I might extend it in the future with MD5 codecs and some other convienient message digesting stuff. Feature requests or patches can be raised at the Grails Plugins JIRA issue tracker.
Posted by Marcel Overdijk at 3:13 PM 4 comments
Labels: Grails
Thursday, February 26, 2009
NetBeans 6.7 M2 released with advanced Grails code completion
Last wednesday the NetBeans team released NetBeans 6.7 M2. For Grails developers this is great as it now supports code completion for dynamic methods and dynamic finders. Just great! And even better: debugging support is next on their priority list!
Check Petr Hejl's Blog for more information.
Posted by Marcel Overdijk at 3:15 PM 2 comments
Saturday, January 31, 2009
Grails, NetBeans and Microsoft Team Foundation Server
At our internal development factory at Valid we use Microsoft Team Foundation Server (TFS) as the central versioning system. As we recently started a new Grails project we had to use TFS for versioning. We also use NetBeans 6.5 as it's has some nice Grails support.
When we started I had a little bit of caution against using TFS... And we faced some really annoying problem immediatly. You have to check out each file manually before you can edit it as the files are read-only. So for example when regenerating the controller and views for a domain class you have to check them out first... For Microsoft developers this is no problem as they are using Microsoft Visual Studio and the IDE is checking out the automatically when the change the file within their IDE.
For Eclipse users Teamprise ($$$) is available, but for NetBeans there is no plugin yet to work against TFS.
After searching for a solution I bumped at SvnBridge. SvnBridge allows you to use TortoiseSVN and other Subversion clients with Team Foundation Server. It converts the calls made by your Subversion client to the API supported by TFS. As NetBeans supports Subversion I gave it try, and my first experience is really good (just tried it out 30 minutes ago). I can connect with TFS as it was a Subversion server, and it automatically checks out the files when I edit them in NetBeans. Just great!
Here some steps to setup the SvnBridge:
- Download SvnBridge from http://www.codeplex.com/SvnBridge.
- Unpack the downloaded file and start SvnBridge.exe.
- A new icon will appear in your taskbar to indicate SvnBridge is running, you can right click it to change settings. I changed the Bridge Port to 8085 as my Grails application is running on the default 8080 port.
- In NetBeans go to Versioning -> Subversion -> Checkout as you would normally check out a Subversion project. You have to enter the bridged TFS/SVN path like:
http://localhost:8085/[tfs.server.name]/[projectname]
(e.g.http://localhost:8085/tfs.mycompany.com/myproject
). Enter your TFS crendentials and you can check out your Grails project from TFS.
That's just it! You can now use NetBeans to enjoy working with a TFS versioning system. Don't forget all creadits go to SvnBridge.
Posted by Marcel Overdijk at 3:54 AM 6 comments
Labels: Grails, Microsoft, Netbeans, SVNBridge, Team Foundation Server