[RESOLVIDO] Probelma com Reflection

33 respostas
A

Então, passo duas Strings como parametro, pq a classe a ser invocada usa dois argumentos(String args[] ).. será q pelo fato da classe a ser invocada possuir um main() da erro na hora de criar o Constructor??

Debugando o código da NoSuchMethodException na linha Constructor ct = classe.getConstructor(paramTypes);

private Object getClassInstance(){
		try {
			Class<?> classe = Class.forName("br.com.snap.diof.download.Download"+Tela.getCaderno());
			Class paramTypes[] = new Class[2];
			paramTypes[0] = String.class;
			paramTypes[1] = String.class;
			
			Constructor ct = classe.getConstructor(paramTypes);
//			Constructor ct[] = classe.getConstructors();
			
			Object argList[] = new Object[2];
			argList[0] = new String(tela.leDataTela());
			argList[1] = m_data;
			Object returnObj = ct.newInstance(argList);
			return ct.newInstance(argList);
//			return null;
			
		} catch (ClassNotFoundException e) {
			System.out.println("Classe não encontrada");
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

Valeu

33 Respostas

Guitar_Men

Os argumentos estão no construtor ou são os argumentos do main mesmo ??
Nunca trabalhei dessa forma, instanciando objetos que tem main…

zoren

Isso não dá problema, vc tem esse construtor mesmo, com esses tipos?

jimmyhc

aonde que está esse type: “br.com.snap.diof.download.Download”

Issso ja aconteceu comigo… problema de classloader da aplicação.

Tenta colocar esse class dentro do mesmo projeto.

A

cara o main não é obrigatório… a principio tinha main na classe… mas com isso não tem necessidade de mante-lo

tipo… o contrutor recebe uma String e um Obj Data

construtor(String str, Data data)

ja fiz o teste sem o main na classe a ser invocada e usei os args do jeito que está mostrado ai no contrutor.
já fiz teste com main na classe a ser invocada e passei duas Strings como args… nas duas tomei exception

to começando a achar que o erro está no jeito que estou passando os args ClasseX.class! não faço a minima idéia de corrigir… primeira vez que uso refelction

Guitar_Men

Eu acho que se fosse problema de não encontrar a classe daria um ClassNotFoundException. De duas uma, ou o construtor não existe ou os argumentos que estão sendo passados para ele estão com o tipo errado…

zoren

arthurmenezes:
cara o main não é obrigatório… a principio tinha main na classe… mas com isso não tem necessidade de mante-lo

tipo… o contrutor recebe uma String e um Obj Data

construtor(String str, Data data)

ja fiz o teste sem o main na classe a ser invocada e usei os args do jeito que está mostrado ai no contrutor.
já fiz teste com main na classe a ser invocada e passei duas Strings como args… nas duas tomei exception

to começando a achar que o erro está no jeito que estou passando os args ClasseX.class! não faço a minima idéia de corrigir… primeira vez que uso refelction

Coloca aqui a classe que vc está tentando acessar por reflexão

A
package br.com.snap.diof.download;

import java.io.File;
import java.net.URL;
import java.util.Properties;
import java.util.logging.Logger;

import br.com.snap.diof.DiofUtil;
import br.com.snap.net.HttpDownload;
import br.com.snap.util.Data;

public class DownloadSTJ implements Download{
	
	public static  Logger s_log = Logger.getAnonymousLogger();
	private static String HOST = "http://dj.stj.jus.br/";
	private static String CADERNO = "stj";
	
	private String m_raiz;
	private Data m_data;
	private HttpDownload m_downloader = new HttpDownload();
	
	DownloadSTJ(String raiz, Data data) {
		s_log.info("DOWNLOAD STJ - Início");
		s_log.info("obtendo pagina de índice...");
		m_raiz = raiz;
		m_data = data;
		try {
			processaDownload();
		} catch (Exception e) {
			s_log.severe("Erro no Download do arquivo!!!");
			e.printStackTrace();
		}
		s_log.info("DOWNLOAD STJ - FIM");
	}
	
	private void processaDownload() throws Exception {
		URL url = new URL(HOST + m_data.getDataDb() + ".pdf");
		String arqOut = diretorio() + File.separator  + CADERNO + ".pdf";
		s_log.info("Iniciando download do arquivo da url: " + url);
		String arquivo = m_downloader.getDownload("[pdf]", url, arqOut, new Properties());
		s_log.info("recebidos " +  arquivo.length() + " bytes");
	}
	
	private String diretorio() {
		StringBuilder sb = new StringBuilder().append(m_raiz)
			.append(File.separator)
			.append(CADERNO)
			.append(File.separator)
			.append(DiofUtil.dataComPontos(m_data.getDataDb()));
		return sb.toString();
	}

//	public static void main(String[] args) {
//		if (args.length < 2) {
//			s_log.severe("Parametros: <Diretorio Raiz> <dd/mm/aaaa> [<dd/mm/aaaa>...]");
//		} else {
//			for (int i = 1; i < args.length; i++) {
//				Data data = DiofUtil.dataDe(args[i]);
//				if (!data.dataValida()) {
//					throw new IllegalArgumentException("Data inválida! " + args[i]);
//				} else {
//					new DownloadSTJ(args[0], DiofUtil.dataDe(args[i]));
//				}
//			}
//			
//		}
//		
//	}
	
}
A

aonde que está esse type: “br.com.snap.diof.download.Download”

Issso ja aconteceu comigo… problema de classloader da aplicação.

Tenta colocar esse class dentro do mesmo projeto.

Está no mesmo projeto… porém em pacotes diferentes… o que não faz mto sentido de dar erro

Guitar_Men

O segundo parâmetro é do tipo Data e vc ta passando um Object. Tentou forçar um cast ??

zoren

vc está invocando o construtor como

class.getConstructor(String.class,Data.class).newInstance(null,null)

é mais ou menos assim?

COloca esse método tbm aqui

A

Cara o erro acontece na linha:

Constructor ct = classe.getConstructor(paramTypes);

nem chegou a ct.newInstance(argList)

zoren

mas vc está passando os tipos de parâmetros corretos?

A

vc está invocando o construtor como

view plaincopy to clipboardprint?
class.getConstructor(String.class,Data.class).newInstance(null,null)

é mais ou menos assim?

COloca esse método tbm aqui

Cara isso ta no primeiro post do tópico… onde tem / no código é comentário

Guitar_Men

Ele ta procurando um construtor que tenha como parâmetro um array de Object e não esta encontrando…

zoren

No primeiro post vc tentou com dois tipos String, assim n vai mesmo.

A
mas vc está passando os tipos de parâmetros corretos?
Class classe = Class.forName("br.com.snap.diof.download.Download"+Tela.getCaderno());
			Class paramTypes[] = new Class[2];
			paramTypes[0] = String.class;
			paramTypes[1] = Data.class;
			
			Constructor ct = classe.getConstructor(paramTypes);
//			Constructor ct[] = classe.getConstructors();
			
			Object argList[] = new Object[2];
			argList[0] = new String(tela.leDataTela());
			argList[1] = m_data;
			Object returnObj = ct.newInstance(argList);
			return ct.newInstance(argList);
paramTypes[0] = String.class;
paramTypes[1] = Data.class;
construtor:
DownloadSTJ(String raiz, Data data){...}
A

ah sim…mals ai… mas ali eu postei um código que troquei os args pra testar… mas ja mudei

zoren

Varargs aceitam arrays de boa, isso não aconteceria

Guitar_Men

Você chegou a fazer testes sem passar parâmetros no construtor ??

zoren

Lista todos os construtores da sua classe

Você por acaso compilou a sua classe?

jimmyhc

então realmente não é problema no ClassLoader

arthurmenezes:
aonde que está esse type: “br.com.snap.diof.download.Download”

Issso ja aconteceu comigo… problema de classloader da aplicação.

Tenta colocar esse class dentro do mesmo projeto.

Está no mesmo projeto… porém em pacotes diferentes… o que não faz mto sentido de dar erro

zoren

Cola o stacktrace completo aqui também pra gente ver

Marky.Vasconcelos

Seu construtor é com o modificador (Sem modificadores), voce com o getConstructor pega apenas o publico.

Faça getDeclaredConstructor invés de getConstructor.

E como provavelmente vai lançar uma exception por causa de ser privado, mude para acessible(true).

A

java.lang.NoSuchMethodException: br.com.snap.diof.download.DownloadSTJ.<init>(java.lang.String, br.com.snap.util.Data) at java.lang.Class.getConstructor0(Class.java:2706) at java.lang.Class.getConstructor(Class.java:1657) at br.com.snap.diof.download.controle.ControleDownload.getClassInstance(ControleDownload.java:46) at br.com.snap.diof.download.controle.ControleDownload.actionPerformed(ControleDownload.java:83) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236) at java.awt.Component.processMouseEvent(Component.java:6237) at javax.swing.JComponent.processMouseEvent(JComponent.java:3267) at java.awt.Component.processEvent(Component.java:6002) at java.awt.Container.processEvent(Container.java:2041) at java.awt.Component.dispatchEventImpl(Component.java:4604) at java.awt.Container.dispatchEventImpl(Container.java:2099) at java.awt.Component.dispatchEvent(Component.java:4434) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168) at java.awt.Container.dispatchEventImpl(Container.java:2085) at java.awt.Window.dispatchEventImpl(Window.java:2475) at java.awt.Component.dispatchEvent(Component.java:4434) at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Guitar_Men

Conforme o zoren disse, lista os construtores da sua classe…

import java.lang.reflect.*;

public class Constructor1 {

	public Constructor1() { }
  
	protected constructor1(int i, double d) { }
  
	public static void main(String args[]) {
		try {
			Class cls = Class.forName("constructor1");
			Constructor ctorlist[] = cls.getDeclaredConstructors();

			for (int i = 0; i < ctorlist.length; i++) {
				Constructor ct = ctorlist[i];
				System.out.println("nome = " + ct.getName());
				System.out.println("membro da classe = " + ct.getDeclaringClass());
        
				Class pvec[] = ct.getParameterTypes();
				for (int j = 0; j < pvec.length; j++)
					System.out.println("parâmetro #" + j + " " + pvec[j]);

				Class evec[] = ct.getExceptionTypes();
				for (int j = 0; j < evec.length; j++)
					System.out.println("exceção #" + j + " " + evec[j]);
			}
		}
		catch (Throwable e) {
			System.err.println(e);
		}
	}
}

tirado do tutorial do guj http://www.guj.com.br/article.show.logic?id=10

A

Marky.Vasconcelos:
Seu construtor é com o modificador (Sem modificadores), voce com o getConstructor pega apenas o publico.

Faça getDeclaredConstructor invés de getConstructor.

E como provavelmente vai lançar uma exception por causa de ser privado, mude para acessible(true).

cara funfou com isso ai que tu me disse
mas agora o erro ta Object returnObj = ct.newInstance(argList);

zoren

Faz o que o Marky.Vasconcelos disse ou mude seu construtor para public

A

Faça getDeclaredConstructor invés de getConstructor.

E como provavelmente vai lançar uma exception por causa de ser privado, mude para acessible(true).

mude o que??? não entendi… mals ai

zoren

Na classe constructor vc tem um método setAcessible(boolean),

Ele método torna algo acessivel pela reflexão, mesmo que seja privado.

Guitar_Men

coloca o modificador public na frente do construtor da classe DownloadSTJ

Marky.Vasconcelos

Qual problema agora?

e por que voce faz o newInstance duas vezes?

Object returnObj = ct.newInstance(argList);   //1°
        return ct.newInstance(argList);   //2°
A

Marky.Vasconcelos:
Qual problema agora?

e por que voce faz o newInstance duas vezes?

Object returnObj = ct.newInstance(argList); //1° return ct.newInstance(argList); //2°

foi falta de // no código!!!

Muito Obrigado a Todos… resolvido o problema foi só dar o ct.setAccessible(true);

Marky.Vasconcelos

Foi isso que eu queria dizer.

Criado 27 de agosto de 2010
Ultima resposta 27 de ago. de 2010
Respostas 33
Participantes 5