Viva.
Eu não sou um programador Java muito experiente…
Neste momento estou a desenvolver um projecto de alguma dimensão. Neste projecto tenho uma “framework” que deve suportar diversos serviços, cada qual tem uma estrutura de ficheiros/classes um pouco diferentes… e como tal a framework para “correr” os serviços, necessita de chamar um método especial dentro de uma class. Este método eu consigo aceder-lhe, pois está num ficheiro xml que contem a descrição dos serviços…
O meu problema é… depois de ter a localização da class/method que contem as funcionalidades para correr o serviço… como posso eu, na framework, usar essa string para correr o método?! Por outras palavras… como posso eu correr esse método, se tenho apenas uma indicação de onde ele está dentro de um string?!
Não sei se fui suficientemente explicito… caso precisem de mais informações… digam-me por favor!
Desde já agradecido pela vossa atenção… e esperando feedback…
Edu
Method method = objeto.getClass().getMethod("nomeDoMetodo",new Class[]{});
valor = method.invoke(objeto,new Object[]{});
Viva.
Obrigado pela rápida resposta…
Eu não sei se estou a fazer alguma coisa mal…
Este é o código que implementei:
Method method = location.getClass().getMethod(“game”, new Class[] {Object.class});
method.invoke(location,new Object[0]);
Na primeira linha… a variavel location… é uma String, que contém o path para a class que contém o method “game”… ou seja não é mesmo um objecto… mas sim uma string que contém o path para esse objecto… que está em outra directoria… de serviços…
Este é o erro que eu obtenho…
Exception: java.lang.String.game()(java.lang.Object)
java.lang.NoSuchMethodException: java.lang.String.game()(java.lang.Object)
at java.lang.Class.getMethod(Class.java:978)
at Siramon.Deployment.Deployment.serviceDeploy(Deployment.java:124)
at Siramon.Gui.MainGuiListeners$2.widgetSelected(MainGuiListeners.java:97)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:89)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:82)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:731)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:2938)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2642)
at Siramon.Gui.MainGui.go(MainGui.java:187)
at Siramon.Siramon.main(Siramon.java:185)
at Main.main(Main.java:56)
Não sei o que se passa… aparentemente poderei estar a colocar mal o path para a class… deveria por nome_class.java, ou nome_class.class… e a localização relativa… na directoria src, onde tenho o código?! ou deverei ter outros cuidados?!
Desculpa as perguntas… mas estou mesmo encravado com isto… e como não tenho muita experiencia… não estou a conseguir ver o que faço mal…
Obrigadão pela ajuda!
Edu
Não… não é assim que funciona…
pense o seguinte
vc tem um método chamado
obter(Object entidade,String nomeDoMetodo)
este método contem:
Method method = entidade.getClass().getMethod(nomeDoMetodo, new Class[] {Object.class});
method.invoke(entidade,new Object[]);
entendeu?
Assim, usando o caminho, não dá, porque você precisa ter a instância do objeto.
substitua o location por Class.forName(location)…
Viva.
Coninuo com um problema… que diz respeito à utilização do “path” que licaliza a class, que contém o metodo que pretendo correr.
o meu código está assim:
"
Class loca = Class.forName(localizacao);
Method[] method = loca.getMethods();
Method theOne = null;
for(int k=0; k<method.length; k++){
if(method[k].getName().equals(“Game”))
theOne = method[k];
}
theOne.invoke(null,new Object[0]);
"
ora bem… a variavel “localizacao”, contem a localizacao do ficheiro/class que contem o metodo do serviço que quero executar… por exemplo um determinado serviço: “src/Services/RolfsBlastPeerToPeer/Game”. Dentro do ficheiro “Game” eu tenho um metodo, “Game”, que é responsavel pela inicialização do serviço…
Eu não sei o que se passa… mas tenho sempre o mesmo erro
:
Exception: src/Services/RolfsBlastPeerToPeer/Game
java.lang.ClassNotFoundException: src/Services/RolfsBlastPeerToPeer/Game
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:141)
at Siramon.Deployment.Deployment.serviceDeploy(Deployment.java:131)
at Siramon.Gui.MainGuiListeners$2.widgetSelected(MainGuiListeners.java:97)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:89)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:82)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:731)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:2938)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2642)
at Siramon.Gui.MainGui.go(MainGui.java:187)
at Siramon.Siramon.main(Siramon.java:185)
at Main.main(Main.java:56)
location = “src/Services/RolfsBlastPeerToPeer/Game”
o metodo que estou a executar está em: “src/Siramon/Deployment/Deployment.java”
os meus directorios:
src/ - source code
bin/ - output
não sei se isto ajuda…
Eu suponho que estou a fazer algo de errado quando coloco o path para o serviço na variavel location… mas não consigo encontrar uma forma solução para o problema
.
Eu experimentei este código, com duas classes diferentes, em dois ficheiros separados, e tudo funcionou bem :)… mas, quando tento por a class que tento invocar noutra directoria… dá sempre confusão 
Agradecia imenso se alguém me pudesse orientar neste problema.
Desde já agradecido pela atenção… e esperando uma resposta. 
Edu
tira o 0 de dentro do []
, e você não tem como substituir o null pela instancia do objeto não?
use o nome qualificado da classe, ou seja:
Class.forName(“java.lang.String”)
ou no seu caso
Class.forName(“Services.RolfsBlastPeerToPeer.Game”);
vc ainda poderia fazer assim:
Class loca = Services.RolfsBlastPeerToPeer.Game.class;
Viva.
Já consigo ver os metodos dentro da class, mas não consigo executar o metodo :(.
codigo:
Class loca = Class.forName(“Services.RolfsBlastPeerToPeer.Game”);
Method[] method = loca.getMethods();
Method theOne = null;
for(int k=0; k<method.length; k++){
System.out.println("---------methods: " + method[k].getName());
if(method[k].getName().equals(“main”)) {
System.out.println("$$$$$$$$$$$$$$$THE ONE :)))))");
theOne = method[k];
}
}
theOne.invoke(loca,new Object[0]);
Fiz algumas experiencias…
- con "theOne.invoke(null,new Object[0]); "
Exception: null
java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at Siramon.Deployment.Deployment.serviceDeploy(Deployment.java:141)
at Siramon.Gui.MainGuiListeners$2.widgetSelected(MainGuiListeners.java:97)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:89)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:82)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:731)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:2938)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2642)
at Siramon.Gui.MainGui.go(MainGui.java:187)
at Siramon.Siramon.main(Siramon.java:185)
at Main.main(Main.java:56)
- com “theOne.invoke(loca,new Object[0]);”
Exception: object is not an instance of declaring class
java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at Siramon.Deployment.Deployment.serviceDeploy(Deployment.java:141)
at Siramon.Gui.MainGuiListeners$2.widgetSelected(MainGuiListeners.java:97)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:89)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:82)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:731)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:2938)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2642)
at Siramon.Gui.MainGui.go(MainGui.java:187)
at Siramon.Siramon.main(Siramon.java:185)
at Main.main(Main.java:56)
- alterando o metodo que quero chamar para “static”, e usando “theOne.invoke(loca,new Object[0]);”
Exception: wrong number of arguments
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at Siramon.Deployment.Deployment.serviceDeploy(Deployment.java:141)
at Siramon.Gui.MainGuiListeners$2.widgetSelected(MainGuiListeners.java:97)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:89)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:82)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:731)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:2938)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2642)
at Siramon.Gui.MainGui.go(MainGui.java:187)
at Siramon.Siramon.main(Siramon.java:185)
at Main.main(Main.java:56)
Enfim… não sei mesmo o que se passa… 
Alguma ideia?!
Obrigado!
Edu
você precisa passar uma instancia do seu objeto, no caso, loca
esse seu método tem que receber a instancia, se nao nao tem como usar o objeto com seus atributos!
Bom… o objecto que eu chamo… é algo que é dinamico… e que em principio não saberei o que é… ou seja, eu creio que nao posso instanciar um objecto assim.
O metodo que chamo nos objectos (“main”), não recebe qualquer argumento… tratando depois de fazer as devidas inicializações… e a criação de um thread para esse serviço…
Por isso… continuo a não conseguir por isto a funcionar… será que me poderias dar alguma pista sobre essa instanciação?! E se é mesmo necessário… não é sufciente depois de ter o objecto, e ter lido os seus metodos… correr um metodo do objecto que faça as inicializações que queremos?!
Obrigado pela atenção!
Edu
você pode passar uma instancia genérica, tipo
metodo(SeuObjeto);
e sua assinatura ser: public void metodo(Object obj)
aí vc usa “obj” como instancia
A ver se entendi…
O que esta a dizer é para definir no serviço (class que contém o metodo a executar ), um metodo genérico que recebe como parametro um elemento do tipo do serviço (Objecto).
Depois na framework, o programa que vai executar o codigo para descobrir e correr o metodo que pretendo correr… podia usar esse metodo para instanciar o objecto, e inicializar a sua execução…
O que eu não entendo, talvez devido à minha pouca experiencia, como devo eu fazer executar esse metodo generico que escrevo no servico?! Depois de o recolher… com o codigo:
Class loca = Class.forName(“Services.RolfsBlastPeerToPeer.Game”);
Method[] method = loca.getMethods();
Method theOne = null;
for(int k=0; k<method.length; k++){
System.out.println("---------methods: " + method[k].getName());
if(method[k].getName().equals(“generic”)) {
System.out.println("$$$$$$$$$$$$$$$THE ONE :)))))");
theOne = method[k];
}
}
Para isso devo usar o que?! o “invoke” ?!
Peço mesmo desculpas pela minha ignorância… mas a verdade é que começei com o java à pouco tempo… e devido a este projecto, tenho mesmo de tentar aprender um pouco à pressa… e faltam-me assim muitos conceitos… mas a verdade é que tenho de terminar o projecto… e é também a verdade que só me falta criar esta funcionalidade…
Agradecia que me dessem uma explicação mais pormenorizada… a fim de eu apanhar a ideia toda… e tentar então implementar isso no meu programa.
Um grande muito obrigado!
Fiquem bem
Edu
Bem… eu também entendo pouco disso…mas estou tentando ajudar…
mas vamos…deixa eu ver…
imagine o seguinte…
Temos uma classe Carro
você quer executar um método de carro, por exemplo, acelerar(),usando invoke.
Para que isso seja possível, você deve ter uma instancia do objeto.
ou seja:
[code]
Carro carro = new Carro();
acelerar(carro);
onde
public void acelerar(Object objeto) {
Method method = objeto.getClass().getMethod("acelerar", new Class[] {Object.class});
method.invoke(objeto,new Object[]);
} [/code]
Se você observar, dentro de objeto, eu tenho uma instancia de uma classe Carro, mas com o formato de um Object.
por isso, usa-se esta chamada, pois não posso usar objeto.acelerar(), pois Object não possui este metodo.
acho que é mais ou menos isso!
e para de pedir desculpas pq vc não sabe isso ou aquilo 
Eu percebi a tua ideia…
Mas o que se passa é o seguinte… eu tenho básicamente duas partes… uma que é a class que contem o metodo que quero correr… e depois tenho um programa (framework), que deve chamar esse metodo na class.
Ou seja… o que acontece é que eu sei onde esta a class, neste caso “Carro”, e sei que tenho de correr o metodo “acelerar”… isto tem de ser chamado da framework… ou seja, o serviço (carro.acelerar) é chamado da framework…
Eu não sei se estou a fazer confusão com o teu código, mas penso que não…
Eu com este código posso aceder ao metodo:
Class loca = Class.forName(“Services.RolfsBlastPeerToPeer.Game”);
Method[] method = loca.getMethods();
Method theOne = null;
for(int k=0; k<method.length; k++){
System.out.println("---------methods: " + method[k].getName());
if(method[k].getName().equals(“generic”)) {
System.out.println("$$$$$$$$$$$$$$$THE ONE :)))))");
theOne = method[k];
}
}
O meu problema é que mesmo que tendo o metodo, não o consigo correr com o codigo:
method.invoke(loca,new Object[]);

Não entendo… Mas creio que entendeste que tenho de chamar o metodo da framework, o que é um pouco diferente da abordagem que me propões… ou talvez eu continue sem perceber a tua ideia.
PS - está prometido que não peço mais desculpas 
Obrigado
Edu
entendi!!!
Acho que agora vai!!!
Class loca = Class.forName("Services.RolfsBlastPeerToPeer.Game");
Object o = loca.newInstance();
Method method = loca.getMethod("nomedometodo",new Class[0]);
method.invoke(o,new Object[0]);
bejeto… NÃO SEI O TEU NOME… MAS QUERO AGRADECER-TE DE CORAÇÃO!!!
ESTÁ A FUNCIONAR PERFEITINHO 
FANTÁSTICO!!!
EHEHEHEHEHEHEH
MUITO MUITO OBRIGADO… APÓS UM DIA DE VOLTA DISTO… ESTÁ A FUNCIONAR!!!
UMA VEZ MAIS OBRIGADO PELA TUA ATENÇÃO… ESPERO UM DIA DESTES PODER AJUDAR-TE TAMBÉM… AINDA TENHO DE EVOLUIR UM POUCO… MAS SE PUDER AJUDAR-TE… FAREI-O COM O MESMO EMPENHO QUE TU COLOCAS-TE NO MEU PROBLEMA!!
UM GRANDE OBRIGADO! E FICA BEM!
A GENTE VE-SE POR AI 
Edu
Hehehe, sinceramente, eu prefiro não precisar, risos!!!
[]`s