Tuesday 26 April 2011

VirtualBox - Increase screen resolution of guest

In order to get a decent resolution in your VirtualBox (Ubuntu) guest, you need to install the virtualbox guest X11 package:

sudo apt-get install virtualbox-ose-guest-x11

Grails part 3 - database and deployment

In this, part 3 of the series on Grails, I am going to talk about how to configure our web application to use the MySQL database as our default permanent store and then how to create a war file and deploy to Tomcat.

Firstly, we're going to install MySQL. Luckily the state of Linux package management has advanced to the point where this is as simple as:

sudo apt-get install mysql-server

It should ask what you want to set the root user password to and then install the database. Once it has installed, the database server should be started. To check this, you can run the ps aux | grep mysql command. You should see a line in the output with:

mysql 1004 0.0 0.6 178908 27960 ? Ssl 21:50 0:00 /usr/sbin/mysqld

Then we need to create the database:

CREATE DATABASE Bookstore_dev;

Now that we have our database ready to go, we need to get the MySQL driver so that our grails application can connect to the database. Go to http://www.mysql.com/downloads/ and download the Connector/J package from the MySQL connectors section. Uncompress the package and copy and paste the mysql-connector-java-5.1.15-bin.jar file into the BookStore/lib folder.

Next we'll need to modify our BookStore/grails-app/conf/DataSource.groovy file to specify that we want grails to use the MySQL database instead of the typical HSQLDB that is used. The DataSource.groovy file has three different sections "development", "test" and "production", corresponding to the three different stages of the development process and the three different environments that you can work with in grails. You can define a different database for each stage/environment. There is also a default "dataSource" section at the top, which is used unless the values are overwritten in each of the different sections. To start with, we're going to specify that the development environment should use the MySQL database. We can do this by modifying the development section to look like:

development {
dataSource {
dbCreate = "create"
url = "jdbc:mysql://localhost/Bookstore_dev"
driverClassName = "com.mysql.jdbc.Driver"
username = "root"
password = "password"
}
}


Ofcourse you'll need to change the username and password to whatever you've set them to. I'll also point out that it's not good practice to use the root user to access our database, because if our application gets hacked, our whole database would be compromised. It would be best from a security standpoint to create a new user with privileges limited to the "Bookstore_dev" database. However, since this is just our development database and we're only making it available to our local computer network for the time being it should be ok.

If we now start up our application using the grails run-app command, and once it's started browse to http://localhost:8080/BookStore, we should be able to see our application. We can then add some dummy data to check that it's getting saved to the database. I've gone ahead and added the authors "Stephen King" and "Robert A. Heinlein" and the books "Pet Cemetery", "Stranger in a Strange Land", "The Moon is a Harsh Mistress" (associating them with their respective authors). If you log into the database and have a look at it's contents you can see that the values have been added:

mysql> USE Bookstore_dev;
mysql> SHOW TABLES;
+-------------------------+
| Tables_in_Bookstore_dev |
+-------------------------+
| author |
| book |
+-------------------------+
2 rows in set (0.01 sec)

mysql> SELECT * FROM author;
+----+---------+--------------------+
| id | version | name |
+----+---------+--------------------+
| 1 | 0 | Stephen King |
| 2 | 0 | Robert A. Heinlein |
+----+---------+--------------------+
2 rows in set (0.01 sec)

mysql> SELECT * FROM book;
+----+---------+-----------+----------------------------+
| id | version | author_id | title |
+----+---------+-----------+----------------------------+
| 1 | 0 | 1 | Pet Cemetery |
| 3 | 0 | 2 | Starship Troopers |
| 4 | 0 | 2 | Stranger in a Strange Land |
+----+---------+-----------+----------------------------+
3 rows in set (0.00 sec)

So, we can see that the data is being saved to the database and that the association between the Author and Book object is represented with the 'author_id' field in the Book table. It's also worth noting the "version" field which is updated by grails every time any of the fields in the row are modified.

So now that we've got an application which uses a database it's time to deploy it to our *production* server. We're going to modify our DataSource.groovy file to ensure that the production environment (the one we're going to deploy) also uses the MySQL database:

production {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost/Bookstore_dev"
driverClassName = "com.mysql.jdbc.Driver"
username = "root"
password = "password"
}
}


Make sure you've executed the run-app command with dbCreate set to "create" before deploying this production code as dbCreate = "update" expects the tables to already be created in the database.

Now we can create the war file which we're going to upload to Tomcat through the manager web-app by running the command grails prod war. This generates a production environment war file. The production environment is optimized for code efficiency, while the development and testing environments are optimized for developer productivity. Once the command finishes executing we should have our war file under BookStore/target/BookStore-0.1.war. The 0.1 is the application version number and can be changed in the BookStore/application.properties file.

Now we can log into our Tomcat manager application (found at http://localhost:8080/manager/html if you've setup Tomcat according to the previous post), go to the Deploy section, select our WAR file and hit 'Deploy'. Once the page refreshes we should see our BookStore app in the list of applications and the column "Running" should be set to "true". We can now click on the link in the Path column to go to our web-app and start using it.

As an alternative way to deploy your application, you can also make use of the tomcat grails plugin. In order to do this you need to add a few variables to the BookStore/grails-app/conf/Config.groovy file, namely:

tomcat.deploy.username = "[tomcat manager user]"
tomcat.deploy.password = "[tomcat manager password]"
tomcat.deploy.url = "http://localhost:8080/manager"


Deploying the application is now achieved from the command line with:

grails prod tomcat deploy

This code essentially does the same thing that we did, makes a war file and deploys it, but might be preferable as it is only one step instead of two.

So there you have it, we've taken our simple web application, configured it to use a permanent datastore and deployed it to our Tomcat webserver.

NOTE: If you need to update your deployed application, the way to do it is to first "undeploy" the application from Tomcat, which can be done with "grails prod tomcat undeploy"

Wednesday 20 April 2011

Tomcat6 on Ubuntu

In this post I'm going to talk about getting Tomcat version 6 up and running on Ubuntu. I'm going to be using Ubuntu 10.10. Installing Tomcat is quite simple, due to it being in the repositories. Simply run:

sudo apt-get install tomcat6 tomcat6-admin tomcat6-examples tomcat6-docs

And that's it :) You now have a working install of Tomcat version 6 on your machine. In order to see it working point your browser to http://localhost:8080/. You'll see the Apache "It Works!" message as well as a message about where everything is and links to the docs, examples, manager and host-manager applications.

Now, in order to get access to the manager and host-manager applications you're going to have to add a user. To do this, modify the file at /etc/tomcat6/tomcat-users.xml and add the following section:

<role rolename="admin"/>
<role rolename="manager"/>
<user username="srdan" password="password" roles="admin,manager"/>


After editing the file and restarting the Tomcat server we should be able to log into the manager application by pointing our browser at http://localhost:8080/manager/html and we should be able to log into the host-manager by going to http://localhost:8080/host-manager/html. The manager will allow us to deploy, undeploy, start and stop our applications and the host-manager allows us to declare, remove, start and stop our virtual hosts.

NOTE: From Tomcat 6.0.3 onwards, there is no "manager" role that is recognised by the manager application, rather it has been split up into four roles for security purposes:

manager-gui - allows access to the HTML GUI and the status pages
manager-script - allows access to the text interface and the status pages
manager-jmx - allows access to the JMX proxy and the status pages
manager-status - allows access to the status pages only

To test out the deployment, we're going to create a very simple web application. First, create a new directory and change into it:

mkdir HelloWorld
cd HelloWorld


Next we're going to create a servlet with the following code:

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {


public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();

out.println("<html>");
out.println("<head>");

out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");

out.println("<h1>Hello World!</h1>);

out.println("</body>");
out.println("</html>");
}
}

And put it into a file called HelloWorld.java. After this we need to create a WEB-INF and WEB-INF/classes directory. Once we've done this, we compile the above code with:

javac -classpath "/usr/share/tomcat6/lib/*" HelloWorld.java

This should result in a HelloWorld.class file in the same directory. We need to move this file to the WEB-INF/classes directory:

mv HelloWorld.class WEB-INF/classes/

Now we need to add a web.xml file, which is going to tell Tomcat about our application. For our purposes we need to create a file with the following contents:

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">

<description>
Simple Hello World Servlet.
</description>
<display-name>Simple Hello World Servlet</display-name>

<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>HelloWorld</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
</web-app>


Once that's done, make sure that the file is in the WEB-INF directory, and we can go ahead and create our war file with:

jar -cvf hello.war .

Now we should be able to go back to the manager application at http://localhost:8080/manager/html, go to the Deploy section, select our war file, upload it and have it deploy straight away.

Assuming everything went fine, we can now go to http://localhost:8080/hello/HelloWorld and see our servlet in action, printing out the famous "Hello World!" message in HTML.

That concludes this post. Hopefully now you know how to install Tomcat on Ubuntu, manage it using the manager and host-manager applications, as well as how to create and deploy a very simple web application to the server.

Monday 18 April 2011

Grails part 2 - First Project

In my last post we talked a little bit about the web framework known as Grails and went through the steps required to get a working Grails development environment setup. In this post we are going to go ahead and create our first working application using the framework.

For the first application, we're going to be creating a very simple application called BookStore. It's going to consist of only two types of "objects", called "Book" and "Author". So, to begin with, the first command we want to run is:

grails create-app BookStore

This will go ahead and create the project as well as producing a lot of output. The output is the result of Grails creating the default project directory structure. Being a COC framework, grails assumes certain things about how we're going to layout our project, meaning that the unit tests are under BookStore/test/unit, the integration tests are under BookStore/test/integration and the CSS files are under BookStore/web-app/css.

Next we need to change into the newly created project directory and create the Book domain class:

cd BookStore
grails create-domain-class bookstore.Book


The "create-domain-class" command has gone and created two new files for our project, one to define our Book class and the other a Unit test class for Book. They can be found under:

BookStore/grails-app/domain/bookstore/Book.groovy
BookStore/grails-app/test/unit/bookstore/Book.groovy


In order to do something a little more useful with our domain class, we're going to have to give it "properties". In order to do this, open the domain class definition for Book and modify it to look like the following:

package bookstore
class Book {

String title
Author author
static constraints = {
}
}


We now have a Book class with a "name" and an "author" property. However, we haven't created the Author class yet, so this property isn't pointing to anything at the moment. Let's change that by creating an Author class:

grails create-domain-class bookstore.Author

This should create the Author domain class in much the same way that it created the Book class. Let's modify this new class to have a name property and let's add a property to point to all of the books that this author has written. Modify the BookStore/grails-app/domain/bookstore/Author.groovy file to look like the following:

package bookstore
class Author {
String name
static hasMany = [books:Book]
static constraints = {
}
}


The line static hasMany = [books:Book] is an important one as it defines the "many" part of the "one-to-many" relationship between Book and Author. i.e. each Book has one Author and an Author can have many Books.

We can now run our application with:

grails run-app

And then navigating to http://localhost:8080/BookStore/. However, at the moment this just shows us the default grails home page and there's not much we can do with it. This is because we haven't defined any controllers in our application. Controllers, of MVC fame, are the things which handle the application logic of our web-app. What does this actually mean? Well, they receive incoming requests, decide where to send them and how to deal with any incoming data. They also supply data to the view layer to be used to display our objects to the user.

In order to grace our application with some controllers and views, we will execute the generate-all command which will get us up and running with both a controller and views:

grails generate-all bookstore.Book

We then also need to do this for the Author class:

grails generate-all bookstore.Author

Now, when we run the grails run-app command and navigate to http://localhost:8080/BookStore we should see two controllers on the default Grails page. Selecting either of these controllers will allow us to execute the full set of CRUD commands on the Book and Author classes.

If you've had a go at creating a new Author and/or Book object(s) you'll notice that when creating a new Book for example there is an Author drop down generated containing a list of all of the Authors. However, instead of displaying the Author's name property, the drop down is listing the id and the class type, which is not very pretty. To change this behaviour we're going to overwrite the toString method for both the Book and Author class.

Modify Book.groovy to look like:

package bookstore
class Book {

String title
Author author
static constraints = {
}
String toString(){ return title }
}


And Author.groovy to look like:

package bookstore
class Author {
String name
static hasMany = [books:Book]
static constraints = {
}
String toString(){ return name }
}


And that's it for now. We've ended up creating a simple BookStore application with two domain objects in a one-to-many relationship.

I've only started scratching the surface of what can be done with Grails. In the coming weeks I'd like to go over unit tests, views, authentication and authorization and as many more topics as time will allow.

Friday 8 April 2011

Grails - Ruby on Rails for the JVM

This post will be about a framework for the JVM called Grails, which stands for (or rather, used to stand for) Groovy on Rails. Grails is a RoR-like framework making use of the Groovy language and the "Convention over Configuration" paradigm which RoR seems to have made so popular.

First a little bit of history as to how I discovered grails. I was introduced to the grails framework in a round about way, when I started looking for the perfect RoR IDE and ended up using Netbeans (funnily enough, Netbeans has since dropped support for RoR). As a way of getting familiar with Netbeans I started working my way through the Netbeans tutorials, trying out the different frameworks and technologies along the way. This eventually led me to Grails. If there's one thing to be taken away from this little story it's to never stop learning new ways to write code and that the Netbeans tutorials are an excellent resource :-)

So, to get on with the show. We will be using a clean install of Ubuntu 10.10 (desktop edition) as our operating system, so bear in mind that you may have to tweak the commands below depending on your enviroment. The first thing we need to do before installing grails is to ensure that we have a Java runtime environment and a Java Developement Kit installed. Ubuntu 10.10 should come with the OpenJDK JRE installed by default. To check this out we open a terminal run java -version and we should see the following as output:

java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.7) (6b20-1.9.7-0ubuntu1)
OpenJDK Client VM (build 19.0-b09, mixed mode, sharing)


To install the JDK, we run:

sudo apt-get install openjdk-6-jdk

and install all of the necessary packages.

In order to run grails from the command line, we'll also need to set the JAVA_HOME and GRAILS_HOME variables as well as adding these to the PATH. We can achieve this by adding the following to the bottom of our ~/.bashrc file:

export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
export GRAILS_HOME=$HOME/grails
PATH=$PATH:$JAVA_HOME/bin:$GRAILS_HOME/bin


NOTE: We'll have to open a new console window for these environment variables to become available.

Now that we've setup the environment, we can go to grails.org and download the latest Grails binary (1.3.7 at the time of this article). I usually move it to the home folder so that it's sitting under ~/grails-1.3.7. The observant amongst you will have noticed that in our ~/.bashrc file we've set $GRAILS_HOME to ~/grails previously, so in order to make this work, we create a symbolic link to this folder using ln -s ~/grails-1.3.7 ~/grails. We should now have our grails environment set up, so running grails from the terminal should give the following output:

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

No script name specified. Use 'grails help' for more info or 'grails interactive' to enter interactive mode


Congratulations, we now have a working grails install!

That's it for this post, in the next one we'll be having a look at creating our first grails project.