Renato M Miyasaki

Como fazer, links de Gestão de TI e programação.

Cluster com Terracotta

Pesquisando sobre clusterização, acabei encontrando o TerraCotta (http://www.terracotta.org/)

Para executá-lo no modo mais simples, sem fazer uma configuração mais fina, bastou instalá-lo no servidor (terracotta-3.2.1_2-installer.jar) e colocá-lo para funcionar.

Configurei um arquivo (tc-config.xml) e coloquei junto com o start-tc-server.bat – na pasta bin.

C:\Arquivos de programas\terracotta\terracotta-3.2.1_2\bin>start-tc-server.bat -n Server1

O meu arquivo de configuração:

<?xml version="1.0" encoding="UTF-8"?>
<!-- All content copyright Terracotta, Inc., unless otherwise indicated.      All rights reserved. -->
<tc:tc-config xsi:schemaLocation="http://www.terracotta.org/schema/terracotta-5.xsd"
xmlns:tc="http://www.terracotta.org/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<servers>
<!– Sets where the Terracotta server can be found. Replace the value of          host with the server’s IP address. –>
<server host=”10.2.0.101″ name=”Server1″>
<data>%(user.home)/terracotta/server-data</data>
<logs>%(user.home)/terracotta/server-logs</logs>
</server>

<!– If using more than one server, add an <ha> section. –>
<ha>
<mode>networked-active-passive</mode>
<networked-active-passive>
<election-time>5</election-time>
</networked-active-passive>
</ha>
</servers>
<!– Sets where the generated client logs are saved on clients. –>
<clients>
<logs>%(user.home)/terracotta/client-logs</logs>
</clients>
</tc:tc-config>

E nas aplicações, eu coloquei no context.xml (no META-INF) ou diretamente na pasta conf do Tomcat:

<Context>
<Valve className="org.terracotta.session.TerracottaTomcat60xSessionValve" tcConfigUrl="10.2.0.101:9510"/>
<param-value>10.2.0.101:9510</param-value>
</Context>

Pronto, acione o Developer Console e veja os clientes de seu cluster.

JSF + Facelets + ICEfaces

Tive alguns problemas para conseguir incluir o ICEfaces (1.8.1) na minha aplicação JSF 1.2 (com MyFaces) + Facelets + Hibernate.

1o passo: incluir os jars necessários
Como já estava utilizando o MyFaces, utilizei o jar just-ice.jar ao invés do icefaces.jar.
backport-util-concurrent.jar
commons-beanutils.jar
commons-collections.jar
commons-digester.jar
commons-fileupload.jar
commons-logging.jar
FastInfoset.jar
icefaces-comps.jar
just-ice.jar
jxl.jar
krysalis-jCharts-1.0.0-alpha-1.jar
xercesImpl.jar
xml-apis.jar

E para utilizar o facelets também no icefaces:
icefaces-facelets.jar

2o passo: configurar web.xml

O Eclipse adicionou essa parte para mim:

<context-param>
<description>To allow multiple windows for a single application.</description>
<param-name>com.icesoft.faces.concurrentDOMViews</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<description>Turn on/off application-wide synchronous or asynchronous updates.    </description>
<param-name>com.icesoft.faces.synchronousUpdate</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<description>Google Maps API key is required if gMap component is used. Sign up for an API key from http://code.google.com/apis/maps/signup.html</description>
<param-name>com.icesoft.faces.gmapKey</param-name>
<param-value>ABQIAAAADlu0ZiSTam64EKaCQr9eTRTOTuQNzJNXRlYRLknj4cQ89tFfpxTEqxQnVWL4k55OPICgF5_SOZE06A</param-value>
</context-param>
<context-param>
<param-name>com.icesoft.faces.uploadDirectory</param-name>
<param-value>upload</param-value>
</context-param>
<context-param>
<param-name>com.icesoft.faces.uploadMaxFileSize</param-name>
<param-value>404857600</param-value>
</context-param>

<listener>
<listener-class>com.icesoft.faces.util.event.servlet.ContextEventRepeater</listener-class>
</listener>

<servlet>
<servlet-name>Persistent Faces Servlet</servlet-name>
<servlet-class>com.icesoft.faces.webapp.xmlhttp.PersistentFacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Blocking Servlet</servlet-name>
<servlet-class>com.icesoft.faces.webapp.xmlhttp.BlockingServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>uploadServlet</servlet-name>
<servlet-class>com.icesoft.faces.component.inputfile.FileUploadServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>Persistent Faces Servlet</servlet-name>
<url-pattern>*.iface</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Persistent Faces Servlet</servlet-name>
<url-pattern>/xmlhttp/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Blocking Servlet</servlet-name>
<url-pattern>/block/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>uploadServlet</servlet-name>
<url-pattern>/uploadHtml</url-pattern>
</servlet-mapping>

E essa parte, eu adicionei para que em algumas páginas eu utilizasse o icefaces e em sem.

<context-param>
<description>
The following parameter will cause the ICEfaces ViewHandler
to process only those pages with a .iface extension:
</description>
<param-name>com.icesoft.faces.delegateNonIface</param-name>
<param-value>true</param-value>
</context-param>

3o passo: configurar faces-config.xml
Tive que basicamente mudar as navegações, onde estava pagina.xhtml, mudei para pagina.iface

4o passo:
Testar

Regras:
Nas expressões, se o icefaces estende o html ou o tomahawk, tive que utilizar a implementação do icefaces. Exemplo: onde era mudei para . Podem até coexistir, porém não funcionará corretamente.

Algumas referências:
Icefaces + Tomahawk – Status of ICEfaces Support for MyFaces Tomahawk Components
http://support.icesoft.com/jive/servlet/KbServlet/download/731-102-1045/ICEfacesTomahawkCompSupport.html
PDF – Guia do desenvolvedor do ICEfaces (ver pasta docs do download do ICEfaces)

JSF + Facelets: alterar objeto agregado em um droplist

Estou fazendo uma prova de conceito com JSF + Facelets + Hibernate, e tive problemas em alterar um objeto agregado em um droplist.

Antes, eu estava somente colocando o código identificador do objeto que queria modificar, e assim ele me dava o erro “org.hibernate.HibernateException: identifier of an instance …

O código antes era:

<h:selectOneMenu id=”forn” value=”#{NotaFiscalBean.notaFiscal.fornecedor.codFornecedor}” >
<f:selectItems value=”#{NotaFiscalBean.fornecedores}” ></f:selectItems>
</h:selectOneMenu>

Onde #{Bean.notaFiscal.fornecedor.codFornecedor} é o código do objeto agregado e;
#{NotaFiscalBean.fornecedores} é uma lista de objetos do tipo Map (na verdade, SelectItem) com os valores possíveis. E a chave continha o código identificador e o valor, o nome do fornecedor.

O novo código passou a ser:

<h:selectOneMenu id=”forn” converter=”#{NotaFiscalBean.fornecedorConverter}
value=”#{NotaFiscalBean.notaFiscal.fornecedor}” >
<f:selectItems value=”#{NotaFiscalBean.fornecedores}” ></f:selectItems>
</h:selectOneMenu>

Onde: #{NotaFiscalBean.notaFiscal.fornecedor} é o objeto agregado;
#{NotaFiscalBean.fornecedores} é igual acima, exceto que na chave do mapeamento passei a utilizar os objetos;
#{NotaFiscalBean.fornecedorConverter} é uma classe que implementa a interface javax.faces.convert.Converter

Na implementação de javax.faces.convert.Converter, você precisa implementar os métodos:
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) e;
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2).

Adicionalmente, inclui o construtor que recebe a lista dos possíveis objetos.

Então, a minha classe Converter ficou assim:

package com.renatom.jsf.converter;

import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

import com.renatom.jsf.model.Fornecedor;

public class FornecedorConverter implements Converter {

List <Fornecedor> list;

public FornecedorConverter(List<Fornecedor> fornecedores) {
list = fornecedores;
}

@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
if (arg2 == null || arg2.length() == 0)
return null;

long id = Long.valueOf(arg2).longValue();
if (id < 0)
return null;

Fornecedor fornRet = null;
for (Fornecedor forn : list) {
if (forn.getCodFornecedor() == id) {
fornRet = forn;
break;
}
}
return fornRet;
}

@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
if (arg2==null) return "-1";
Fornecedor forn = (Fornecedor)arg2;
return String.valueOf(forn.getCodFornecedor());
}
}

Fonte: http://seamframework.org/Community/SelectOneMenuAndJPAManyToOne

Hibernate + JPA no Eclipse com Hiber Objects

Hiber Objects – http://objectgeneration.com/eclipse/index.html

Plugin para eclipse que gera, através de um diagrama de classes, todo o código necessário para persistir dados de uma tabela.

Gera código Java dos POJOs, DAOs, classes de teste.

Agiliza o desenvolvimento com o Hibernate para Java.

Rubis


Ruby OnRails, ouvi isso faz uns dois anos atrás. Não tinha dado muita importância na época, mas no meio do ano passado, acabei pegando um projeto em PHP, e a equipe resolveu que iríamos utilizar o CakePHP, programei cerca de 4 meses em cima desse framework. A produtividade realmente é impressionante, muito fácil de criar formulários para cadastro em tabelas de Banco de dados. O CakePHP, segundo os seus desenvolvedores, foi baseado no Ruby On Rails (RoR).

Ontem, eu baixei um tutorial, que dizem ser muito bom – se bem que eu nem acho que é um tutorial, mas sim um livro eletrônico, ele tem 312 páginas. O tutorial pode ser encontrado aqui.

Vou lê-lo e fazer seus exercícios, para aprender um pouco. Para substituir o PHP, ainda parece muito cedo, mas eu vou aprendê-lo, nunca se sabe o dia de amanhã.

E ainda para ajudar tem o Groovy, que é uma mistura de Ruby, Python e Perl e roda sobre JVM (Java Virtual Machine). Bom, mas isso fica para um próximo post.

[]s
miyasaki

Comandos básicos de Subversion – linha de comando

Bom, hoje eu resolvi organizar meus projetos no Subversion, mas como eu estou acostumado a utilizar o TortoiseSVN, eu não lembrava mais como era a sintaxe dos comandos. E sim, aqui no meu notebook com Linux, vou utilizar via linha de comando, para desenferrujar e lembrar os velhos tempos da faculdade.

Ah, e como fonte vou utilizar um tutorial da faculdade: http://www.linux.ime.usp.br/wiki/Subversion

Só para criar o repositório que não tem lá, isso porque quem cria o repositório são os administradores da rede.

Para isso utilizei o comando:

svnadmin create <diretório do repositorio>, no meu caso svnadmin create ~/repositorios/brimagens

Para fazer o checkout, utilizei o comando svn co file:///home/renato/repositorios/brimagens dentro do meu workspace (aka seu diretório de desenvolvimento de projetos).

[]s
renato