Upgrade no Grails Brasil: o que precisamos melhorar?

Como mencionei no Grails Brasil, retomei com tudo o projeto “Grails Brasil em Grails”. Para tal, estou criando uma aplicação open source chamada GForum (faltou criatividade no nome, confesso) que, posteriormente, poderá inclusive ser reaproveitada por aqueles que se interessarem em criar novas comunidades virtuais (dentro de um mês ou menos pretendo liberar o código fonte para que todos possam dar suas contribuições).

Um dos pontos principais no projeto consiste em melhorar o visual do site atual, que é bastante precário.

Sendo assim, gostaria de saber as opiniões dos membros da comunidade a respeito do que poderia ser melhorado no site. Aproveito também para pedir sugestões com relação ao nosso novo logotipo, que inclusive já comecei a esboçar:

Sim sim, eu sei que ainda está tosco. E é exatamente por isto que preciso da ajuda de vocês. Aos interessados em ajudar no projeto do novo site, por favor, enviem suas sugestões de layouts/logotipos para meu e-mail: loboweissmann@gmail.com. Publicarei todas as sugestões enviadas neste blog (e também no Grails Brasil) para que juntos possamos.

Aproveitando, eis uma bela oportunidade para que todos façam o maior número de críticas ao Grails Brasil atual, pois é a partir destas críticas que a estrutura de nossa comunidade será aprimorada.

Aos que quiserem uma participação mais direta no projeto (por a mão na massa), podem me contactar por msn (kicolobo@itexto.net) ou pelo e-mail que mencionei acima.

Aguardo o feedback de vocês!

[OFF] Como irritar quem diz “não foi isto que eu quis dizer”

Confesso: AMO uma boa discussão, mais ainda se for puramente retórica (sou intencionalmente irritante)! Adoro discutir por nada só pelo prazer de tentar vencer o oponente no final. Recentemente, numa de minhas batalhas retóricas me diverti tanto que resolvi compartilhar com vocês alguns argumentos contra a expressão “não foi isto que eu quis dizer”. :)

(Já mencionei aqui que esta expressão é um belo sinal para se detectar um profissional de TI incompetente)

Convenhamos: nada mais chato em um debate do que apresentar um bom argumento e ser respondido por seu oponente com o pseudo-argumento “não foi isto o que eu quis dizer!”.

Pra começar, vamos pensar um pouco no próprio significado da frase. Se alguém disse “não foi isto o que eu quis dizer”, é sinal de que o locutor falou contra a própria vontade, certo? Afinal de contas, diz-se o que se intenciona comunicar, correto?

Sendo assim, o que “não quero dizer”, simplesmente não é pronunciado. Ora, se não é pronunciado, não é ouvido! Logo, a pessoa que afirmou “não foi isto o que eu quis dizer” na realidade disse EXATAMENTE o que queria. (trata-se de um argumento fraco, porém divertido)

Se o que foi ouvido não possui o significado intencionado, um dos casos abaixo se aplicam:

  • Você não possui controle sobre as próprias palavras. Afinal de contas, disse algo que não intencionava! Portanto também não controla as próprias ações. Logo, é irresponsável pelo que diz!
  • Você não é humano (!!!). Dado que a característica primordial do homem é a linguagem, e o locutor não está dizendo o que intenciona, é sinal de que não sabe usar as palavras. Logo, não possui o atributo básico que o caracteriza como tal!
    (este argumento pode ser transformado em “você é burro” se levar-se em conta o fato de ser a linguagem a matéria básica do raciocínio)

    (aviso: não utilize este argumento com pessoas que possuam tendências físico/agressivas!!!)

  • Você é ignorante! Descreve-se o que se conhece. Se o significado transmitido for diferente do intencionado, é sinal de que esta condição não ocorre.

    (um bom teste para se verificar a inteligência alheia: chame alguém de ignorante. Se a pessoa confundir ignorância com capacidade intelectual, sua burrice estará comprovada)

É também possível responder a maldita frase simpaticamente: ”Se diz o que se sabe. Se não sabe escolher as palavras, não as use!”

Claro: nada impede que você realmente esteja distorcendo as palavras do seu oponente e ele lhe responda isto (neste caso, o único uso justo que conheço para a expressão). Se este for o caso, pelo menos você terá uma boa saída retórica para a situação (e terá se divertido um bocado também). :)

Apache Ant: how could I ignore you for so long???

I’m so used to the way Netbeans treats the process of building and deploying my Java projects that I completely neglected one of the most powerful tools I had ever met: Apache Ant.

Actually, Netbeans wasn’t the only reason of my neglect. My own laziness have a big part on it. In the few times I had to read an Ant build script (always generated by Netbeans) I felt a certain angst of all that XML code. It always made me remember when I used to work with GNU make. Besides that, I’m not a big XML based DSL fan. Until I had to automate the process of deploying one of my applications using Java Webstart.

This application uses Spring + Hibernate. As a consequence, I have lots of jar files to deploy. The process consist in:

  • Sign all my jar files
  • Generate a JNLP file
  • Deploy all the files above to the server

Actually, Netbeans is progressing in this task , but it still isn’t right where I need. So, until then I had to manually (SHAME ON ME!!!) execute this task. My first attempt was to write a Groovy script. But just by accident I discovered a set of ant tasks named Orange Volt which led me to finally learn Apache Ant. And the result was just WONDERFUL!

After all this rant about Ant, I must at least describe this beast. It’s a build tool similar to GNU Make. Actually, I see it as a make refined at it’s best. All the annoyances of make are gone in ant: no more problems with characters like tab, and what is even more interesting: instead of being based on commands of the local machine, Ant is based on Java classes. As a consequence, Ant scripts are easier to transport among different computers. And the XML syntax for my surprise is actually quite useful in this case!

Installing Ant

Installing Ant is quite easy:

  1. Download the latest version at: http://ant.apache.org
  2. Unpack the downloaded file in any directory you want.
  3. Declare a system variable named ANT_HOME. This variable value must be the directory which you unpacked your Ant distribution.
  4. Add the ANT_HOME/bin directory to your system path
  5. Check if the JAVA_HOME variable is already declared on your system.

To test your installation, just type ant on your system shell. If everything is ok, the following prompt will appear:


Buildfile: build.xml does not exist!
Build failed

Using Ant

An Ant build script consist in an XML document similar to the following example:


<project name="myProject" default="dist" basedir=".">
<description>
An useless Ant script!
</description>
...
<target name="dist">
<!-- Maybe I'll do something -->
</target>
</project>

This file must be named build.xml. When you execute the ant command, Ant will seek for this file on your current directory (it’s the default behavior). As you can see on the above example: the root element of this document is called project.

The main attributes of this tag are:
name: the name of the project
default: the default target to be executed
basedir: the base directory of the script.

The description is optional. It’s used for documentation uses only.

An Ant project may have more than one target. A target is a set of tasks to be executed by the script. As in make, you may also define dependencies among targets as in the following example:


<project name="project" default="deploy" basedir=".">

<target name="copy">
...
</target>

<target name="compile">
...
</target>

<target name="deploy" depends="compile, copy">
...
</target>

</project>

In the above example, the deploy target is the default target executed by the script. But before it is executed, the compile and copy targets must be executed (they are the dependencies).

If you want, you can also execute a specific target by the command line. In this case, you only have to type the command ant [name of the target]

Tasks

As a project is composed of targets, a target is composed of tasks. You may see a task as a command to be executed. To add a task to a target, you will (as everything in Ant) use plain pure XML syntax like bellow:


<task_name attribute1="value1" attribute2="value2" ... attributeN="valueN"/>

Ant already comes with several core tasks ready to use, which list can be seen on this link.

To better understand how to use tasks, here is a quick example:


<project name="backup" default="backup" basedir=".">

<property name="destiny" location="../backup"/>

<target name="backup">

<mkdir dir="${destiny}"/>
<zip destFile="${destiny}/backup.zip"
basedir="."/>

</target>

</project>

This script will execute the backup target. It’s first action will be to execute the task mkdir. As it’s name already says, it will create a new directory (just in case it doesn’t exist) using the value defined on the property destiny.

A property is actually a global variable used by the Ant script. In this case, the destiny property is referring to a directory (that’s why I used the location attribute).

This property was used on the mkdir task using a syntax really close to the EL:


<task attribute_name="${property_name}"/>

After the execution of the mkdir task, the zip task is called. As it’s name already says, it will generate a zip file based on the two attributes I declared.

TIP: Ant have a GREAT online manual: http://ant.apache.org/manual/index.html

Writing your own tasks

Of course the Ant core tasks aren’t going to answer ALL your needs. In these cases, it’s possible to write your own. On the Ant manual there’s a great guide of how to do it: http://ant.apache.org/manual/developlist.html

With your own tasks ready, these must be packed on a jar file which then must be copied to the ANT_HOME/lib directory. (you may also add your jar files to your classpath if you want)

Here is an example of how to use external tag libraries in your own scripts:


<project name="blabla" basedir="." default="blablaTask">
<taskdef name="mytask" classname="packate.where.your.task.is.Task" />
...
</project>

To use an external task, you must declare the taskdef task in the project tag. It have two main attributes:
name: the name of your task (how you’ll declare it on your build script
classname: the complete class name

So, to see how your custom task could be used, let me complete the above example:


<project name="blabla" basedir="." default="blablaTarget">
<taskdef name="mytask" classname="caminho.para.sua.Task" />

<target name="blablaTarget">

<mytask attribute1="some value" attribute2="another value"/>

</target>

</project>

Remember: you may only declare tasks inside targets!

Usefull core tasks

In my short experience with Ant. Some of it’s core tasks where really usefull for me:

signjar: used to sign your jar files

jar: generate jar files

war/ear: it’s actually a specialization of the jar task. Used to generate .war and .ear files.

tar: used to create tar files.

zip/unzip: Compress/decompress files using the ZIP format.

patch: applies a diff file to originals

sync: synchronized a target directory with the files stored on another location.

Conclusions

  • Laziness generate ignorance :). It’s always a good thing to see things outside your favorite IDE.
  • Ant XML syntax is pretty handy. But if you don’t like it, you may also try GANT (it’s WONDERFUL for me how Groovy can always make things more elegant!)
  • Ant is easy!
  • Try not to get too much addicted to Ant (as I’m right now)

Apache Ant: como pude te ignorar por tanto tempo???

“Comodismo emburrece”. Sempre repito orgulhosamente esta frase. Nesta semana acabei por perceber que também cai vítima do mesmo. Devido à comodidade que o Netbeans nos oferece no deploy e build de aplicações, acabei por ignorar completamente o motor responsável por esta comodidade: o Apache Ant.

Na realidade, não foi só o comodismo que me privou de aprender a ferramenta: confesso que a preguiça foi o fator fundamental. Toda vez que lia os scripts do Ant (escritos em XML), me lembrava dos meus tempos do make. Além disto, sempre via os scripts do Ant com certo desdém (não sou fã de DSLs baseadas em XML). Mas recentemente topei com um problema: como automatizar o deploy de minhas aplicações utilizando Java Webstart?

Como utilizo o Spring + Hibernate, a quantidade de arquivos no formato JAR que preciso distribuir é significativa. O que implica na necessidade de executar sempre executar as mesmas tarefas:

  • Assinar todos os meus arquivos .jar
  • Criar um arquivo .jnlp
  • Enviar tanto o arquivo .jnlp quanto os arquivos jar assinados para o servidor

O Netbeans está atualmente caminhando para tornar esta tarefa corriqueira, porém enquanto isto ainda não se tornou realidade, eu precisava repetir esta tarefa manualmente (SHAME ON ME!). Posteriormente escrevi um script em Groovy, porém acabei decidindo por me arriscar com o Ant. E o resultado foi maravilhoso!

A opção pelo Ant se deu quando encontrei por acaso na Internet uma biblioteca de tags chamada Orange Volt cujo objetivo era justamente a automatização do processo que listei acima. Basicamente, a utilizo para gerar o arquivo jnlp, porém todo o procedimento anterior é executado usando as tags nativas do próprio Ant.

Bem, visto que já babei o ovo do Ant, convém descrever a criatura. Trata-se de uma ferramenta de build similar ao GNU Make, porém sem os problemas decorrentes desta. Para começar, não é baseada na execução de aplicações instaladas no computador do usuário, mas sim em classes Java, o que torna seus scripts muito mais fácilmente portáveis. Além disto, o fato de usar o XML acabou se mostrando uma alternativa bastante interessante também (e ai eu paguei lingua) em comparação com a sintaxe do Make (qualquer um que já enfrentou problemas com o caractere tab no make sabe do que estou falando).

Instalação

A instalação do Ant é muito simples, e é composta pelos seguintes passos:

  1. Baixar o Ant em seu site oficial: http://ant.apache.org
  2. Descompactar o conteúdo do arquivo zipado em um diretório de sua escolha
  3. Criação de uma variável de ambiente chamada ANT_HOME, cujo valor deve consisistir no diretório no qual o arquivo zipado foi descompactado.
    Sendo assim, se você descompactou o arquivo no diretório C:\Ant, esta variável deverá possuir o valor C:\Ant
  4. Incluir no path do seu sistema o diretório ANT_HOME/bin
  5. Verificar se a variável de ambiente JAVA_HOME está definida no seu sistema.

Executados estes passos, no seu shell digite o comando ant. Se obtiver uma resposta similar a


Buildfile: build.xml does not exist!
Build failed

é sinal de que o ant foi instalado com sucesso.

Usando o Ant

Como mencionei acima, um script de build do Ant consiste em um documento no formato XML tal como no exemplo abaixo:


<pre><project name="meuProjeto" default="dist" basedir=".">
<description>
Um script ant que não serve para nada!
</description>
...
<target name="dist">
<!-- Eu irei fazer alguma coisa -->
</target>
</project></pre>

Este documento no formato xml deve se chamar build.xml. Quando o comando ant é executado, é buscado no diretório corrente a existência deste arquivo (trata-se do comportamento default da ferramenta). Como pode ser visto no exemplo acima, o elemento raiz deste documento se chama project.

Os principais atributos a serem definidos nesta tag são:
name: o nome do projeto
default: o alvo (target) a ser executado por default pelo script caso nenhum seja definido na linha de comando (mais sobre isto adiante)
basedir: o diretório base para a execução do script. No exemplo acima, se trata do diretório corrente.

A tag description é opcional. Serve apenas para fins de documentação.

Em um projeto podem ser definidos mais de um alvo (target). Um target consiste em um conjunto de tarefas a serem executadas pelo script. Tal como no make, você também pode definir interdependências entre as mesmas, tal como no exemplo abaixo:


<project name="projeto" default="distribuir" basedir=".">

<target name="copiar">
...
</target>

<target name="compilar">
...
</target>

<target name="distribuir" depends="compilar, copiar">
...
</target>

</project>

No exemplo acima, o target distribuir que é o default ao ser executado irá antes chamar os alvos compilar e copiar. Convém mencionar no entanto que a ordem de execução não necessáriamente será compilar e copiar. Se houver mais dependências nas tags compilar ou copiar, estas serão executadas antes das mesmas.

É possível também pela linha de comando executar um target específico. Se for executado o comando ant compilar, por exemplo, a tag distribuir (definida como default no exemplo) não será executada.

Tasks

Assim como um projeto é composto por alvos, um alvo é composto por tarefas (tasks). Uma task nada mais é do que um pedaço de código que pode ser executado. Simplificando ainda mais esta descrição, pense em uma task como um comando. A sintaxe de definição de uma task dentro de um target é muito simples:


<nome_da_task atributo1="valor1" atributo2="valor2" ... atributoN="valorN"/>

O Ant já vêm com uma série de tasks pré definidas, cuja lista pode ser acessada neste link.

Para melhor entender o funcionamento das tasks, segue abaixo um exemplo de build file bem simples. No caso, ele irá fazer o backup de um projeto qualquer.


<project name="backup" default="backup" basedir=".">

<property name="diretorioDestino" location="../backup"/>

<target name="backup">

<mkdir dir="${diretorioDestino}"/>
<zip destFile="${diretorioDestino}/backup.zip"
basedir="."/>

</target>

</project>

Ao ser executado, o script irá executar o alvo default (que também é o único no caso): default. As tasks definidas em seu interior serão executadas na ordem em que são definidas.

Sendo assim, primeiro será criado um diretório um nível abaixo do corrente chamado backup (convém mencionar que este diretório somente será criado caso já não exista). Para tal, utilizamos uma propriedade do script de build.

Pense em uma propriedade como se fosse uma variável utilizada pelo script. No caso, a propriedade em questão diz respeito a uma localização no disco rígido do usuário (o que explica o atributo location passado para a mesma).

Utilizamos o valor da propriedade diretorioDestino na task mkdir utilizando uma sintaxe bastante similar à EL com a qual estamos acostumados a trabalhar em arquivos JSP. Basicamente é a seguinte:


<task nome_do_atributo="${nome_da_propriedade}"/>

Em seguida, é executada a task zip. A função desta tag consiste em criar um arquivo no formato zip. No caso, usei apenas dois dos seus atributos: destFile (que indica o nome do arquivo a ser criado) e basedir (que diz qual o diretório raiz que contém os arquivos a serem incluídos no conteúdo compactado).

Dica importante: sempre consulte o manual do Ant online. http://ant.apache.org/manual/index.html

Criando e usando suas próprias tasks

Óbviamente as tasks que acompanham o Ant não irão suprir 100% das suas necessidades. Neste caso, é possível criar as suas próprias tasks. No manual do Ant há um guia muito simples de como fazê-lo: http://ant.apache.org/manual/developlist.html

Criadas as suas tasks, estas deverão ser empacotadas em arquivos jar. Uma vez gerados os seus arquivos jar, basta copiá-los para o diretório ANT_HOME/lib e em seguida utilizá-las em seus projetos do Ant.

Em seguida, para utilizá-las em seus scripts, utilize a task taskdef, tal como no exemplo abaixo:


<code><project name="blabla" basedir="." default="blablaTask">
<taskdef name="mytask" classname="caminho.para.sua.Task" />
...</code>
</project>

Esta task possui apenas dois atributos:
name: o nome que identificará a sua task dentro do seu script
classname: o caminho da classe que contém a sua implementação

Sendo assim, no mesmo exemplo acima a task poderia ser utilizada como


<code><project name="blabla" basedir="." default="blablaTarget">
<taskdef name="mytask" classname="caminho.para.sua.Task" />

<target name="blablaTarget"></code>

<mytask attribute1="algum valor" attribute2="outro valor"/>

</target>

</project>

Lembre-se: tasks só podem existir dentro de targets!

Tasks realmente úteis

Dentre as tasks disponíveis pelo Ant, algumas se mostraram incrívelmente úteis para mim:

signjar: é a tag que utilizo para assinar todos os meus arquivos .jar (e que me ajudou a resolver o problema com o Java Webstart)

jar: gera arquivos .jar

war/ear: Geram respectivamente arquivos .war e .ear (trata-se de uma especialização da tag jar

tar: gera arquivos .tar

zip/unzip: Compacta/descompacta arquivos no formato .zip

patch: executa patchs em arquivos originais

sync: sincroniza arquivos presentes em diretórios diferentes.

Conclusões

  • Comodismo gera ignorância :). Procure sempre que possível pensar FORA de sua IDE favorita.
  • A sintaxe em XML do Ant, apesar de inicialmente gerar resistência é uma mão na roda.
    Mas se você não gostar da sintaxe XML do Ant, pode contar com o GANT também (eu acho lindo como Groovy sempre torna as coisas mais bonitas)
  • Ant é MUITO mais simples do que aparenta em um primeiro momento.
  • Muito cuidado para não ficar viciado no Ant (agora gero scripts do Ant pra basicamente TODAS as minhas tarefas de manutenção em meus computadores (e em alguns momentos apenas por diversão))

Why so few developers are using Firebird SQL?

Recently I started a new project in which I need to choose another database besides MySQL. Since then, I had been using MySQL for basically everything, but given the MySQL licensing scheme and a few restrictions of the project itself, this time I had to use something else. So I choose Firebird SQL.

But there’s something about Firebird that always bothered me: why so few developers actually know and use Firebird? Basically (at least here in Brazil) I only see it being used among Delphi developers. Why isn’t it as popular as MySQL or PostgreSQL? Given its features (listed below), can we say that the project lives an unfair situation?

Firebird have several features which makes it a great choice:

  • Really free:: contraty to MySQL, you can use Firebird in your commercial applications without any fee or legal problem. (BTW: I know that PostgreSQL have this advantage too)
  • All the basic features of large RDBMS:: stored procedures, triggers, A.C.I.D. compliance, online backup, generators, referential integrity, etc…
  • Small footprint: had you seen its embeddable version? Just amazing: in less then 1 Mb you have all the features of the default one without cutting anything!
  • Low hardware requirements: basically, if something computes, it can run Firebird.
  • Available in all the major OS platforms: Linux, Windows, Mac OS, Solaris and others
  • Reasonable performance: Firebird performance remains between MySQL and PostgreSQL.
  • Really active project: despite its low popularity, it’s a quite active project. In april/2009, for example, was announced the 2.5 beta version of the project.
  • Databases with unlimited size: the database size limit is determined by the filesystem in which the database is stored. But, if your database exceed its limit its always possible to split it in several files.
    (the largest database known have 960 Gb link)
  • 100% SQL 92 compability
  • Connectivity: basically you can access a Firebird SQL through any programming language

My experience with Flamerobin is being really pleasant, but it’s really sad to see that since I wrote my Microsoft Access to Firebird database converter (MDB2FDB http://www.firebase.com.br/fb/downloads.php?categ=8) in 2006 that the Firebird popularity hadn’t changed at all!

Since I really like this software, and I think that its current popularity situation is unfair, maybe it could be interesting to list some actions that may help this project. So, here is my list:

Of course, I couldn’t finish this post without guessing (just guesses) the reasons why Firebird SQL is so unpopular if compared to MySQL or PostgreSQL:

  • There’s no big player like Sun/Oracle or IBM supporting it right now.
  • The official website is terrible (http://www.firebirdsql.org). Seems futile, but the first impression of the project is horrible. Makes you think it’s stalled.
    Firebird’s biggest sponsor today is IBPhoenix , which main business IS Firebird. But even it’s website falls in the same problem.
  • The fact of being Delphi related since it’s begning. With Delphi’s decadence, its popularity just floundered with it.
  • Poor documentation

Maybe things may change to Firebird SQL after Oracle bought Sun (many MySQL users are getting scared (I see no reason for this by the way)) and may play with Firebird, but it’s something improbable to happen. :)

Of course, these are just my opinions about it. I really whould like to know yours. Why do you think so few developers are using Firebird today?

Firebird SQL: por que tão impopular? (e como melhorar a situação)

Recentemente iniciei um novo projeto no qual  precisei responder a questão: qual SGBD usar? Até então, vinha usando o MySQL para basicamente tudo (fou fanático pelo MySQL), porém, devido ao seu esquema de licenciamento e algumas restrições do próprio projeto, tive de ignorá-lo desta vez.
Foi quando me lembrei de um velho conhecido: o Firebird! [...]

Oracle/Sun explained in two pictures


Brasil quer macs!

Olá a todos. Se você é brasileiro e, como eu, também gosta dos produtos da Apple (especificamente os computadores), deve de também estar ultrajado com os novos preços adotados aqui no Brasil. Convenhamos: R$ 6700,00 pelo modelo básico do iMac é no mínimo um insulto. Será que a Apple pensa que nós brasileiros somos milionários?
Pensando [...]

How to restore corrupted MyISAM/InnoDB tables on MySQL 5.0

I know that it’s not our job to manage database servers. But if you don’t have a competent crew for that, you have to face the problem yourself.
Well, here is what happened to me this week. Waiting for the end of the day, in which the number of connections to our MySQL server is [...]

Como recuperar uma base de dados InnoDB e MyISAM (MySQL) corrompida

Eu sei: não é nosso trabalho cuidar da manutenção de servidores de bancos de dados. Mas quando você não possui uma equipe competente para tal, esta “responsabilidade” acaba caindo sobre você.
Pois bem: vejam o que aconteceu comigo na semana passada. Esperando o final do dia, no qual o número de conexões ao MySQL é [...]