Mostrando postagens com marcador Java. Mostrar todas as postagens
Mostrando postagens com marcador Java. Mostrar todas as postagens

quinta-feira, 7 de junho de 2012

Preservando as Permissões do Linux com Script Java Ant Build

O projeto Ant da Apache é uma biblioteca utilíssima que, lendo um pequeno script em XML, é capaz de compilar todo o código do seu projeto, empacotá-lo em arquivo JAR, WAR, EAR, ZIP ou outros formatos e ainda faz mais uma série de outras coisas divertidas, a maioria envolvendo manipulação de arquivos e diretórios.
Embora seja o compilador/empacotador padrão de quase qualquer projeto Java profissional, o Ant lida com manipulação de arquivos e execução de programas tão bem que pode facilmente ler scripts que, com certa criatividade, podem compilar e empacotar programas e C, C++, dentre outras linguagens, além de servir de empacotador para outros projetos genéricos.


  • As Permissões no Linux

(Mais informações sobre as permissões do Linux, vide aqui).
No Linux, as permissões de acesso e execução de arquivos é gravada em forma de atributos de arquivo, e estão dispersas em 3 níveis: usuário (dono do arquivo), os outros membros do grupo principal (do usuário dono do arquivo) e, finalmente, os outros usuários que sobraram. Cada um destes três níveis tem 3 atributos de permissão: leitura somente, leitura e gravação, execução. Assim, temos uma combinação de 7 possibilidades para cada nível, ficando:

0 --- sem permissão
1 --x execução
2 -w- escrita
3 -wx escrita e execução
4 r-- leitura
5 r-x leitura e execução
6 rw- leitura e escrita
7 rwx leitura, escrita e execução

Como se pode perceber, estas permissões, nesta ordem (rwx) formam uma seqüência de 3 bits, que pode então ser representada por um número octal (sim, já que 23 = 8).

0: 000
1: 001
2: 010
3: 011
4: 100
5: 101
6: 110
7: 111

Assim, se temos 3 níveis, e se cada nível pode ser representado por um número octal, então as permissões completas podem ser representadas por uma seqüência de 3 números octais. Exemplos:


rwx rwx rwx = 777
r-x r-x r-x = 555
rwx r-- r-- = 744
e assim por diante...


  • O Problema das Permissões no Linux

Muito bem, e qual o problema disso?? É bem simples, meu caro Watson...
Se a permissão de execução de um arquivo, no Linux, é tão-somente um atributo deste arquivo, como podemos preservá-lo, caso o arquivo seja compilado via Ant?? Suponhamos os seguintes cenários:

1- Que o Ant empacote um programa que tem um arquivo executável (por exemplo, script.sh) gerando um arquivo ZIP. Isso funciona?

Não funciona. O formato ZIP não retém as permissões de arquivos do Linux. Ainda que retivesse, se o programa estiver sendo empacotado numa máquina que roda outro sistema (ex: Windows), as permissões não existirão e, no momento em que o Ant ler o arquivo, elas continuarão perdidas.
Exemplo:

[Este exemplo não faz o que pretendemos]
[arquivos compilados e copiados para a pasta "build"]
<zip destfile="pacote.zip" basedir="build"/>


2- Ah, mas o Ant tem uma task tar. E se ele empacotar o programa como tar??

O formato tar suporta o que queremos, de fato, mas ainda é pouco. Exatamente porque o Java é multiplataforma, a task tar do Ant não usa o programa tar do seu Linux. Usa uma implementação totalmente feita em Java do padrão tar. Só poderia ser assim, para que a task funcionasse inclusive em máquinas que não têm o programa tar, garantindo a compatibilidade entre as diversas plataformas.
O resultado disso é que o arquivo tar é gerado perfeitamente, porém sem as permissões herdadas de cada arquivo, e sim com permissões genéricas.
Exemplo:

[Este exemplo não faz o que pretendemos]
[arquivos compilados e copiados para a pasta "build"]
<tar destfile="pacote.tar">
     <fileset dir="build" includes="**/*"/>
</tar>


  • A Solução do Problema

Finalmente, existem algumas opções que podem resolver o problema. Vamos a elas.

1- Usando o Programa tar de seu Linux

Esta sabemos que não é a melhor opção, embora funcione. Através da task exec, o Ant permite a execução de um programa externo, inclusive passando parâmetros (argumentos) para o mesmo (mais sobre esta task aqui).
O exemplo abaixo indica como chamar o programa tar de um script Ant, passando argumentos que indicam o que deve ser empacotado (diretório ".") e uma lista de arquivos a serem excluídos. O problema é que, como o programa tar normalmente só existe em ambientes Linux, para evitar erros, a task é instruída a só executar se este ambiente for detectado. Esta detecção, internamente, é feita pela propriedade de sistema "os.name".

[Este exemplo não é a melhor opção]
<exec executable="tar" output="/dev/null" os="Linux">
        <arg value="--exclude-from=arquivos_a_excluir.txt"/>
        <arg value="-cvz"/>
        <arg value="--file=${pacote.tar}"/>
        <arg value="."/>
</exec>

A fragilidade desta opção é que, dependendo de um programa externo, ela não funciona em qualquer plataforma. Se você constrói seu sistema sozinho ou se a sua equipe tem o ambiente todo padronizado, então ela pode ser usada. Caso contrário, você teria que criar tantas task exec quanto sistemas usados por sua equipe, e torcer para que, em cada sistema, todos tenham o programa tar no mesmo lugar (ou no PATH).


1- A Forma Correta

A maneira abaixo despreza chamadas para programas externas e constrói a solução ideal. Como isto é possível??
Simples, meu caro Watson: substituímos (ou incluímos) a tag (elemento) fileset pela tag tarfileset. Esta tag é específica da task tar e herda de fileset. Esta faz o mesmo que aquela, ou seja, define uma lista de arquivos para serem considerados, porém com duas propriedades (atributos) a mais, a saber:

- filemode: define as permissões de arquivo Linux que os arquivos incluídos nesta tag deverão ter após incluídos no pacote tar, independente de os arquivos originais terem ou não estas permissões.
- dirmode: faz o mesmo, porém para diretórios.

Assim, é possível se manter ou mesmo trocar as permissões de arquivos no momento de serem empacotados no pacote tar. Evidentemente, devido a esta arquitetura de trabalho, o pacote tar será formado como desejado mesmo que você esteja rodando o script Ant de ambiente Windows, que não suporta as permissões de arquivos Linux. Ou seja: funciona em qualquer plataforma, por mais louca que seja a maneira como ela armazena seus arquivos.

Veja na prática como funciona, pelo exemplo abaixo:

[Este exemplo é o recomendável]
<tar destfile="pacote.tar">
    <fileset dir="build" includes="**/*" excludes="build/script.sh"/>
    <tarfileset dir="build" includes="build/script.sh" filemode="755"/>
</tar>

 No exemplo, selecionamos os arquivo que não são executáveis dentro do elemento fileset, como é feito normalmente. Porém, excluímos o único arquivo diferente, o que queremos que seja um executável. Logo abaixo, incluímos o arquivo executável, porém agora utilizando o elemento (tag) tarfileset, que está instruído a adicioná-lo ao pacote usando as permissões 755.
Como vimos acima, as permissões são representadas por 3 algarismos octais. Os atributos filemode e dirmode de tarfileset somente recebem estes 3 algarismos numéricos. No exemplo, 755 representa: rwx  r-x  r-x, ou seja, todos podem ler e executar, mas somente o dono do arquivo pode modificá-lo.


  • Conclusões

Neste artigo apresentamos como utilizar, no escopo de um script Ant, a task tar, de modo a elegantemente preservar as permissões de arquivos Linux ao se criar um pacote. Claro, estas permissões podem inclusive serem alteradas e/ou criadas no momento do empacotamento, uma vez que esta solução é ágil e flexível. Porque a implementação do tar no Ant é feita em puro Java, a solução dispensa o uso de chamadas a programas externos, o que poderia consistir em fragilidade no script, e, o melhor de tudo, pode ser rodada a partir de qualquer sistema, mesmo aqueles para quem estas permissões não existam nativamente.
Espero ter ajudado e, claro, COMENTEM!!!

domingo, 4 de setembro de 2011

Testando o Som com JavaSound

A API JavaSound é responsável pela execução de som no sistema operacional através de um dispositivo de som (placa de som) devidamente instalado. O JavaSound é uma API relativamente de baixo nível e não contém implementações de algoritmos sofisticados que ultrapassem a manipulação de sons em si, como um recurso automático para tocar arquivos de som comprimidos ou recursos para converter entre formatos de som com compressão de dados, filtragem de banda, análise de espectro, etc. Claro que tudo isso pode ser implementado e realizado usando o JavaSound, mas não vem pronto de cara.
O JavaSound possui basicamente duas formas de tratar os sons: via streams de áudio formatadas (chamada sampled) e via sinais MIDI. Cada qual possui seus próprios objetos e funcionalidades.


  • Testando o som com JavaSound

Para se testar o som, ou seja, para se verificar se o seu equipamento de som na máquina em que seu programa está rodando está realmente acessível ao Java, utilize estes comandos:

// Testando se é possível tocar MIDI
MidiSystem.getSequencer();

// Testando se é possível tocar áudio (wave)
AudioSystem.getMixer(null);

Note que foram testadas duas coisas: áudio e MIDI. Se tudo correr bem, estas linhas rodarão perfeitamente. Isto significa que seu sistema é capaz de prover ao menos um seqüenciador MIDI para receber sinais deste protocolo e ao menos um Mixer capaz de receber pelo menos uma entrada de áudio padrão. O argumento "null" na última linha significa que desejamos obter o Mixer padrão, e não Mixers específicos e alternativos, que podem ou não estar disponíveis, dependendo da placa de som.
Se a primeira linha falhar, você receberá um MidiUnavailableException. Caso a segunda falhe, você receberá um SecurityException, indicando que não é possível encontrar ou não se tem permissão de escrita para o dispositivo (isto pode acontecer, por exemplo, se já tiver algum outro processo escrevendo áudio para o Mixer padrão no momento em que você o testa).
Lembre-se de testar ambos os casos separadamente, para tratar cada problema de modo isolado.

Bom, espero ter ajudado. Qualquer coisa, COMENTEM!!

quinta-feira, 4 de agosto de 2011

Como criar um Pool de Conexões no JBoss

Este artigo ensina de maneira prática e rápida como criar um pool de conexões para qualquer banco de dados no JBoss, independente das aplicações. O pool criado terá suporte a transações e poderá ser usado de qualquer aplicação através da tecnologia JNDI. Ele será inicializado quando o JBoss iniciar e aguardará as solicitações das aplicações para compartilhar uma conexão. Note que este assunto é muito vasto e não pretendo exaurí-lo, mas sim criar um tutorial fácil e simples para que seu pool funcione.


  • Instalando o Driver do Banco de Dados no JBoss

O driver de seu banco de dados é simplesmente uma biblioteca jar. Basta copiá-lo para um dos seguintes locais (sendo JBOSS_HOME o diretório de instalação de seu JBoss):


JBOSS_HOME/common/lib
[aqui funcionará para o JBoss em qualquer situação ou configuração. É este local que eu recomendo ficarem os drivers dos bancos de dados que você tem]

Outras opções:

JBOSS_HOME/server/default/lib
[funcionará para a configuração default]

JBOSS_HOME/server/minimal/lib
[funcionará para a configuração minimal]
 
JBOSS_HOME/server/standard/lib
[funcionará para a configuração standard]

JBOSS_HOME/server/all/lib


  • Nomeando o Arquivo do Pool de Conexões

Vamos criar um arquivo que descreva a conexão com seu banco de dados e crie o seu pool. Este arquivo deve se chamar "aplicacao-banco-ds.xml", onde aplicacao é o nome do sistema que deve utilizar suas conexões (não obrigatório) e banco é o nome do sistema de gerenciamento de banco de dados (SGDB) a que o arquivo se refere (obrigatório). O importante é que o nome de seu arquivo termine com "-ds.xml", indicando que é um arquivo de um DataSource. Exemplos de nomes de arquivos são:

sistemas01-mysql-ds-xml
auditoria-oracle-ds.xml
sqlserver-ds.xml

O JBoss suporta vários pools de conexões, inclusive conexões a bancos diferentes. Assim, você pode criar quantos destes arquivos você quiser ou precisar. Note que as conexões só serão realmente abertas quando uma aplicação solicitar ao JBoss a conexão. Enquanto não houver solicitação, o DataSource existirá, porém sem conexão ativa.


  • Conteúdo do Arquivo de Pool de Conexões do JBoss

Suponhamos que você tenha criado um arquivo chamado "mysql-ds.xml" (ou qualquer outro nome que você deseje). O conteúdo do arquivo deverá ser:

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>MysqlDS</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/database</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>nomeusuario</user-name>
<password>senhausuario</password>
<min-pool-size>5</min-pool-size>
<max-pool-size>10</max-pool-size>
<idle-timeout-minutes>5</idle-timeout-minutes>

<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
<!-- should only be used on drivers after 3.22.1 with "ping" support    -->
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>

<!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml -->
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>

OBS: Mantenha uma tag em cada linha. Talvez a listagem acima quebre muitas tags em mais de uma linha, dependendo do seu monitor e resolução. Como se trata de um arquivo XML, então a quebra de linha é entendida como um caracter, e pode provocar erros na interpretação (
parser) do arquivo.

Entendendo as tags do arquivo:

datasources = Indica que aqui serão listadas informações para completar um DataSource, ou seja, uma fonte de conexões. Existem 3 tipos de DataSources, basicamente:

no-tx-datasource - um DataSource que não suporta JTA Transactions (transações).
local-tx-datasource - um DataSource que suporta transações com JTA, mas não suporta two phase commit.
xa-datasource - suporta transações com JTA e two phase commit usando javax.sql.XADataSource.



O que você precisará, na maioria das vezes, é o local-tx-datasource. Ainda que você não use transações diretamente, esta é a melhor opção.


local-tx-datasource = É a fonte de conexões em si.

jndi-name = O nome do JNDI que você usará para pedir uma conexão quando dentro de sua aplicação. Escolha um nome claro e simples. Este nome é a sua referência para obter a conexão dentro de qualquer aplicação rodando em seu JBoss.

connection-url = É a URL de conexão com o banco. Cada banco tem uma URL de um jeito. Uma lista das URLs de bancos de dados mais comuns está neste tutorial aqui, na seção "Set up specific DataSources". Não coloque aqui o nome do usuário do banco.

driver-class = A classe de seu Driver. Consulte o manual de seu driver para saber qual a classe que deve ser colocada aqui.

user-name = O nome do usuário do banco que será usado. Não coloque este nome diretamente na URL lá em cima!! Deixe para colocá-lo aqui, nesta tag.

password = Sim, aqui você escreverá a senha do usuário do banco. CUIDADO: se seu JBoss está em algum lugar acessível pelos usuários da rede, mesmo que somente como leitura, a senha poderá ser lida facilmente (está em texto puro), o que representa uma grande vulnerabilidade em seu sistema. Zele pelas permissões de acesso a este arquivo!!

min-pool-size e max-pool-size = representam, respectivamente, o valor mínimo e máximo de quantas conexões devem ser mantidas abertas. Assim que uma conexão é solicitada, ela é aberta e será mantida aberta se o total de conexões abertas é menor ou igual ao min-pool-size. Controle estes dados atentamente, de acordo com a carga de uso de seu sistema. Mantenha valores diferentes para ambientes de desenvolvimento e produção ou para sua máquina local.

idle-timeout-minutes = O valor em minutos máximo de ociosidade para que uma conexão seja fechada. Se uma conexão alcançar este valor de tempo sem ser utilizada, ela será fechada. Isto poupa recursos e memória da máquina. Assim como no caso acima, use-o com cuidado e de acordo com o perfil de seu sistema. Recomendo valores diferentes para máquinas locais, servidores de desenvolvimento e de produção.

As outras tags citadas acima são específicas do MySQL e estão comentadas.


  • Testando Conexões (DataSources) Diretamente no JBoss

Bom, vamos testar tudo, né?? Sem testes, como garantiremos que este trabalho todo funcionará?? Com o JBoss, é possível testar os DataSources diretamente na interface administrativa JMX-Console Admin. Dúvidas sobre esta interface?? Consulte nosso artigo Trocando a Senha do Administrador do JBoss (JMX-Console Admin).
Acesse o JMX-Console e faça login. Na tela de administração, acesse a opção:

Resources --> Datasources

Conforme mostra a Figura 01. Deve aparecer uma listagem com os seus DataSources, exibindo o nome de cada um deles (JNDI name), o tipo de DataSource, o status ("Up" significa que está funcionando) e um botão "Delete" para apagá-lo.


Figura 01: Tela de administração de DataSources do Administrador do JBoss.


Clique no nome do DataSource e logo surgirá uma nova tela, com todas as opções de administração do mesmo. Vá até a última aba (Control) e selecione "Test Connection" (Figura 02).


Figura 02: Controle administrativo do Pool de Conexões.


Se a conexão funcionou, então a sua tela vai mostrar uma linda mensagem de sucesso verdinha, conforme a Figura 03.


Figura 03: Tela de teste de conexão, após realizado.


Existe outra maneira de se testar a conexão, que é obtendo um objeto DataSource ao se fazer um Lookup a partir do InitialContext. Mas isto fica para outro artigo, onde poderemos detalhar melhor estes passos.


  • Dicas de Boas Práticas

1- Nunca crie pool de conexões dentro das aplicações, mesmo que elas usem um framework em especial, como o Hibernate. O JBoss serve para isso e ele oferece flexibilidade e recursos para as mais diferentes situações e cenários.

2- Conforme você pode ver, é possível se criar vários pools de conexão em um mesmo arquivo -ds.xml (vários local-tx-datasource, por exemplo). Não é errado, mas não é recomendável. Para se administrar melhor, mantenha um pool em cada arquivo específico.

3- Zele pela carga de seu sistema, controlando a quantidade de conexões abertas e o tempo de ociosidade delas. Se muito necessário, crie dois pools com perfis diferentes, de forma a flexibilizar seus ambientes.



Bom, este artigo detalhou bastante um processo que é mais do que comum em qualquer projeto web usando Java e JBoss, mas a que usualmente se precisa voltar e revisar, especialmente quando se é preciso criar o ambiente todo desde o início. Espero sinceramente ter ajudado. Não se esqueça de tecer seus comentários abaixo!!



sábado, 30 de julho de 2011

Trocando a Senha do Administrador do JBoss (JMX-Console Admin)

O JBoss é um servidor de aplicação dos mais utilizados mundialmente, extremamente robusto e seguro. Contudo, a sua configuração, refinamento, implementações de segurança e otimização nem sempre são muito fáceis. Este pretende ser o primeiro artigo de uma série sobre configuração e otimização do JBoss.
Como você já deve ter visto, o JBoss tem um administrador, que faz login via web no chamado JMX-Console, uma interface completa de administração do JBoss. Para fazer login, basta acessar o endereço (vide Figura 01):

http://localhost:8080/   ou
http://10.0.0.2:8080/
OBS: Troque o "10.0.0.2" pelo IP do seu servidor ou da sua máquina, e o "8080" pela porta que o JBoss está usando. O padrão é 8080.


Figura 01: Tela inicial de administração do JBoss.


Tente as duas opções acima. Dependendo da configuração, o JBoss responde a uma ou a ambas. Se você não sabe qual é a porta, então a porta deve ser 8080, que é a padrão.
Clique em "Administration Console". O usuário e senha padrões são "admin" e "admin" (Figura 02).



Figura 02: Tela de login do administrador do JMX-Console.


Para trocar a senha do administrador, vá ao arquivo:

[JBOSS_HOME]/server/default/conf/props/jmx-console-users.properties
onde JBOSS_HOME é o diretório de instalação do JBoss.

O arquivo tem o formato "user=password" e conterá os seguintes dados:

admin=admin

Agora troque o "admin" depois do sinal de "=" por uma senha segura e secreta (ex: "admin=ps9284nvlsfj!%%!Z"). Reinicie o JBoss e, pronto!! Seu usuário administrador já está protegido com uma senha novinha!!
Lembre-se de que o diretório onde este arquivo se encontra tem uma série de arquivos de configurações críticas do JBoss. Explore-os com cautela.
Bom, espero ter ajudado!! Boa sorte e bom trabalho!!

domingo, 13 de fevereiro de 2011

Tutorial Java: Convertendo uma String em Decimal, Hexadecimal ou Octal em Inteiro

Este artigo é um complemento para o artigo anterior desta série: Convertendo Binário, Octal, Hexadecimal em Inteiro em Java. A diferença entre os dois é que, no artigo citado, você precisa saber em qual formato (sistema numérico) o número está (precisa saber se está em decimal, em octal, ou em hexadecimal antes de tentar a conversão). Assim, a conversão seria feita facilmente com sobrecargas dos métodos valueOf ou parseInt, ambos da classe Integer. Este artigo ensina uma técnica para converter uma String em formato numérico desconhecido em um Inteiro.
A técnica apresentada no primeiro artigo pode ser muito útil em cenários como:

  • Leitura de dados de um arquivo XML;
  • Entrada de dados oriundo de interconversões;
  • Entradas específicas para determinados formatos (ex: uma classe que exige forçosamente a entrada de uma String em hexadecimal para a perfeita computação de seus dados, e não só a simples conversão desta String em inteiro);

A técnica apresentada neste artigo é mais flexível e pode ser usada em cenários como:

  • Entrada de dados de um componente gráfico (ex: Swing);
  • Entrada de dados de um formulário Web;
  • Entrada de dados de um arquivo texto sem formatação rigorosa (ex: um CSV);


  • Aferindo o Sistema Numérico de uma String e Convertendo-a em Inteiro

Para situações como esta, a classe Integer tem um método que é uma "mão na roda": o método estático decode(String s). Seu retorno é um Integer carregado com o valor correspondente ao que a String represente. Ele reconhece tanto valores decimais quanto octais e hexadecimais, positivos ou negativos.
Note que, para valores hexadecimais, é preciso informar o "0x" ou "0X" na frente, e para valores octais, o "0" na frente. Isto é necessário para que se cumpra a convenção numérica e que se evite ambigüidades no reconhecimento do sistema numérico empregado (sem isso, um valor como "12" estaria em decimal, octal ou hexadecimal?? Você saberia dizer?? Nem eu!!). Se nada for informado, supõe-se que o valor esteja em decimal. O método pode lançar um NumberFormatException. Esta exceção não é marcada (unchecked), mas pode ser sabiamente capturada.

Exemplo: decodificando uma String em hexadecimal:

String hexadecimal = "0xff";
Integer result = Integer.decode(hexadecimal);
System.out.println(result);

// Resultado:
255

Exemplo: decodificando uma String em octal:

String octal = "010";
Integer result = Integer.decode(octal);
System.out.println(result);

// Resultado:
8

Exemplo: decodificando uma String em decimal:

String decimal = "10";
Integer result = Integer.decode(decimal);
System.out.println(result);

// Resultado:
10


  • Interconvertendo os Dados!!

Como o resultado é sempre um Integer, e não um int (primitivo), ele pode ser igualmente auto-vertido para qualquer formato:

String number = "16";
Integer result = Integer.decode(number);
System.out.println(Integer.toHexString(result));
System.out.println(Integer.toOctalString(result));
System.out.println(Integer.toBinaryString(result));

// Resultado:
10
20
10000


  • Observações

1- Lá em cima eu havia afirmado que a técnica apresentada neste artigo permite a conversão de uma String em formato numérico desconhecido, ou seja, você não precisa saber em que formato ela está. É claro que estou fazendo uma metonímia e, assim, refiro-me não a você, desenvolvedor, mas ao código de seu programa. O mais formal seria: seu programa não precisa saber de antemão em que formato está a String para funcionar corretamente. Isto é uma coisa boa pois permite a aplicação do conceito de ocultamento de Orientação a Objetos. Na verdade, a entrada de dados precisa ser de alguma forma conhecida, para evitar ambigüidades ou para evitar o lançamento de uma exceção. Disto, não há escapatória, infelizmente...

2- Todos os exemplos foram testados e nenhum deles se machucou no processo de feitura deste artigo. :-)

3- Feliz?? Triste?? Este artigo salvou a sua vida (ou seu emprego) ou você agora odeia o Pajé?? Não faz mal, pelo menos COMENTE!!!

sexta-feira, 14 de janeiro de 2011

Como Implementar uma Lista Circular em Java

Uma lista circular é uma lista ordenada (encadeada) onde o item após o último é o primeiro, e o item anterior ao primeiro é o último. É um caso curioso de algoritmos que, não menos curiosamente, reflete uma infinidade de situações reais. Exemplos:

  1. O itinerário de um ônibus circular. Ao chegar ao último ponto, o ônibus não pára nem volta pelo caminho contrário, mas sim continua em frente e alcança o primeiro ponto, de onde partiu inicialmente, perfazendo todo o caminho de novo.
  2. Os dias da semana ou os meses do ano. Após o último, vem sempre o primeiro de novo, reiniciando um novo ciclo.
  3. A roleta de um jogo. Percorrida seqüencialmente, após completar um círculo completo a roleta volta à primeira posição.

Listas circulares são associadas a qualquer situação onde haja um ciclo característico. E periodizar ou repetir as coisas é uma característica extremamente humana ("Tenho fases, como a lua", lembrando o "Lua Adversa", de Cecília Meireles ou, quem sabe, de outras poetisas...).
Listas circulares têm grande aplicação em jogos, manipulação de imagens, manipulação de streams e arquivos, vários sistemas humanos, além de milhares de outras ocasiões.
A classe abaixo implementa a criação de uma lista circular em Java a partir de um ArrayList. Não é uma classe Thread-safe, assim como o ArrayList também não o é, mas é um exemplo razoavelmente completo, testado e seguro que você poderá utilizar livremente em muitas situações. Se você utilizar esta classe em seus programas e sistemas, por favor, faça as referências do seu autor, data, etc, conforme mostrado no javadoc. Considere-a lançada sob licença LGPL.


FONTE: http://pastebin.com/NSw67CbW

Note que esta classe se comporta exatamente como um ArrayList, podendo inclusive ser construída a partir de qualquer Collection. No entanto, existem 3 métodos de navegação que implementam o comportamento circular da lista:

getActual(): retorna o objeto atual. Existe um índice interno que controla a navegação. Assim, você poderá navegar passo a passo pela lista, indo tanto na direção progressiva (para frente) quanto na direção regressiva (para trás). Cada vez que a lista é percorrida, este índice interno é alterado. Se precisar pegar o objeto que corresponde exatamente à posição onde o índice está parado no momento, este método faz isto por você!

next(): retorna o próximo objeto, caminhando com o índice para frente e posicionando-o sobre este objeto retornado. Como é uma lista circular, se você está no último item da lista e dá um "next()", então você receberá o primeiro item da lista, mantendo a característica cíclica da mesma.

previous(): faz o mesmo que o next(), mas em direção oposta: retorna o objeto anterior, caminhando com o índice para trás e posicionando-o sobre este objeto retornado. Como é uma lista circular, se você está no primeiro item da lista e dá um "previous()", então você receberá o último item da lista, mantendo a característica cíclica da mesma.

Além destes métodos, o método get(int index), que já existe na superclasse, foi sobrescrito de forma que nunca lance ArrayIndexOutOfBoundsException, ou seja, qualquer índice que seja passado vai sempre retornar um elemento dentro da lista, calculado circularmente de acordo com o total de elementos da lista. Assim, é seguro usar uma lista como esta dentro de um laço arbitrário, onde o índice do laço é bem maior que a lista. Como exemplo, imagine que você quer desenhar um quadro de tamanho 100x100 com apenas 3 cores que se repetem. Você poderia muito bem fazer:

// Lista circular com 3 elementos apenas!!
CircularArrayList circularList = new CircularArrayList(colors);

for (int i=0; i<100;>

Bom, esta classe ainda pode ser mais aprimorada, se for de seu interesse. Possíveis melhorias seriam:

  • Métodos como "moveTo(int newIndex)" e "moveTo(E element)", que reposiciona o índice em uma posição arbitrária. É útil se a navegação tender a se tornar mais alternada que seqüencial, especialmente se a lista for grande.
  • Métodos "first()" e "last()", se houver necessidade.
  • Uma versão desta classe completamente Thread-safe e otimizada para bom desempenho!! Isto seria de fato uma grande contribuição!!

Espero ter ajudado com este artigo!! Qualquer coisa, COMENTEM!!!

sexta-feira, 16 de julho de 2010

Alterando o Volume e Ganho com JavaSound

Não foi incomum que algumas pessoas me perguntassem como alterar o volume de um Clip ou uma Stream de Áudio usando a API de som do Java, o JavaSound. Vamos à explicação rápida!!

  • Qual a Diferença Entre Volume e Ganho??

Muitas bibliotecas de execução e manipulação de som (especialmente as mais baixo nível) não têm controle de volume, mas sim de ganho. Ganho é a medida em deciBels (dB) que regula a intensidade do som (mais detalhes aqui). Volume é uma medida adimensional e escalar de intensidade de som.
Tudo estaria resolvido se o ganho variasse da mesma maneira que o volume, já que os dois medem, na prática, a mesma coisa. Porém, o ganho é uma medida logarítmica, ou seja, ela varia muito mais numa extremidade e muito menos na outra, dados os cálculos em exponensiais. O volume é uma interpretação desta variação, porém de maneira escalar, de forma que varie sempre da mesma forma.


  • Implementando Mudaças de Volume em JavaSound

Primeiramente, é preciso se obter o controle de ganho (MASTER_GAIN). Depois, é preciso que se transforme o valor do volume (uma simples percentagem, ou seja, um número entre 0 e 1) em deciBels, usando a fórmula logarítmica abaixo. Com este valor em deciBel, basta agora atribuí-lo ao controle de ganho.

public void setVolume(int percent) {
FloatControl gainControl =
(FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
double gain = percent/100; // deve ser entre 0 (mudo) e 1 (mais forte)
float dB = (float) (Math.log(gain) / Math.log(10.0)*20.0);
gainControl.setValue(dB);
}

Cuidado: não tente obter o controle VOLUME, a não ser que você saiba o que está fazendo, já que ele não costuma existir em muitos sistemas de som, vindo a retornar uma referência nula.


  • Trocando Entre Mudo e Não-Mudo

A rigor, definir o valor como mudo significa simplesmente atribuir valor zero para o ganho. Mas, existe uma maneira mais simples para se trocar entre mudo e audível, mantendo o ganho inicial:

BooleanControl muteControl =
(BooleanControl) clip.getControl(BooleanControl.Type.MUTE);
muteControl.setValue(true); // Define como mudo
muteControl.setValue(false); // Retorna para audível

É isso aí, gente!! Agora ficou fácil!! Claro, é bom lembrar: COMENTEM!!!

sábado, 8 de maio de 2010

Convertendo Binário, Octal, Hexadecimal em Inteiro em Java

Essa é outra dica rápida de programação na linguagem Java: como converter uma String representando um número binário, octal ou hexadecimal (e, portanto, que podem conter letras, e não somente números) no inteiro correspondente??

Simples: a classe Integer tem duas sobrecargas do método parseInt: uma recebe somente a String, e supostamente esta String está representando um inteiro em base decimal. A outra recebe a String e a base de cálculo para a conversão. Assim, temos:

Primeira sobrecarga:
int value = Integer.parseInt("16");
System.out.println(value);

Console:
16

Internamente, este método: parseInt(String s) não faz nada além de redirecionar a chamada para a segunda sobrecarga, passando a base 10:

Segunda sobrecarga:
int value = Integer.parseInt("16", 10);
System.out.println(value);

Console:
16

Esta segunda sobrecarga pode receber os valores abaixo como base, usando-os para interpretar a String e fazer a conversão necesária:

2 - Binário
8 - Octal
10 - Decimal
16 - Hexadecimal
27 - base 27 (alguém usa isso??)

Assim, podemos converter binários (usando a base 2), octais (usando a base 8), decimais (usando a base 10) e hexadecimais (usando a base 16), além da não menos esdrúxula base 27.
Exemplos:

Binário:
Integer.parseInt("10", 2); - retorna 2
Integer.parseInt("101", 2); - retorna 5
Integer.parseInt("1100110", 2); - retorna 102

Octal:
Integer.parseInt("10", 8); - retorna 8

Hexadecimal:
Integer.parseInt("f", 16); - retorna 15
Integer.parseInt("a", 16); - retorna 10

Base 27:
Integer.parseInt("Kona", 27); - retorna 411787


  • Outra opção:

Ainda na classe Integer, temos a opção de usar o método valueOf, que tem igualmente duas sobrecargas similares, porém retorna o objeto do tipo Integer de valor correspondente, e não o tipo primitivo. Assim, podemos fazer:

Binário:
Integer i = Integer.valueOf("10", 2);
System.out.println(i.intValue()); - imprime 2

Octal:
Integer i = Integer.valueOf("10", 8);
System.out.println(i.intValue()); - imprime 8

Hexadecimal:
System.out.println(Integer.parseInt("f", 16).intValue());
imprime 15

Uma segunda técnica de conversão numérica e de interconversão entre formatos numéricos pode ser obtida na segunda parte deste artigo, clicando-se aqui!!

Espero que esta dica tenha ajudado!! Qualquer coisa: COMENTEM!!!

terça-feira, 27 de abril de 2010

Tocando Guitarra no Linux (Editor de Tablatura)


Esta dica rápida ensina a instalar o programa de código livre Tuxguitar, um editor de tablatura e partituras multipista, criado por nossos vizinhos argentinos, escrito em Java (em SWT) e dedicado ao público de guitarristas, violonistas e demais instrumentos de cordas que fazem uso da tablatura, acordes cifrados no braço do instrumento e recursos similares.
Com o Tuxguitar é possível se fazer desde simples cópias de músicas até arranjos ou composições arrojadas para a sua banda. Suas versões mais recentes trabalham com diversas opções de áudio: OSS, Java Sound (engrenagem de som nativa do Java), ALSA e Fluidsynth. Suporta plugins e pode converter arquivos em padrões como MIDI, Lilypond e MusicXML, tornando a integração com outros aplicativos de música e som muito mais cômoda. Existe hoje traduções para dezenas de línguas, sendo a tradução para Português do Brasil muito boa.
Uma das características do Tuxguitar é a atenção que é dada também para o público amador, permitindo a edição e/ou criação musical por meios convencionais e alternativos: desde tablatura e partitura até clicando-se sobre o braço do violão! Assim, mesmo quem não sabe ler partitura poderá compor confortavelmente!!
A página do projeto inclui ainda um detalhado manual de usuário e um ativo fórum de problemas e dicas, além de várias capturas de tela (para dar um gostinho antes de instalar...).

  • Instalando o Tuxguitar

E, por falar em gostinho, é possível baixá-lo diretamente de sua página, onde há compilações para os mais diversos sistemas: diversas distros de Linux (e algumas genéricas), Windows, FreeBSD e Mac OSX. Para quem quer experimentar sem compromisso, é possível também rodar a versão online, via Java Web Start.
Opcionalmente, é possível instalá-lo via apt-get, para distros baseadas em Debian. Basta digitar, como root:

apt-get install tuxguitar

  • Rodando o Tuxguitar com o Java Personalizado

Se você instalou o Tuxguitar pelo apt-get e não tem o Java e o SWT instalados, pode ser que você tenha problemas. Pode ser que esteja tudo certo também, mas você tem um outro Java (JRE ou JDK) instalado em seu sistema e quer utilizar este. Como fazer??
A solução simples: o Tuxguitar procura pelo diretório do Java através da variável JAVA_HOME. Basta trocar o valor desta variável e você estará mudando a JRE utilizada para rodar o Tuxguitar. Exemplo:

$ echo $JAVA_HOME
/usr/lib/java

Veja: meu JAVA_HOME padrão é /usr/lib/java. Vamos trocar por uma versão mais recente que eu instalei manualmente em minha máquina:

$ export JAVA_HOME=/opt/jdk1.6.0_10/
$ echo $JAVA_HOME
/opt/jdk1.6.0_10/

Tudo alterado e funcionando normalmente!!
Note que o Tuxguitar também necessita de algumas bibliotecas do SWT. Se você estiver tendo algum problema com isto, ou se quiser usar uma outra versão destas bibliotecas (que você baixou e instalou manualmente), você pode editar o script de inicialização do Tuxguitar, digitando (como root):

vi /usr/bin/tuxguitar

Bom, agora é mãos à obra, compositores!! E, claro, se a música ficar boa, se ficar ruim, se a inspiração veio ou foi embora: COMENTEM!!!!

terça-feira, 11 de agosto de 2009

Desenhos do Duke: O Mascote do Java é Open Source!!

Todo mundo já deve ter visto ao menos uma vez o Duke, aquele camaradinha em forma de gota, de corpo branco e cabecinha preta, com um narigão vermelho impressionante (nem sei como ele enxerga!!). Pois é, o Duke é open source!! Isto quer dizer que você pode desenhar, distribuir e utilizar o desenhozinho do Duke em seus programas e trabalhos livremente!! Ao menos é o que nos contam os próprios camaradas da Sun (veja aqui).
O Duke foi criado por Joe Palrang, um artista e animador de grande envergadura, que trabalhou na Sun de 1992 a 1994 e já trabalhou inclusive na Dreams Works. Na ocasião, o Duke foi criado para o Green Project, da Sun, de onde o Java se originou. Assim que anunciaram o lançamento da primeira versão do Java, na mesma época em que criaram a famosa xícara de café, lá estava o Duke como mascote do Java!!
Hoje, com o Duke open source, já temos uma recente mas fiel leva de animadores, artistas gráficos e entusiastas desenhando e contextualizando o Duke das mais diversas maneiras possíveis!! Vejamos algumas imagens do Duke...


No início, era só um Dukerino...


O Duke num momento de lazer (afinal, ninguém é de ferro!!)



Duke pronto para mais uma missão interestelar!!



Porque o Duke também é Brasileiro!!


Mamãe Duke e seu filhinho...


...e enquanto isso, o papai Duke só enchendo a cara!!


Duke de férias em Natal, RN, bebendo água de côco em Ponta Negra!!


Êta Duke bão dimais, Sô!!


Como o Duke influenciou Da Vinci...


Amigos para sempre, Duke e Tux Forever!!


Ufa!! Alguém precisava salvar o mundo dos tenebrosos usuários!!

Mais um monte de imagens gratuitas do Duke podem ser encontradas na página dele, no Projeto Kenai, da Sun: clique aqui!! Inclusive se vê por lá esta última aí em cima, numa versão gigante de fundo de tela com quase 4 megas (sim, eu a diminuí com pena de você, pelo quão que sofreria para baixar 3,8 megas de apenas 1 figura...).
Gostou?? Detestou?? Adorou?? Com corda ou sem corda?? Então COMENTE!!!!!!

sábado, 1 de novembro de 2008

Tutorial: Como Obter e Formatar Datas em Java

Mês passado, publiquei um extenso tutorial sobre como obter e formatar datas em javascript, dividido em duas partes: parte 01 e parte 02. Reparei que algumas pessoas, ao lidar com o mesmo problema, porém em java, têm iguais dificuldades, devido à maneira específica com que o objeto Date é tratado no momento de se formatar uma data.
Em java, uma data é comumente armazenada no objeto java.util.Date. Como em muitas outras lingugens, este objeto retém uma certa quantidade de informações internas além da data em si. Esta é representada por um número gigantesco e único, correspondete à quantidade de milissegundos decorridos desde a data convencionada como inicial (dependendo do caso, pode ser 01/01/1900, às 00:00:00, ou outra data parecida, anterior ou posterior, dependendo de qual objeto e qual linguagem você esteja utilizando) até a data do momento em que o objeto foi instanciado na memória. Por isso, converter este número imenso em uma data inteligível, com dia, mês, dia da semana, ano, hora, minuto, segundo e centésimo... isto é uma operação interna do objeto que envolve diversos cálculos, ou seja, não é simplesmente recuperar um dado guardadinho ali dentro.
Embora pareça complicado, formatar datas em java é muito simples!! Existe uma classe especial só para fazer o trabalho de tradução da formatação de data que o desenvolvedor deseja para o conteúdo que o objeto Date armazena em si. Esta classe é o SimpleDateFormat, do pacote java.text.
O SimpleDateFormat tem dois métodos de especial interesse:

  • format - recebe um objeto Date e retorna uma String formatada, segundo a configuração desejada;
  • parse - faz o inverso; recebe uma String e, baseado na configuração desejada, interpreta-a, gerando um objeto Date correspondete.
Como você já deve ter notado, para se formatar uma data é preciso, antes, informar como é esse formato que imaginamos. Em outras palavras, é preciso configurar o formatador. Felizmente, o SimpleDateFormat foi construído baseado em abstract factory (um padrão de projeto prórpio para este tipo de situação), e sua configuração é muito fácil!! Basta construí-lo passando uma String, com caracteres que representam as partes do formato de data que queremos. Exemplos:

SimpleDateFormat formatador1 = new SimpleDateFormat("dd/MM/yyyy")
(formataria datas para: 25/12/2008)
SimpleDateFormat formatador2 = new SimpleDateFormat("HH:mm:ss")
(formataria datas para apenas a hora: 23:45:02)

Apenas esta String é o suficiente para o SimpleDateFormat entender como você deseja o formato de sua data. Todavia, opcionalmente você ainda pode definir em que localidade você está! Isto é útil para dados de formatação que dependam de idioma e país, como o nome dos dias da semana ou do mês. Para fazer isto, basta acrescentar mais um argumento no construtor do SimpleDateFormat, o objeto Locale, do pacote java.util. O locale deve ser construído com as siglas da língua e do país, como nos exemplos:

Locale local1 = new Locale("pt", "BR"); //Português, Brasil
SimpleDateFormat formatador1 = new SimpleDateFormat("EEE", local1)
(formataria datas para: "Seg")
Locale local2 = new Locale("fr", "FR"); //Francês, França
SimpleDateFormat formatador1 = new SimpleDateFormat("EEE", local2)
(formataria datas para: "Lun")

No caso acima, "E" significa o nome do dia da semana. Ele foi repetido 3 vezes porque queríamos exatos 3 caracteres do nome. Para saber quais letras significam o que e como manipular a quantidade de caracteres de cada item, verifique a lista completa na documentação da Sun: aqui.

Exemplo 01: formatando uma data:

//Configurando tudo...
Locale local = new Locale("pt", "BR");
String dataHoraConfig = "dd/MM/yyyy HH:mm:ss";
SimpleDateFormat formatador = new SimpleDateFormat(dataHoraConfig, local);

//Obtendo e formatando a data...
Date data = new Date(); //Data do exato instante em que o objeto é carregado
String dataFormatada = formatador.format(data);

Isto cospirá algo como "01/11/2008 03:08:50".

Exemplo 02: recuperando o objeto Date correspondente a uma data formatada:

//Configurando tudo...
Locale local = new Locale("pt", "BR");
String dataHoraConfig = "dd/MM/yyyy HH:mm:ss";
SimpleDateFormat formatador = new SimpleDateFormat(dataHoraConfig, local);

//Obtendo o objeto Date...
String dataString = "01/11/2008 03:08:50";
Date data = formatador.parse(dataString);

Cuidado!

  • O parse pode falhar, então é preciso tratar a exceção ParseException;
  • O objeto Date tem sempre a precisão do milésimo de segundo. Se a sua String não chega até lá, o objeto terá os itens de maior precisão iniciados em zero. Exemplo: se a String informar apenas o ano "1980", o objeto Date será algo como "01/01/1980 00:00:00".

É isso aí, gente!! Espero ter ajudado!! Gostou?? Não gostou?? Comente!!

domingo, 5 de outubro de 2008

Struts, JSF, GWT, Qual o Melhor Framework Java para WEB?

Java é uma linguagem que tem diversos frameworks para desenvolvimento WEB, uns mais parecidos com outros, e alguns nem tanto. Como a ênfase do Java no mercado é WEB, isto tem motivado inclusive o surgimento de novas soluções nesta área.
Semana passada tive um debate com alguns colegas sobre arcabouços (frameworks) para desenvolvimento WEB em Java. De certa forma, ter muitas opções é bom, indica a riqueza de ferramentas disponíveis aos desenvolvedores, porém demanda mais cuidado na escolha da opção mais propícia. Vamos a uma análise comparativa simples de alguns dos frameworks mais comuns, que pode o ajudar na hora da decisão certeira e fundamental de seu projeto...

  • JSF (Java Server Faces): Este é original da Sun, que de início foi preterido porque não parecia funcionar tão bem, mas hoje é bem sólido e poderoso. Desenvolver em JSF tem se tornado trivial com a ajuda de ferramentas poderosas como o Netbeans, que agiliza muito o trabalho. Para sistemas de telas padronizadas e arquitetura baseada em CRUD, o JSF é o ideal: agiliza o desenvolvimento, simplifica e previne erros com o uso de JSTL, etc.
  • Apache Struts Framework: Durante muitos anos, esteve presente na maioria maciça de sistemas WEB em Java, junto com o Tiles, que se tornou um projeto independente a partir da versão 2.0 (o Tiles 2 pode ser integrado a JSF e a outros frameworks). É indicado para sistemas de páginas mais flexíveis. Também tem suas taglibs (que nunca foram exatamente muito boas) e suporta JSTL. É indicado para os sistemas onde o JSF não vai tão bem, com telas diferenciadas, muito complexas ou muito personalizadas.
  • Direct Web Remoting (DWR): Como você vê, tanto Struts quanto JSF são arcabouços tradicionais que supõem um cliente burro, passivo, e, embora não se oponham ao DHTML (manipulação de dados da página com Javascript), só conseguem falar com o servidor no recarregamento da página (refresh). Por padrão, não suportam AJAX. Mas não se preocupe: para isto existem pequenos frameworks como o DWR. O DWR implementa chamadas remotas via RPC, possibilitando que seu sistema faça AJAX muito comodamente. Integra bem com Struts e JSF. A partir da versão 2 permite, inclusive, o reverse AJAX: mecanismo pelo qual o Java no servidor controla o navegador através da publicação de scripts. Sem dúvida, a melhor saída para páginas dinâmicas ricas, em Web 2.0, que necessitam de muito AJAX.
  • Google Web Toolkit (GWT): O GWT recolucionou drasticamente o desenvolvimento WEB para Java. Desconstruiu toda a complexidade dos sistemas carregados em múltiplos frameworks, descritores XML, etc., e mergulhou profundamente em Web 2.0. Com o GWT, seu sistema só carrega uma vez a partir de um arquivo HTML. Não tem recarregamento de página. Todas as requisições ao servidor são RPC implementados via callback (AJAX). Não tem sequer arquivos JSP!! O segredo é que a programação é feita toda em Java, inclusive as telas e seus elementos, com direito a breakpoints e debug, e o motor do GWT, em tempo de compilação, transforma todo o Java relativo à tela em Javascript. É muito parecido com o Swing, onde o desenvolvedor compõe, em Java, a GUI do sistema, embora voltado para Web. É ideal para sistemas que exijam uma implementação visual sofisticada, muito AJAX e características de GUI, com elementos como árvores, abas, tabelas dinâmicas, DIVs móveis, Drag & Drop de componentes, exploração de CSS e estilo, etc.
  • Apache Wicket: Muito semelhante ao GWT, o Wicket tem a mesma filosofia: programe a sua GUI em Java e deixe que ele a converta para HTML. Não parece ser tão sofisticado quanto o GWT, mas tem a enorme vantagem de que a correspondência entre seus componentes e os objetos HTML DOM gerados é exata. Ou seja: enquanto, no GWT, os seus componentes normalmente geram em Javascript estruturas complexas de objetos DOM, no Wicket a correspondência é a mesma: um objeto de cá gera um de lá e pronto! Com isso, é possível que web designers e programadores Java trabalhem independentemente e com mais liberdade que com o GWT. Por outro lado, é uma alternativa ideal para sistemas mais simples que, entretanto, terão dificuldades ao sofisticar os componentes visuais, aos moldes do que o GWT oferece.
Conclusão: qual framework devo usar em meu projeto? Todos eles têm vantagens e desvantagens, mas cada um tem uma ênfase em certo aspecto. Não tenha preconceitos nem idéias megalomaníacas. A sua escolha deve ser baseada nas características do seu projeto: como ele é e o que faz. Certamente há uma melhor opção para você, que lhe facilitará a vida e alhiciará conforto e prazer ao encontrar na sua ferramenta exatamente as funcionalidades de que você precisa.

quinta-feira, 2 de outubro de 2008

Resumão de Plugins do Eclipse: Java, C, PHP, Python, Rails, etc!!

Uma IDE para a todas governar...

Não, não estou falando do Um-Anel nem de nenhum romance do J. R. R. Tolkien. Estou falando de uma IDE de desenvolvimento open-source chamada Eclipse.

  • O que é o Eclipse??
Criado nos laboratórios da IBM, o Eclipse - escrito integralmente em Java - foi planejado (naturalmente!) para desenvolvimento em Java. Todavia, impulsionado pelo fato de o Java ter muita aplicação para Web e pela sua própria popularização como ferramenta, além da facilidade de sua arquitetura extremamente plugável, começaram a surgir inúmeros plugins e modificações do eclipse, habilitando-o a suportar muitas outras linguagens.
O primeiro grande passo foi com os plugins do projeto WTP (Web Tools Platform - hoje integrado diretamente às versões mais recentes do Eclipse), onde o Eclipse veio a reconhecer fontes em HTML, CSS, XML, Javascript, XSD, etc. Muitos outros projetos (vários de código aberto) modificaram e adaptaram o Eclipse para os mesmos ou semelhantes fins, como o Lomboz, o (antigo) JBoss IDE ou o Aptana.

  • Uma IDE Baseada em Plugins
O Eclipse é, na verdade, uma pequena IDE enxuta com arquitetura voltada para plugins. Isto permite que se criem facilmente novos plugins para fazer virtualmente qualquer coisa no Eclipse. Na verdade, ao baixar o Eclipse, você já traz uma infinidade de plugins, responsáveis pela maior parte das suas funcionalidades originais!!
Devido a esta flexibilidade, o Eclipse tem se tornado uma ferramenta poderosa para qualquer desenvolvedor, seja ele programador de Javascritp/AJAX, web designer, desenvolvedor Java, PHP, C ou Python, por exemplo.


Alguns dos Principais Plugins para o Eclipse

  • Aptana: Este é sem dúvida o melhor plugin para quem desenvolve ricamente para Web. Suporta maravilhosamente Javascript e AJAX, com direito a reconhecimento de variáveis, auto-completar objetos e funções, breakpoints em Javascript, além de CSS, DOM, PHP, Ruby on Rails, Adobe Air, Apple iPhone, Python, e conta com inúmeras outras funcionalidades. Trata-se na verdade um conjunto de pequenos plugins e (prepare-se!!), ao todo, são dezenas de megas de download. É tanto que tem uma modificação do Eclipse só para o Aptana (o Aptana Studio), que permite ao usuário rodar o plugin de forma standalone, ou seja, sem o resto do Eclipse, deixando o ambiente mais leve. É ideal para web designers e desenvolvedores web. Com o Aptana, seu Eclipse estará simplesmente turbinado com tudo para Web que você precisa e mais um pouco!!
  • PHP: Se você desenvolve para Web em PHP mas prefere manter o Eclipse original, então é recomendável ter algo como o PHPEclipse. Com este plugin, você terá tudo que uma boa IDE pode oferecer. Outra opção é um projeto do próprio Eclipse denominado PDT.
  • JBoss Tools: Assim como o Aptana é muito mais do que um plugin, o JBoss Tools também o é. Trata-se de uma grande suíte de aplicativos para desenvolvimento corporativo da JBoss. É tão grande que há uma modificação do Eclipse feita pela própria JBoss, contendo todas as suas ferramentas. Se você trabalha com J2EE e usa o JBoss, então esta ferramenta é essencial! Ela lhe ajudará não só a manipular o servidor, como também oferecerá suporte ao Hibernate, Struts, JBPM, JSF, etc.
  • Sysdeo Tomcat Plugin: para quem faz sistemas menores e utiliza o formidável Jakarta TomCat, da Apache, como servidor, um plugin indispensável é este. Ele permite, de dentro do Eclipse, parar e reiniciar o servidor, além de fazer o autodeploy. Agora você pode mudar qualquer JSP e ver a modificação na mesma hora!! Agiliza em muito o trabalho!!
  • Any Edit Plugin: excelente plugin para tratar textos. Converte todos os símbolos do Unicode em notação HTML, inclusive os acentos, além de pequenas coisinhas, como converter um trecho entre maiúsculo ou minúsculo, sublinhados e CamelCase, etc. É simples, mas muito útil!!
  • Subclipse Plugin: o Eclipse já vem com um ótimo plugin para CVS, mas (ainda não sei por que!!) não traz nenhuma ferramenta para SVN. Com este plugin, seus problemas se acabaram!! Ele é muito parecido com o tradicional plugin de CVS, inclusive usando algumas imagens idênticas, e fornece todas as funcionalidades que você precisa para controlar seus projetos no repositório do Subversion.
  • Maven Eclipse Plugin: Então imagina que seu super projeto necessite de mais do que simples controladores de versão; necessita de um controlador eficiente de dependências. Ótimo, temos o Maven, da Apache, que permite inclusive a criação de seu repositório particular de dependências!! A partir do Maven Eclipse Plugin, é possível usar o Maven para compilar seu projeto, resolver as dependências e inclusive achar erros no seu pom.xml!!
  • PyDev: Você desenvolve em Python?? Ainda não tem uma IDE de primeira linha?? Então conheça o PyDev, o plugin que transforma o Eclipse num primoroso ambiente de desenvolvimento para Python. Extremamente poderoso, faz Debugger e Breakpoints no código Python, inspeção de variáveis e objetos no modo Debug, auto-complementação de código, verifica a sintaxe, marca erros e TODOs, suporta refatoração completa de código, enfim, todas as maravilhas que o Eclipse faz para Java, ele o faz para o Python!!
  • C/C++ Development Toolkit (CDT): Mas você gosta mesmo é de C, né?? Então fica frio e ouça O Pajezinho aqui - prepare-se para usar o Eclipse!! O CDT é um excelente plugin, que não só identa e marca o código, como também tem ferramentas para automatizar seu desenvolvimento. Ele gera diretivas de Header, cria automaticamente o Header (*.h) e a Classe C++ (*.cpp) a partir de janelas de diálogos, controla Breakpoints, faz Debug, mostra as Threads... em suma: eleva a IDE, consoante ao desenvolvimento em C, ao mesmo patamar em que ela está para o Java.
  • Ruby Development Tools (RDT): Se você trabalha com Ruby ou Ruby on Rails, aqui está um ambiente de desenvolvimento de primeira: marcação (highlight) e verificação de sintaxe, ferramentas gráficas e controle de testes, assistentes de contexto, formatador de código, ferramentas para rodar e debugar, visão hierárquica, refatoramento, etc...
  • Cypal Studio For GWT: Mas você desenvolve em Java e é fã do GWT?? Não se preocupe!! Existe um plugin bem interessante que vai agilizar as tarefas chatinhas de criação/edição de serviços e módulos, criação de projetos e ainda lhe ajudará a rodar o seu módulo com o Hosted Mode. Vale a pena conferir!!
  • JSEclipse - Plugin para Javascript: OK, você não precisa de tanto para ter que instalar o Aptana, mas você precisa lidar com Javascript de uma forma um pouco melhor que o plugin original do Eclipse... então, a sua melhor escolha vai ser usar o JSEclipse. Ele auto-completa e faz marcação (highlight) de seu código, suporta bibliotecas de javascript, identifica objetos e classes criados e modificados, faz sugestão de funções e propriedades, marca erros de sintaxe, e você pode até criar um XML próprio com suas definições de classes!! Muito ágil para quem desenvolve para Web e precisa de uma ferramenta sólida para Javascript...
  • COBOL IDE: Este aqui eu coloquei para mostrar o poder do Eclipse!! Imagine que existe uma pequena suíte de plugins para o Eclipse, criando uma formosa IDE de desenvolvimento para COBOL!! Se você de repente se deparou com um código legado monstruoso em COBOL, feito pelo Tutankamon em pessoa, e está com medo dele, agora seus problemas podem não ter se acabado, mas apareceu uma boa luz no fim do túnel!!
  • SQL Plugin - QuantumDB: Não poderíamos nos esquecer de nossos grandes amigos DBAs ou ADs (ou os bons programadores WEB que precisam freqüentemente colocar a mão na massa e fazer milhares de queries em banco de dados). Com o QuantumDB, você tem uma interface fantástica para não só fazer queries simples, como também fazer muitas outras coisas: controlar schemas, tabelas, views e sequences, constraints, colunas, índices e chaves estrangeiras, salvar e editar arquivos *.SQL, tem wizards para facilitar DELETEs, UPDATEs e INSERTs, reconhece a linguagem SQL, exibe a estrutura do banco em árvore, suporta os mais diversos bancos (acessando via JDBC) e muito mais!!

Bom, pessoal... esta é apenas uma pequena mostra do que os plugins para o Eclipse podem fazer por você!! Muito mais pode ser pesquisado e baixado no portal oficial: Eclipse Plugin Central.
Espero ter ajudado com este resumão e que, agora, você se sinta encorajado e orientado para munir-se de melhores e mais propícas ferramentas, aprimorando seu trabalho e tornando sua vida mais confortável!!
Gostou do artigo?? Deixe sua opinião aí embaixo!! O Pajé também é open source e free!!