Classpath e ficheiros .jar

Uma ajudinha neste problema:

Tenho uma aplicação que ao iniciar verifica que ficheiros .jar existem no directorio “modulos” e guarda essa informação (até aqui tudo bem).

O objectivo é utilizar a classe Main.class existente em cada ficheiro .jar (começa aqui o problema), como posso definir a classpath dentro do proprio programa depois de ter verificado que ficheiros .jar existem?

Alguma dica de como criar este sistema de “plugins” ?

Obrigado a todos.

Você terá que fazer isso usando classloaders. Eu fiz isso num programa meu:

File jarFile = new File("c:\\seu\\jar\\aqui.jar");
URL jarUrl = jarFile.toURL();
ClassLoader cl = URLClassLoader.newInstance(new URL[] { jarUrl }, this.getClass().getClassLoader());
Object o = cl.loadClass("sua.classe.Aqui").newInstance();

Tentei fazer como disse e consegui instanciar a classe, mas como faço agora para aceder aos metodos dessa classe?

Exemplo:

A classe seguinte seria o programa que instanciava uma outra classe e utilizava o metodo getUmaString() dessa outra classe.

[code]
public class Teste {

public Teste() {
    Object o = null;
    try {
        java.io.File jarFile = new java.io.File("/home/pek/teste/modulos/modulo1.jar");
        java.net.URL jarUrl = jarFile.toURL();
        ClassLoader cl = java.net.URLClassLoader.newInstance(new java.net.URL[] { jarUrl }, this.getClass().getClassLoader());
        o = cl.loadClass("classes.MainClass").newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    String str = o.getUmaString(); // ... ???
    System.out.println(str);
}

public static void main(String args[]) {
    new Teste();
}

}[/code]

[code]package classes;

public class MainClass {

public MainClass() {
	System.out.println("classe instanciada");
}	

public String getUmaString() {
	return "A minha string";
}

}[/code]

Existe alguma forma de aceder aos métodos desta segunda classe?

Você tem que fazer o casting pra sua classe… assim:

MainClass main = (MainClass) o;

Seria bom vc dar uma estudada na parte mais básica, porque sem saber isso vai ser difícil para você conseguir montar esse esquema de plugin que você quer…

[]´s

Tchiii … tem razão! Foi mesmo desatenção minha (já eram quase 4h da manhã, mal conseguia manter os olhos abertos :shock: :oops: )

Hoje de manhã é que me lembrei que seria melhor ter uma classe abstracta com todos os métodos que os modulos têm que implementar e utilizo esta classe para fazer o casting.

Sabe, quando “desenhei” este sistema de módulos pensei que podia modificar a classpath de dentro do programa utilizando System.setProperty(“java.class.path”, “a_nova_classpath”); só depois me apercebi que depois de entrar no método main(String args[]) já a classpath foi definida e não adianta tentar modifica-la.

De qualquer forma já está tudo a funcionar, a sua ajuda foi preciosa, mais uma vez obrigado. :smiley:

Abraço

Vegetto, como o rapaz disse, ele quer trabalhar no esquema de plugins, então fazer o casting não é uma boa idéia, mesmo porque ele não sabe qual o tipo (nome) da classe que vai trabalhar, certo.

pek, o mais correto é usar reflection ou que suas classes de plugin implementem uma interface em comum, o que acho mais razoável.

danieldestro, foi isso mesmo que eu fiz. Criei uma class que contem a interface que todos os modulos têm que implementar, depois foi só fazer o casting usando esta classe.

Obrigado a todos pelas dicas.

Daniel, eu tinha pensando que aquela classe lá seria a classe mãe de todos os plugins, por isso sugeri o casting… mas usar reflection, como vc sugeriu, é uma boa também!

[]´s