Classpath e ficheiros .jar

7 respostas
pek

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.

7 Respostas

danieldestro

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

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.

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();
    }
}
package classes;

public class MainClass {

	public MainClass() {
		System.out.println("classe instanciada");
	}	
	
	public String getUmaString() {
		return "A minha string";
	}
}

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

V

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

pek

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

danieldestro

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.

pek

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.

V

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

Criado 20 de fevereiro de 2005
Ultima resposta 21 de fev. de 2005
Respostas 7
Participantes 3