Chamada de classe por string (RESOLVIDO)

8 respostas
DAREK6920
Ola a todos, Sera que alguem pode me dizer o que esta errado no codigo abaixo ?
public static void alocar(String metodo, String valor) throws ClassNotFoundException{
    try {
            Class c = Class.forName("TNFE.IDE");
            Field f = c.getDeclaredField(metodo);
            f.setAccessible(true);
            try {
                f.set(c,valor);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(jd.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(jd.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        } catch (NoSuchFieldException ex) {
            Logger.getLogger(jd.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(jd.class.getName()).log(Level.SEVERE, null, ex);
        }
}

Esta classe existe e esta no classpath, mas esta gerando o seguinte erro:

28/02/2012 04:54:01 ta01.jd jButton2ActionPerformed
GRAVE: null
java.lang.ClassNotFoundException: jPegasus
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at ta01.funcoes.alocar(funcoes.java:852)
at ta01.ts.readConfig(ts.java:97)
at ta01.ts.main(ts.java:123)
at ta01.jd.jButton2ActionPerformed(jd.java:203)
at ta01.jd.access$100(jd.java:36)
at ta01.jd$2.actionPerformed(jd.java:114)
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:6288)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6053)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
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:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
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)

Este erro esta aparecendo até quando muda a classe, TNFE.IDE para uma classe tipo a classe principal.
Agradeço a ajuda.

8 Respostas

mauricioadl

vc esta colocando o nome inteiro do pacote??? mesmo que a classe esteja no mesmo pacote eh preciso colocar (se não me engano)

aeciovc

Bom... um exemplo simples de chamada de método pode ser assim:

public static void alocar(String metodo, int valor) throws ClassNotFoundException{

try{

    Class c = Class.forName("MyClass");

    Method meth = c.getMethod(metodo, Integer.TYPE);

    Constructor ct = c.getConstructor();

    Object obj = ct.newInstance();
							
    meth.invoke(obj, valor);
						
    System.out.print(obj.toString());

} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException 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 (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
}

Nesse caso eu tenho uma classe chamada MyClass e a chamada no método principal fica assim:

try {
			alocar("setCampo", 10);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

No Exemplo acima você ainda precisaria tratar o tipo do parametro de entrada e alguns outros detalhes.

OBS: é necessário sim o nome do pacote inteiro.

drsmachado
java.lang.ClassNotFoundException: jPegasus

É essa a classe que pretende chamar?
Em que pacote ela está?

DAREK6920

Na realidade a classe a ser chamada é “TNFE.IDE”, dentro de um pacote TA01. jPegasus foi um teste que fiz para saber se o metodo identificava pelo menos a classe principal mas nem isto ele fez. Vou tentar agora passando o caminho completo do pacote, ou seja “TA01.src.ta01.TNFE.IDE” para ver no que da.

A chamada do metodo esta correta, tanto que se eu colocar a classe diretamente para pegar o getmethod funciona que é uma beleza. Mas o que eu queria era tornar a identificação da classe um processo dinamico independente de uma arvore de ifs.

De qualquer forma, obrigado pela ajuda até agora.

DAREK6920

Ja tentei de todas as maneiras mas ainda assim, ele não identifica a classe. Sei que estou fazenda alguma coisa errada e provavelmente é besteira, coisa simples mas não consigo enxergar. De novo vai o codigo alterado e o resultado

public static void alocar(String metodo, String valor) throws ClassNotFoundException{
    try {
            Class c = Class.forName("ta01/TNFE$IDE");
            Field f = c.getDeclaredField(metodo);
            f.setAccessible(true);
            try {
                f.set(c,valor);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(jd.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(jd.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        } catch (NoSuchFieldException ex) {
            Logger.getLogger(jd.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(jd.class.getName()).log(Level.SEVERE, null, ex);
        }
}

o Resultado:
28/02/2012 14:26:22 ta01.jd jButton2ActionPerformed
GRAVE: null
java.lang.ClassNotFoundException: ta01/TNFE$IDE
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at ta01.funcoes.alocar(funcoes.java:853)
at ta01.ts.readConfig(ts.java:97)
at ta01.ts.main(ts.java:123)
at ta01.jd.jButton2ActionPerformed(jd.java:203)
at ta01.jd.access$100(jd.java:36)
at ta01.jd$2.actionPerformed(jd.java:114)
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:6288)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6053)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
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:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
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)

O mais engraçado é que quando peço uma listagem de todas as classes atraves de um outro metodo ele me lista a classe como existente normalmente:

ta01/TNFE$emit.class
ta01/TNFE$IDE.class
ta01/TNFE$total$ICMSTot.class
ta01/TNFE$total.class
ta01/TNFE$transp.class
ta01/TNFE.class
ta01/tracess.class
ta01/tre$1.class
ta01/tre$ClockRunnable$1.class
ta01/tre$ClockRunnable.class
ta01/tre.class
ta01/ts.class
ta01/txml.class
ta01/ut.class
ta01/variaveis.clas

Esta é apenas uma parte da listagem.
O mais curioso de tudo é que o erro não esta na classe, porque se isto fosse ele acharia as outras classes do pacote, entretanto nem mesmo a classe principal ele esta achando.
Creio que o erro esta nos parametros do comando class.forname, mas não sei qual é !
A proposito ja tentei "d:/TA01.src.ta01.TNFE.IDE", "ta01/TNFE.IDE", "TA01.src.ta01.TNFE.IDE" e todo tipo de combinação, inclusive a mais basica de todas que seria apenas o nome da classe mesmo, "IDE".

Se alguem puder me ajudar, agradeço de montão !

lindberg713

Use ‘.’ ao invés de ‘/’.

Ao invés de

Class c = Class.forName("ta01/TNFE$IDE");

Faça

Class c = Class.forName("ta01.TNFE$IDE");
DAREK6920

A resposta, bem boba por sinal, pelo menos para mim, está no “cifrão”. Não me dei conta de que para atingir uma classe dentro de outra classe tivesse de utilizar outro separador que não o ponto.
Dai se utilizar o ponto, obviamente a tal classe não existe, tipo ta01.TNFE.IDE não será encontrada porque esta sendo chamada de modo incorreto.
O modo correto seria ta01.TNFE$IDE. Isto foi o que me atrapalhou, isto e mais o fato de que eu estava tentando colocar o caminho inteiro da classe quando o correto é colocar apenas o nome do pacote.

Agora, vendo tudo, parece tão simples que acho que ninguem notou que eu estava fazendo besteira.

Agradeço a todos pela ajuda.

lindberg713

Lembro que o fato de usar ‘.’ ou ‘/’ não implica, como você disse, em a classe ser uma inner class (uma classe dentro da outra) ou não. Class.forName funciona usando ‘.’ e não ‘/’ independente de ser inner class ou não.

Espero ter ajudado.

Criado 28 de fevereiro de 2012
Ultima resposta 1 de mar. de 2012
Respostas 8
Participantes 5