domingo, 31 de maio de 2009

10 Milhas Mizuno - 2009 - Etapa Rio de Janeiro

Hoje eu participei da corrida título deste post. Foi muito bom! Quando sai daqui do Leme para pegar o ônibus até o Flamengo, local da corrida, conheci o Pedro, outro corredor daqui que também estava indo participar. Conversamos bastante até chegarmos ao local da corrida. Chegando lá, encontrei o Adolfo, colega de trabalho do BC. Largamos e corremos juntos as três primeiras milhas. Em seguida, o Adolfo disparou e foi embora! Amanhã eu pergunto como ele terminou a corrida...

Eu fiz os dez primeiros kilômetros junto com o Pedro. O tempo para mim, que estou acima do peso, foi pra lá de bom neste trecho: 1 hora e 1 minuto. Mas em seguida, meu rendimento caiu e só fui terminar a prova (10 milhas ou 16,09Km) em 1 hora e 48 minutos. O Pedro sentiu a perna e chegou um pouquinho depois de mim. Mas é isto aí... agora é continuar os treinos!

sábado, 30 de maio de 2009

E o bronzeado na areia, pelo esporte na orla

Hoje eu fechei a semana com 40Kms de corridas concluídos, no período da manhã. Amanhã vou participar da corrida Mizuno 10 Milhas 2009. Por acaso, já próximo a minha chegada no Leme, a Globo estava fazendo uma reportagem, que foi mostrada na primeira edição do RJTV. Eu apareci correndo no momento em que a repórter cita a frase do título deste post! Veja no vídeo abaixo e/ou clique neste link para ler a reportagem completa:



sexta-feira, 29 de maio de 2009

Hackeando o JBoss AS

O JBoss AS é o servidor de aplicações que utilizo em meu trabalho e nos cursos que ministro relativos a Java EE e JBoss. Por isto mesmo, quero que ele esteja sempre seguro e que as informações de segurança a respeito dele, sejam as mais divulgadas o possível. Quero compartilhar com vocês neste e nos próximos posts, um trabalho que venho desenvolvendo, relativo ao hardening do JBoss no meu ambiente de trabalho.

Nos diversos cursos de JBoss que ministrei, eu sempre demonstrei aos meus alunos que o JBoss, sem um ajuste mínimo de segurança, permite que qualquer um tenha acesso a suas funcionalidades administrativas. No fim do ano passado, eu escrevi ESTE ARTIGO, que atualizei hoje e que trata de aspectos básicos relativos a configuração de segurança de algumas aplicações administrativas do JBoss e de como implantar uma aplicação qualquer, num servidor que esteja sem estas configurações realizadas.

Em próximos posts irei falar sobre diversas outras configurações que são necessárias em ambientes de produção. Acompanhe-me e boa leitura!

quarta-feira, 27 de maio de 2009

Hoje é Dia do Desafio! Eu me desafiei... E você?

Eu fui correr hoje, como de costume, antes de ir para o trabalho. Ao chegar ao forte do Leme, o Exército estava fazendo alongamento na praia, com uma faixa na frente de seu pessoal, dizendo: Dia do Desafio!

Eu não entendi o que isto significava. Mas sei que fiquei, como sempre, extremamente motivado, ao ler esta frase. Minha intenção ao sair de casa, era correr os 8Km (ida/volta) entre o forte do Leme e de Copacabana em 50 minutos. Mas, após ler a faixa, me senti desafiado a fazer mais com menos, ou seja, correr os 8Km em menos tempo. Começei a corrida às 07:46 e terminei às 08:33. Sendo assim, meu tempo melhorou em 3 minutos em relação a corrida de ontem. 8KM EM QUARENTA E SETE MINUTOS!!!!

Quando passei dos 7Km, corri alguns metros junto com um militar (do Exército também) que me explicou que este era um dia diferente. E eu, disse a ele o quanto havia me sentido motivado durante a corrida, em função de ter visto aquela faixa.

O Dia do Desafio foi criado no Canadá e vem sendo difundido mundialmente pela TAFISA - Trim & Fitness International Sport for All Association, entidade alemã de promoção do esporte para todos. Com um conceito simples, o evento incentiva cidades dos cinco continentes a promover a prática da atividade física diária, ressaltando a importância do esporte e do lazer para a manutenção da saúde.

Realizado anualmente, sempre na última quarta-feira do mês de maio, o Dia do Desafio propõe que as pessoas interrompam suas atividades rotineiras e pratiquem, qualquer tipo de atividade física.



Durante a corrida, eu não pude deixar de pensar no que a palavra desafio significa para mim, no momento atual de minha vida. E este post, é para que eu possa sempre me lembrar dos desafios que estou me propondo.

Eu estou estendendo o conceito do Dia do Desafio (leia mais sobre ele aqui, aqui e aqui, ou procure mais no Google) e me desafiando a:
  • Perder 5Kg, chegando aos 77Kg, até o dia 28 de junho, quando irei participar da meia maratona do Rio;
  • Cumprir minhas metas no SELIC durante este semestre e a dar o melhor de mim durante o próximo semestre;
  • Terminar de ler os seguintes livros:
  • Namorar muito no dia 12 de junho;
  • Dar um excelente treinamento em Brasília, no período de 13 a 16 de julho;
  • Descansar, passear com minha família e brincar muito com meus filhos, durante minhas férias em julho, no período de 17 de julho a 4 de agosto;
  • Codificar de vez o projeto eucorro.net e lançar a primeira versão no final de agosto;
  • Finalizar a escrita do meu livro até o dia 30 de novembro;
  • Participar novamente da Corrida de São Silvestre este ano e baixar muito o meu tempo em relação a minha última vez nesta prova, em 31/12/2006;
Vou conseguir concluir estes desafios!!!
E você? Quais são os seus?

segunda-feira, 25 de maio de 2009

Geek Gang Signs

48Km de corridas na última semana

Aumentei um dia a mais de corrida em relação a semana anterior! O único dia em que não corri na semana passada (de domingo até sábado) foi a sexta-feira pela manhã, quando me exercitei de outra forma, para relaxar ;-). Foram 8Kms diários, ida/volta entre os fortes do Leme e de Copacabana, levando em média o tempo de 52 minutos. No sábado, corri um pouco mais rápido, em 50 minutos.

Minha semana de corridas, desta vez, começou hoje. O tempo entretanto, no mesmo percurso habitual, foi de 49 minutos.

Deverei participar da Meia Maratona do Rio, dia 28 de junho. Mas, se eu for, irei na "pipoca" já que as inscrições online com preços razoáveis para simples mortais como eu, se esgotaram. Ainda restam inscrições para a categoria Elite VIP, com o preço iniciando em R$ 240,00. Fora de cogitação para mim! Quem sabe, com muuiiiito treinamento, eu algum dia me anime a participar desta categoria e pagar este preço...

sexta-feira, 15 de maio de 2009

Scala

Eu não falei de Scala em meu último post, que foi enriquecido com alguns comentários nas listas xprio e agildf, um na lista DFJUG e nenhum no RioJUG (até 15/05/09). Mas, como citei as linguagens Groovy, Ruby e Python, sinto que fiquei em falta com para com o Scala, como uma boa alternativa de linguagem para execução na plataforma Java. E, apenas para não ser injusto com outras linguagens, você pode ver uma lista de linguagens suportadas pela plataforma java, neste link.

Scala é uma linguagem que integra características de linguagens funcionais como o Python, Erlang e Haskell mas é estaticamente tipada, como o Java.

Bill Vennners, co-autor do livro Programming in Scala, comenta como a programação em Scala alterou seu estilo de programação. Eu li seu artigo e digo: é realmente interessante notar o quanto nosso estilo de programação é alterado em função da aprendizagem de novas linguagens.

O Scala é estaticamente tipado (ao contrário do Python por exemplo) e, em função de suas características funcionais (dentre outras), oferece uma boa performance para a escrita de programas e uma performance de execução similar a de aplicações Java. E apenas para me lembrar, ainda vou falar este assunto: performance na execução de aplicações x performance na escrita de programas.

Quando utilizar uma linguagem estática ou dinamicamente tipada é um assunto interessante de ser lido nesta thread, citada por este post.

Outros textos sobre Scala:

40Km de corridas nesta semana

Sim... Corri de segunda a sexta, 8Km diários, totalizando 40Km. Amanhã é dia de descanso e domingo de recomeço. Em breve você poderá me acompanhar, ver meus tempos de corrida e percursos no projeto que comanda meus pensamentos enquanto corro. Aguarde! Darei notícias ;-)

quinta-feira, 7 de maio de 2009

Java e linguagens dinâmicas

Ontem andei conversando com um amigo que tem a opinião que eu tinha em 2004/5: ele acredita que HOJE, Java está tão evoluído que não há necessidade de se utilizar alguma outra linguagem para solucionar qualquer problema na empresa em que estamos trabalhando. Eu fui contra e defendi a minha opinião atual do uso de Python, Groovy, Ruby, Bash ou de qualquer outra linguagem e/ou framework que for necessária para entregar uma boa solução para um problema, rapidamente e com qualidade. Escrevo este post para ele e para todos os outros amigos Javaneses que tenho e que talvez, tenham uma opinião/visão similar. Eu também gostaria muito de ter seu comentário sobre este assunto em meu blog.

Eu, estive palestrando no FISL em 2006 (baixe a apresentação). Ele ocorreu em Porto Alegre, e eu pude ver o quanto a comunidade open source do Brasil é mista. Naquela época, o Ruby on Rails estava começando a aparecer mundialmente como um framework altamente produtivo para a produção de aplicações Web 2.0. Meu intuito era falar sobre como o Java poderia estar mais próximo do que o Ruby fazia utilizando linguagens dinâmicas como o Groovy, JRuby ou frameworks como o Grails, Trails, etc e, a conclusão final era que Java, para se tornar melhor, não deveria mais ser vista como a LINGUAGEM Java, mas sim, como a PLATAFORMA Java. Pois bem, isto foi em 2006. Três anos depois, eu ainda defendo esta opinião. Estão aí no mercado produtos como Groovy, Rhino, Jython, JRuby. Excelentes frameworks Java como o Spring e o Seam fazem uso do Groovy. A SpringSource (dona do Spring) foi ainda mais longe e adquiriu a G2One (que era a dona do Groovy). O lista de usuário do Grails no Brasil cresceu muito de uns tempos para cá. E até mesmo o Ruby on Rails roda no JRuby, se você quiser. Ou seja, Java está realmente consolidando o conceito de PLATAFORMA, e a LINGUAGEM Java é apenas mais uma que roda nela. E eu digo mais: você consegue ser mais efetivo e programar mais, com menos código, se for utilizar linguagens dinâmicas como o Groovy ou o Python. Se você tiver a necessidade de se aproveitar de algum legado Java, utilize a PLATAFORMA Java e tente ser mais "dinâmico" utilizando o Groovy, por exemplo. Se você acha o Seam produtivo e gosta de utilizá-lo, eu lhe digo que você pode ser ainda mais produtivo com o seu uso, se utilizá-lo junto com o Groovy.

Em 2006 eu conhecia Groovy e Ruby de leitura e testes caseiros. Não sabia nada de Python e tinha muita experiência em Java, C/C++ e Pascal. Do início do ano passado até hoje, eu posso dizer que me aprofundei muito em Bash e Groovy para solucionar meus problemas, e que Python tem sido a minha diversão neste momento. Utilizei o Bash para a automação da implantação de aplicações em diversas instâncias de JBoss do meu trabalho e, apesar da solução ter ficado legal, hoje eu acredito que se eu eu a tivesse desenvolvido em Python, por exemplo, teria escrito muito menos. Foi por isto que resolvi adotá-lo agora, num novo projeto que precisará de integração com o Subversion e com diversas aplicações do Linux. Outro processo que estou conduzindo neste momento, é a definição de uma estrutura legal para o build de diversas aplicações Java, hoje construídas com o Ant. Penso que a utilização do Groovy (ou de ferramentas que o utilizem como linguagem, como o Gant + Ivy ou o Gradle) seria uma das melhores alternativas. Outra alternativa, talvez em segundo lugar, seria a adoção do Maven.

Na minha opinião, bons desenvolvedores devem trabalhar com metodologias ágeis e utilizar as linguagens/ferramentas certas para cada ocasião. E as empresas devem incentivar esta característica. É claro que há um custo nisto e que talvez, possa até ser verdade que o gerenciamento seja mais difícil numa situação como esta. Mas, eu conheço algumas empresas no Brasil (algumas com mais de 100 desenvolvedores) que parecem não se preocupar com isto e adotam esta filosofia. Ou seja, elas utilizam as melhores soluções para os problemas, escolhendo a melhor linguagem para resolvê-lo. E, para mim, meu amigo tem sido um pouco controverso quando me diz, de vez em quando, uma frase que ele ouviu de outra pessoa: "Se você só tem um martelo como ferramenta, todos os parafusos são vistos como pregos!".

Atualmente, após me aventurar por linguagens tão dinâmicas quanto o Groovy e o Python, eu fico me perguntando porque ainda utilizo o Java. Eu tenho um outro amigo (Helder Moreira), do trabalho também, que diz para mim que ainda é o mainframe que paga o meu salário. Pode até ser, neste momento. E posso dizer também, que ainda vou depender do Java, por muito tempo, assim como meu amigo depende do mainframe. Mas, aprendendo outras linguagems, eu agora tenho um leque maior de alternativas para solucionar meus problemas. Eu sei de todas as características que tornaram Java, o sucesso que ele é, ainda hoje. Ministro cursos de Java e JBoss e de uma porção de frameworks e ferramentas para Java. Possuo algumas certificações da Sun e da Red Hat que, para mim, simplesmente comprovam que eu tinha estudado para uma prova e que talvez tivesse alguma experiência. Atualmente, programo com a LINGUAGEM Java criando extensões para o JBoss no ambiente do meu trabalho. Não tenho dúvida que ele é a melhor ferramenta em casos como este e em diversas outras situações. Mas, o que eu quero dizer com este texto é que Java, como linguagem, pode não ser a única e nem mesmo a melhor opção, em muitos casos.

Vou exemplificar com um programa ridículo e inútil, o que estou escrevendo. Daí então, você terá alguma base para comentar comigo, qualquer programa mais sério. Implementarei um programa, com os requisitos a seguir, em três linguagens diferentes (Java, Python e Groovy):

  1. Verificar se argumentos foram passados na linha de comando. Se nenhum for passado, a lista de argumentos deverá ser populada com três strings: "Nenhum", "argumento", "foi passado!";
  2. Imprimir os argumentos;
  3. Criar uma lista de strings contendo nomes de linguagens nesta ordem: JavaScript, Bash, Java, Python, Groovy
  4. Imprimir a lista de linguagens de maneira ordenada;
  5. Utilizar esta lista de linguagens para popular um mapa (chave=linguagem/valor=prioridade) das linguagens utilizadas no próximo projeto, por prioridade. A prioridade terá seu valor (de 0 a 10) obtido aleatoriamente;
  6. O mapa deverá ser impresso por ordem de prioridade, com a linguagem menos usada sendo impressa primeiro;
  7. Imprimir as cinco primeiras linhas do código do programa, lendo-as de seu arquivo fonte;

Antes de implementar este programa bobão, e de você me criticar dizendo que um programa idiota como este não deveria nem ser considerado por ser tão inútil, quero que você entenda que o meu objetivo é apenas comparar a sintaxe das linguagens e a facilidade de codificação para o desenvolvedor. Além disto, muitos programas são tão simples e idiotas como este. Não estou preocupado com qualquer outro tipo de requisito neste momento. Eu, como administrador de servidores de aplicações, sei muito bem que características uma aplicação real deve suportar num ambiente de produção, clusterizado, tolerante a falhas e não estou levando isto em consideração neste momento. Vou discutir isto em outro post.

Vou desconsiderar o cabeçalho dos programas (imports do Java, do Python e do Groovy) e começar em Java, a implementar os requisitos acima descritos, da maneira mais simples possível. No método main de uma classe Teste, o código a seguir implementa os requisitos 1, 2, 3 e 4:

if (args.length == 0) args = new String[] { "Nenhum", "argumento", "foi passado!" };
System.out.print("Lista dos argumentos passados: ");
for (String arg : args)
 System.out.print(arg + " ");
List<String> linguagens = new ArrayList<String>();
linguagens.add("JavaScript");
linguagens.add("Bash");
linguagens.add("Java");
linguagens.add("Python");
linguagens.add("Groovy");
System.out.print("\nLista ordenada de linguagens: ");
Collections.sort(linguagens);
for (String linguagem : linguagens)
 System.out.print(linguagem + " ");

O mesmo código poderia ser implementado em Python assim:

argv = sys.argv[1:]
if argv == []: argv = ["Nenhum", "argumento", "foi passado!"]
print 'Lista dos argumentos passados:', " ".join(argv)
linguagens = ["JavaScript", "Bash", "Java", "Python", "Groovy"]
print 'Lista ordenada de linguagens:', ' '.join(sorted(linguagens))

E, em Groovy, o código seria o seguinte:

if (args.size() == 0) args = [ "Nenhum", "argumento", "foi passado!" ]
println "Lista dos argumentos passados: ${args.join(" ")}"
def linguagens = ["JavaScript", "Bash", "Java", "Python", "Groovy"]
linguagens.sort()
println "Lista ordenada de linguagens: ${linguagens.join(" ")}"

Alguns comentários:

  • Em Java, como dito anteriormente, o código precisa estar dentro do método main de uma classe. Python e Groovy não tem esta limitação.
  • Em Python, o módulo sys contém o array argv. A questão é que o primeiro argumento deste array é sempre o nome do programa Python que está sendo executado. A sintaxe argv = sys.argv[1:] indica que a variável argv receberá uma cópia do array, mas iniciando pela posição 1, ao invés de 0.
  • Em Python, uma string tem um método join. Este método recebe uma lista e faz o contrário do split, ou seja, ele insere o contéudo da string " " entre os elementos do vetor recebido como parâmetro. Em Java, eu estou imprimindo um espaço a mais após o nome do argumento. O problema disto, é que se no lugar do espaço, fosse uma vírgula, ela iria sobrar após a impressão do último argumento. Se eu não quisesse que isto ocorresse, eu teria que trocar a sintaxe do for e testar se estou no último elemento. Caso estivesse, não concatenaria a string.
  • Em Groovy, a sintaxe é semelhante a do Python. Também estou utilizando o método join. Mas ele não é o método de uma string e sim de uma lista. Ele retorna uma string que terá, entre os elementos da lista de strings, o espaço informado como parâmetro. No Groovy utilizamos uma GString ao invés de uma String do Java e isto torna as coisas muito mais simples, como você viu.
  • Tanto Python quanto Groovy possuem uma sintaxe mais amigável para o trabalho com listas e mapas. Java não. Além disto, listas nestas duas linguagens possuem o método sort e o Python, suporta ainda, o build-in sorted que estou utilizando. No Java é necessário o uso do método sort de outra classe (Collections).
  • Sei que a quantidade de linhas não é uma boa métrica para indicar a facilidade de codificação, mas através da comparação desta métrica nas três linguagens, nós ficamos realmente tentados a pensar sobre isto.

Agora, vamos para a implementação dos requisitos 5 e 6:

Em Java:

Map<String, Integer> map = new LinkedHashMap<String, Integer>();
for (String linguagem : linguagens)
 map.put(linguagem, (int) ((Math.random() * 10)));
List<Map.Entry<String, Integer>> list = new Vector<Map.Entry<String, Integer>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
 public int compare(Map.Entry<String, Integer> entry, Map.Entry<String, Integer> entry1) {
     return (entry.getValue().equals(entry1.getValue()) ? 0 :
         (entry.getValue() > entry1.getValue() ? 1 : -1));
 }
});
map.clear();
for (Map.Entry<String, Integer> entry : list)
 map.put(entry.getKey(), entry.getValue());
System.out.print("\nLinguagens do proximo projeto (ordem por prioridade, de 0 a 10): ");
for (Map.Entry<String, Integer> entrySet : map.entrySet())
 System.out.print(String.format("%s (%d) ", entrySet.getKey(), entrySet.getValue()));

Em Python:

map = sorted(dict([nome, random.randint(0, 10)] for nome in linguagens).items(), key=lambda x: x[1])
print 'Linguagens do proximo projeto (ordem por prioridade, de 0 a 10):', \
 " ".join(["%s (%s)" % (item[0], item[1]) for item in map])

Em Groovy:

def map = [:]
linguagens.each{ map.put(it, new Random().nextInt(10)) }
print 'Linguagens do proximo projeto (ordem por prioridade, de 0 a 10): '
map.sort{ a, b -> a.value <=> b.value }.each{ k, v -> print "$k ($v) " }

Meus comentários:

  • Novamente, se eu fosse pensar em quantidade de linhas, comparando com Python ou Groovy, eu não utilizaria Java. Mas, como disse anteriormente, esta não é uma boa métrica. Vou então passar para a observação da clareza de sintaxe destas linguagens;
  • Generics é bom em Java até o momento em que a sintaxe começa a ficar estranha como a utilizada nesta solução. Eu pressuponho que você, leitor deste post, seja um programador Java mas, caso não seja, eu lhe peço: não se assuste! Muitos programadores Java quase chegam a ter um "orgasmo" ao ver um código como este que eu escrevi e acham ele lindo. Não os culpo. Eu também já passei por esta fase. Vou tentar explicar o que está ocorrendo no código Java:
    1. Crio um mapa cuja chave é uma string (nome da linguagem) e cujo valor é um inteiro (a prioridade);
    2. Populo o mapa, utilizando o for estendido do Java, a partir dos elementos da lista e obtendo o valor da prioridade como um número aleatório;
    3. Estruturas de dados como mapas podem ter elementos inseridos em ordem, se a implementação do mapa for uma árvore (TreeMap, por exemplo). Entretanto, a ordenação em mapas neste caso é realizada através da chave e não do valor. E eu preciso ordenar em função do valor. Sendo assim, meu próximo passo é criar uma lista onde, cada entrada do mapa, é um elemento. Daí então eu ordeno a lista com o método sort da classe Collections. Para realizar esta ordenação, eu utilizo um comparador que vai testar o valor de cada entrada e não a chave.
    4. O próximo passo é limpar o conteúdo da lista e populá-la novamente, com os elementos da lista ordenada. Como o mapa foi implementado como uma lista ligada, a ordem de inclusão será preservada ao percorrer a lista com o último for.
  • A sintaxe do Python é mais interessante e inteligente. Vou explicá-la:
    1. Montamos uma lista de tuplas "(linguagem, prioridade)" a partir da lista de linguagens utilizando uma característica do python chamada List Comprehensions
    2. O valor (de 0 a 10) da prioridade é obtido randomicamente a partir da função randint
    3. O build-in dict recebe esta lista e a transforma num mapa
    4. O build-in sorted recebe como parâmetros o mapa e um outro parâmetro. Este parâmetro é uma função anônima (lambda) que informa qual o campo (dentro dos elementos da lista) que será utilizado como chave para comparação. Neste caso, o segundo campo (prioridade);
    5. Os elementos do mapa são impressos, novamente utilizando a sintaxe de "List Comprehensions";
  • A sintaxe do Groovy é tão interessante quanto a do Python:
    1. Como em Groovy, listas e mapas estão entre [], um mapa, para ser inicializado vazio deve receber [:];
    2. Groovy, assim como Ruby, utiliza clousures, que lembram as funções anônimas do Java em termos de funcionalidade. Na linha linguagens.each{ algumacoisa } o código algumacoisa será executado para cada elemento da lista. Em nosso código, o mapa será populado com cada elemento (it) da lista e um valor randômico para a prioridade;
    3. Os elementos do mapa são ordenados através da clousure passada para sort. a e b são parâmetros passados pelo sort para a clousure. Indicamos então que a comparação destes elementos deve ser realizada pelo atributo value. O operador <=> equivale a escrevermos a.value.compareTo(b.value). Como não precisamos especificar um return, o valor desta expressão será retornado para a função sort. Cada clousure retorna o próprio objeto. Sendo assim, o método each pode então ser chamado e recebendo outra clousure que imprime cada um dos elementos do mapa (k=key, v=value).

E, por fim, a implementação do último requisito (7):

Em Java:

String fn = "Teste.java";
System.out.printf("\nPrimeiras cinco linhas de %s:\n", fn);
BufferedReader br = new BufferedReader(new FileReader(fn));
try {
 int i = 0;
 String line;
 while ((line = br.readLine()) != null && i++ < 5)
     System.out.println(i + ": " + line);
} finally {
 br.close();
}

Em Python:

fn = 'Teste.py'
with open(fn, 'r') as f:
 print 'Primeiras cinco linhas de %s:' % fn
 i = 0
 for line in f:
     i += 1
     if i > 5: break
     print "%s: %s" % (i, line[:-1])

E em Groovy:

def fn = 'Teste.groovy'
println "\nPrimeiras cinco linhas de ${fn}:"
File f = new File(fn)
f.withReader{ reader ->
 i = 0
 for (line in reader.iterator()) {
     println "${++i}: $line"
     if (i == 5) break
 }
}

Novamente, meus comentários:

  • Python utiliza um iterator implicitamente na navegação das linhas do arquivo. Mas, no meu entendimento, um programador Java faz um bom trabalho com o uso método readLine de BufferedReader.
  • Tanto em Java, quanto em Python, o uso do bloco finally é utilizado para garantir o fechamento de um arquivo, caso ocorra alguma exceção durante o processamento do arquivo aberto. Mas, do Python 2.5 em diante, é possível utilizar a palavra chave with, que simplifica a escrita da linguagem e, garante o fechamento do arquivo, automaticamente, na saída do bloco ou na ocorrência de uma exceção.
  • O versão Groovy do programa, passa uma clousure para o método withReader que, após a execução da clousure, fecha o arquivo, automaticamente.
  • Sendo assim, tanto o Python, quanto o Groovy, tem recursos de linguagem que auxiliam o programador a não se esquecer de liberar recursos, coisa que não ocorre no Java de maneira tão natural.

Baixe o código completo da versão Java, Python e Groovy deste programa.

Concluo este post, deixando a seguinte mensagem: Vá além do Java! Se você deseja ou precisa utilizar a plataforma Java, explore linguagens alternativas para ela, como o Groovy, o Jython, o JRuby ou o Rhino. Você só tem a ganhar com isto.

terça-feira, 5 de maio de 2009

Python + Subversion

Estou envolvido no trabalho de criação de alguns scripts que, além de atualizar um repositório do Subversion, também precisam realizar algumas atividades extras. Hoje estive em uma reunião falando que se eu estivesse desenvolvendo tais scripts utilizando o Bash, estaria codificando muito mais (em termos de linhas de código) do que estou agora. Eu me amarro em Bash mas, para este trabalho, Python é a melhor opção. Ele possui integração com o Subversion através do projeto pysvn. Para ter uma boa idéia de suas funcionalidades, leia o pysvn Programmer's Guide.

Só pra constar: sei que, em termos de integração com o Python, o Mercurial (ou o Bazaar) seriam ótimas alternativas em relação ao Subversion pois estes dois DVCS foram escritos em Python! A integração com o Python pode ser apenas um motivo para a adoção do Mercurial (por exemplo). Mas, eu também posso citar diversos outros motivos.

Algumas referências extras para trabalho de integração do Python ao Subversion:

sábado, 2 de maio de 2009

Trabalho submetido ao JustJava 2009

Dia 30 de abril (quinta-feira) foi o último dia de submissão de trabalhos para a oitava edição do JustJava, que está prevista para ocorrer entre os dias 15 e 17 de setembro deste ano.

Eu submeti a apresentação do trabalho: "Construindo e implantando aplicações Java com o Groovy". Recebi ontem um email confirmando que o trabalho está sendo avaliado pela comissão organizadora do evento.

Neste trabalho, pretendo falar sobre como o Groovy pode auxiliar na construção de aplicações Java, desde o processo de build, até a implantação remota de pacotes em servidores. Ou seja, esta palestra, caso seja aprovada, irá falar sobre automação: um importante e complexo assunto quando existem várias aplicações e ambientes para implantá-las. Ultimamente, eu tenho trabalhado muito neste assunto e falo sobre isto nestes artigos. O resumo da palestra é o seguinte: "Esta apresentação explora as soluções e problemas relativos a construção de aplicações Java através do uso do Ant (+Ivy) e do Maven e mostra ferramentas alternativas que utilizam o Groovy. Por se tratar de uma linguagem dinâmica, simples e totalmente OO, o build de aplicações Java com o uso do Groovy pode reduzir e simplificar drasticamente scripts Ant que fazem este trabalho. A substituição de código do Ant por Gant por exemplo, traz mais clareza e poder na criação dos builds. Além disto, ferramentas como o Gradle, seguem princípios consolidados no Maven como convenção ao invés de configuração, aproveitando-se ainda, de todo o poder e flexibilidade oferecidos por ferramentas como o Ant. Utilizando ferramentas Groovy, esta palestra tem, como objetivo principal, lhe trazer conhecimento para a automação de processos como a construção e a implantação de aplicações Java em ambientes complexos."

Já participei do JustJava duas vezes, como palestrante:

  1. Em 2004 minha palestra teve o título "Implementando Java com Qualidade". Falei sobre o AppFuse e sobre diversas ferramentas utilizadas por ele, naquela época.
  2. Em 2005, falei sobre EJB3 no JBoss. Naquela tempo, EJB3 estava começando a ser suportado por versões do JBoss e eu apresentei vários tópicos deste EJB 3.0 Tutorial. Em 24 de Junho de 2005, alguns dias após o evento, eu criei estes vídeos e os publiquei para a comunidade Java. Se você tiver interesse, ainda pode baixar os arquivos de configuração que utilizei nos vídeos, e os exemplos. Informo que este material está antigo e talvez precise de adaptações se você for testá-lo com ferramentas em versões diferentes das apresentadas.

Se minha palestra for aprovada, ficarei contente em poder dividir com vocês, pessoalmente, o conhecimento que estou obtendo sobre este assunto.

Pequenos ajustes em meu blog

Fiz alguns pequenos ajustes em meu blog (gerenciado com o Blogger) hoje:

  1. Estou usando um template ainda mais simples (o "Simple II" de Jason Hunter). Agora só utilizo uma coluna: É O SUFICIENTE!
  2. Fiz um segundo cabeçalho pro blog (através da adição de um gadget HTML/JavaScript), contendo links para coisas do meu blog e serviços que utilizo, que são as seções: "Eu!" (Meu Profile); "Compartilho Contigo:" ("Shared Items" que compartilho através do meu leitor de feeds: o Google Reader); "Coisas que escrevi:" (Artigos, PJ's GNU/Linux short hints, Eu no Twitter e quaisquer outros textos que publicar); "Diversos" (Meus Links, Minha vida fora do trabalho, Fotos, etc.) e o fundamental "Assine!".

Porque estou escrevendo isto se está visível no meu blog? Se você está se perguntando isto, é porque você está lendo o texto diretamente a partir do meu blog não é? Mas, eu tenho alguns leitores que, como eu, lêem blogs a partir de ferramentas como Google Reader. Ou seja, eles não se importam com qualquer mudança no visual do meu blog, mas sim com o conteúdo dele. Sendo assim, este post é apenas para informar a estes leitores, esta mudança (que com certeza, não fará diferença alguma na vida deles... Dahhhh! ;-)

As atividades que descrevi aqui, fazem do processo de recuperação do meu site.

Só para aproveitar este post com uma única informação útil ;-): Twitar via shell é muito simples e, como o Bash é o principal "IDE" de muita gente (inclusive eu), achei legal compartilhar esta dica.

sexta-feira, 1 de maio de 2009

Dia do Trabalho: nada de trabalho!

Hoje estive apenas curtindo um dia legal com minha família e sogra (segunda mãe), que veio de Brasília para nos ver, neste fim de semana.

Começamos indo pra praia (aqui no Leme mesmo). Fui correndo com meus filhos pra não perder a apresentação da esquadrilha da fumaça!



Na hora do almoço, comi uma picanha maravilhosa feita por minha sogra.

Depois fui com meus filhos assistir monstros x alienígenas (em 3D) no Cinemark do Botafogo "Estada" Shopping. O filme foi espetacular: a qualidade dos gráficos e o efeito do cinema em 3D foram os diferenciais. Minha esposa e sogra aproveitaram o tempo do filme para gastar dinheiro fazendo compras (coisas de mulher).