BlogBlogs.Com.Br

segunda-feira, 15 de março de 2010

IReport 3.7.X - A Saga

Num sei vcs, mas tivemos diversos problemas com as versões do ireport pós 3.0, EJBQL Connection não funcionava, e ninguem sabia como resolver, cheguei a cirar 2 threads no Forum do JasperForge e ambas sem resposta, no final, ficamos com o IReport 3.0, a versão funcionava bem, apesar da interface ser meio bugada (algumas janelas eram fechadas e sumiam misteriosamente).

Sempre gostamos de ter nossas bibliotecas atualizadas, saiu um novo release lá estamos nós atualizando, e resolvemos testar as novas versões do IReport, porém nenhuma delas funcionava com EJB Connection, e existia um maldito EJBCascadingStyle, que a única coisa que pesquisando encontrei, foi referencia errada da versão do Hibernate. E eu atualizando os jar no diretorio ext no IReport e o erro persistia, então navegando encontrei uma solução, aparentemente, era copiar os jars principais do meu projeto no diretorio IREPORT_HOME/plataform9/lib

Realmente conectou usando EJB Connection, porém uma lesma ganharia na velocidade, o IReport ficou intrabalhavel, não conseguia editar um jasper qualquer quem diria criar um novo. Abandonamos e voltamos para a versão 3.0.

Buscando agora encontrei um topico realmente interessante, e esse sim fez o IReport funcionar.
Resumindo oq vc precisa é ir ao diretorio IREPORT_HOME/ireport/modules/ext

e REMOVER as libs ehcache, hibernate3, hibernate-annotations, hibernate-commons-annotations e jpa

e adicionar esses jar do seu projeto :D, assim funciona, agora encontrei um NullPointer na hora de editar a query, quem sabe até amanha eu consiga usar essa nova versão :P

terça-feira, 9 de fevereiro de 2010

O conto do merge, persist e do No Transaction

Era uma vez...

Ehehhe, brincadeiras a parte, esses tempos tive um pequeno problema com uma certa demora usando JPA em um modulo EJB.

Tive de fazer a rotina de leitura de um arquivo texto e importar os registros para o sistema. até ai sem problemas, fiz a rotina e ela rodava em menos de 5s e importava todos os registros. Porém os registros que vinham no arquivo não atendiam a modelagem do sistema, ou seja, teria que inserir nas outras tabelas caso não existisse.

feita as Querys para encontrar o registro, e caso não existisse criar um novo, do nada ele demorou aproximadamento 6hrs e ao final la pela 1h30min da manhã uma execessão de No Transaction Active foi lançada em um flush no Entity Manager.

Lá fui eu aplicar algums caches de memoria para diminuir as consultas ao banco e os salvamentos. resolvemos mudar alguns merges para persist pois seguindo o que o pessoal fala, o persist é somente para objetos novos e é muito mais rapido.

Pois é não foi. Os objetos usando persist se tornaram pesados, e o procedimento ficou pesado, interrompido em 30min de execução tendo percorrido somente 200 registros (o arquivo possuia 30k). Removi o persist e deixei tudo como merge, mais uma vez uma No Transaction lá pelo registro 3mil é lançada. mais por que existe transação até o 2999. Eis que me dizem, põe um clear no começo do loop.

Galera, nunca vi o treco ir tão rápido ehhehe. Todo o gargalo de processamento se foi e o procedimento rodou em 5min.

Pra quem já teve esse problema não esqueça, o clear é muito importante :)

Aproveitando que estou falando sobre JPA e EJB...
Estavamos também com um problema ao salvar (merge) alguns objetos, a performance muito baixa, levava quase 2min para salvar o objeto, isso pos a chamada do em.merge.

Fiz varios testes, inclusive usando o clear, porém não deu em nada, resolvi arriscar, o problema estava nos objetos que eram atualizados e vinham do cliente, ou seja, estavam foram do contexto do EJB e do entity manager. Não sei se isso é gambiarra ou não, mas a performance melhorou drasticamente caindo para 2s.


  • primeiro passo eu recupero o objeto usando o em.find.

  • depois atribuo a esse objeto recuperado o objeto passado como parametro

  • dai só fazer o merge



Simples e pratico não :)

Espero que isso seja de ajuda para mais alguém. Até a próxima

terça-feira, 26 de janeiro de 2010

Especialista – Sim ou Não?

Um especialista é alguém com anos de pratica no seu serviço. Antigamente era algo muito comum, vide o filme Tempos Modernos de Charles Chaplin, ele era um especialista, em apertar parafusos, no final das contas, um especialista nada mais é do que alguém que passou a vida inteira fazendo a mesma coisa e no final não sabe fazer nada alem do que ele é especializado.

É comum eu ouvir muitas criticas, do tipo, você conhece um pouco de varias linguagens mais não conhece nenhuma muito bem. Na verdade o que eu não quero é ser dependente de uma única linguagem, digamos que sou especialista em Java (o que não é verdade), se um dia o Java morresse? Se um dia não existisse mais? O que eu faria?

Provavelmente não iria trocar de área, porém ia ter que me sujeitar a um cargo inferior ao meu para trabalhar com uma linguagem mais nova que eu ainda teria que aprender. Quando se tem uma base, é muito mais simples de evoluir na nova linguagem, você tem um conhecimento básico, e na área de T.I. onde existem mudanças frequentemente, você tem que estar apto a elas, e preparado. A especialização pelo menos na nossa área é passado, você não pode se ater a uma tecnologia, pois ele pode morrer amanha.

Por esses motivos prefiro sempre estar aprendendo, sempre atrás de coisas novas que me tornem um profissional melhor e mais apto.

Desculpem a demora por um novo post =).

terça-feira, 24 de novembro de 2009

Uma IDE na Nuvem

A algum tempo atrás eu estava imaginando como seria uma IDE (ou editor de texto se preferir) usando cloud computing, fiquei imaginando como isso funcionaria e como seria agregado as empresas. A algum tempo atraz ouvi falar no Heroku Garden, uma IDE para desenvolvimento na nuvem para RoR, porém aparentemente o projeto foi abandonado. Esses dias olhando no forum do RubyOnBr, um cara comenta de um tal de Bespin, e eu resolvi procurar, eis que me surge o Mozilla Bespin, me registei e começei a brincar, achei o projeto promissor, vc pode criar projetos onde ele lista, vc tem uma linha de comando para utilizar, porém só funciona HTML, tentei usar PHP, Ruby, Java, e infelizmente a IDE ainda está engatinhando, o suporte é bem limitado, mas a interface gráfica é atraente.

Busquei os fontes do projeto e encontrei dois repositorios Mercurial, um para o server-side e um para o client-side, basicamente o backend do projeto roda em python e Java, e o front-end é uma mistura de JavaScript e JSON usando Prototype (pelo menos é parecido), para gerenciar as informações e enviar para o servidor.

baixei ambos os fontes, e estou ainda analisando, o servidor roda usando o virtualenv do python, ou seja emula uma maquina para que possa ser usado o servidor, infelizmente o README é precario quando a instalação, eu que sou leigo no virtualenv, apanhei um pouco até descobrir o easy_install para instalar as dependencias do projeto, ainda estou tentando por a IDE rodar na minha máquina. E acredito que valha a pena dar uma olhadinha no Bespin, mesmo que não haja muito o que fazer.

Parece que temos um projeto interessante saindo do forno.

terça-feira, 17 de novembro de 2009

Objetopolis

Bem Vindo a Objetopolis.

Assim começa o segundo capitulo do livro Java! Use a Cabeça (Se não for também não interessa :P), copiei esse termo do livro, simplemente para ressaltar o que quero dizer.

Existem alguns que dizem que controlar o fluxo da informaçã com IFs é uma quebra ao paradigma orientado a objeto, porém nem todos os casos existe a necessidade de criar uma Interface e/ou ENUM para contornar IFs, salvo em alguns casos. Muitas vezes o excesso de abstrações para forçar/evitar o uso de algumas estruturas de controle ditas não-oo podem tornar o código menos legivel. Eu acredito que a beleza do codigo é grande parte da beleza de um sistema, concerteza um sistema bem escrito será um sistema que conterá a integração continua, e nenhum desenvolvedor que chegar até o sistema vai abandona-lo.

O que eu defendo quando se escreve um software é, pense em como vc vai ler isso aqui daqui a alguns meses, normalmente 1 mês basta para termos vontade de excluir todos os nossos codigos e reafaze-los aplicando novas tecnicas e funções, isso não é regra, mas como qualquer desenvolvedor que se preze está sempre em constante evolução seu novo conhecimento pode melhorar ou ajudar a escrever o codigo de forma mais elegante.

Apesar de tudo que eu disse sobre os IFs, eu não gosto de usa-los, acredito que deixa o código "tosco", existem situações em que ele é necessário. Muitos ifs podem ser evitados como por exemplo:


if( c == 0){
return true;
}else{
return false;
}


esse código é facimelmente convertido em uma linha:

return c == 0;


Em alguns casos o operador ternário tbm pode ser muito bem empregado, aumentado a legibilidade do código, lembre-se um sistema não é mais definido por linhas de código :D

Algo que eu gosto muito de fazer e usar um pouco de reflection, atrelado a um HasMap, com simples linhas de código temos um código mais legivel, como por exemplo, no item abaixo, abre-se uma determinada tela de um sistema utilizando esse recuro.


class Controller implements ActionListener{
private Map> botoes = new HashMap>();

public void actionPerformed(ActionEvent e){
Class tela = botoes.get((JButton) e.getSource());
if(tela != null){
criaTela(tela);//Cria a tela para ser mostrada
}else{
raiseErro("Tela não encontrada!"); //monstra erro na tela
}
}
public void registraBotao(JButton botao, Class tela){
botoes.put(botao, tela);
}
}


voila, temos um código limpo e facil de ser explicado, não existe problema em ler esse codigo, ele é completamente intuitivo, um único if, e um pouco de dinamismo, e lhes apresento um Controller desvinculado a uma tela. e se adiconar um botão não existe necessidade de criar um novo actionListener para abrir uma tela.

PS: esses exemplos foram criados a mão, aqui no blog, as chances disso não compilar são grandes, é meramente ilustrativo

Por isso que ressalto, muitas vezes para usarmos objetos, sempre que existe uma necessidade, cada objeto deve ter suas funções bem definidas, como li um dia o Sergio Taborda disse, se um objeto é somente para ser um apunhado de atributos com getters e setters que seja, desde que ele tenha sua funcionalidade bem definida.

Viajei nesse post, começei criticando algo que eu faço pra defenter o uso de objetos sempre hehhe.

Só mais um detalhe
Esqueçam os tipos primitivos, utilizem os wrappers A perca de performance é minima, e vc trabalha em um nivel superior aos tipos primitivos.

isso aí povo até mais.

segunda-feira, 19 de outubro de 2009

Um poco de RSpec

Estou focando um pouco dos meus estudos em RSpec e BDD, e é incrivel como existe pouco material em portugues sobre o RSpec, então, esse é um post rapido explicando como se validar algumas propriedades dos seus modelos no Rails usando RSpec.

PS: Estou utilizando I18n do Rails para a versão que eu traduzi do rails. seus erros podem estar na versão não traduzida, então o ideal é cuidar, pois seus testes podem não passar.

Validação um campo que deve ser informado.


#Imagine que User é uma classe de usuário qualquer
describe User do
it "should be have an login" do
@user = User.new
@user.save
@user.errors.on(:login).should be_eql("não pode ser em branco")#substitua essa string por seu texto customizado ou pela mensagem padrão em inglês
end
end


Esse codigo simula a gravação de uma entidade, e verifica se existe o erro. lembrando que você deve adicionar na classe user:

class User < ActiveRecord::Base
validates_presence_of :login
end


validando um número

#classe user.rb
validates_numericality_of :age, :only_integer => true
#user_spec.rb
it "should be have a valid number for age" do
@user.age = "a"
@user.save
@user.errors.on(:age).should be_eql("não é um número")
end


Validanto tamanho de um campo

it "should be invalid when the name is greater than 100" do
@user.name = "a"*101
@user.save
@user.errors.on(:name).should be_eql("é muito grande (máximo é 100 caracteres)")
end
#user.rb
validates_length_of :name, :maximum => 100


3 validações básicas para quem ta começando a mexer com o RSpec, não é lá grandes coisas, mas pode ajudar iniciantes em RoR a praticar o BDD.

[]'s

terça-feira, 29 de setembro de 2009

Rails - Editando o CSS do seu formário uma unica vez

Acredito que todo o desenvolvedor tenha alguns problemas com CSS, ou de esquecer um maldito campo, e ele ficar sem o layout, muitas vezes, todos os campos são renderizados de maneira diferente, de acordo com a definição do designer, ou da equipe.
Normalmente o saco, é por exemplo em rails criar um form da seguinte maneira

- form_for(@foo) do |f|
%p= f.error_messages
%table
%tr
%td= f.label 'Nome:'
%td= f.text_field :name, :class => :atext_field
%tr
%td= f.label 'Descrição:'
%td= f.text_area :description, :class => :atext_area
%tr
%td= f.submit 'Salvar'

PS: Esse código foi escrito em HAML. é bem simples modifica-lo para ERB.
O que vemos é que existem dois campos com a tag :class, que indica a classe do componente para o Rails renderizar na tela. Eis que nessa tela imagine mais uns 10 text_field, e outras páginas de cadastro com quantidades semelhantes de campos. Ai o desgraçado do design resolve mudar o layout (não me levem a mal designer, muitas vezes vocês nos dão raiva mesmo, :D), e para mander compatibilidade ele cria outras tags, e la veio no minimo meio dia de serviço para ajustar esses campos ai para o nova classe (por ex: btext_field).

Mas vamos relembrar um conceito simples do Ruby as classes abertas. Nessa situação é um modulo (module), que gerencia os forms, o querido ActionView::Helpers::FormTagHelper.
Ele é o responsavel por renderizar esses objetos. agora basta simplesmente você alterar esse modulo, veja como fazer (editei no meu environment.rb, como ele não é recarregado tem que para o servidor e iniciar novamente, vocês podem fazer esse código em qualquer lugar)

module ActionView
module Helpers
module FormTagHelper
def text_field(object_name, method, options={})
super object_name, method, options.merge(:class => :btext_field)
end
def text_area(object_name, method, options={})
super object_name, method, options.merge(:class => :btext_area)
end
def check_box(object_name, method, options={}, checked_value="1", unchecked_value = "0")
super object_name, method, options.merge(:class => :bcheck_box), checked_value, unchecked_value
end
end
end
end

Caso não conheça o metodo merge dos hash do ruby, seria interessante conhece-lo, dessa maneira, não existe mais a necessidade de definir o atributo :class em cada text_field, essa alteração coloca automáticamente essa informação disponivel. Existem coisa que o ruby faz que surpreendem :D.