terça-feira, 5 de junho de 2007

Evolution e rdesktop

Na empresa onde trabalho utilizamos o Microsoft Exchange Server e todas as suas funcionalidades colaborativas. Apesar de não ser um fã da Microsoft, devo reconhecer que esta ferramenta (em conjunto com o Outlook) é realmente muito boa. O problema é que na área em que trabalho utilizamos Linux, porque várias ferramentas que utilizamos simplesmente dariam muito trabalho para rodar no Windows (além do que, gostamos mesmo de Linux). Surgiu aí um problema: como usar o Outlook?

Primeira idéia: VMware. A gente separa um pedaço do disco, instala o Windows lá e o executa dentro do VMware. O leitor mais astuto logo se espanta - "Gastar espaço em disco, memória e processamento mantendo o Windows rodando dentro do Linux, só por causa do Outlook? Fala sério!". Pois é ... muito esforço pra pouco retorno ... idéia facilmente descartada.

Segunda idéia: Evolution. Esta é uma aplicação que faz quase tudo que o Outlook faz (integra e-mail, lista de contatos, calendários, ...), e consegue conversar com o Exchange. Perfeito ... até o dia em que tivemos que visualizar as agendas de outros usuários ... simplesmente não conseguimos fazer isto funcionar. Mas como esta não é uma funcionalidade crucial, não iríamos desistir do Evolution só por causa disso. Mais fácil conectar numa máquina Windows e rodar o Outlook pra ver as agendas dos demais quando necessário - desde que eu não tenha que levantar da minha cadeira pra isso. E como fazer isso?

Primeira alternativa: VNC. Basta rodar um servidor de VNC numa máquina Windows pouco utilizada (temos uma aqui), e nos conectarmos através dela. Problema: para cada usuário, teríamos ter que ter um servidor rodando (e para tal, mais de uma sessão rodando ao mesmo tempo rodando no Windows). Não havia forma de fazermos isso.

Segunda alternativa: rdesktop. Este é um cliente open source que fala Remote Desktop Protocol (RDP) - o mesmo protocolo usado pelo Desktop Remoto que temos no Windows. O único problema, é que podemos ter somente um usuário logado na máquina (se alguém estiver logado na máquina, e alguém quiser utilizá-lo remotamente, o usuário é "chutado", sem chances de defesa) ... mas, como precisamos disso ocasionalmente e a máquina que iremos utilizar é pouco usada, resolvemos adotar a combinação Evolution / rdesktop. Não é perfeito, mas funciona - além disso, temos a esperança que um dia esse problema do Evolution será resolvido. Mas caso alguém tenha uma solução melhor para este problema, não se acanhe ... coloque aqui para nós.

De qualquer maneira, fica aqui a dica de duas ferramentas muito interessantes para minimizar os problemas da distância entre os mundos Linux e Windows - Evolution e rdesktop.


Powered by ScribeFire.

terça-feira, 8 de maio de 2007

MyFaces e Tiles

Estou iniciando o desenvolvimento de uma aplicação utilizando MyFaces. Esta escolha se deu porque gosto do esquema do Java Server Faces (JSF), e após ter trabalhado com a implementação JSF da Sun, resolvi dar uma chance ao MyFaces, pois parece ter algumas soluções interessantes para alguns problemas que enfrentei com o anterior. Em conjunto, estou utilizando diversas componentes providas pelo Tomahawk, que extendem as funcionalidades das componentes básicas do JSF, além de oferecer diversas outras componentes.

JSF é muito bom, mas não resolve todos os problemas. Um destes problemas é a questão de gerenciamento de layouts - em JSF, se você quiser que todas as páginas de sua aplicação obedeçam a um mesmo layout, você tem que replicá-lo em todas as suas páginas; imagina se depois você quiser mudar esse layout, o problema que não vai ser alterar todas as páginas. Para resolver este problema, integramos ao JSF o Tiles. Este é um framework inicialmente desenvolvido dentro do Struts, mas que agora foi separado deste, que simplifica o desenvolvimento de interfaces de aplicações web. Ele se baseia no padrão Composite View, permitindo que se definam fragmentos de página (menu, header, footer, etc ...), que podem ser agrupados em um layout, que pode ser aplicado às suas páginas. O conceito é bastante interessante, e para quem quiser mais detalhes, sugiro que leia o tutorial do Tiles.

Vou aqui explicar como estou realizando esta integração. A primeira coisa que fiz foi definir a estrutura do meu layout, que é composto por:

  • Header
  • Menu
  • Conteúdo
Basicamente, o header e o menu são sempre o mesmo. A única coisa que varia é o conteúdo a ser exibido. Com isto, defini uma página ( layout.jsp ) onde defini o posicionamento destas componentes de layout, e a utilizei em uma definition no arquivo de configuração do Tiles:


<definition name="layout" template="/layout.jsp" >
<put-attribute name="header" value="/header.jsp" />
<put-attribute name="menu" value="/menu.jsp" />
<put-attribute name="content" value="/blank.jsp" />
</definition>


Note que para cada componente do layout há uma página associada. Estes valores podem ser alterados em tempo de execução, e irei utilizar esta funcionalidade para exibir diferentes conteúdos da minha aplicação (alterando a página a ser exibida pela componente content. Abaixo, mostro o código de layout.jsp, onde posiciono um elemento embaixo do outro:


<tiles:importAttribute scope="request" />

<f:subview id="header">
<tiles:insertAttribute name="header" flush="false"/>
</f:subview>
<f:subview id="menu">
<tiles:insertAttribute name="menu" flush="false"/>
</f:subview>
<f:subview id="content">
<tiles:insertAttribute name="content" flush="false"/>
/<f:subview>


Um problema desta forma de integração que adotei é que, para cada página (conteúdo) que desejo exibir, preciso criar dois arquivos jsp: um para definir o conteúdo, e outro para inserir este conteúdo dentro do layout. Abaixo, um exemplo da página que insere o conteúdo dentro do layout. Note-se que isto é feito utilizando a definition que criamos anteriomente, e sobrescrevendo-se a propriedade content:


<f:view>
<tiles:insertDefinition name="layout" flush="false" >
<tiles:putAttribute name="content" value="/pageContent.jsp" />
</tiles:insertDefinition>
</f:view>


Certamente esta não é a melhor solução, mas foi a primeira que veio à minha cabeça. No futuro, pretendo gastar um pouco de neurônios pensando em uma forma de gerar apenas um arquivo jsp por página a ser exibida.


Para configurar o Tiles para ser utilizado pelo JSF, basta você acrescentar o seguinte código em seu arquivo web.xml (além dos jar's do Tiles):


<servlet>
<servlet-name>tiles</servlet-name>
<servlet-class>org.apache.tiles.servlet.TilesServlet</servlet-class>
<init-param>
<param-name>org.apache.tiles.DEFINITIONS_CONFIG</param-name>
<param-value>/WEB-INF/tiles-defs.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>


Nesta solução, o que eu gostaria de alcançar era:

  • facilidade de gerenciamento de layout
  • manter o controle de navegação do JSF
  • facilidade de integração
Tirando o overhead de gerar um arquivo a mais por página gerada, acho que a solução é boa. E tem funcionado bem para os meus propósitos. Se você tiver alguma sugestão, dica, crítica, não esqueça de deixar seu comentário.





Powered by ScribeFire.

quarta-feira, 17 de janeiro de 2007

Exemplos de código

Para aqueles que estão aprendendo uma nova linguagem, ou como utilizar uma nova API, exemplos de código ajudam bastante. Uma excelente fonte de códigos são os softwares abertos, desenvolvidos nas mais diferentes linguagens.

Mas quando você está interessado em algo específico, como por exemplo, como utilizar a API do JMS, fica difícil procurar exemplos nos códigos abertos, a não ser que se utilize um mecanismo de busca, como o Koders, e o Google Code Search. Outra opção são os livros, e os tutoriais disponíveis na rede. Mas um serviço interessante oferece diversos códigos de exemplo, para linguagem Java, C#, ASP.Net, JavasScript, PHP, SQL, etc, etc, etc ... este serviço está disponível no endereço www.java2s.com.

Parece ser bem organizado, mas não consegui descobrir que mantém o site, tampouco quão atualizado ele é ... de qualquer forma, pode ser uma fonte interessante, especialmente para quem está iniciando o aprendizado.

powered by performancing firefox

quinta-feira, 11 de janeiro de 2007

Monitoramento de memória do JBoss

Recentemente ao testar uma funcionalidade que havia implementado no JBoss, tive um problema de falta de memória. Problema normal, fácil de resolver ... mas isto me chamou a atenção para que eu monitorasse o consumo de memória do JBoss.



Há algum tempo, ao começar a usar o ActiveMQ, tive a necessidade de monitorar os objetos dessa aplicação, e graças a isto conheci o JConsole. Minha primeira idéia foi usar o JConsole para monitorar o JBoss, e realmente funcionou. Para tanto segui os conselhos descritos por Steve Brownlee em seu blog (fusioncube). Segue o link para o post em questão:



Fusioncube » Blog Archive » JVM Memory Monitoring







powered by performancing firefox

quarta-feira, 2 de agosto de 2006

[JSF] - DataTables, CommandLink's e CommandButton's

Aqueles que já tiveram o prazer de tentar fazer uma componente commandLink ou commandButtons funcionar dentro de uma componente ''dataTable'' utilizando o escopo request para o managed bean que armazena os dados exibidos pelo dataTable, sabem que não dá. O jeito é mudar o escopo do managed bean para session.

O problema com esta "solução" é que os dados perduram. Exemplificando: imagine que você está implementando um caso de uso que mostra uma lista de entidades que obedecem às restrições impostas por filtros de busca cujos valores são determinados pelo usuário. O comportamento esperado é que, ao acessar a página, não se mostre nenhum valor, e após o usuário ordenar a busca, os elementos sejam obtidos e exibidos. Simples assim. Com a "solução" acima, isto ocorre na primeira vez que o usuário acessa esta página. Porém, dentro da mesma sessão, nas próximas vezes que o usuário acessar a página, ele irá automaticamente visualizar os dados da última busca que ele realizou.

Um pouco de pesquisa, na tentativa de manter o escopo como request, me levou à seguinte descrição de bug (que no final mostrou não ser um bug) - javaserverfaces:issue 69.

Conforme entendi, o problema é que no momento do processamento da fase Apply request values, o managed bean com os dados utilizados pela dataTable ainda não foi inicializado (ele somente será na fase Render response). Desta forma, a decodificação desta componente não funcionará como esperado, e tampouco a decodificação das componentes filhas (incluindo os commandLink's e commandButton's). Por isso, nenhum método de ação associado a estes elementos será executado.

Chegamos então à seguinte conclusão: nossa aplicação só funciona se usarmos escopo session. Mas isto é necessário somente para os dados a serem exibidos pelo dataTable. Com isto, sugiro a seguinte solução:

  1. Crie um managed bean (requestBean) em escopo request para gerenciar os dados não associados ao dataTable, e para gerenciar as ações da sua página
  2. Crie um managed bean (sessionBean) em escopo session somente para armazenar os dados exibidos pelo dataTable
  3. Você deve atribuir um valor vazio para os dados do sessionBean no construtor do requestBean, e com o resultado da busca, sempre que o método que realiza a busca em requestBean for executado

Surge aí outro problema. Como alterar os dados de sessionBean a partir do requestBean? Basta usar o seguinte código dentro do requestBean:


FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().
createValueBinding("#{SessionBean.data}").setValue( context, newData );


Você pode reparar que o EL #{SessionBean.data} é igual ao EL que você usa no seu JSP associado ao atributo value da sua componente dataTable (h:dataTable).

É uma solução trabalhosa. Muito melhor seria se o JSF funcionasse de forma um pouco mais intuitiva. Mas nada é perfeito ...