Instanciar classe desconhecida

Rau,

Pessoal, estou tentando instanciar uma classe “quase” desconhecida. A unica coisa que sei é que ela possui uma Interface.

A coisa é +/- assim:
Quero poder em uma aplicação (já compilada e pronta) poder instanciar algumas classes extras que não foram criadas por mim e a unica coisa que eu preciso que ela tenham é uma Interface.

Estou fazendo assim (ex) …

String className = “Aplicacao1”;
FormPanel app = (FormPanel)Class.forName(className).newInstance();

… onde FormPanel é a Interface.

Se compilar separado e depois juntar as duas classes da “ClassNotFoundException” mas se compilar tudo junto funciona.

Alguem sabe como posso fazer isso? (é tipo robocode, conhecem?)

robocode? sei não…

mas que tal usar Reflection?

http://www.guj.com.br/java.tutorial.artigo.10.1.guj

=]]

E onde usar Reflection vai ajudar no meu caso?

Não estou querendo saber o que tem dentro da classe não e sim apenas querendo poder instanciar sem precisar compilar tudo junto.

public class App {
public App (String className) {
System.out.println("Nome da classe: " + className);
try {
Class.forName(className).newInstance();
} catch (Exception ex) {
System.out.println(“Falhouuuu…”);
System.out.println(ex);
}
}
public static void main(String args[]) {
App aplicacao = new App(args[0]);
}
}

public class Teste {
public Teste() {
System.out.println(“Hello World”);
}
}

Compile separado os 2, em pastas separadas, depois junto os 2 na mesma pasta e após isso chame:

java App Teste

Agora veja o que acontece

O exemplo que escrevi foi horrivel, da forma acima funciona.

O problema é que os 2 estão em JAR separados.

É como um jar com o CORE da aplicação e o segundo com as regras de negocios do cliente.

E porque um não pode referênciar o outro?

que tal SuaClass.newInstance() ?!?

[]'s

[quote=marciobarroso]que tal SuaClass.newInstance() ?!?

[]'s[/quote]

Essa classe não tem nada de desconhecida :stuck_out_tongue:

[quote=Maurício Linhares][quote=marciobarroso]que tal SuaClass.newInstance() ?!?

[]'s[/quote]

Essa classe não tem nada de desconhecida :P[/quote]

Eu acho que não entendí o que ele precisa … É melhor eu acompanhar o tópico quieto … :frowning:

[]'s

Voce esta compilando FormPanel junto com as duas aplicacoes?

Desculpem, acho que não estou conseguindo me expressar direito.

Meu dilema é o seguinte, resolvemos (the boss) aqui na empresa mandar um ERP chamado Microsiga para casa da cucuia, pois o suporte aqui em Salvador - BA da criança é horrível e da forma como nos atendem demonstra que não conhecem a própria aplicação direito. Resolvemos então desenvolver internamente

Eu tenho um .jar com como um CORE da aplicação, onde ela gerencia impressora, banco de dados, montagem de relatorios, menus, gerenciar de usuário, ambiente, interfaces e etc. Também tem vários Beans que eu precisei criar, como JButton, JPanel, JTable, JTree, JDialog, tudo especialização e modelos. Este CORE é tudo que a aplicação precisa.
O nome deste .jar é Aplicacao.jar (Exemplo)

O outro .jar é onde esta as regras de negocio do cliente, como relatorios (o sql), formularios, janelas. Também tem o diagrama de classe, bem… as coisas/modelo de negocio do cliente. Tudo utilizando os Beans dos pacotes contidos em Aplicacao.jar. O nome deste .jar é AplicacaoCLib.jar

Eu sei que ai tem um pequeno problema em relação ao ClassLoader quando ele for olhar para dentro do AplicacaoCLib.jar (se não existir na hora de compilar ele nem sabera que existe) e então quando compilo e junto o Aplicacao.jar eu deixo em branco um AplicacaoCLib.jar (no classpath) para depois ser criado um e substituído por um com a aplicaçoes do cliente.

Obs.: quando substituo o AplicacaoCLib.jar eu preciso cadastrar as aplicações contidas nele no DB utilizando um formulario de Aplicacao.jar (no momento estou fazendo assim, depois vejo um forma de como sair procurando dentro do jar e sair adicionando automaticamente do DB)

Deu para entender? Creio que seja alguma coisa com o ClassLoader (acho eu).

Aqui tem um snapshot compilando/juntando o Aplicacao.jar e um AplicacaoCLib.jar com alguns programas já prontos.
http://www.felicio.com.br/downloads/snapshot1.jpg

E este é com um AplicacaoCLib.jar em branco e depois substituido por um com aplicações validas (só para o classloader saber que existe um AplicacaoClib.jar), olhem só o classnotfoundexception…
http://www.felicio.com.br/downloads/snapshot2.jpg

O código para instanciar é quase aquele que eu escrevi anteriormente.
“Class.forName(className).newInstance()”

Agradeço realmente muito qualquer ajuda :lol:

PS1.: Sei que o Menu não esta bem montando ainda e também sei que não estou nomeando os pacotes como manda o figurino (padrão), domínio inverso + nome do pacote. Mas depois utilizando refactor mudo isso rapidinho. E uma coisa boa, estou tentando convencer o The Boss a liberar a aplicação OpenSource, nada mais justo já que esta sendo desenvolvido utilizando ferramentas livres, netbeans, postgresql entre outros.

PS2.: cv - O FormPanel é uma interface contida em Aplicacao.jar mas que eu utilizo em AplicacaoCLib.jar. Só instancio formularios que implementem esta interface.
PS3.: marciobarroso - eu só sei o nome da classe em tempo de execução e da forma que você falou eu precisaria saber em tempo de compilação.

[quote=antigerme]
PS3.: marciobarroso - eu só sei o nome da classe em tempo de execução e da forma que você falou eu precisaria saber em tempo de compilação.[/quote]

Eu pensei q vc pelo menos teria esta classe como parametro. Ou até mesmo uma String com o nome da classe … Q é como vc fez.

Blz …

Ps.: Disponibiliza um link prá baixar este seu wallpaper … :smiley:

Um método bem porquinho, mas que funciona:

[code]
private List findPlugins(URLClassLoader l, ArrayList plugins) throws ClassNotFoundException {
List retorno = new ArrayList();

for (Iterator i = plugins.iterator(); i.hasNext(); ) {
    JarFile file = null;
    String tempStr = ((URL)i.next()).getPath();
    if (tempStr.indexOf("file:") != -1) {
        tempStr = tempStr.substring(tempStr.indexOf("file:") + 5);
    }
    if (tempStr.endsWith("!/")) {
        tempStr = tempStr.substring(0, tempStr.length() - 2);
    }
    try {
        file = new JarFile(tempStr);
    } catch (Exception ex) {
        System.out.println("...não foi possível ler:" + tempStr);
    }
    if (file != null) {
        Enumeration enumeration = file.entries();
        while (enumeration.hasMoreElements()) {
            JarEntry filefound = (JarEntry) enumeration.nextElement();
            String foundClassName = filefound.getName();
            if (foundClassName.toLowerCase().endsWith(".class") && foundClassName.toLowerCase().indexOf('$') == -1) {
                foundClassName = foundClassName.substring(0, foundClassName.length() - 6);
                foundClassName = foundClassName.replace('/', '.');

                Class loadedClass = l.loadClass(foundClassName);
                Class[] interfaces = loadedClass.getInterfaces();
                for (int j = 0; j < interfaces.length; j ++) {
                    if (interfaces[j].getName().equalsIgnoreCase("o package + nome da interface")) {
                        System.out.println("...achou plugin: " + foundClassName);
                        retorno.add(foundClassName);
                    }
                }
            }
        }
    }
}

return buf.toString();

}[/code]

O argumento plugins é uma lista contendo todos os “jar” nos quais quero procurar pelas classes que implementam a interface. O retorno é uma lista contendo os nomes de todas as classes encontradas que implementam aquela interface.

Aí é só instanciar.

[quote=marciobarroso][quote=antigerme]

… (ZIP)

Ps.: Disponibiliza um link prá baixar este seu wallpaper … :smiley: [/quote]

hehehe…

Aqui o link para o wallpaper

http://www.felicio.com.br/downloads/wallpaper.png

[]'s