Adcionar referencia ao jar em tempo de compilação!?

Bom, para executar um applet sao necessários uns 8mb de download no embeded do mesmo.
Para evitar isto eu nao os coloco no embeded…
o que daria um erro em tempo de execução, porque nao encontraria as classes …

POrtanto … no inicio do meu applet eu verifico se no diretorio lib/ext do java existe os jars da minha applicação… se nao existir…
eu faço o download dos mesmos para este diretório …

até ai tudo bem !
Funciona… mas porem, entretanto, contudo…
Como a minha JVM ja foi instanciada na hora da execução da minha aplicação…
neste momento ainda nao havia os .jar naquele diretório …
foi inserido depois, em tempo de execução …

Como raios eu posso fazer para a JVM reconhecer esses .jar sem ter que fechar e abrir o navegador( ação que recarregaria a jvm)
???
Ajuda ae :stuck_out_tongue:

Tem como vc atualizar a página?

Nao adianta recarregar a pagina, somente fechando o navegador e abrindo denovo para reconhecer os jars.
ou terminando a sessao talvez…
mas a intenção reconhecer direto …

tipo um JVM.RELOAD() KKKKKKKK
ou EXTENSIONCLASSPATH.RELOAD() :twisted: :roll:

Talvez dê para fazer algo manipulando classloaders.
Ou, via comunicação Applet-Browser, após o download dos jars faltantes, tu force um refresh na página que contém o applet.

Inté.

Achei esses links:
http://snippets.dzone.com/posts/show/3574
http://stackoverflow.com/questions/60764/how-should-i-load-jars-dynamically-at-runtime

Inté.

Nao é bem o que eu quero…
Ja consegui fazer uma instancia de ClassLoader tipo UrlLoader minha…
buscar a classe…

queria digamos…
compartilhar esse path que o meu UrlClassLoader criou com o classPath do ClassLoader da JVM em execução…
para poder fazer referencias diretas as classes no meu código…
ou seja… para poder importar as classes…

algo como pensado aki :
http://javafree.uol.com.br/artigo/876400/ClassLoader-Desmitificado.html

por hora estou fazendo uma nova classe pegando tudo que precisa dos jars e subtituind as referencias usando o UrlClassLoader e refleção…
mas não é o que eu quero …

pessoal, encontrei algumas coisas… que ja me ajudaram
mas ainda tem problemas…

vou reescrever aqui pra ver se alguma alma bem entendida me ajuda…

[b]

se eu tenho um classPath digamos meu C:
quando eu inicio um programa java…
ele inica uma JVM…
o classPath dele pega tudo que tem em C:

se ali no meu do meu codigo… no meio da execução eu copiar um jar de D: para C:

o classLoader nao vai reconhecer esse meu jar certo ?
porque quando a JVM foi startada o classPath dela nao tinha esse jar …

certo ?

a partir dai meu problema começa…

applets podem carregar os jars pra dentro da maquina do cliente…
tenho um applet que precisa de jars que somam uns 8mb …

entao toda vez que o browser eh fechado… e aberto denovo…
abrindo o applet… tem que carregar esses 8mb toda vez…

pensei em armazenar os jars na maquina do cliente… no diretorio JAVA_HOME/LIB/EXT
estando la…
quando o applet eh carregado ele consegue encontrar os jars…

o problema é a primeria execução…
como o applet foi chamado… e uma JVM eh instanciada… e ainda nao tem os jars…
eles acabaram de ser copiados pra maquina…
a JVM nao reconhece eles ainda… so fechando e abrindo denovo…

o que posso fazer é criar uma classe a parte, que caso seja a primeira execução, ou seja. o classLoader n achar as classes que eu quero…
eu executo essa classe a parte…
que ao invez de ter as referencias as classes… eu uso tudo por refleção…
pego as classes com um URLClassLoader… que eu instancio… passando as urls dos jars. na maquina do cliente…

isso é um poooorre alem de ter que fazer reflexção de muitas classes com dependencias dos jars…
ainda por cima uma logica esta dando erro.

um jar de uma API para renderizar e serializar imagens…
Uma classe SerializableRenderedImage usada para serializar meus objetos com as imagens por exemplo scaniadas…
eu pego meu objeto SerializableRenderedImage e jogo num ObjectOutPutStream e mando dou um object.write …
criando um arquivo…

até ai beleza… onde eu instancio o objeto por reflexação e o objectOutput faz a parte dele…

mas quando eu vou ler a merda do arquivo…
dava um erro…
o ObjectImputStream nao conseguia ler meu objeto porque o classLoader nao achava a class(logico como comentado no inicio)
entao sobEscrevi um método da classObjectImputStream onde ele lia a classe…
eu retornei pra ele a mesma instancia de class que eu usei pra escrever o objeto…

só que deu uma exception java.io.InvalidClassException…local class incompatible …

porque o serialId da classe persistida era diferente do serialId da classe que ele tava tentando ler…

eu acho que o problema é que essa classe nao tem definido seu serialId (seja default ou generated) …
talves se tivesse nao aconteceria o erro…nao posso alterar essa classe…

conseguiu intender o problema ?
pode me dar algum tipo de ajuda?[/b]

[quote=jack_utfpr]pessoal, encontrei algumas coisas… que ja me ajudaram
mas ainda tem problemas…

[…]

[/quote]

Ei, a classe ClassLoader tem o método estático “getSystemClassLoader()”, que retornaria o ClassLoader padrão da JVM, tentou adicionar URLs nesse ClassLoader padrão?

Inté.

nao existem métodos para adcionar urls na classe ClassLoader
:frowning: :roll:

[quote=jack_utfpr]nao existem métodos para adcionar urls na classe ClassLoader
:frowning: :roll: [/quote]

Tentou trocar o SystemClassLoader pelo seu próprio ClassLoader usando a propriedade de JVM “java.system.class.loader”?

Inté.

Como assim ?
voce diz fazer System.setProperty("java.system.class.loader","minhaClasseLoader.class")

?
agora nao posso testar, segunda cedo eu tentarei…
ate la vou pesquisando umas coisas …

me confirma se é isso mesmo…
mas acredito que eu nao vo ter permissao pra alterar essa propriedade.

uma duvida… o que eu passaria como parametro ?
o nome de uma classe mesmo ?
e esta classe poderia estar dentro do meu .jar que é carregado no embeded do meu applet ?
Obrigado pela ajuda

[quote=jack_utfpr]Como assim ?
voce diz fazer System.setProperty("java.system.class.loader","minhaClasseLoader.class")

?
agora nao posso testar, segunda cedo eu tentarei…
ate la vou pesquisando umas coisas …

me confirma se é isso mesmo…
mas acredito que eu nao vo ter permissao pra alterar essa propriedade.

uma duvida… o que eu passaria como parametro ?
o nome de uma classe mesmo ?
e esta classe poderia estar dentro do meu .jar que é carregado no embeded do meu applet ?
Obrigado pela ajuda
[/quote]
Em teoria, só precisa passar o nome da Classe que se tornaria o ClassLoader padrão, sem o “.class”, sendo que tu deve passar um “-Djava.system.class.loader=[suaClasseDeClassLoader]” na inicialização da JVM.
Mais links:
http://accu.org/index.php/journals/285
http://en.wikipedia.org/wiki/Java_Classloader

Inté.

Link de apoio a parâmetros de JVM em applets:
http://www.rgagnon.com/javadetails/java-0531.html

Inté.

Caramba, estou vendo agora que o que estou fazendo é te ajudar a dar voltas insanas em torno de um problema simples. Se os 8 mb de jars não estiverem instalados, faça o applet baixar os 8 mb e faça o applet avisar o usuário para atualizar a página porque o sistema já foi instalado, o que deve reiniciar a jvm do applet.
O problema estranho de números seriais acho que deve dar para consertar trocando serializable por externalizable, ainda que deixe o processo de serialização muito mais “na mão”.

Inté.

[quote]Caramba, estou vendo agora que o que estou fazendo é te ajudar a dar voltas insanas em torno de um problema simples. Se os 8 mb de jars não estiverem instalados, faça o applet baixar os 8 mb e faça o applet avisar o usuário para atualizar a página porque o sistema já foi instalado, o que deve reiniciar a jvm do applet.
O problema estranho de números seriais acho que deve dar para consertar trocando serializable por externalizable, ainda que deixe o processo de serialização muito mais “na mão”.

Inté.[/quote]

mas intao, realmente eu nao quero que ele tenha que fechar e abrir denovo…
quero realmente a solução sem ter que abrir e fechar…

seria muito facil de resolver assim :stuck_out_tongue: :lol:
mas é serio, o usuário ja esta acessando o sistema…
e a partir de um link no sistema ele vai chamar o applet…
digamos que ele ja tenha colocado um par de informação no sistema…
e ta ali pronto so pra usar aquela funcionalidae…
sei la… que ele esteja com pressa ou n sei…
“pqp vo te que fechar e abrir denovo essa merda…”
o melhor é fazer a coisa transparecer :stuck_out_tongue:

o meu applet ja faz a função de copiar os jars para o diretorio java_home/lib/ext

uma coisa que pensei em fazer, e comecei a testar…para contornar o problema…
foi fazer parecido com o que eu estava tentando no inicio…

meu primeiro applet so traz no embeded o jar realmente necessario, da classe do applet…
ele é responsavel por verificar se existe os jars (8mb) na maquina do cliente…

CASO NAO EXISTAM…
– ele vai fazer o download pra maquina…e atravez de uma chamada a uma função JS implementada com a ajuda do JQuery
fazer o reRender do target onde esta meu applet… com outra pagina…esta pagina iria conter um applet com a real funcionalidade
e os 8mb embeded…
OBS: sao 16mb de dowload… 8mb pro diretorio… e +8mb do embeded…
e pah… funciona…

CASO JA EXISTAM…
–ele nao faz o download… e atravez do JS faz o reRender chamando uma pagina que ira conter um applet com a mesma real funcionalidade mas sem os 8mb embeded, resultando em quase nada de download :twisted:

POREM, como sempre um problema tem que ocorrer…
nao estava dando certo este reRender…
pelo menos nao no firefox … esta ocorrendo um erro do JQuery …(isso eu so descobri depois de horas de tentativas e pesquisas)
acho que o JQuery tem algum tipo de erro nesse reRender para applets…
dizia que a função JQuery#NUMEROQUALQUER nao existia para meuApplet.class …

entao foi que testei no IECA :twisted: e deu certo !
agora é descobrir como arrumar esse erro para o firefox e esse meio de resolver o problema esta funcionando…
:roll: porem, ainda não é um bom jeito…
porque mesmo que da segunda execução eu tenha conseguido reduzir para quase zero o download…
na primeira … :cry: eu dobrei pra 16mb :shock:
a
é foda…
por isso ainda continuo buscando a solução do ClassaLoader …
se realmente não conseguir… ai vo te que consegur arrumar essa por JavaScript e me conformar…

vlws a ajuda…
agora é final de semana…
minha politica pessoal n permite trabalhar no final de semana…
preciso de descanso as vezes :twisted:
tou lendo os links que voce passou, pra testar mesmo, só na segunda feira cedo

OBRIGADO AE :stuck_out_tongue:
SEGUNAD FEIRA EU RETORNO O RESULTADO DA TUA AJUDA :slight_smile:

http://forums.sun.com/thread.jspa?threadID=548757&start=15
http://accu.org/index.php/journals/285

com base nesses dois links estou tentando fazer testes…
mas nao to conseguindo, nao ta dando certo…
sei la se eu n to conseguindo capturar as ideias e informações dos links
voce pode me ajudar com isso ?

  1. CARREGAR MINHAS CLASSES COM O URLCLASSLOADER CRIADO POR MIN QUE RECONHECE OS JARS
    RECEM COLOCADOS NO DIRETORIO E, ADCIONAR ESTAS NA VARIÁVEL "classes" DO CLASS LOADER ATUAL…

"this.getSystemClassLoader()" … isso eu tentei mas nao deu certo nao.

Field field = ClassLoader.getDeclaredField( "classes" ); field.setAccessible( true ); Vector currClasses =(Vector)field.get( currLoader ); currClasses.add(urlLoader.loadClass("com.google.common.collect.Lists")); field.set( currLoader,currClasses);

eu tento "ClassLoader customLoader = ClassLoader.getSystemClassLoader();
e dai carregar a classe e ele nao carrega

  1. ADICIONAR O MEU URLCLASS LOADER QUE CONSEGUE BUSCAR AS CLASSES… COMO PAI DO SYSTEMCLASSLOADER
    tambem nao deu certo…

[code]public void inject(ClassLoader parent, ClassLoader url )
{
// get the current topmost class loader.
ClassLoader root = parent;
while ( root.getParent() != null )
root = root.getParent();

  if ( root instanceof ClassLoader )
     return;
  try
  {
    // we want root->parent = newRoot;
    java.lang.reflect.Field field =  ClassLoader.class.getDeclaredField("parent");
    field.setAccessible( true );
    field.set( root, url );
  }
  catch ( Exception ex )
  {
    ex.printStackTrace();
    System.out.println( "Could not install   ClassLoadTracer: " + ex );
  }
}[/code]
  1. CRIAR UM CLASSLOADER MEU E SUBSTITUIR A PROPRIEDADE System.getProperty("java.system.class.loader"))
    ainda nao tentei exatamente, ainda nao percebi que métodos eu vo ter que modificar do ClassLoader padrao pra
    ele conseguir ver as classes como o meu URLClassLoader consegue…

Olá jack_utfpr, provavelmente estou tendo o mesmo problema.
http://www.guj.com.br/posts/list/196892.java

Quando tento executar um classe que compilei dinamicamente, surge o erro que determinada dependencia não foi encontrada

O que não entendo é que coloquei o jar “antlr” na lib da aplicação e no classpath do sistema.
Creio que se tivesse uma forma de informar quais os jars que a classe depende no momento da execução, não teria problema.
No meu caso sõ informo qual a classe que quero executar “teste.java”. Como informar os jars dependentes ? ?

   1. URL[] urlsToLoadFrom = new URL[]{new URL("file:" + "/home/mkj/tomcat-6.0.16/bin/")};  
   2.             URLClassLoader loader1 = new URLClassLoader(urlsToLoadFrom);  
   3.             Class d = loader1.loadClass("teste");  
   4.             Method method = d.getMethod("getPLans", new Class[0]);  
   5.             result = method.invoke(new Object(), new Object[0]);  

Caso resolva seu problema poste a solução…grato.

Ola mackj, estou aqui fazendo alguns testes
e reparei que retirando o codigo

if ( root instanceof ClassLoader ) return;

deu certo…
eu adcionei na ierarquia dos loaders meu URLClassLoader que conhece meus jars…
e entao o ClassLoader padrao consegue, através do padrao chain , carregar .

mas will meu bom que tem me ajudado, ainda gostaria de aprender a minha terceira alternativa…
como substituir o ClassLoader padrao pra funcionar, entao nao desista de min pff :roll:

no teu caso mackj, eu dei uma lida sobre colocar as dependencias de um .jar no seu arquivo manifest…
mas eu perdi o link que falava disso certinho…
entao pesquisa ai… sua classe vai ter que estar dentro de um .jar e esse jar vai ter um arquivo manifest que la dentro vai ter as dependencias desse jar.

o link da sun deve ajudar nisso.
GL :wink:
http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html

EDITED -> NAO REPAREM O PORTUGUES -.-

Acho que essa opção 3 não deve funcionar se tu chamar via código o “System.setProperty” e passar o seu class loader para ser o padrão, já que a documentação da jvm explica que uma mudança nessa propriedade só seria efetiva na primeira vez que se tentou carregar a classe do classloader de sistema, então só funcionaria passando essa propriedade na inicialização da JVM via “-Djava.system.class.loader=[seuClassLoader]”, algo que, via Applet, precisa ser feito pelo usuário no lado do browser dele, seguindo os passos do meu post anterior sobre passagem de parâmetros de JVM em Applets.
Resumindo, acho que é trabalho demais por pouca coisa no cenário atual e não me parece tão tosco pedir pro usuário dar refresh na página após a instalação dos 8 mb.

Inté.

pah :stuck_out_tongue:
brigado ae KWill
voce me ajudou bastante…interessante saber que o 3) so funcionaria mesmo como parametro … um dia ainda vou precisar …

sobre o problema…
como eu comentei no ultimo post…
a minha solução

2) ADICIONAR O MEU URLCLASS LOADER QUE CONSEGUE BUSCAR AS CLASSES.. COMO PAI DO SYSTEMCLASSLOADER tambem nao deu certo..

deu certo depois que eu alterei meu código :stuck_out_tongue:
agora mesmo sendo a primeira vez… e os jars acabaram de ser copiados em tempo de execução o ClassLoader consegue carregar as classes :stuck_out_tongue:
muito obrigadao :stuck_out_tongue:

RESOLVIDO