Outro dia um amigo me pediu para instalar o Ubuntu no netbook dele, um HP Mini (não lembro exatamente qual modelo). Baixei o Ubuntu Netbook Remix 10.10 e instalei no pen drive, seguindo as instruções que aparecem na página de download. Em seguida, fiz o boot pelo pen drive e iniciei a instalação. Tudo ia bem até que em determinado momento recebi uma mensagem de erro. Não lembro qual era a mensagem, mas parecia ser algo relacionado a disco. Tentei novamente e o erro se repetiu.

Em seguida, lembrei que quando eu havia instalado este mesmo sistema operacional num outro netbook HP Mini, mas a versão do Ubuntu era 10.04. Como a página principal do Ubuntu só disponibiliza links para download da última versão, encontrei as versões anteriores na página Ubuntu Releases. Na página específica da versão 10.04 (Lucid Lynx) o link aparece como PC (Intel x86) netbook live CD.

Após baixar esta versão e instalá-la no pen drive, tudo funcionou. Aparentemente é algum problema relacionado com a versão 10.10 mesmo. Tudo funciona de primeira, sem necessitar qualquer configuração (bluetooth, som, webcam, etc.), exceto o wifi. A página Hardware support do wiki do Ubuntu traz a solução: basta conectar o netbook à Internet via porta Ethernet e reinstalar o driver bcmwl, digitando no terminal: sudo apt-get install bcmwl-kernel-source. Após a instalação, reinicie o netbook e tudo funcionará.


No dia 09 de outubro aconteceu o Dev in Rio 2010. Como a edição de 2009 foi muito boa, a expectativa para a deste ano era alta. E foi correspondida! Desta vez foram duas salas com palestras acontecendo simultaneamente. Eu fiquei na sala 2, onde assisti às seguintes palestras:

  • HTML 5 e as novas JS APIs - Leonardo Balter

    Na primeira palestra foram apresentadas as principais APIs do HTML5. A palestra foi bem interessante, apesar de bastante prejudicada pela falta de WiFi no local, o que impediu que o palestrante mostrasse os vários exemplos que ele tinha preparado.

  • NodeJS - a performance que eu sempre quis ter - Emerson Macedo

    A palestra do Emerson foi excelente. Ele apresentou o problema de bloqueio de I/O no acesso a banco de dados, que é um dos principais gargalos no desempenho para a maioria das linguagens de programação. O NodeJS ajuda a resolver este problema pois usa Javascript, que é uma linguagem orientada a eventos. No final da apresentação, ele divulgou o Nodecasts, site de screencasts sobre NodeJS que ele acaba de criar. A apresentação está disponível no blog do Emerson.

  • Lightning Talks

    Após o almoço, foi disponibilizado um horário para lightning talks, pequenas apresentações de 5 minutos para quem tivesse algo interessante para mostrar. Como o tempo foi curto, foram apenas duas apresentações: a primeira sobre desenvolvimento de aplicações Python para celular e outra sobre a Apache Foundation.

  • Symfony - OO PHP para gente grande - Luã de Souza

    Nesta palestra, foi apresentado o Symfony, um framework PHP para desenvolvimento web que vem crescendo bastante. É um framework MVC que, a exemplo de praticamente qualquer framework atual, inspira-se no Rails para simplificar o desenvolvimento de aplicações web.

  • Refactoring - Porque apenas fazer funcionar não é o suficiente - Caike Souza

    Esta foi uma das melhores palestras do evento. Caike Souza falou sobre refactoring - destacando que não existe refactoring sem testes -, apresentou as principais vantagens e alguns exemplos práticos em Ruby.

  • Arquitetura: cansado da mesmice? - Guilherme Silveira

    Apesar do título não deixar claro, esta palestra foi direcionada a arquitetura com serviços Restful. Como todas as palestras dele, Guilherme Silveira foi bastante claro, mostrando as vantagens de uma arquitetura voltada para serviços, que vai além da simples troca de arquivos XML entre aplicações. Ele mostrou um exemplo bem interessante, sobre integração entre sites de viagens, reserva de hotéis e calendário, onde o compartilhamento de recursos permite que uma aplicação acesse diretamente os serviços de outra. Mais detalhes no post que ele escreveu no blog da Caelum.

  • Testes unitários em JavaScript: usar ou não usar mock? - Márcio Santana

    Na última palestra, foram apresentadas ferramentas para testes de código Javascript. Esta palestra também foi muito interessante, pois testes de Javascript são muito pouco comuns, mas não deveriam, já que Javascript também é código, e as aplicações web atuais possuem uma quantidade cada vez maior de código Javascript, principalmente para manipular interações com os usuários. Além do QUnit - framework para testar Javascript -, foram apresentadas bibliotecas de mock, como o Chameleon.

Enquanto isso, na sala 1 ocorreram palestras sobre Arduino, empreendedorismo, Scum e Ruby.

Apesar de tudo, o evento teve alguns problemas de organização. Além da já citada indisponibilidade de WiFi, as duas salas ficavam em andares diferentes, e o coffee break era ao lado da sala 1, o que dificultava o deslocamento. Num determinado momento, a palestra da sala 2 terminou e todos desceram para o andar da sala 1 para o coffee break, porém não podíamos entrar, pois a palestra não havia terminado. Apesar destes pequenos problemas, o Dev in Rio deste ano manteve a qualidade da primeira edição. Agora, ficamos aguardando a edição de 2011!


Desde a versão 3.6.4, o Firefox possui um recurso chamado Crash protection (somente para Windows e Linux). Agora o browser cria um processo à parte chamado plugin-container para execução dos plugins do Flash, QuickTime e Silverlight. O objetivo é impedir que um erro na execução de um destes plugins trave o browser - caso isto ocorra, somente o plugin será interrompido.

Depois que atualizei o Firefox para esta versão - na verdade, atualizei diretamente do 3.6.3 para o 3.6.6 - no Ubuntu 10.04, o Flash simplesmente parou de funcionar, exibindo a mensagem “The Adobe Flash plugin has crashed”. Tentei reinstalar o Flash diversas vezes, tanto pelos pacotes adobe-flashplugin e flashplugin-installer usando o apt-get quando baixando um arquivo .deb diretamente. A página plugin check informava que o Flash estava instalado, porém com uma versão desatualizada (9.x). Também tentei reinstalar o Firefox e nada.

Depois de alguns dias de tentativas frustradas, finalmente tive a ideia de testar com outro browser. Pelo Chrome o Flash funcionava perfeitamente, ou seja, o problema estava diretamente relacionado com o Firefox.

Após mais algumas pesquisas, encontrei o artigo Plugin-container and out-of-process plugins. Descobri que há um parâmetro na configuração do Firefox (digite about:config na barra de endereços para acessá-la) chamado dom.ipc.plugins.enabled que permite habilitar ou desabilitar o crash protection para plugins de terceiros. Este parâmetro serve para qualquer plugin não especificado, e o valor padrão é false. Há um parâmetro específico para o plugin do Flash: no Linux é o dom.ipc.plugins.enabled.libflashplayer.so, e no Windows é dom.ipc.plugins.enabled.npswf32.dll. Este parâmetro tem o valor padrão true; depois que mudei para false, o Flash passou a funcionar na maioria dos sites; porém, os vídeos da Globo.com, por exemplo, continuaram não funcionando, mas passaram a exibir uma mensagem dizendo que o Flash estava desatualizado.

Para descobrir mais informações sobre os plugins, digitei about:plugins na barra de endereços. A página que apareceu mostrou duas versões de Flash instaladas: uma era a mais recente (10.x) e a outra estava desatualizada (9.x). Porém, esta tela não mostrava a localização de cada plugin. Para descobrir o path completo para cada plugin, voltei para a tela de configuração (about:config) e alterei o valor do parâmetro plugin.expose_full_path para true. Agora, a tela do about:plugins passa a exibir o path de cada plugin instalado.

Desta forma, descobri que havia uma versão mais antiga do Flash instalada no meu home (em /home/guilherme/.mozilla/plugins/libflashplayer.so). Não sei a ordem em que o Firefox procura os plugins, mas aparentemente este estava sendo utilizado em vez do mais atual, que fica em /usr/lib/flashplugin-installer/libflashplayer.so. Removi a versão que estava no home e o Flash voltou a funcionar perfeitamente, inclusive depois de reativar o crash protection.

Outras referências úteis não citadas:


Atualmente estou trabalhando em alguns projetos que possuem diversas características em comum. Para facilitar o reaproveitamento de código, criamos um módulo à parte, uma espécie de framework, com todo o código comum aos projetos, e modularizamos os projetos usando Maven.

Quando chegamos na camada de apresentação, percebemos que não estávamos reaproveitando código como nas demais camadas. Pelo contrário, os XHTMLs de várias telas eram bastante parecidos, e estávamos basicamente copiando e colando quando surgia uma tela nova. Inclusive dentro de um mesmo XHTML, muita parte do código era copiada, pois vários elementos se repetiam (ex: elementos de formulário, com um label e um campo de texto ao lado). Decidimos então criar componentes Facelets.

A criação de componentes Facelets é muito simples, basta seguir os passos abaixo:

  1. Criar o componente. Como exemplo, criei um chamado itemFormulario, que exibe um label, um campo de texto e as mensagens de erro correspondentes:

    ```xml <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

    ```

    Esse arquivo será salvo em /WEB-INF/facelets/ com o nome itemFormulario.xhtml. Neste exemplo, o componente utiliza os parâmetros id, label e value.

  2. Criar um arquivo de taglib para registrar os componentes criados. Este arquivo, que vou chamar de projeto.taglib.xml, será criado no diretório /WEB-INF/facelets do projeto, e será como no exemplo abaixo:

    ```xml <!DOCTYPE facelet-taglib PUBLIC “-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN” “https://facelets.dev.java.net/source/browse/checkout/facelets/src/etc/facelet-taglib_1_0.dtd”>

    http://exemplo.com.br/jsf itemFormulario itemFormulario.xhtml</source>

    ```

    Neste exemplo, registrei o componente itemFormulario. Sempre que criar um novo componente, ele deverá ser registrado neste arquivo, através de uma nova tag <tag>.

  3. Registrar a biblioteca de taglib no projeto, adicionando o trecho abaixo ao arquivo web.xml:

    ```xml

    facelets.LIBRARIES /WEB-INF/facelets/projeto.taglib.xml

    ```

    Desta forma, os componentes declarados no arquivo de taglib poderão ser usados no seu projeto, como neste exemplo:

    ```xml <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

    ```

A partir deste ponto, precisamos compartilhar estes componentes entre os diferentes projetos. Para isso, seguimos os passos abaixo:

  1. Mover o conteúdo do diretório /WEB-INF/facelets (arquivo de taglib e componentes criados) para o módulo compartilhado. Colocar estes arquivos na raiz do diretório /META-INF

  2. Atualizar no arquivo web.xml o trecho que registra a taglib:

    ```xml

    facelets.LIBRARIES /META-INF/projeto.taglib.xml

    ```

    Se for utilizar mais de uma taglib, declare-as separadas por “;” no trecho acima.

  3. Repetir o passo anterior para cada projeto que irá utilizar os componentes criados

Nas versões atuais do Facelets, a declaração da taglib no arquivo web.xml é desnecessária caso este arquivo esteja na raiz do diretório /META-INF. Os arquivos de componentes poderão ficar em outro diretório (ex: /META-INF/facelets), bastanto atualizar o arquivo de taglib de acordo com o diretório escolhido:

<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "https://facelets.dev.java.net/source/browse/*checkout*/facelets/src/etc/facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://exemplo.com.br/jsf</namespace>
    <tag>
        <tag-name>itemFormulario</tag-name>
        <source>/META-INF/facelets/itemFormulario.xhtml</source>
    </tag>
</facelet-taglib>

Há ainda um passo opcional, que é a criação de um arquivo TLD (taglib descriptor) para que a IDE possa validar os componentes que você criou. Um arquivo TLD tem o seguinte formato:

<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
    <tlib-version>1.0</tlib-version>
    <jsp-version>2.0</jsp-version>
    <short-name>Componentes</short-name>
    <uri>http://exemplo.com.br/jsf</uri>
    <display-name>Minha biblioteca de componentes</display-name>
    <tag>
        <name>itemFormulario</name>
        <tag-class />
        <body-content>empty</body-content>
        <description>
            Cria um item de formulário com label, campo de texto e mensagens de erro.
        </description>
        <attribute>
            <name>id</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
            <type>java.lang.String</type>
            <description>
                Identificação do componente
            </description>
        </attribute>
        <attribute>
            <name>label</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
            <type>java.lang.String</type>
            <description>
                Texto exibido no label do componente
            </description>
        </attribute>
        <attribute>
            <name>value</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
            <type>java.lang.String</type>
            <description>
                Valor associado ao inputText do componente
            </description>
        </attribute>
    </tag>
</taglib>

Salve esse arquivo com o nome projeto.taglib.tld, no mesmo diretório do arquivo projeto.taglib.xml. Agora, ao abrir um arquivo XHTML que esteja usando o componente itemFormulario, a IDE exibirá os erros de validação (ex: um atributo marcado como required não foi definido). Com este arquivo criado, ao abrir um XHTML no Eclipse usando o editor de JSP, você terá também o recurso de autocomplete (Control + espaço), que exibirá todos os atributos do componente, assim como a descrição de cada um.

Referências:


Outro dia, quando fui me logar no Gmail, digitei rapidamente meu login, apertei tab, digitei a senha e apertei enter. Na pressa, não percebi que, em vez de tab, eu tinha apertado shift. Ou seja, o campo login ficou preenchido como “loginsenha”, e a senha ficou em branco. Até aí tudo bem, o Gmail simplesmente me deu um aviso de login ou senha inválidos. Porém, esse “loginsenha” ficou no histórico de preenchimento de campos, o que é bem incômodo, já que contém minha senha. Eu queria excluir este item do histórico, mas sem perder todo o histórico do browser.

O Firefox possui uma opção “Clear Recent History”, no menu “Tools”, que permite excluir o histórico somente para um período de tempo (última hora, últimas 2 ou 4 horas, último dia ou tudo), e permite selecionar também o que se deseja excluir (URLs acessadas, downloads, formulários preenchidos, cookies, cache, logins ativos e preferências de sites). Apesar de esta opção ser bastante completa, eu queria algo mais específico: excluir somente aquele item.

Após uma rápida pesquisa no Google, encontrei algumas referências interessantes, e descobri que a solução era extremamente simples. Para excluir um item do histórico de preenchimento de campos de formulários, basta clicar no campo e, ao aparecer a lista de valores armazenados no histórico, selecione o item que você quer excluir usando a seta para baixo e pressione Del. É só isso!

Também é possível excluir itens individuais do histórico de URLs acessadas. Para isso, repita o procedimento acima, trocando apenas o Del por Shift+Del.

Referências: