Categorias → Java
Grails: resolvendo o problema de queda de conexão com o MySQL
Você que trabalha com Grails e MySQL já topou com excessões como estas: “com.mysql.jdbc.CommunicationsException: Communications link failure“, “java.net.SocketException: Broken pipe” , “java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.” ?
Normalmente ocorrem após algumas horas de inatividade da sua aplicação. Normalmente acontecem porquê o MySQL fecha as conexões inativas, algumas das quais eram justamente as do seu projeto. Há duas soluções para o problema: uma porca e outra elegante.
A porca é simplesmente não fazer nada: ao mandar recarregar novamente a página será recriada a conexão com o MySQL e parecerá que o problema foi resolvido.
A elegante é alterar a seção dataSource do arquivo grails-app/conf/DataSource.groovy para que fique parecido com o exemplo abaixo:
dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
username = "seu_usuario"
password = "sua_senha"
properties {
maxActive = 50
maxIdle = 25
minIdle = 5
initialSize = 5
minEvictableIdleTimeMillis = 60000
timeBetweenEvictionRunsMillis = 60000
maxWait = 10000
validationQuery = "/* ping */"
}
}
A diferença é a seção properties. Nela basta incluir as configurações do pool de conexões do Hibernate. Por deafult, o Hibernate utiliza como gerenciador de pool de conexões o C3P0 que, por sua vez, evita que você obtenha uma conexão inválida com o banco de dados.
Agora, explicando os parâmetros:
maxActive: número máximo de conexões abertas e ativas com o SGBD
maxIdle: número máximo de conexões em stand by que você quer manter
initialSize: número inicial de conexões com o banco de dados
minEvictableIdleTimeMillis: tempo mínimo em milisegundos para que o pool de conexões comece a fechar conexões em idle
timeBetweenEvictionRunsMillis: o tempo entre as limpezas de conexão em milisegundos
maxWait: tempo máximo de espera em milisegundos para se obter uma conexão ou de espera de resultado de uma conexão
validationQuery: qualquer comando a ser enviado para o SGBD apenas para verificar se a conexão está válida ou não.
E é isto: agora seus usuários (e você) não verão mais aquela maldita mensagem de erro ao acessar seu sistema pela manhã
Grails: do Groovy à Web – Quinta e última parte publicada na Java Magazine 79
Acaba de sair a edição digital (o que quer dizer que a versão impressa já deve estar a caminho) da revista Java Magazine n. 79, que contém a quinta e última parte da minha série “Grails: do Groovy á Web”.
Desta vez o assunto é a camada de visualização: dei foco ao detalhamento da tecnologia GSP (Groovy Server Pages). Serão expostas todas as similaridades com o JSP, incluindo melhores e piores práticas do seu uso. Acredite: conhecer BEM GSP vale muito à pena.
Também veremos o uso de templates, criação de tags customizadas, gerenciamento de layouts com SiteMesh e aplicação de Ajax com Grails, abrangendo assim a esmagadora maioria dos temas (em detalhes) que você precisa conhecer para criar uma camada de visualização de alto nível usando Grails.
Foi um prazer imenso escrever esta série de artigos, e pelo que pude observar, incentivou muita gente a aprender este framework maravilhoso que é o Grails. Sendo assim, agradeço a todos aqueles que me incentivaram com críticas, sugestões e elogios na produção desta série (principalmente o Eduardo Spinola).
Aproveito também o post para lhes convidar a ler o meu próximo artigo a ser publicado na Java Magazine, no qual tratarei do uso do padrão de injeção de dependências com o Spring 3.
Aguardo ansiosamente pelo feedback de vocês.
Até lá!
Uma experiência bem sucedida com o Memcached
Memcached é um sistema de cache em memória distribuido muito fácil de usar. Como recentemente tive uma experiência maravilhosa com esta ferramenta acredito que é interessante expô-la neste post (prometo que o próximo post será sobre MongoDB). A natureza do Memcached é extremamente genérica – trata-se de um serviço de rede – sendo assim, o que descreverei pode ser aplicado sem grandes mudanças a básicamente qualquer linguagem/ambiente de execução. Mas antes de falar sobre minha experiência, vou falar um pouco sobre o funcionamento da criatura e como usá-lo com Java (consequentemente, com Groovy também).
Idéia básica
Para muitos, o conceito de cache é algo novo. Sendo assim, convém fazer uma introdução ao conceito. Imagine que você possua um conjunto de informações que repetidas vezes precise ser buscado na sua base de dados. A cada consulta, você precisa:
- Enviar a consulta (por exemplo: SQL)
- Esperar o processamento do SGBD
- Receber o resultado obtido
- Transformá-lo, tornando-o útil para sua aplicação
O objetivo do cache é evitar temporáriamente os três últimos passos do procedimento que descrevi acima, retornando para o usuário o resultado do processamento dos dados em estado cru. Se 2 + 2 são 4, por que calcular este valor toda vez que você receber esta pergunta se é possível armazenar apenas o resultado e reaproveitá-lo quando necessário?
O Servidor Memcached
O Memcached é um serviço de rede. No site oficial (http://www.memcached.org) é possível baixar a última versão, que vêm como código fonte (veja este link para maiores detalhes sobre como proceder com a instalação). Se estiver usando Linux, instalá-lo é ainda mais fácil, visto que muito provávelmente a criatura já estará disponível nos repositórios de sua distribuição.
Instalado, basta executar o comando memcached para iniciar o serviço. É importante conhecer alguns parâmetros, cuja listagem segue abaixo:
-m : quanta memória (em Mbs) o Memcached irá usar. Caso omitido, o valor default é 64 Mb.
-p : qual a porta TCP a ser usada. Caso omitido, o valor default é 11211
-u : qual a porta UDP a ser usada. Como a porta TCP, o valor default é 11211 caso omitido.
-v : Modo verboso: o Memcached irá expor na tela o que está executando. É bacana quando estamos aprendendo a usar o bichinho. Interessante mencionar que há duas outras opções: -vv (mais verboso) e -vvv (ainda mais verboso)
Sendo assim, se eu executar o comando memcached -m 540 -v -p 11000 -u 11000 iniciará o serviço com 540 Mb de memória no modo verboso definindo como portas UDP e TCP a 11000.
Como mencionei, o Memcached é um servidor distribuido, mas como minha experiência até o momento envolveu apenas uma instância ainda não tenho conhecimento suficiente para compartilhar.
O que é e como é armazenado
Pense no Memcached como uma tabela de hash gigante. Toda informação individual armazenada possui basicamente 3 elementos:
Identificador: um texto com tamanho máximo de 250 caracteres que identifica um corpo de informação. Equivale à chave primária com a qual já estamos acostumados a trabalhar no modelo relacional. Não há regras com relação ao seu valor: sendo assim, você é livre para identificar suas informações como quiser.
Tempo de duração: o tempo (em segundos) que o Memcached manterá esta informação na memória. O tempo máximo suportado é 30 dias.
Corpo: a informação em si. No caso do Memcached, esta possui tamanho máximo de 1 Mb. Se for pouco pra você, sempre é possível dividir a sua informação em mais de um bloco, compactá-la ou, se preferir, alterar o código fonte do Memcached (eu o li inteiro, e é BEM fácil de entender (se você souber C)).
Lembre-se: não se trata de um banco de dados. Tudo no Memcached, assim como na vida (sôou poético!) é passageiro. A idéia é evitar que tenhamos de acessar o SGBD, que é um processo MUITO mais caro computacionalmente, e não substitui-lo!
O cliente Memcached
O primeiro passo é escolher qual biblioteca cliente usar para acessar o Memcached. Há diversas, implementadas em tudo o que você imaginar: C, C++, PHP, MySQL, Python, Perl, Ruby… No nosso caso, vou falar do SpyMemcached, que é um cliente para Java. Uma lista com “alguns” dos clientes disponíveis atualmente pode ser acessada neste link.
O SpyMemcached é composto por um único arquivo Jar, o que torna seu deploy muito simples. Basicamente o único pacote que você vai precisar é do net.spy.memcached.
Obtendo uma conexão com o Memcached
Basta criar uma nova instância da classe MemcachedClient, tal como no exemplo abaixo:
MemcachedClient client =new MemcachedClient(AddrUtil.getAddresses("0.0.0.0:11211 10.10.10.69:11211"));
Repare que passei dois servidores distintos. Usando este construtor você poderá adicionar um ou mais servidores aonde serão feitas as suas buscas.
Buscando e inserindo informações
Buscar e inserir informações com o SpyMemcached é simples. O código abaixo é quase que auto-explicativo.
MemcachedClient client =new MemcachedClient(AddrUtil.getAddresses("localhost:11211"));
// O que irei armazenar no Memcached
Pessoa pessoa = new Pessoa();
pessoa.setNome("Kico");
pessoa.setCidade("BH");
// Incluindo informações
client.add("chave_pessoa", 120, pessoa);
// Buscando a informação
Pessoa noCache = (Pessoa) client.get("chave_pessoa");
Quando incluimos uma informação no Memcached, devemos passar 3 parâmetros: a chave de identificação, o tempo em segundos e o que queremos armazenar. No caso de um objeto, este obrigatóriamente deverá implementar a interface java.io.Serializable. Caso contrário será disparada uma excessão.
Já para obter a informação, basta passar a chave que a identifica e em seguida fazer o type casting para o tipo desejado.
Ah: e como fechar a conexão com o servidor? Simples: execute o método shutdown() da classe MemcachedClient.
Conhecendo os métodos abaixo da classe MemcachedClient você já pode começar a trabalhar (e bem) com o Memcached:
void MemcachedClient.add(String chave, int segundos, Object valor): insere uma informação no servidor Memcached. Se já existir um valor definido para esta chave no servidor, este será mantido pelo Memcached.
Object MemcachedClient.get(String chave): retorna um valor armazenado no Memcached
void MemcachedClient.shutdown(): fecha a conexão com o Memcached
void MemcachedClient.remove(String chave): remove uma informação armazenada no servidor
void MemcachedClient.replace(String chave, int segundos, Object valor): substitui um valor armazenado no servidor.
Dica: aproveite ao máximo suas conexões com o Memcached buscando o maior número possível de registros, mas nunca se esqueça de fechá-las, pois o serviço começa a apresentar problemas quando o número de conexões simultâneas é muito alto.
Minha experiência
Eis a situação: possuimos uma aplicação feita em Grails cuja base é uma biblioteca escrita em Java. Esta biblioteca é também usada por diversas aplicações executadas no ambiente desktop dentro da empresa. Fiz uma imagem que, espero, ilustre a situação.
Em nosso servidor físico aonde já se encontrava instalado o Tomcat aproveitei para colocar em execução o servidor do Memcached.
Como sou o pai da biblioteca legada que mencionei acima, a refatorei para que ao invés de usar a biblioteca de cache anterior, passasse a usar o Memcached.
Em seguida, atualizei tanto a nossa aplicação Grails quanto os clientes desktop (nestas horas você começa a AMAR o Java Webstart) e voilá: resultado imediato.
Como todos acessam o mesmo servidor Memcached, no momento em que uma aplicação desktop ou web alimentam o servidor de cache, automáticamente todas as demais instâncias se beneficiam. Resultado? Nossa performance global aumentou no mínimo 3 vezes, e o número de chamadas ao nosso SGBD diminuiu em aproximadamente 40%.
É importante mencionar que em nosso ambiente é muito comum mais de um usuário concorrentemente necessitar do mesmo conjunto de informações. Isto é fundamental, pois caso contrário não teriamos um ganho de performance, mas sim perda, pois antes de executar uma consulta no SGBD, sempre seria feita uma busca no Memcached.
É fundamental lembrar o seguinte aqui: não temos um cache local, mas remoto. O ganho da performance é obtido em grande parte porque não precisamos popular objetos, visto os mesmos já virem “prontos” do servidor para nós.
Antes do Memcached haviamos pensado sériamente em usar o Terracota. Mas como nosso ambiente é heterogêneo, e há programas escritos em .net, C/C++, VB6 e PHP, o Memcached caiu como uma luva, pois assim podemos aproveitar a mesma estrutura (e dados!) entre estas diferentes plataformas de execução/desenvolvimento (claro, com os devidos cuidados para evitar a bagunça).
Recomendadíssimo portanto o seu uso. Espero que este post seja útil aos que estejam interessados em usar a ferramenta.
Como instalar o Apache Cassandra
Recentemente enfrentei alguns problemas ao tentar instalar o Apache Cassandra. Como o getting started do projeto não me ajudou muito, aqui segue um guia rápido sobre como instalar o bichinho no seu computador/servidor.
1. Faça o download da última versão no site oficial: http://incubator.apache.org/cassandra/
2. Verifique os seus requisitos de sistema.
Como o Cassandra é feito em Java, o ideal é que você tenha a última versão do JRE instalado na sua máquina. No meu caso, usei o JDK 1.6.0_18. Caso você tenha no seu computador tanto o JDK quanto o JRE convencional instalado, recomendo que você defina a sua variável JAVA_HOME apontando para o diretório do JDK – ainda não está claro na documentação do Cassandra se o JDK é obrigatório.
3. Descompacte o conteúdo do arquivo baixado em um diretório de sua escolha
4. Crie uma variável de ambiente chamada CASSANDRA_HOME que aponte para o seu diretório de instalação do Cassandra
5. Edite o arquivo storage-conf.xml, que se encontra em CASSANDRA_HOME/conf
Neste arquivo encontram-se pré-configurados os diretórios nos quais o Cassandra irá armazenar os seus dados. O problema é que muito provávelmente estes diretórios não existem ainda no seu computador. Procure pelas tags CommitLogDirectory (que armazena o log de commits do Cassandra), DataFileDirectories (aonde seus dados serão armazenados), CalloutLocation e StagingFileDirectory
Como você verá, eles estão configurados para diretórios do tipo /var/cassandra, ou seja, já vieram pré-configurados para Linux. Se você está usando Windows, com certeza o Cassandra não irá funcionar de cara.
Há dois caminhos para solucionar o problema: Você pode criar a estrutura de diretórios exposta por estas tags ou simplesmente editá-las definindo aonde suas informações deverão ser armazenadas.
Feito isto o Cassandra executará perfeitamente no seu computador.
PS: bem que podia haver um instalador hein? Hmm…. (estalo na cabeça) :)
Por que resolvi largar o HTML e partir pro Flash (Flex na realidade)
No decorrer de 2009 iniciei um projeto cujo principal objetivo técnico consistiu em levar ao extremo o que consigo fazer atualmente usando Grails na camada de controle e domínio e a dobradinha HTML/CSS/Javascript na camada de visualização (atualmente, só de ver uma interface 100% baseada em campos textuais e caixas de seleção já começo a bocejar).
Na camada de visualização quis ver o quão próximo do desktop eu conseguiria chegar usando HTML, CSS e Javascript (muito JQuery neste caso). Nos primeiros momentos, fiquei bastante surpreso com o que estava conseguido: muito drag and drop e uma interface bem diferente do feijão com arroz que estava habituado a produzir. Porém, conforme o projeto progredia, algo ficava nítido pra mim: na camada de visualização estava usando ferramentas erradas. Sendo assim, parei de me auto enganar e resolvi aceitar um fato: HTML não foi feito para se criar aplicações ricas.
É importante que nos lembremos das raízes históricas da web: sua estrutura foi construída ao redor do que se intencionava ser um mecanismo de distribuição de documentos, e não para se criar aplicações (só pra lembrar, é Hypertext Transfer Protocol). Resumindo: faz muito sentido usar HTML para se expor conteúdo textual, mas muito pouco para se criar aplicações com interfaces ricas (o que é o meu caso).
O pesadelo do HTML (os tais “web standards”)
A verdade é: usar HTML para criar aplicações com interfaces ricas ainda é (e vai continuar sendo por um bom tempo) um pesadelo.
Sim, é verdade que as coisas estão melhorando, e temos alguns bons indícios disto:
- Google tá puxando o HTML 5 no Chrome, e o Firefox e Internet Explorer já estão começando a oferecer algum suporte
- O maldito Internet Explorer 6 está começando a desaparecer
- Bibliotecas como jQuery conseguem minimizar a discrepancia entre as diferentes implementações do JavaScript presente nos navegadores
- Aplicações como Google Maps expõe que de fato é possível criar aplicações ricas usando “apenas” HTML, CSS e muito JavaScript
Yeap: mundo lindo né? Só que tem alguns “pequenos” problemas.
Microsoft Internet Explorer ainda domina
Ainda não sairam as estatísticas do quarto trimestre de 2009, mas é fato: até o terceiro trimestrede 2009 quase 70% das pessoas ainda usam o maledeto IE. (fontes: NetApplications, W3Counter, StatCounter). O IE8 é mais próximo dos padrões do W3C, é verdade, porém sabendo um pouco de história, fica nítido que será temporário, e em pouco tempo a Microsoft irá incluir novas “features” no seu navegador. (pior: IE6 ainda é o browser mais usado (fonte: NetApplications).
Os browsers ainda não são todos 100% compatíveis com os padrões web
Se você quer criar uma aplicação rica usando apenas web standards, ou seja, HTML, CSS e Javascript, no mínimo os navegadores devem ser compatíveis com o padrão, certo? Atualmente apenas o Chrome 2 e o Safari 4 conseguem passar no Acid3 (fonte). Juntos correspondem atualmente a algo em torno de no máximo uns 9% do mercado. (só pra “animar”, o IE8 conseguiu passar com nota 10/100).
HTML 5 ainda está longe de se tornar realidade
O HTML 5 cuja especificação começou em 2004 vai ter a sua primeira versão candidata publicada (talvez) em 2012 E vai ser recomendado pelo W3C a partir de 2022 (fonte). Ok: então se o mundo não acabar em 2012, teremos de esperar “apenas” mais 10 anos.
Claro, nada impede que os navegadores comecem a implementar o padrão, certo? De novo, não é lá muito animador, basta ver o que temos hoje (fonte (yeap: Wikipédia mesmo, porém as fontes indicam ser um post confiável)). Seu cliente topa esperar todo este tempo?
Nada contra os web standards (muito a favor!), desde que sejam usados no lugar certo
Se o seu trabalho não exige uma interface rica (com drag and drop, multimídia de fato e interação que vá além de meros campos textuais e caixa de seleção), e serve apenas para expor conteúdo, web standards é o canal (aliás, o único que conheço), pois apresenta diversas vantagens:
- Maior compatibilidade entre navegadores (sempre relativa)
- Carregamento mais rápido
- Facilidade de indexação por motores de busca
- Código limpo
Quer usar apenas web standards para criar aplicações ricas? Ok! Faça um jogo que valha à pena usando apenas Javascript, HTML/CSS compatível com todos os navegadores e depois ma apresente. :)
Como acabei optando pela plataforma Flash
O caminho natural para o meu caso, que sou especializado de fato na plataforma Java seria o JavaFX. No entanto, alguns fatores pesaram muito a favor da solução da Adobe:
- Flash é uma tecnologia madura
- 98% dos computadores possuem o Flash Player instalado (fonte)
(multiplataforma e PADRÃO é ISTO) - É lingua franca entre designers (com os quais a cada dia que se passa, tenho tido de interar mais e mais), pois é completamente integrado às ferramentas gráficas da Adobe (que são as melhores)
- ActionScript é uma linguagem que se mostrou surpreendentemente poderosa para mim, que até então a esnobava com a maior tranquilidade (bem feito pra mim!)
- Foco na parte visual
- Flex é agora completamente open source (se não o fosse, estaria usando JavaFX agora)
- Flex e Air
O que me fez realmente me apaixonar de fato, confesso, foi o Flex. Conforme ia estudando a tecnologia, fiquei fascinado com a riqueza que ela me oferece. Basicamente, é o Flash, porém com uma roupagem mais próxima da que desenvolvedores de aplicações como eu estamos acostumados. O projeto que mencionei no início deste blog está sendo atualmente refeito em Flex: e o resultado está sendo maravilhoso.
Com Flex consigo acessar via HTTP (e também por WebServices, bancos de dados, etc) de uma forma MUITO simples tudo o que preciso, ou seja, é fácililimo de integrar com meu código legado. Existe inclusive um plugin para Grails bastante interessante (fonte). Ou seja, continuo trabalhando no backend com as mesmas ferramentas que usava antes: a única diferença é que agora uso Flex na camada de visualização quando preciso de algo mais elaborado.
Além disto, outro fator importantíssimo foi o Air, que nos permite transformar a nossa aplicação web em uma aplicação desktop de uma forma incrívelmente simples.
Conclusões
A conclusão que chego é a seguinte: se sua interface será simples, e não requer nada que vá além do que o HTML 4 de hoje com JavaScript e CSS podem te oferecer, fique com os padrões web de hoje. Eles te atenderão perfeitamente. Abrace-os e defenda-os com unhas e dentes.
No entanto, se sua aplicação requer uma interface rica, que vá além dos controles HTML, e não é algo cujo principal propósito seja expor informação textual ou pictórica, opte por alguma tecnologia RIA (Silverlight, JavaFX e Chrome Frame (considero o Frame uma plataforma RIA, visto que é um plugin assim como os demais) são MUITO interessantes também), pois irá lhe poupar MUITO tempo e, querendo ou não, é a ferramenta certa para este tipo de trabalho.
Acredito em um meio termo: nada impede misturar web standards com algum framework RIA, pois no caso do projeto que mencionei, é exatamente o que estou fazendo neste momento.
Neste ano estou apostando no Flex. Aguardem por vários posts a respeito conforme me aprofundo na ferramenta e, mais importante: Feliz 2010!
PS: agora, por caridade: não empolgue e faça seu blog ou página corporativa usando apenas algum framework RIA ok? Assim você quebra a bicicleta! :)
Outra causa para o maldito erro “Não é possível abrir mais tabelas” do MS Access com JDBC ODBC Bridge!
Como sempre, o Access apronta das suas comigo. Quando achava que já tinha resolvido todos os problemas relacionados ao maldito problema “Não é possível abrir mais tabelas” (veja este link), encontrei outra possível causa para o mesmo no StackOverflow.
O que pode ocorrer é o seguinte: há situações nas quais o seu cliente pode perder conexões com a rede. Quando a conexão é fechada, não necessáriamente é liberado o socket de conexão com os arquivos de conexão com o Access até que seja executado o coletor de lixo do Java.
Ou seja: você fecha a sua conexão, assim como todas as suas instâncias de PreparedStatements e ResultSets, define-as como null mas o driver ainda não as fechou porque perdeu conexão com a rede momentaneamente.
Como picos de rede são comuns em ambientes mais complexos (e não tão complexos assim), a solução é a seguinte: ao trabalhar com Access e Java, execute o garbage colector de tempos em tempos para garantir que as conexões fechadas e nulificadas sejam de fato fechadas no driver ODBC.
A minha pergunta relacionada no StackOverflow pode ser vista aqui com ainda mais detalhes.
Dica: iniciando processos em Groovy
Há situações nas quais se torna necessário iniciar processos externos.Em Java, podemos usar a classe Runtime para iniciar novos processos, tal como no código abaixo:
java.lang.Runtime.getRuntime().exec("notepad.exe")
O resultado será uma nova instância da classe abstrata java.lang.Process, cujos métodos poderemos acessar e assim direcionar o stream de saída, etc.
Groovy simplifica esta tarefa da seguinte forma: caso queira iniciar um novo processo, digite o nome do comando dentro de uma string e em seguida chame o método execute() embutido pela linguagem dentro desta classe, tal como no exemplo abaixo:
"notepad.exe".execute() // BEM mais simples, não é mesmo?
O resultado da execução deste método será uma instância de java.lang.Process, exatamente como o exemplo em Java que citei acima.
Sabe: da pra ir além. Você também pode processar a saída de um comando linha a linha se quiser. Supondo que você esteja executando o sistema operacional Linux (ou o Windows com o cygwin) instalado, o código abaixo também seria válido:
<pre class="code-java">def processo= <span class="code-quote">"ls -l"</span>.execute()
processo.in.eachLine { linha -> println linha }</pre>
Não é bacana?
Link útil: acessando bases de dados MS Access com Java
Sempre enrolei pra escrever um post assim, até que encontrei um pronto na internet.
Sendo assim, se você também sofre tendo de acessar o maldito Access usando Java, recomendo que leia o guia abaixo: muito útil.
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=2691&lngWId=2#SECTION0
Em número de usuários registrados, Grails Brasil é o maior grupo de usuários Grails do mundo
Recentemente resolvi fazer uma pesquisa para descobrir, dentre os grupos de usuários de Groovy e Grails (foco em Grails) aonde se situava o Grails Brasil.
Eis o resultado: em número de usuários registrados, Grails Brasil é de longe (apenas o grupo de Minessota chega perto de nós com 224 usuários) o maior do mundo, levando-se em consideração o número de usuários registrados (562).
A listagem dos usuários foi obtida no site oficial do Grails: http://www.grails.org/User+Groups
Segue a lista, com os dados de 5 de setembro de 2009:
| Nome | Número de usuários registrados |
| Grails Community at OSUM | 28 |
| Belgium Groovy and Grails User Group | 8 |
| Grails Brasil | 562 |
| Montreal Groovy/Grails User Group | 9 |
| Toronto Groovy and Grails User Group | 11 |
| Vancouver Groovy and Grails User Group | não divulgado |
| The Egyptian Groovy and Grails User Group | não divulgado |
| French Grails User Group | não divulgado |
| Indian Groovy and Grails User Group | 99 |
| Mexico Groovy and Grails User Group | não divulgado |
| Dutch Groovy & Grails User Group | 49 |
| Philippine Groovy/Grails Users Group | 72 |
| Russian Developer Group | não divulgado |
| Grails Singapore | 4 |
| grails.sk | não divulgado |
| Groovy and Grails User Group Switzerland | 47 |
| SweGUG – Groovy, Grails & Griffon User Group | 32 |
| Thai Grails User Group | 116 |
| Ukranian Grails User Group | 20 |
| The London Groovy and Grails User Group | não divulgado |
| The North West Grails User Group | não divulgado |
| Chicago Groovy User Group | não divulgado |
| SF Bay Groovy and Grails Meetup Group | 155 |
| Groovy Users of Minnesota | 224 |
| The New York Groovy / Grails Meetup Group | 107 |
| Boston Grails Users’ Group | 44 |
Claro: não levei em consideração aqui as listas de e-mail, apenas os grupos de usuários presentes na listagem do site oficial do Grails.
Sendo assim, abro o questionamento: na opinião de vocês, quais as razões desta popularidade do Grails?
Upgrade gigante no Grails Brasil
Esta é uma grande semana para o Grails Brasil, pois diversas melhorias finalmente foram implementadas no site, dentre as quais, a mais importante consistiu no upgrade do motor utilizado pelo site. O phpBB foi atualizado para a versão 3.0.5 que, de fato, é muito superior à 2.0.
Dentre as novidades, as mais importantes consistem em:
- SPAM: yeap, não temos mais este problema no Grails Brasil agora. Se você acompanha o Grails Brasil há algum tempo, sabe a luta que foi este problema. Captchas eram implementados, porém não duravam mais do que algumas semanas. E por mais que lutassemos para apagar as mensagens indesejadas (aqui entra o meu MUITO OBRIGADO aos moderadores), estas acabavam entrando no feed do site, tornando-o inútil.
A solução para o problema foi, no entanto, mais simples do que o esperado: de agora em diante, qualquer um que deseje se registrar no Grails Brasil deverá passar por uma pré-aprovação dos moderadores. É a única maneira de se evitar que os bots invadam nosso sistema. - Novo layout: estou alterando o layout do Grails Brasil. Acredito que agora temos um site mais próximo do “espírito Grails” atual. No entanto, o trabalho ainda não está perfeito (conto com as opiniões de vocês: http://www.grailsbrasil.com/viewtopic.php?f=7&t=714). A propósito, o que acharam do novo logotipo?
- Grails Brasil no twitter: é possível agora acompanhar tudo o que acontece por trás do Grails Brasil via Twitter: http://www.twitter.com/grails_brasil
- Feed atualizado: nesta história, o nosso motor de feed (RSS) também foi atualizado. Para configurar o seu leitor de RSS, acesse o seguinte endereço: http://www.grailsbrasil.com/smartfeed_url.php
Tal como o anterior, o usuário configura quais fóruns deseja acompanhar, gerando assim a URL que será usada pelo seu browser/leitor de feeds.
Há algumas opções a mais nesta nova versão, como por exemplo a possibilidade de gerar html seguro, dentre outros pequenos detalhes.
Porém, o trabalho ainda está longe de finalizado. Sempre há melhorias que podemos implementar. Sendo assim, peço-lhes que me enviem suas opiniões a respeito do que podemos melhorar no site. TODA opinião é bem vinda.
Espero por todos vocês portanto no novo Grails Brasil: http://www.grailsbrasil.com.br


