Lucas Teixeira

@lucastex

Arquivo para February, 2010

[GSolr] Beans declarados automagicamente

com 3 comentários

GSolr, é o nome do plugin de solr que estamos fazendo de solr para grails. Para quem quiser acompanhar o trabalho, o repositório está no github: http://github.com/lucastex/gsolr.

Uma coisa que já está feita é a leitura da configuração do gsolr e a declaração mágica de beans, um para cada servidor solr que estiver configurado. Exemplificando, vamos imaginar que a configuração esteja declarando três servidores Solr que serão consultados:

gsolr {
   solr {
      produtos {
         (...)
      }
      noticias {
         (...)
      }
      usuarios {
         (...)
      }
   }
}

Particularmente, achei bem interessante usar o nome da closure para o nome do servidor ao invés de termos um atributo name = produtos :)
A mágica legal mesmo, é que o plugin vai ler esta configuração quando a aplicação for para o ar, e depois disso irá declarar / criar beans spring dinâmicamente, usando a Spring DSL. E os beans vão ter no nome a declaração feita na closure do usuário.

Ou seja, para os servidores solr declarados acima, o plugin irá declarar os Spring Beans produtosGSolr, noticiasGSolr e usuariosGSolr .

Desta maneira, vamos garantir que se você quiser o usar o plugin, o processo como um todo ficará o menos intrusivo possível, e você poderá usar os métodos (de pesquisa e outros) do GSolr apenas injetando o bean do servidor Solr que você quiser.

class PesquisaService {
   def noticiasGSolr

   def pesquisar = {
      (...)
   }
}

Achei no mínimo, muito prático. Tudo isso graças a Spring DSL que temos em groovy. Com um pouco mais de tempo, coloco o procedimento passo a passo para declarar os beans desta maneira. Enquanto isso, conheça um pouco mais sobre a Spring DSL aqui, ou veja o código fonte aqui e também aqui.

Tem alguma idéia ou sugestão para o plugin? Deixe um comentário!

Written by Lucas Teixeira

February 28th, 2010 at 11:18 pm

Postado em GSolr, Grails, Solr

Com as tags , , , ,

Resolvendo dependências de sua aplicação Grails usando Ivy

com 6 comentários

Estamos fazendo o desenho do plugin do Solr para o Grails, e precisei das libs do solr/lucene. Dessa vez quis fazer diferente e usar o gerenciamento de dependências que o grails traz usando o ivy. Pra mim, que nunca tinha trabalhado com ivy antes, foi bem simples até.

Bastou eu levantar os grupos/artifactsId e versão do solr-core e do solrj (1.4) e adicionar no meu BuildConfig.groovy. Consegui estas informações no próprio wiki do solr, nesta página: http://wiki.apache.org/solr/Solrj#Maven

Depois disso, bastou adicionar um repositório para buscar os jars

repositories {
    mavenRepo "http://mirrors.ibiblio.org/pub/mirrors/maven2"
}

E declarar as dependências que eu precisaria em runtime:

dependencies {
    runtime 'org.apache.solr:solr-core:1.4.0'
    runtime 'org.apache.solr:solr-solrj:1.4.0'
}
Depois, foi só rodar a aplicação que os jars já estavam todos carregados e prontos para serem importados, ponto para o Grails.

Written by Lucas Teixeira

February 28th, 2010 at 1:45 am

Postado em Grails, ivy

Com as tags , , , , ,

Grails e Solr juntos, o melhor dos mundos

com 6 comentários

Tá rolando uma discussão legal na lista “grails-users” sobre Solr.

Estamos levantando alguns pontos que seriam essenciais e interessantes para um plugin grails que cuidasse disso. Se você gosta também de Solr, ou está interessado, acompanhe os e-mails na Grails-Users ou no nabble aqui.

Você usa solr? O que acha interessante nele que deva existir em um plugin grails?

Written by Lucas Teixeira

February 26th, 2010 at 3:11 pm

Postado em Grails, Solr

Com as tags , , ,

Criando um DataSource JNDI no JBoss

com 4 comentários

Ok, agora que temos uma aplicação grails rodando no ambiente jboss, temos que configurar um DataSource JNDI para ser usado, com isso evitamos que as credenciais e informações do banco fiquem diretamente configuradas em nossa aplicação.

Este procedimento é simples e facilmente descrito em dois simples passos:

  1. Driver do banco de dados: Você deve copiar o jar do driver JDBC do seu banco de dados para dentro da pasta <jboss_home>/common/lib
  2. Configuração do DataSource: No jboss ela é feita através de um arquivo XML. Após criar este arquivo, tenha certeza que o salvou dentro da pasta <jboss_home>/server/<seu_server>/deploy.

No meu caso, o arquivo se chama database-ds.xml e possui as seguintes tags (são altamente descritivas, acredito não precisar detalhar):

<?xml version="1.0" encoding="UTF-8" ?>
<datasources>
  <local-tx-datasource>
    <jndi-name>jdbc/databaseDS</jndi-name>
    <connection-url>jdbc:mysql://localhost:3306/banco_dev</connection-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <user-name>root</user-name>
    <password>senha</password>
    <min-pool-size>5</min-pool-size>
    <max-pool-size>30</max-pool-size>
    <idle-timeout-minutes>1</idle-timeout-minutes>
    <prepared-statement-cache-size>32</prepared-statement-cache-size>
  </local-tx-datasource>
</datasources>

Agora para acessá-lo basta buscar pelo nome JNDI java:jdbc/databaseDS, ou no meu caso, como é uma aplicação grails, usar a declarativa no DataSources.groovy

production {
  dataSource {
    jndiName = "java:jdbc/databaseDS"
    dbCreate = "update"
  }
}

Written by Lucas Teixeira

February 15th, 2010 at 12:08 am

Postado em jboss

Com as tags , , ,

Como fazer o deploy de uma app grails no JBoss

com 5 comentários

Neste fim de semana quis fazer alguns testes pela primeira vez com uma aplicação grails no jboss.

Já tinha acompanhado na grails-users que existem alguns problemas para efetuar o deploy, e para cada um deles, uma sequência de passos obscuros para fazer o deploy acontecer com sucesso. Minha versão de grails neste procedimento é a 1.2.1 e do JBoss é a 5.1.0.GA

Efetivamente, o que acontece é que jboss traz junto com suas common libs vários jars que são empacotados juntamente com a sua aplicação quando você utiliza o comando grails war.

Existem alguns workarounds na internet que te mostram como modificar o BuildConfig.groovy (arquivo que define propriedades do empacotamento de sua app) para que após montar a estrutura de arquivos que irão ser empacotados, remova estes arquivos (principalmente o log4j onde o problema é mais aparente) do chamado stagingDir e os deixe de fora do pacote final.

Particularmente, achei a solução um tanto quanto diferente e acabei achando no FAQ do Grails e depois com mais detalhes nesta página uma solução menos intrusiva ao pacote, que é definir a prioridade de carregamento dos jars da aplicação.

Bom, para isso, precisamos criar um arquivo jboss-web.xml dentro do diretório WEB-INF de nossa aplicação que irá mostrar ao jboss que queremos “blindar” nossa aplicação para utilizar os jars que estão dentro de seu lib, e que estes por sua vez não deverão ser sobrescritos pelos jars do classpath do servidor. O conteúdo do arquivo segue abaixo:

<jboss-web>
   <context-root>/projeto</context-root>
   <class-loading java2ClassLoadingCompliance="false">
      <loader-repository>
         projeto:archive=projeto.war
         <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
      </loader-repository>
   </class-loading>
</jboss-web>

Na tag context-root estamos apenas aproveitando que a aplicação terá seu arquivo de configuração específico para o jboss e definindo o contexto em que ela será publicada. Nas tags seguintes pedimos para o jboss criar o nosso classloader isolado, com o nome “projeto:archive=projeto.war”. Com este nome (que deve ser único, por isto leva em consideração o nome do projeto), garantimos que as classes pedidas pelo nosso projeto serão procuradas ali, e caso não encontradas, nos classpaths seguintes (common/lib, depois no tomcat).

Basicamente isto seria suficiente para conseguir que o projeto rodasse sem problemas. Porém no meu cenário de versões (grails 1.2.1 e jboss-5.1.0.GA) existe outro ponto de conflito. O Hibernate Validator que está junto ao jboss também difere em versão e gera conflito com o grails. Neste caso a solução é ainda mais interessante e simples que a anterior.

Para resolver o problema no deploy que indica claramente problema de versão no Hibernate Validator, basta que você faça o download da última versão deste jar (no meu caso, 4.0.2-GA) nesta url: https://www.hibernate.org/30.html. Depois disto, resta apenas colocar o jar do hibernate validator dentro da pasta <jboss_home>/common/lib.

Pronto, a aplicação está rodando e funcional dentro do jboss!

10:36:32,815 INFO  [[/projeto]] Initializing Spring root WebApplicationContext
10:36:41,155 INFO  [[/projeto]] Initializing Spring FrameworkServlet 'grails'

PS: Vale lembrar que o arquivo jboss-web.xml é padrão para arquivos war, se você quiser configurar a ordem do classpath para aplicações ear ou sar, consulte o link acima para entender as diferenças.

Written by Lucas Teixeira

February 14th, 2010 at 10:51 am

Postado em Grails

Com as tags , , , , , ,

Como acessar uma taglib de dentro de um service

com 4 comentários

Uma situação que acontece muito, é a reutilização das funções de taglibs dentro dos controllers de sua aplicação grails. Isso é muito fácil de se fazer, basta chamar o método usando o objeto com o nome do namespace da taglib.
Ou seja, para usar dentro do controller a função de formatação de números, definida pela função formatNumber (taglib já no core do grails), é só fazer a chamada assim:

def myAction = {
render g.formatNumber([number:5000.234, type: "number", maxFractionDigits: 2])
}

Esta função é equivalente a chamar a taglib de dentro de um gsp da seguinte maneira:

<g:formatNumber number="5000.234" type="number" maxFractionDigits="2" />

Mas quando precisamos fazer isto, por exemplo, dentro de um service, encontramos um probleminha chato, as taglibs não são injetadas automaticamente. Para contornar essa “situação“, temos que buscar a taglib manualmente, da seguinte maneira:

def myTag = grailsApplication.mainContext.
            getBean('org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib')
def value = myTag.formatNumber([number:5000.234, type: "number", maxFractionDigits: 2])

Ahhh, para isso não se esqueca de injetar o objeto da grailsApplication da seguinte maneira

class MeuService {
   def grailsApplication
   (...)
}

Bin-go.

Written by Lucas Teixeira

February 3rd, 2010 at 10:35 pm

Postado em Grails

Com as tags , , , , ,

Get Adobe Flash playerPlugin by wpburn.com wordpress themes