[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

G

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

Z

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

J

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

G

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…

Z

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

G

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

Z

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)

Z

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

G

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

Z

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

Z

Varargs aceitam arrays de boa, isso não aconteceria

G

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

Z

Lista todos os construtores da sua classe

Você por acaso compilou a sua classe?

J

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

Z

Cola o stacktrace completo aqui também pra gente ver

M

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)

G

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);

Z

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

Z

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

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

G

coloca o modificador public na frente do construtor da classe DownloadSTJ

M

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);

M

Foi isso que eu queria dizer.

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