Stephen Connolly / Deploy your java apps to the cloud

Created Sun, 01 May 2011 00:00:00 +0000 Modified Sun, 01 May 2011 00:00:00 +0000
649 Words

I work for CloudBees Inc., they are a great company with great products. I have mostly been working on the DEV@ side of the fence which is focused on continuous integration and basically the development side of your application, but we also have the RUN@ side of the fence where we provide a platform as a service (PaaS) for running your java web applications on the cloud. I could give you the sales pitch, but I’ll leave it at: the technologies and people behind RUN@ were one of the key reasons why I decided to join CloudBees.

Well I’ve been busy on some stuff since joining, so I decided it was time to actually try out the RUN@ stuff for my self.  So here is my experience:

My test application:

I’m on the Apache Maven PMC, so I’m going to build it with… shock… horror… Maven.

I am partial to the odd bit of JSF, so it will be a JSF 2.0 application based off of Apache MyFaces.

I love Jetty as a servlet container for local testing, so we’ll use that hammer too.

Let’s get started…

First the pom.xml

<project xmlns=“http://maven.apache.org/POM/4.0.0" xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.blogspot.javaadventure.cloudbees.run

jsf2-hello-world

0.1-SNAPSHOT

war

JSF 2.0 Hello World

A JSF 2.0 web application that says hello world.

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<project.build.outputEncoding>UTF-8</project.build.outputEncoding>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

org.apache.myfaces.core

myfaces-api

2.0.5

org.apache.myfaces.core

myfaces-impl

2.0.5

junit

junit

4.8.2

test

maven-clean-plugin

2.4.1

maven-compiler-plugin

2.3.2

1.6

1.6

maven-deploy-plugin

2.6

maven-failsafe-plugin

2.8.1

integration-test

verify

maven-install-plugin

2.3.1

maven-jar-plugin

2.3.1

maven-surefire-plugin

2.8.1

maven-release-plugin

2.1

maven-resources-plugin

2.5

org.mortbay.jetty

jetty-maven-plugin

8.0.0.M2

maven-release-plugin

true

install

Then the src/main/webapp/WEB-INF/web.xml

<web-app version=“2.5” 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">

JSF 2.0 Hello World

A JSF 2.0 web application that says hello world.

javax.faces.STATE_SAVING_METHOD

server

javax.faces.DEFAULT_SUFFIX

.xhtml

javax.faces.FACELETS_SKIP_COMMENTS

true

javax.faces.PROJECT_STAGE

Production

org.apache.myfaces.webapp.StartupServletContextListener

Faces Servlet

javax.faces.webapp.FacesServlet

1

Faces Servlet

*.xhtml

60

index.xhtml

Then the backing bean (src/main/java/com/blogspot/javaadventure/cloudbees/run/GreeterBean.java)

package com.blogspot.javaadventure.cloudbees.run;

import javax.faces.bean.ManagedBean;

import javax.faces.bean.ViewScoped;

import java.io.Serializable;

@ManagedBean(name=“greeter”)

@ViewScoped

public class GreeterBean implements Serializable {

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getResponse() {

if (name != null && !name.isEmpty()) {

return “Hello " + name;

} else {

return null;

}

}

}

Should always have some tests (src/test/java/com/blogspot/javaadventure/cloudbees/run/GreeterBeanTest.java)

package com.blogspot.javaadventure.cloudbees.run;

import org.junit.Test;

import static org.hamcrest.CoreMatchers.*;

import static org.junit.Assert.*;

public class GreeterBeanTest {

@Test

public void nullNameMeansNoGreeting() throws Exception {

GreeterBean instance = new GreeterBean();

instance.setName(null);

assertThat(instance.getResponse(), nullValue());

}

@Test

public void noNameMeansNoGreeting() throws Exception {

GreeterBean instance = new GreeterBean();

instance.setName(””);

assertThat(instance.getResponse(), nullValue());

}

@Test

public void aNameMeansGreeting() throws Exception {

GreeterBean instance = new GreeterBean();

instance.setName(“Fred”);

assertThat(instance.getResponse(), notNullValue());

}

}

Next the page of our web application (src/main/webapp/index.xhtml), i’m going to use the JSF 2.0 ajax support (because it’s there)

xmlns:ui=“http://java.sun.com/jsf/facelets"

xmlns:h=“http://java.sun.com/jsf/html"

xmlns:f=“http://java.sun.com/jsf/core">

<ui:insert name=“metadata”/>

<h:head>

JSF 2.0 Hello World

</h:head>

<h:body>

<f:view>

<h:form>

<h:outputLabel for=“greeter” value=“Please tell me your name:”/>

<h:inputText id=“greeter” value=”#{greeter.name}">

<f:ajax event=“keyup” render=“text”/>

</h:inputText>

</h:form>

<h:outputText id=“text” value="${greeter.response}”/>

</f:view>

</h:body>

Let’s test it locally

$ mvn jetty:run[INFO] Scanning for projects…

[INFO]

[INFO] ————————————————————————

[INFO] Building JSF 2.0 Hello World 0.1-SNAPSHOT

[INFO] ————————————————————————

[INFO]

…WARNING:


*** WARNING: Apache MyFaces-2 is running in DEVELOPMENT mode. ***

*** ^^^^^^^^^^^ ***

*** Do NOT deploy to your live server(s) without changing this. ***

*** See Application#getProjectStage() for more information. ***


2011-05-17 10:22:10.982:INFO::Started SelectChannelConnector@0.0.0.0:8080

[INFO] Started Jetty Server

Fire up a browser to http://localhost:8080/ and here’s what we get:OK, so now I turn off DEVELOPMENT mode in the web.xml, build my app and deploy it to RUN@cloud… and here’s what we get:That was cool. Didn’t have to change anything (other than switch to production mode for safety as it’s being deployed in the wild) and I did all this in under 20 minutes (including signing up for RUN@cloud)

My next steps will be to integrate this web application with DEV@cloud and our Jenkins plugin for deployment to RUN@cloud so that I can show off continuous deployment! But that will be a different day!