WinTricks Forum

WinTricks Forum (http://forum.wintricks.it/index.php)
-   Programmazione (http://forum.wintricks.it/forumdisplay.php?f=21)
-   -   [Java] Classi esterne (http://forum.wintricks.it/showthread.php?t=69443)

Kjow 21-06-2004 13.08.11

[Java] Classi esterne
 
Ciao ragazzi, mi serve il vostro aiuto :)

Devo utilizzare per un'applet una classe esterna che non è presente nei pc-client dove girerà l'applet stessa... ho provato delle soluzioni per far girare il prog, ma l'unica funzionante è stata quella di copiare le classi (contenute in alcuni jar) nella dir lib/ext del jre locale (client).
(In particolare questa applet si collega via soap al server che ha le classi necessarie... sono proprio le classi soap che devo "esportare")

Qualche idea? (oltre quella di far copiare i jar manualmente)

Grazie :)

quipo.it 21-06-2004 16.33.04

non puoi creare degli stub SOAP per le funzioni rilevanti di quelle classi?

Kjow 21-06-2004 16.50.16

Ciao, grazie per la risposta.

Purtroppo non mi sono mai trovato di fronte ad un simile problema e non so usare gli stub. Sto cercando con google degli esempi e dai commenti letti dovrebbe essere in effetti la mia soluzione, ma non riesco a capirne il funzionamento per ora... non è che mi sai indirizzare su qualche esempio e/o farmene uno semplice tu?

Ciao e grazie ancora

quipo.it 21-06-2004 17.41.37

il concetto è abbastanza semplice: gli stub in pratica sono delle interfacce (SOAP, in questo caso) a funzioni esistenti.
Il mio consiglio è quello di vedere alcuni esempi esistenti tipo quello di Amazon. Scarica il developers' kit, ci sono delle implementazioni in vari linguaggi, java compreso. Se hai problemi, posta pure qui.

Ciao

Kjow 21-06-2004 17.56.57

Gli sto dando un'occhiata... ma non è che sia il massimo della comprensibilità (tra l'altro li usano Apache AXIS, io ho Apache SOAP).

Per quanto riguarda le classi "remote" ho intuito che bisogna fare una cosa del tipo un import di java.rmi.RemoteException e nel metodo dove utilizzo soap ("la chiamata esterna") invece che un "throws SOAPException" devo mettere un "throws RemoteException"... ma quasi quasi non credo neanche sia la via giusta e sopratutto non so come fare... sigh :(

quipo.it 21-06-2004 18.21.19

no, quel che ti stavo suggerendo di fare io non è di usare RMI dal client al server, ma di incapsulare le chiamate di funzioni in un'interfaccia soap.

Esempio:

sul server hai tutte le classi di cui hai bisogno, e in particolare la funzione
Codice:

String faiQualcosa(String Nome) {
    return "Ciao " + Nome;
}

che è richiesta dall'applicativo sul client.

Il client, invece di chiamare direttamente faiQualcosa (visto che non ha tale funzione disponibile in locale), la chiama tramite SOAP:

Codice:

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> 
<soap:Body xmlns:m="http://myserver.com/page">
    <m:faiQualcosa>
      <m:Nome>Luca</m:Nome>
    </m:faiQualcosa>
  </soap:Body></soap:Envelope>

Il server traduce questo messaggio in una chiamata alla funzione java, e costruisce una risposta anch'essa in XML, che il client a sua volta decodificherà:

Codice:

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> 
<soap:Body xmlns:m="http://myserver.com/page">
    <m:faiQualcosaResponse>
      <m:Messaggio>Ciao Luca</m:Messaggio>
    </m:faiQualcosaResponse>
  </soap:Body></soap:Envelope>

Ci sono un sacco di funzioni per la creazione e il parsing di questi messaggi SOAP, dai un'occhiata alle API, magari fai una ricerca su Google per Java+SOAP+API.

Ciao :)

Kjow 21-06-2004 18.33.29

io attualmente utilizzo questo metodo nell'applet client e se la macchina client ha il file soap.jar (di apache soap) funziona perfettamente:

Codice:

private String SOK(String SendTxt) throws SOAPException {
                Vector params = new Vector();
                params.addElement(new Parameter("Say", String.class, SendTxt, null));
               
                Call call = new Call();
                call.setTargetObjectURI("urn:CiaoServer"); //RIFERIMENTO ALL' isd:service
                call.setMethodName("sayCiao"); //IL METODO CHE VOGLIO INVOCARE
                call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
               
                call.setParams(params); //IL VETTORE CONTIENE I PARAMETRI DA
                                        //PASSARE AL METODO sayCiao
               
                try {
                        url = new URL(url1); //PASSO LA URL PER RAGGIUNGERE SOAP
                        resp = call.invoke(url,""); //resp CONTERRA' L'ESITO DELLA CHIAMATA
                } catch (MalformedURLException e) {
                        // exception handler code here
                }
               
               
                if(!resp.generatedFault()) {
                        Parameter ret = resp.getReturnValue();
                        System.out.println(ret.getValue());
                        return ret.getValue().toString();
                } else {
                        Fault fault = resp.getFault();
                        System.err.println("--------------------------------");
                        System.err.println("Attenzione: Condizione di Fault");
                        System.err.println("Codice: "+ fault.getFaultCode());
                        System.err.println("Descrizione: "+ fault.getFaultString());
                        System.err.println("--------------------------------");
                        return resp.getFault().toString();
                }
        }

non utilizzo quindi soap "direttamente".

Se invece il client che carica via internet l'applet non ha il soap.jar (e credo anche i relativi activation.jar, mail.jar e xerces.jar) nella console java mi ritrovo con questo errore:

Codice:

java.lang.NoClassDefFoundError: org/apache/soap/SOAPException

        at java.lang.Class.getDeclaredConstructors0(Native Method)
        at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
        at java.lang.Class.getConstructor0(Unknown Source)
        at java.lang.Class.newInstance0(Unknown Source)
        at java.lang.Class.newInstance(Unknown Source)
        at sun.applet.AppletPanel.createApplet(Unknown Source)
        at sun.plugin.AppletViewer.createApplet(Unknown Source)
        at sun.applet.AppletPanel.runLoader(Unknown Source)
        at sun.applet.AppletPanel.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

perchè ovviamente non trova le classi usare dall'applet.
Ricapitolando, quindi se mi copio sul %jre%\lib\ext i jar suddetti tutto funziona correttamente.

Ora mi chiedo... non c'è nessun modo per scaricare in locale questi file o inglobarli in un jar complessivo di tutto (applet + classi esterne)?
Su google ci ho passato settimane a cercare di fare qualche cosa di buono, ma non ho risolto niente :(
Ripeto, le chiamate soap con i jar mi funionano benone, anche via web, ma il client deve avere questi jar...

ciao e grazie

quipo.it 21-06-2004 18.45.52

forse con java web start, ma non ho mai provato.

Però non ho capito il tuo problema... quel jar ti serve per le librerie di SOAP o per altre cose? Perché se non erro sono già incluse nella jre. Cmq puoi anche fare a meno di soap per queste chiamate e usare XML-RPC, più semplice. Se non è già fornito con il linguaggio, scrivere un parser per i messaggi xml è molto semplice...

Per le altre cose, il mio suggerimento era quello di delegarle al server, e il client interroga il server (tramite soap o xml-rpc) quando ne ha bisogno.

Kjow 21-06-2004 18.58.45

Le librerie soap non sono incluse con l'sdk java, ne con il jre. Vanno installate a parte con il relativo server tomcat e grazie a quelle svilupare.
Devo fare così perchè lo impone l'esame che sto preparando, altrimenti andavo di socket e via :p
Il problema però non è tanto soap, ma caricare delle classi e/o dei jar via remoto per quei pc (la maggior parte, se non tutti) sprovvisti di queste classi.

Pensavo ad una cosa tipo mettere le classi esterne nella dir web-inf/lib o cose del genere, ma oltre a non funzionare (anche modificando il manifest del jar che li contiene) non so come utilizzarlo.
Insomma, nel mio caso è soap.jar, ma estendendo il problema poteva essere anche una "miaclasseinventata.jar".
:crying: :)

quipo.it 21-06-2004 19.08.59

boh, allora forse la cosa migliore è proprio usare RMI... se non sbaglio sono trattate in Thinking in Java di Bruce Eckel. Online c'è una versione scaricabile: http://www.mindview.net/Books/TIJ/

Kjow 21-06-2004 21.27.23

Ok grazie lo stesso :)
Vedrò di arrangiarmi.

Kjow 22-06-2004 12.30.45

Scusami di nuovo, ma le RMI/stub come funzionano? Mi sembrano un po' complicate...

tra l'altro mi sembra di aver capito che non posso usare rmi con una classe gli compilata, ma posso solo con delle classi da me create (quindi che ho il sorgente in modo da settare l'RMI server)

o sbaglio? :confused:

quipo.it 22-06-2004 13.30.13

Non esattamente... quel che devi creare tu è uno stub lato server, che a sua volta chiama funzioni presenti sul server (non importa che siano state definite da te o già esistenti). Le funzioni in sé non devi riscriverle/ricompilarle. Pensa allo stub come ad un wrapper intorno a qualcosa di esistente, che traduce le eccezioni in RemoteException e fa da proxy per le funzioni non disponibili sul client.

Due links utili:

http://www.javacoffeebreak.com/artic...i/javarmi.html
http://java.sun.com/docs/books/tutorial/rmi/index.html

realtebo 23-06-2004 13.58.04

ho una idea forse stupida... perchè non provi con un EXE wrapper ? tipo JSmooth, scaricabile gratis da sourceforge.

questo prende la tua classe, prende tutti i jar di cui ha bisogno e all'atto ell'esecuzione il prg trova tutto. certo che gli exe sono per windows . se hai linux non girerà mai

Kjow 23-06-2004 14.06.11

Ragazzi ho risolto ^_^

Era semplicemente necessario lavorare sul tag che lancia l'applet (:eek:)!

Non sapevo della possibilità di caricare più .jar/classi direttamente dal tag html nella jvm locale.

In pratica è sufficiente fare così:

(premesso che "NomeProg" è il class applet da caricare e che sia contenuto nel jar "NomeProg.jar" e che ClasseEsternaX.jar siano le classi aggiuntive esterne)

Codice:

<applet code="NomeProg" ARCHIVE="NomeProg.jar,ClasseEsterna1.jar,ClasseEsterna2.jar,ClasseEsterna3.jar,ClasseEsterna4.jar" width="500" height="400">
Così facendo, quindi, tutti i jar contenuti in ARCHIVE verranno scaricati e posizionati nella JVM locale :)


Byez


Orario GMT +2. Ora sono le: 21.36.08.

vBulletin 3.8.6 - Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.