Como fazer o deploy de uma aplicação web com PrimeFaces no OpenShift

Neste artigo vou mostrar como importar a User interface (UI) Framework PrimeFaces (http://primefaces.org/) para o desenvolvimento de uma aplicação web de JavaServer Faces (JSF) utilizando NetBeans (https://www.netbeans.org) e alojar a mesma aplicação na plataforma OpenShift por SFTP.

O OpenShift Online (https://www.openshift.com) é um serviço em nuvem da Red Hat (http://www.redhat.com) para desenvolvimento de aplicações e alojamento ou seja é um Platform as a service (PaaS) que permite otimizar a aplicação web e não necessitamos de preocupar com a infraestrutura necessária para distribuir a aplicação web.

Uma das vantagens de utilizarmos o OpenShift é a utilização de um plano gratuito sem necessitarmos de cartão de crédito.

Principais diferenças nos planos disponíveis:

PlanoGratuitoBronzePrateado
Preço baseGratuitoGratuito15€/mês
Inatividade da aplicação24 HorasNuncaNunca
EscalabilidadeSim (3 min / 3 max)Sim (3 min / 16 max max)Sim (3 min / 16 max)
Alojamento1 GB1 GB6 GB
SuporteComunidadeComunidadeRed Hat e Comunidade

No plano gratuito se a aplicação não receber nenhum pedido a mesma é desligada e apenas volta a ser ligada quando receber um novo pedido. Para que a aplicação se mantenha ligada normalmente utilizam-se técnicas para fazer pedidos de X em X tempos.

 Um dos principais concorrentes do OpenShift é a Microsoft Azure que permite também um plano gratuito para alojamento de aplicações Java, mas este apenas permite 1 GB de tráfego. No OpenShift nunca fui avisado por utilização de tráfego e a aplicação web continua a funcionar.

O PrimeFaces é uma UI Framework para Websites em JSF. Esta Framework contém um grande conjunto de componentes UI em JSF Ajax APIs, e pode consultar os componentes no showcase que estão disponíveis na página de internet do PrimeFaces. O desenvolvedor tem à sua disponibilidade quatro versões PRO, CASE, Elite e Comunidade.

 PROCASEEliteComunidade
CustoSubscrição anual por desenvolvedorGratuito (incluído comercial)
SuportePrimeFaces (resposta no máximo em um dia útil)PrimeFaces PrimeTek www.primetek.com.trComunidade PrimeFaces 

O criador do PrimeFaces também disponibiliza o Mobile UI kit para aplicações mobile, Layouts e temas para as mesmas.

Para criar a aplicação deste projeto web em JSF vai ser utilizado IDE Netbeans.  Esta aplicação é patrocinada pela Oracle e permite o desenvolvimento de projetos Java, HTML5, PHP e C/C++, não tem nenhum custo para o utilizador nem para empresas.

O idioma utilizado neste Netbeans é o Inglês. Selecione a opção New Project  para iniciar um novo projeto depois é selecionada a categoria Java Web em que é selecionado o projeto Web Application sem código incluído, após a seleção avança para fase seguinte.

NetBeans: novo projeto

É definido o nome do projeto e a localização do mesmo mas não é definida a localização da pasta das bibliotecas e avança para fase seguinte.

NetBeans: definição do projeto

O servidor a ser utilizado é o Apache Tomcat e é o mesmo que vai ser utilizado no OpenShift após a seleção avança para fase seguinte.

NetBeans: definições do servidor

O projeto vai trabalhar com JavaServer Faces.  O NetBeans já inclui as bibliotecas para o PrimeFaces mas não vai ser utilizada esta funcionalidade vais ser descarregado a última versão e importada para o projeto. Após a seleção avança para fase seguinte.

NetBeans: escolha de frameworks

Com o projeto criado a primeira coisa fazer é definir o Source/Binary Format do projeto para JDK 7, porque o OpenShift ainda não trabalha com o Java 8. Para definir clica-se com o botão direito do rato em cima no nome do projeto, seleciona-se Properties, seleciona-se a opção Sources e define-se Source/Binary Format para JDK 7.

NetBeans: versão do Java

Agora pode importar-se o PrimeFaces. Por norma eu crio uma pasta com nome libs na raiz do projeto onde coloco todas as bibliotecas que utilizo e que não estão integradas no IDE ou que são mais recentes, já que assim consigo abrir o projeto noutros computadores sem problemas. Também pode se utilizar o Maven.

openShift8

Após a importação da biblioteca é necessário que a mesma seja reconhecida nas páginas XHTML que utilizem os componentes UI assim é necessário adicionar a seguinte linha xmlns:p="http://primefaces.org/ui" no tag <html> .

O PrimeFaces tem uma ótima compilação de documentação disponível na sua página de internet (http://primefaces.org/documentation) como aplicar os seus componentes e também estão disponíveis demonstrações dos seus componentes em http://www.primefaces.org/showcase/.

Vão ser utilizadas três demonstrações. A primeira um input com validação, a segunda é idêntica à primeira mas com mensagens sobrepostas e a terceira é um menu para navegarmos entre as duas demonstrações anteriores.

Antes de iniciar a criação das demonstrações O tag url-pattern no ficheiro web.xml na pasta WEB-INF será alterado e adicionado um context-param para o PrimeFaces.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
 <context-param>
 <param-name>javax.faces.PROJECT_STAGE</param-name>
 <param-value>Development</param-value>
 </context-param>
 <context-param>
 <param-name>javax.faces.CONFIG_FILES</param-name>
 <param-value>/WEB-INF/faces-config.xml</param-value>
 </context-param>
 <servlet>
 <servlet-name>Faces Servlet</servlet-name>
 <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
 <servlet-name>Faces Servlet</servlet-name>
 <url-pattern>*.xhtml</url-pattern>
 </servlet-mapping>
 <session-config>
 <session-timeout>
 30
 </session-timeout>
 </session-config>
 <welcome-file-list>
 <welcome-file>index.xhtml</welcome-file>
 </welcome-file-list>
</web-app>

É criado um novo ficheiro com nome faces-config.xml na mesma pasta com o seguinte conteúdo.

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
 xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
</faces-config>

As alterações anteriores não são obrigatórias mas fica a conhecer os ficheiros onde se definem as configurações a serem utilizadas no PrimeFaces. Com por exemplo a configuração das páginas em que o utilizador consegue aceder sem sessão e as páginas que apenas acede com uma sessão iniciada.  

Demo 1

Validação de entrada de dados executados no servidor (http://www.primefaces.org/showcase/ui/ajax/validation.xhtml)

Na página de índex (index.xhtml) é apagada a linha referente ao Hello World e introduzido o seguinte código que contém o formulário que solicita a introdução de dados.

<h:form>
 <p:panel id="panel" header="Demo: http://www.primefaces.org/showcase/ui/ajax/validation.xhtml">
 <p:messages id="msgs" />
 <h:panelGrid columns="3" cellpadding="5">
 <p:outputLabel for="name" value="Insira o seu nome:" />
 <p:inputText id="name" value="#{welcomeView.name}" required="true" label="name">
 <f:validateLength minimum="2" />
 </p:inputText>
 <p:message for="name" display="icon" />
 </h:panelGrid>
 <p:commandButton value="Submeter" update="panel" actionListener="#{welcomeView.welcome}" icon="ui-icon-check" />
 </p:panel>
</h:form>

Para validar dos dados introduzidos é necessário criar uma nova classe Java que contém o código que o servidor vai utilizar para validação dos dados recebidos pelo formulário e entregar a mensagem construída.

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;

@ManagedBean
public class WelcomeView {
 
 private String name;
 
 public String getName() {
 return name;
 }
 
 public void setName(String sname) {
 this.name = sname;
 }
 
 public void welcome() {
 FacesContext.getCurrentInstance().addMessage(null,
 new FacesMessage("Olá " + name + " bem-vindo"));
 } 
}

Demo 2

É idêntico ao demo 1 mas com mensagem de informação ao utilizador sobrepostas.

É criado uma nova página XHTML que vai estar na raiz. É necessário introduzir a linha xmlns:p="http://primefaces.org/ui" no tag <html> e alterar os seguintes tags head para h:head e body para h:body.

É inserido o código referente ao formulário:

<h:form> 
 <p:growl id="growl" showDetail="true" sticky="true" /> 
 <p:panel header="Demo 2 - http://www.primefaces.org/showcase/ui/message/growl.xhtml"> 
 <h:panelGrid columns="2" cellpadding="5"> 
 <p:outputLabel for="msg" value="Mensagem:" /> 
 <p:inputText id="msg" value="#{growlView.message}" required="true" /> 
 </h:panelGrid> 
 <p:commandButton value="Guardar" actionListener="#{growlView.saveMessage}" update="growl" /> 
 </p:panel> 
</h:form>

É criada uma nova classe Java que contém o código para validação.

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
 
@ManagedBean
public class GrowlView {
 
 private String message;
 
 public String getMessage() {
 return message;
 }
 
 public void setMessage(String message) {
 this.message = message;
 }
 
 public void saveMessage() {
 FacesContext context = FacesContext.getCurrentInstance();
 context.addMessage(null, new FacesMessage("Com sucesso", "Sua mensagem: " + message) );
 context.addMessage(null, new FacesMessage("Segunda mensagem", "Detalhe adicional"));
 }
}

Demo 3 – Menu

A Framework disponibiliza vários tipos de menu onde é utilizada a componente Breadcrumb que fornece informações contextuais sobre a hierarquia da página.

Para o menu é criada uma nova página XHTML e a mesma é importada nas restantes páginas assim cada vez que é necessário atualizar o menu essa alteração é feita apenas numa única página XHTML.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://xmlns.jcp.org/jsf/html"
 xmlns:p="http://primefaces.org/ui">
 <h:body>
 <h:form> 
 <p:breadCrumb>
 <p:menuitem value="Demo 1" url="index.xhtml" />
 <p:menuitem value="Demo 1" url="index.xhtml" />
 <p:menuitem value="Demo 2" url="demo2.xhtml" />
 </p:breadCrumb>
 </h:form> 
 </h:body>
</html>

Nas restantes páginas em que o menu vai ser utilizado é necessário introduzir a linha xmlns:ui="http://xmlns.jcp.org/jsf/facelets" no tag <html>.

É inserida a importação do menu antes dos formulários.

<ui:include src="menu.xhtml"></ui:include>

O projeto está terminado. Agora pode ser executado para visualizar o resultado final. Ao iniciar o projeto e deparar-se com o seguinte erro.

Erro Tomcat

Para ser corrigido tem que definir a não utilização do proxy nas opções gerais do NetBeans.

NetBeans: definição do proxy

E assim terá o seguinte resultado quando inicia o projeto com o Tomcat.

openShift11

Com o projeto terminado, já se pode criar o ficheiro WAR que contém todos os ficheiros do projeto a serem enviados para o OpenShift através de SFTP. Para criar o ficheiro clique no projeto com o botão direito do rato selecione Clean and Build.

NetBeans: compilação do projeto

O ficheiro WAR é basicamente um ficheiro compactado no formato zip com todos os ficheiros do projeto se o abrir com o compactador de ficheiros com suporte zip pode ver o seu conteúdo.

Conteúdo do ficheiro WAR

Antes de enviar o ficheiro o projeto para OpenShift é necessário configurar o SFTP com o nosso certificado digital para que o mesmo aceite a ligação SFTP.

Para criar o certificado é utilizada a aplicação PuTTYgen (http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html). Atenção: faça download apenas do site oficial já que existem versões não oficiais que “roubam” as credenciais criadas.

Para criar o certificado inicia-se o PuTTY Key Generator e clica-se no botão Generate, a seguir move-se o rato aleatoriamente na área em branco até o certificado ser criado e depois define-se a key passphrase.

Criação de chaves com o PuTTY Key Generator

É necessário guardar a chave pública e a chave privada.

Inicie a sua conta do OpenShift, clique em definições e insira a sua chave pública conforme aparece no PuTTY Key Generator.

OpenShift: introdução da chave pública

Se pretender alterar ou apagar a chave pública pode sempre apagar no botão Delete e criar uma nova.

OpenShift: gestão de chaves

Com a chave inserida podemos criar uma nova aplicação clicando em Applications e selecionando  Tomcat 7 (JBoss EWS 2.0), a seguir define-se o endereço da aplicação.

OpenShift: criação de nova aplicação

Nos planos gratuitos por norma não é possível definir-se a região, é necessário definir-se No preference.

OpenShift: definição da região

Com a aplicação criada pode consultar-se o endereço e o utilizador para a ligação SSH que está definido no Soure Code  que tem o seguinte aspeto: 854a6dZ40c000d820@xpto-pap.rhcloud.com.

OpenShift: utilizador e endereço

Para ligarmos através de SFTP vou demonstrar com a aplicação FileZilla. Primeiro é necessário adicionar a chave privada. No menu  da aplicação selecione a opção Editar e depois Configurações.

FileZilla: adicionar chave

Na janela Configurações selecione a página SFTP e clique em Adicionar chave de ficheiro…, adicione a mesma, que foi criada anteriormente e a aplicação questiona se quer converter. Clique Sim vai ser solicitado a passphrase que foi definida  na criação da chave privada.

FileZilla: chaves

Agora pode criar-se a ligação ao OpenShift. Com as indicações do Soure Code  que tem o seguinte aspeto: 854a6dZ40c000d820@xpto-pap.rhcloud.com, o nome de utilizador é 854a6dZ40c000d820 e servidor xpto-pap.rhcloud.com. Para iniciar a ligação clica-se no botão Ligar.

FileZilla: ligação ao OpenShift

Com a ligação efetuada já pode substituir o ficheiro WAR existente pelo WAR do projeto criado.  Para isso selecione a pasta webapps localizada em /var/lib/openshift/[Nome de Utilizador]/app-root/runtime/dependencies/jbossews/webapps e substitua o ficheiro. Mas antes de o fazer é obrigatório mudar o nome do ficheiro WAR do projeto para ROOT.war. Se não mudar o nome do ficheiro e o mesmo se chamar PAP123 a aplicação não fica na raiz mas sim numa subpasta da raiz com o nome PAP123.

FileZilla

Depois de enviarmos o ficheiro reiniciamos a aplicação no painel do OpenShift.

openShift24

Atenção: Apagar outras pastas ou ficheiros pode danificar a aplicação web.

E ficamos com o seguinte resultado.

OpenShift: resultado

A vantagem de se  criarem aplicações web em Java no próprio servidor é não obrigar o utilizador a instalar o Java. Mas se o projeto trabalhar com os certificados digitais do utilizador então já é obrigado a instalar o Java para que o mesmo seja validado e identificado. A vantagem de utilizarmos uma UI Framework é de não necessitarmos criar os componentes UI e assim poupar tempo nos projetos. Mesmo utilizando a versão de comunidade existe um grande suporte no fórum do PrimeFace e em grupos do Google ou Facebook. É necessário ter atenção as novas versões em que algumas propriedades são alteradas, mas estão identificadas no manual do PrimeFaces. O OpenShift é uma ótima solução de projetos para clientes em SASS/PASS mas também se pode utilizar para experimentar o seu comportamento e/ou para mostrar. Também podemos utilizar o plano gratuito para alojamento de uma página pessoal, blog ou outros.

Os ficheiros do projeto estão disponíveis no GitHub em https://github.com/rramoscabral/pap-2015-openshift_and_primefaces.

Publicado na edição 50 (PDF) da Revista PROGRAMAR.