Obter parametros de um método em tempo de execução

10 respostas
cristian_clever

Bom dia pessoal!

Estou estudando um forma de, ao ocorrer uma exceção qualquer dentro da aplicação … eu possa obter os valores correntes (Dinamicamente… ou seja sem conhecer em qual método eu estou) dentro do método onde este erro teve início.

A idéia é facilitar a vida da equipe de desenvolvimento, que recebe a exceção por email (com o stack), a linha onde foi gerado o erro… mas não sabe quais parâmetros foram utilizados no método,e que ocasionaram o erro.

Uma das idéias que tive, é utilizar um Filter de forma a manter sempre os parametros do último request (neste caso em especial, a aplição é JSF) no contexto da sessão do usuário, porém eu não gostaria de me ater a esta idéia… eu gostaria de algo mais “localizado” e independente dõ meio da aplicação …como o fato de serweb, ou ejb…etc.
Essa idéia, acima ira atacar o início do erro, e não o local exato em especial.

Sugestões são bem vindas!
Obrigado!

10 Respostas

pablosaraiva

@SuppressWarnings("unchecked") public void dumpMyInfo(Object obj) { Class[] paramTypes; for (Method m: obj.getClass().getMethods()) { if (m.getDeclaringClass() != obj.getClass()) { continue; } paramTypes = m.getParameterTypes(); if (paramTypes.length == 0) { System.out.println(m.getName()); try { System.out.println(m.invoke(obj)); } catch (Exception e) { } } } }

Chame este método passando o objeto em questão como parâmetro.

Ele vai imprimir no console todos os métodos do objeto que não necessitam de parâmetros (ou seja, os gets e mais alguma coisa) seguido do valor que o método retornou.

Outra verificação que coloquei foi pra rodar apenas os métodos declarados na classe, não os das superclasses.

Caso queira rodar todos, independente de ser método de superclasse, retire a seguinte parte do código:

if (m.getDeclaringClass() != obj.getClass()) { continue; }

Boa sorte! :smiley:

pablosaraiva

Agora que li denovo, acho que o que você quer não é o que eu respondi.

Vou repensar.

Sexta-feira, fim de dia… :slight_smile:

cristian_clever

kkkkk…
Acontece com todo mundo!

imagine o seguinte

public Boolean efetuarPagamento(Fatura f,double umValor,boolean fiado) { throw new RuntimeException(); }

O codigo acima gera a exceçao. que ira ‘subir’ dentro da pilha de chamadas, e deverá chegar a um método de Negocio(provavelmente).
O objetivo de tudo isso é uma forma de obter os dados dentro do contexto da execução que levaram ao erro.

Se eu possuisse propriedades para a classe (como em um command) seria extremamente simples, seria possível até serializar o objeto no momento do erro… mas o fato é queasclases não possuem estado.

valeu!

volnei

Dá uma olhada em AOP, se tiver usando o guice ou spring as coisas ficam mais fáceis… Mas me parece um pouco estranho querer saber os parâmetros. Talvez seja melhor utilizar uma api de logging.

pablosaraiva

Ainda não é exatamente o que você quer, mas já ajuda.

Dá uma olhada no método getMessage() da exception.

Ela mostra justamente o valor do parâmetro que causou a exception.

cristian_clever

Não vejo nada de estranho… pelo contrário.

A aplição na qual trabalho (ERP) envolve muitos parametros/variantes… por exemplo ao se escolher um determinado ‘Cliente’ como parâmetro de entrada, são inúmeras as variáveis associadas a esta entidade… como por eexmplo notas fiscais, linguagem, produtos adquiridosno decorrer de um determinado período, perfis de compra… emfim…

A diferença entre passar horas a fio investigando a causa de um erro pode ser exatamente os parâmetros de entrada… e até onde vejo, isso é algo desejável em qualquer aplicação seja Java, VB php, prova disso é a existência de mecanismos de Debug que tem por objectivo exatamente exibir os valores correntes de uma execução…

Já é utilizada uma API de logging, a idéia é exatamente melhorar o LOG já existente, afinal obter a linha do erro e o motivo é uma coisa simples… mas obter o “estado” do método no momento da exceção… é outra coisa. O envio de e-mails no qual me referi, é apenas um apoio ao desenvolvedor.

Já utilizamos tbm injeção de dependencias, mas não vejo como isso pode me ajudar… vc poderia me dar um exemplo volnei?

Obrigado pelo interesse pessoal.

volnei

cristian_clever:
Não vejo nada de estranho… pelo contrário.

A aplição na qual trabalho (ERP) envolve muitos parametros/variantes… por exemplo ao se escolher um determinado ‘Cliente’ como parâmetro de entrada, são inúmeras as variáveis associadas a esta entidade… como por eexmplo notas fiscais, linguagem, produtos adquiridosno decorrer de um determinado período, perfis de compra… emfim…

A diferença entre passar horas a fio investigando a causa de um erro pode ser exatamente os parâmetros de entrada… e até onde vejo, isso é algo desejável em qualquer aplicação seja Java, VB php, prova disso é a existência de mecanismos de Debug que tem por objectivo exatamente exibir os valores correntes de uma execução…

Já é utilizada uma API de logging, a idéia é exatamente melhorar o LOG já existente, afinal obter a linha do erro e o motivo é uma coisa simples… mas obter o “estado” do método no momento da exceção… é outra coisa. O envio de e-mails no qual me referi, é apenas um apoio ao desenvolvedor.

Já utilizamos tbm injeção de dependencias, mas não vejo como isso pode me ajudar… vc poderia me dar um exemplo volnei?

Obrigado pelo interesse pessoal.

Cada um tem sua opinião, na minha isso é responsabilidade do LOGGING.

cristian_clever

E eu concordo com vc, cabe ao log, fazer o Log.

Porém não concordo com o fato de ser estranho, obter dados complementares para serem adicionados ao Erro, e obviamente fazerem parte do LOG, que é o foco da discussão.
Eu não preciso somente logar uma exception com um stackTrace, posso (e devo) tambem adicionar outros fatores que facilitem o entendimento do erro, com a Hora, dados de usuario…etc.

obg.

E

De fato, esse tipo de informação (obter os dados completos do stack, não somente o ‘stack trace’) é um pouco mais difícil que parece.
Pra começar, a JVM ordinariamente omite algumas coisas na chamada de métodos se ela conseguir provar, durante a execução, que é possível passar o parâmetro via registrador em vez de passá-lo na pilha, ou então se o parâmetro vai ou não ser usado na rotina que vai ser chamada.
É por isso que os depuradores que conseguem fazer isso têm de rodar seu programa em um modo especial que faz com que a JVM desligue tais otimizações.
Provavelmente você terá de usar algo semelhante a AOP para poder ter esse tipo de informação (que não pode ser obtida apenas com reflection e/ou StackTraceElement).

cristian_clever

Show, já é um início…
Vou seguir a dica de vcs sobre AOP… e começar a conhece-la.

Obg.

Criado 4 de dezembro de 2009
Ultima resposta 7 de dez. de 2009
Respostas 10
Participantes 4