quarta-feira, 21 de dezembro de 2011

Instalando features do Eclipse via linha de comando com Provision Platform, p2

O Eclipse é a minha IDE favorita, por algumas razões:
  • OpenSource: sendo uma ferramenta de código livre, além de ser possível contribuir, analisar, reutilizar o código-fonte e aprender com o mesmo, a comunidade de desenvolvedores ao redor do mundo pode ampliar os horizontes da plataforma com suas contribuições.
  • Multi-plataforma: assim como a maior parte das ferramentas open-source, o Eclipse também é multi-plataforma, oferecendo assim ainda mais liberdade para que você trabalhe no ambiente que lhe proporciona mais segurança e mais recursos.
  • Multi-linguagem: como todo bom programador, eu não sou viciado em uma única linguagem, e procuro sempre utilizar a linguagem apenas como ferramenta. Apesar de ter trabalhando recentemente mais com a linguagem Java, Python, C e C++, PHP são outros sabores que eu aprecio. Claro, um pouco de shell script para automatizar tarefas corriqueiras são uma boa pedida. O Eclipse lhe oferece um ambiente uniforme para trabalhar com as linguagens, o que para mim é um fator importante, evitando atritos ao programar em mais de uma linguagem em curtos intervalos de tempo.
Por estes e outros motivos, me tornei um Amigo do Eclipse, e fiz uma modesta contribuição para o projeto. Recentemente, descobri um recurso da plataforma que facilita automatizar a instalação de plugins via linha de comando. Este recurso permite que você faça a instalação de uma série de plugins de uma única vez, realize deploys ou até mesmo, construa a partir de sua própria seleção de plugins, uma versão customizada da IDE.

Background
O processo faz uso de um recurso da plataforma do Eclipse chamado Provisioning Platform (p2). Especificamente, uma aplicação do p2 chamada Director [1]. Com esta aplicação, é possível automatizar o processo via linha de comando.

Basicamente, tudo que você tem a fazer é executar a aplicação org.eclipse.equinox.p2.director, e informar as features a serem instaladas, bem como os repositórios a serem consultados para resolução de dependências.

Tecnicamente, este é o mesmo processo que a interface gráfica realiza, com exceção de que você está automaticamente concordando com as licenças dos softwares que está instalando, uma vez que a tela de confirmação não é exibida.

Passo a passo
Terminologia básica para o processo de instalação:
  • Director: a aplicação do Eclipse que está realizando a instalação ou remoção de software. Ela está no bundle org.eclipse.equinox.p2.director.app.
  • Builder: uma aplicação baseada na plataforma do Eclipse que contém o bundle do Director e suas dependências. Pode ser utilizado, por exemplo, para criar uma nova instalação de plugins (modo shared) ou da IDE completa em um diretório diferente.
  • Produto alvo: uma aplicação alvo onde o software será instalado. Pode ser o mesmo do Builder, quando você quer instalar plugins e features em uma versão da IDE, como o Java EE.
Tudo que precisamos é do p2 Director para começar. O modo mais fácil é você já ter baixado o Eclipse para Java, Java EE ou qualquer outro de sua preferência, e começar a adicionar um conjunto de plugins. Você também pode, por exemplo, criar também uma aplicação mínima do eclipse que tenha apenas o Director e então, criar um instalador para baixar um pacote completo.

Vamos supor que você tenha baixado o Eclipse for Java EE Developers, e queira adicionar o Mobile Tools For Java (MTJ). Para isso, você precisará utilizar o seguinte comando (supondo que o binário ou script launcher do Eclipse esteja em seu PATH):


$ eclipse -nosplash -application org.eclipse.equinox.p2.director -repository http://download.eclipse.org/releases/indigo/ -installIU org.eclipse.mtj.feature.group -tag “Added-org.eclipse.mtj.feature.group”

O parâmetro -nosplash evita que a tela de splash seja exibida e fique congelada, já que não precisamos de interface gráfica. Com o parâmetro -application indicamos que o Director deve ser iniciado e não a Workbench. Os parâmetros seguintes, -repository e -installIU, permitem configurar, respectivamente, de onde os plugins e features serão baixados e quais instalation units devem ser adicionadas (plugins, features ou feature-groups). Esses dois parâmetros recebem uma lista separada por vírgulas, o que permite instalar vários plugins de diferentes fontes ao mesmo tempo. O parãmetro -tag permite marcar o que foi feito nesta operação, assim fica fácil “reverter” pela itnerface gráfica do Eclipse (ou mesmo pelo director) para uma tag mais antiga caso a instalação falhe.

Depois de rodar este comando, você vai ver algumas linhas no prompt:

Installing org.eclipse.mtj.feature.group 1.1.2.201109111413.
Operation completed in 337201 ms.

Ao iniciar novamente o Eclipse, você vai poder confirmar que o MTJ foi adicionado com sucesso ao sistema:

Você pdoe conferir nossa tag clicando em Help → About Eclipse, depois no botão Instalation Details. Na aba Instalation History, você vai ver:


Apesar dos parâmetros -repository e -feature aceitarem multiplas opções separadas por vírgula, eu notei que ao tentar instalar muitos plugins em uma única vez pode resultar em conflitos. Eu acredito que o resolvedor de dependências começa a ficar confuso. Eu também notei isso na própria interface gráfica, via Eclipse Marketplace ao tentar instalar o Google Plugin + SDKs, Apache Ivy e Pydev ao mesmo tempo.

p2-install
O que me motivou a descobrir este recurso foi ter que, nas últimas semanas, configurar várias vezes uma mesma instalação do Eclipse padrão com as ferramentas do Google Plugin for Eclipse, SDKs do AppEngine e Google Webtoolkit, Apache Ivy e IvyDE, e o MercurialEclipse. Este conjunto de ferramentas é o mínimo  essencial no meu emprego atual. Como erros intermitentes ao baixar todas de uma vez só pelo Eclipse Marketplace, tive que procurar uma alternativa.

O trabalho rendeu até um pequeno script que eu compartilhei no Bitbucket no projeto ronoaldo-utils. O script já facilita um pouco com alguns defaults, prevê multiplas instalações do Eclipse e permite que você faça também um “discover” pelos feature-groups disponíveis.

Veja o código-fonte aqui. Se tiver alguma sugestão ou melhoria, crie um fork e submita um patch!

Próximos Passos
Além de instalar plugins e feature groups (Uma feature ou grupo de features composta por vários plugins), o Director permite que você instale em um outro diretório: ou seja, instale a partir de uma aplicação, tendo uma aplicação diferente como alvo. O interessante é que você pode baixar e construir a IDE inteira com este recurso. Outra ferramenta interessante do p2 é que você pode também fazer mirror e gerenciar repositório com os plugins. Ao ler isso, imaginei uma forma bem interessante de realizar o deploy de versões já pré-configuradas do Eclipse via linha de comando, para diversas máquinas, como em um laboratório ou departamento de TI. Mas, isso é assunto para outro post...

Happy hacking!

Referências

sábado, 17 de setembro de 2011

Calculando MD5 e SHA1 em Java

Hashes são extremamente úteis para representar em uma pequena cadeia de bits uma outra cadeia de bits que pode ser bem maior. Podemos considerá-lo uma forma de criptografia assimétrica, uma vez que não é possível (a não ser por meio de algoritmos de força bruta) recuperar a cadeia original a partir do hash.

Existem diversos algoritmos para o cálculo de hashes, e em Java utilizamos a classe MessageDigest para recuperar a implementação desejada. Por exemplo, para calcular o MD5 de uma string, podemos utilizar:

MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update("string original".getBytes());
byte[] digest = md5.digest();

Para exibir os dados como string, recurso util quando você pretende utilizar o MD5 para conferir se todos os bytes de um arquivo foram baixados, basta formatá-lo com:

String.format("%1$032x", new BigInteger(1, digest));

O resultado é exatamente o hash MD5 da string:

~$ echo "string original" | md5sum
3ced9d1f470cd18f06a8b6492d3ea94e  -

Neste exemplo, utilizamos a string de formatação "%1$032x", porque queremos o resultado em hexadecimal, alinhado em 32 casas à esquerda. Construímos um BigInteger positivo, com os bits resultantes da soma, e isso nos permite converter os bytes do array para hexadecimal de forma simples.

Podemos fazer de forma semelhante ao calcular o SHA1:

MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
sha1.update("string original".getBytes());
byte[] digest = sha1.digest();
String.format("%1$040x", new BigInteger(1, digest));

Generalizando, você pode também utilizar os seguinte métodos:

public static String computeHash(String data, String algoritm,
        Integer resultSize) {
    try {
        MessageDigest digest = MessageDigest.getInstance(algoritm);
        digest.update(data.getBytes());
        return hexdigits(digest.digest(), resultSize);
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException("Unable to hash with " + algoritm);
    }
}

public static String hexdigits(byte[] data, Integer resultSize) {
    return String
            .format("%1$0" + resultSize + "x", new BigInteger(1, data));
}

Até a próxima dica!

quinta-feira, 25 de agosto de 2011

Coletânea de Soluções do GDD-BR

O Google Developer Day Brasil 2011 teve suas inscrições encerradas na última sexta-feira. Na empresa onde trabalho, eu e meus colegas fizemos uma coletânea de soluções em Java e estamos compartilhando com o mundo hoje!

As soluções são apenas para fins de exercício e oferecem diferentes visões de como podemos resolver o problema. Obviamente, para publicar nossas respostas o mais rápido possível, não otimizamos o código, e resolvemos as questões da primeira forma que nos veio em mente.

Deixem suas opiniões e comentários! E, claro, podem ficar à vontade para clonar o repositório de códigos de exemplo.

Se você gostaria de contribuir com sua solução, deixe um comentário que eu entro em contato para habilitar push no repositório.

terça-feira, 26 de julho de 2011

Pelo mundo (virtual) afora

No ano passado tive um acesso de inspiração e publiquei alguns cliparts no OpenCliparts.org, um portal de hospedagem de ilustrações vetoriais sob domínio público.

Algumas semanas depois, o Google começou a mostrar estes cliparts nos resultados de pesquisa por imagens com meu nome. Dias depois, cada clipart passou a aparecer várias vezes na mesma busca por imagens. Notei que os desenhos estavam se espalhando pela web de portal em portal, e como o OpenClipart adicionou meu nome no nome do arquivo e nos seus meta-dados, eu tive certeza que eram os mesmos.

Tudo bem, publiquei no OpenClipart com esse objetivo mesmo: divulgar os desenhos. Hoje fui até o OpenClipart novamente, e agora eles exibem os top 10 downloads na página de cada artista. Para minha surpresa, alguns cliparts já passaram dos mil downloads! Claro, a maior parte deve ser dos robozinhos dos sites que republicaram o trabalho, mas já é gratificante.

Também achei interessante que alguns dos modelos de documento do Google Docs que eu publiquei já foram utilizados diversas vezes. Agora os templates já não possuem mais a contagem de utilizações, apenas a avaliação dos usuários, que até agora foi de 4 estrelas.

sábado, 4 de dezembro de 2010

Hacks para o Blogger

Se você também utiliza o Blogger para os seus posts, aqui vão algumas dicas que eu descobri recentemente googlando por aí.

Remover barra de navegação


Neste tópico da ajuda, você vai encontrar informações a respeito de como ativar a barra de navegação, e vai notar que a desativação é feita publicando seu blog por FTP. Eu nem sabia que poderia publicar via FTP, e não quero isso. Uma forma mais simples de escondê-la é alterar a folha de estilos padrão para deixá-la invisível. Acesse o painel de configurações, e em seguida:
  • Clique na aba Design, e depois em "Designer do Modelo"
  • Em seguida, vá em "Avançado", e clique na seção "Adicionar CSS"
  • Insira a seguinte regra CSS ao modelo escolhido:
body .navbar {
    display: none !important;
}

Pronto, agora a barra não estará visível. Note que ela continua lá, na verdade, mas ninguém deve vê-la.

Adicionar coloração de sintaxe


Se você vai postar trechos de código, provavelmente vai preferir que eles estejam com a sintaxe em destaque, pois isso ajuda (e muito) na leitura. Existem algumas formas de se fazer isso, e a que eu achei mais simples é a de utilizar o prettyprint. Ele é bem mais simples, e detecta automaticamente a linguagem utilizada para inserir a coloração.

Você precisa baixá-lo e hospedá-lo em algum lugar. Se você tem uma conta do Google Storage for Developers ou em algum dos serviços como o Dropbox ou simliares, pode publicar o arquivo na Web.

Uma forma de inserí-lo em seu Blog é editar o HTML do seu modelo. Os novos modelos são bem interessantes, e construídos em formato XML. Entretanto, ao trocar de modelo ou realizar alguma configuração mais avançada, você pode acabar perdendo este código e ter de refazê-lo.

Outra alternativa é inserir um gadget no Blog que permita inserir código JavaScript e que não é perdido ao trocar/alterar seu modelo. Para isso, em seu painel de controle:

  • Clique na aba "Design", e em seguida na seção "Elementos da página".
  • Na área do rodapé (para evitar que o carregamento dos posts fique muito lento), adicione um gadget do tipo HTML/JavaScript com o seguinte conteúdo:
<script type="text/javascript" 
    src="http://<local onde hospedou o script>/prettify/prettify.js"></script>
<script type="text/javascript" language="javascript">
(function() {
var css = document.createElement('link');
css.rel = 'stylesheet'; css.type = 'text/css';
css.href = 'http://<local onde hospedou o script>/prettify/prettify.css';
var s = document.getElementsByTagName('script')[0]; 
s.parentNode.insertBefore(css, s);
})();
prettyPrint();
</script>

Substitua os campos marcados com <local onde hospedou o script> apropriadamente para a sua situação.

Pronto, agora basta inserir em seus posts os trechos de código envolvidos por uma tag pre ou code, com o elemento class="prettyprint". Por exemplo:

<pre class="prettyprint">
<b>Sintaxe HTML</b>
</pre>

Alterar o favicon


Semelhante ao processo acima, você pode alterar o favicon do seu Blog utilizando um gadget de Script, agora com o seguinte conteúdo:

<script>
var icon = document.createElement('link');
icon.rel = 'shortcut icon'; icon.type = 'image/vnd.microsoft.icon';
icon.href = 'http://<local onde voce hospedou>/favicon.ico';
var s = document.getElementsByTagName('script')[0]; 
s.parentNode.insertBefore(icon, s);
</script>

Ao acessar o seu blog, ele terá um ícone customizado. Utilizei esta abordagem porque estava com uma certa preguiça em procurar as opções de configuração, mas eu acredito que isso seja possível de ser realizado de forma diferente.