Repositório Git no Apache2

Programação No Comments

Algum tempo atrás eu coloquei um repositório Git disponibilizado através do Apache2 + WebDAV utilizando a seguinte configuração do apache:

<Location /repositorio.git>
	Dav on
	AuthType Basic
	AuthName "Repositorio Git"
	AuthUserFile /etc/apache2/repositorio.passwd
	Require valid-user
</Location>

Após algum tempo comecei a receber erros ao tentar fazer o push de muitas alterações. Se eu tentasse realizar vários push’s com erro, uma hora o push funcionava.

Fui procurar outras formas de disponibilizar o repositório Git no Apache2 e encontrei a forma descrita abaixo:

SetEnv GIT_PROJECT_ROOT /var/www/git
SetEnv GIT_HTTP_EXPORT_ALL
AliasMatch ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /var/www/git/$1
AliasMatch ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /var/www/git/$1
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

Esta configuração até agora não deu problema.

Mais detalhes dessa configuração podem ser encontrados no help do comando git-http-backend:

http://manpages.ubuntu.com/manpages/lucid/man1/git-http-backend.1.html

O Guia de Dez Minutos de diff e patch

Programação No Comments

O seguinte texto foi traduzido e adaptado de:

http://jungels.net/articles/diff-patch-ten-minutes.html

Primeira situação: você está tentando compilar um pacote à partir do código fonte e descobre que alguém já o modificou para compilar na sua plataforma. Ele disponibilizou o seu trabalho como um “patch”, mas você não tem certeza de como utilizá-lo. Para utilizá-lo você deve aplicar o patch no código fonte original com uma ferramenta de linha de comando chamada patch.

Segunda situação: você fez o download do código fonte de um pacote open source e depois de algumas alterações você conseguiu compilá-lo na sua plataforma. Você gostaria de disponibilizar o seu trabalho para outros programadores, ou para os autores do pacote, sem distribuir todo o pacote modificado. Nesta situação você deve criar um patch, e a ferramenta necessária é a diff.

Este é um guia rápido para gerar ou utilizar patches que irá ajudá-lo nestas situações, mostrando como usar as ferramentas nas situações mais comuns.

Aplicando patches com patch

Para aplicar um patch em um arquivo, vá ao diretório onde o arquivo está e chame o comando patch:

patch < foo.patch

O comando acima assume que o patch está distribuído no formato unificado, que identifica o arquivo no qual patch deve ser aplicado. Se não estiver no formato unificado, você pode especificar o arquivo na linha de comando:

patch foo.txt < bar.patch

A aplicação de patches em um diretório (caso mais comum) é similar, mas você deve setar um "p level". Isto significa que dentro dos arquivos de patches, os arquivos são identificados por caminhos que possam ser diferentes de quando o patch foi criado. O "p level" faz com que o patch ignore partes do caminho do arquivo para que seja possível identificar os arquivos corretamente. Geralmente um "p level" de 1 irá funcionar, então utilize:

patch -p1 < baz.patch

Você deve mudar para o diretório raiz do código fonte antes de executar este comando. Se o "p level" utilizado não identificar corretamente os arquivos, procure nomes de arquivos no patch. Se você ver um nome como:

/users/stephen/package/src/net/http.c

E você estiver trabalhando em um diretório que contenha net/http.c, use:

patch -p5 < baz.patch

Em geral, conte quantos separadores de diretório (/) você precisa remover à partir do começo do caminho, até que o restante seja um caminho que exista no diretório atual. O valor encontrado será o "p level" que deve ser utilizado.

Para remover um patch, use a flag -R:

patch -p5 -R < baz.patch

Criando patches com diff

Utilizar a ferramenta diff é simples quer você esteja trabalhando com um arquivo ou com diretórios. Para criar um patch à partir de um arquivo, use:

diff -u original.c new.c > original.patch

Para criar um patch de um diretório inteiro, faça uma cópia do diretório:

cp -R original new

Faça as alterações necessárias no diretório new/. E então cria o patch com o comando:

diff -rupN original/ new/ > original.patch

Isto é tudo o que você precisa saber para começar a utilizar as ferramentas diff e patch. Para mais informações utilize:

man diff

man patch

Weblogic 10.3.0.0 + JSF 2.0 + @EJB Injection

Java EE, Programação 5 Comments

Ao se colocar o JSF 2.0 no Weblogic 10.3.0.0, os EJB’s não são injetados nos manageds beans do JSF através da anotação @EJB.

Para corrigir esse problema, basta utilizar a classe abaixo:

import java.lang.reflect.Field;
import java.util.*;

import javax.ejb.EJB;
import javax.el.*;
import javax.naming.NamingException;

import com.sun.faces.el.ManagedBeanELResolver;

public class VariableResolver extends CompositeELResolver {

    private final Map, List> ejbFields;

    public VariableResolver() {
        this.ejbFields = new HashMap, List>();
        add(new ManagedBeanELResolver());
    }

    private void preencherEjbFields(List fields, Class clazz, Set> visitados) {
        if (clazz != null && !visitados.contains(clazz)) {
            visitados.add(clazz);

            for (Field field : clazz.getDeclaredFields()) {
                EJB ejb = field.getAnnotation(EJB.class);
                if (ejb != null) {
                    field.setAccessible(true);
                    fields.add(new EJBField(field, ejb.mappedName(), field.getType()));
                }
            }

            preencherEjbFields(fields, clazz.getSuperclass(), visitados);

            for (Class i : clazz.getInterfaces()) {
                preencherEjbFields(fields, i, visitados);
            }
        }
    }

    private List getEjbFields(Object obj) {
        List fields = ejbFields.get(obj.getClass());

        if (fields == null) {
            fields = new ArrayList();
            Set> visitados = new HashSet>();
            preencherEjbFields(fields, obj.getClass(), visitados);

            synchronized (ejbFields) {
                ejbFields.put(obj.getClass(), fields);
            }
        }

        return fields;
    }

    private void processarEjbs(Object obj) throws IllegalAccessException, ClassCastException, NamingException, IllegalArgumentException {
        for (EJBField field : getEjbFields(obj)) {
            if (field.getField().get(obj) == null) {
                Object ejb = ServiceLocator.lookup(field.getType(), field.getMappedName());
                field.getField().set(obj, ejb);
            }
        }
    }

    @Override
    public Object getValue(ELContext arg0, Object arg1, Object arg2) {
        try {
            Object obj = super.getValue(arg0, arg1, arg2);
            if (obj != null) {
                processarEjbs(obj);
            }

            return obj;
        } catch (IllegalArgumentException ex) {
            throw new ELException(ex.getMessage(), ex);
        } catch (IllegalAccessException ex) {
            throw new ELException(ex.getMessage(), ex);
        } catch (NamingException ex) {
            throw new ELException(ex.getMessage(), ex);
        }
    }

    private class EJBField {

        private Field field;

        private String mappedName;

        private Class type;

        public EJBField(Field field, String mappedName, Class type) {
            this.field = field;
            this.mappedName = mappedName;
            this.type = type;
        }

        public Field getField() {
            return field;
        }

        public String getMappedName() {
            return mappedName;
        }

        public Class getType() {
            return type;
        }

    }

}

E declarar o el-resolver no faces-config.xml:

<faces-config>
 <application>
  <el-resolver>VariableResolver</el-resolver>
 </application>
</faces-config>

Weblogic + JPA + Hibernate = ClassNotFoundException: org.hibernate.hql.ast.HqlToken

Java, Java EE, Programação No Comments

Ao tentar efetuar o deploy de uma aplicação com JPA (implementação: Hibernate), ocorre o seguinte erro:

org.springframework.orm.hibernate3.HibernateQueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken [SELECT p FROM PARAMETRO p WHERE UPPER(RTRIM(p.parametroPK.parametroGeral)) = :parametroGeral AND UPPER(RTRIM(p.parametroPK.codigo)) = :codigo]; nested exception is org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken [SELECT p FROM PARAMETRO p WHERE UPPER(RTRIM(p.parametroPK.parametroGeral)) = :parametroGeral AND UPPER(RTRIM(p.parametroPK.codigo)) = :codigo]
Caused by: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken [SELECT p FROM PARAMETRO p WHERE UPPER(RTRIM(p.parametroPK.parametroGeral)) = :parametroGeral AND UPPER(RTRIM(p.parametroPK.codigo)) = :codigo]
at org.hibernate.hql.ast.HqlLexer.panic(HqlLexer.java:57)
at antlr.CharScanner.setTokenObjectClass(CharScanner.java:340)
at org.hibernate.hql.ast.HqlLexer.setTokenObjectClass(HqlLexer.java:31)
at antlr.CharScanner.<init>(CharScanner.java:51)
at antlr.CharScanner.<init>(CharScanner.java:60)
at org.hibernate.hql.antlr.HqlBaseLexer.<init>(HqlBaseLexer.java:56)
at org.hibernate.hql.antlr.HqlBaseLexer.<init>(HqlBaseLexer.java:53)
at org.hibernate.hql.antlr.HqlBaseLexer.<init>(HqlBaseLexer.java:50)
at org.hibernate.hql.ast.HqlLexer.<init>(HqlLexer.java:26)
at org.hibernate.hql.ast.HqlParser.getInstance(HqlParser.java:44)
at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:242)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
at org.springframework.orm.hibernate3.HibernateTemplate$29.doInHibernate(HibernateTemplate.java:837)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:367)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:835)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:827)
at db.ProductManagerDaoHB.getProductList(ProductManagerDaoHB.java:14)
at bus.ProductManager.getProducts(ProductManager.java:25)
at web.controllers.SpringappController.handleRequest(SpringappController.java:33)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:819)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:754)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:399)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:354)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:971)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:402)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:305)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:6350)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:317)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:118)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3635)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2585)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)

Para resolver este problema basta alterar o persistence.xml e adicionar a seguinte linha:

<property name="hibernate.query.factory_class" value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory"/>

Fonte: http://forum.springsource.org/showthread.php?t=36860

Passando propriedades de sistemas para os testes no maven

Java, Programação No Comments

Esses dias precisei fazer alguns testes que verificavam se existia uma propriedade de sistema para tomar determinada ação.

Ao se passar a propriedade através da seguinte linha de comando:

mvn -Dminha.propriedade=valor test

Verifiquei que o teste nunca encontrava a propriedade passada através da chamada System.getProperty("minha.propriedade").

Dois jeitos fáceis para fazer a passagem de propriedade corretamente para os testes são:

mvn -Dminha.propriedade=valor test -DforkMode=never

ou

mvn test -DargLine="-Dminha.propriedade=valor"

Particularmente eu prefiro o segundo jeito.

Fonte: http://stackoverflow.com/questions/824019/maven-2-1-0-not-passing-on-system-properties-to-java-virtual-machine

Describe no Oracle de uma tabela com dblink

Oracle, Programação No Comments

Primeiramente vamos encontrar o nome do dblink onde a tabela está realmente localizada. Isto é feito através do comando:

SELECT    DB_LINK
FROM    ALL_SYNONYMS
WHERE    SYNONYM_NAME = 'MINHA_TABELA'

Após isto basta obter as informações da tabela com os seguintes selects:

SELECT    *
FROM    ALL_TABLES@MEU_DB_LINK
WHERE    TABLE_NAME = 'MINHA_TABELA'

SELECT    *
FROM    USER_TAB_COLUMNS@MEU_DB_LINK
WHERE    TABLE_NAME = 'MINHA_TABELA'

Fonte: http://forums.oracle.com/forums/thread.jspa?messageID=4411870&tstart=0

Selenium + Wait for Ajax

Java, Programação, Selenium No Comments

Hoje tive que fazer um teste automatizado que deveria obrigatoriamente esperar por um Ajax ser executado para continuar a sua execução.

Encontrei este link: http://agilesoftwaretesting.com/?p=111, que fala o seguinte:

Faça um método em java como:

public static void waitForAjax(Selenium selenium, String timeout) {
    String js_condition =
      "selenium.browserbot.getCurrentWindow().jQuery.active == 0";
    selenium.waitForCondition(js_condition, timeout);
}

O valor da variável js_condition dependerá do framework JS que está sendo utilizado no site. Basicamente ele segue o seguinte formato:

"selenium.browserbot.getCurrentWindow()." + library specific string + " == 0"

Onde a parte específica pode ser:

jQuery: "jQuery.active"
Prototype: "Ajax.activeRequestCount"
Dojo: "dojo.io.XMLHTTPTransport.inFlight.length"

The Duct Tape Programmer

Programação No Comments

Hoje voltei a ler os artigos que estavam armazenados nas abas do meu firefox! Este eu não lembro quem me enviou, acho que foi pelo twitter.

Alguns trechos interessantes:

And the duct-tape programmer is not afraid to say, “multiple inheritance sucks. Stop it. Just stop.”

Here’s what Zawinski says about Netscape: “It was decisions like not using C++ and not using threads that made us ship the product on time.”

Peter asked Zawinski, “Overengineering seems to be a pet peeve of yours.”
“Yeah,” he says, “At the end of the day, ship the fucking thing! It’s great to rewrite your code and make it cleaner and by the third time it’ll actually be pretty. But that’s not the point—you’re not here to write code; you’re here to ship products.”

Zawinski didn’t do many unit tests. They “sound great in principle. Given a leisurely development pace, that’s certainly the way to go. But when you’re looking at, ‘We’ve got to go from zero to done in six weeks,’ well, I can’t do that unless I cut something out. And what I’m going to cut out is the stuff that’s not absolutely critical. And unit tests are not critical. If there’s no unit test the customer isn’t going to complain about that.”

http://www.joelonsoftware.com/items/2009/09/23.html

O mínimo que todo o desenvolvedor de software precisa saber sobre Unicode e CharSets

Programação No Comments

Hoje, após muito tempo resolvi ler um artigo recomendado por um colega do trabalho (Willian).

O artigo fala sobre o problema da representação de string nos computadores e como escrever uma aplicação de forma correta para que os usuários não vejam o texto com problemas (como por exemplo letras substituídas por uma ? ou um quadrado preenchido com uma interrogação no meio).

http://www.joelonsoftware.com/articles/Unicode.html

PHP + Zend + PDO + MySQL

MySQL, PHP, Uncategorized 2 Comments

Hoje eu estava fazendo um site utilizando php, Zend Framework, PDO e MySQL.

Quando fui fazer uma tela que se conectava com o banco de dados, ocorria o seguinte erro:

SQLSTATE[HY000] [2005] Unknown MySQL server host ''localhost'' (1)

Removi do arquivo de configuração a linha que informava o host onde estava o banco de dados e o erro passou a ser:

SQLSTATE[28000] [1045] Access denied for user 'user'@'localhost' (using password: YES)

Não, as permissões não estavam erradas. O problema todo era o arquivo de configuração do zend (application.ini), que estava assim:

resources.db.params.host = 'localhost'
resources.db.params.username = 'user'
resources.db.params.password = 'pass'
resources.db.params.dbname = 'db'

O problema todo era as aspas simples, deveriam ser aspas duplas:

resources.db.params.host = "localhost"
resources.db.params.username = "user"
resources.db.params.password = "pass"
resources.db.params.dbname = "db"

Acabei perdendo a manhã toda até achar este pequeno problema.

« Previous Entries