[java] Sockets, classloader & ClassNotFoundException

Pagina: 1
Acties:

  • Tyf
  • Registratie: December 2002
  • Laatst online: 28-11-2025
Ik zit met een lastig probleem. Ik ben een spel aan het maken en moet op een gegeven moment objecten doorzenden van de server naar de clients via sockets. Het verzenden van "standaard" objecten vormen geen probleem en heel het netwerkgedeelte werkt dus.
Mijn spel heeft een spelbord die bestaat uit vakken. Elke vak wordt ingeladen @runtime op basis van een xml file die verwijst naar de juiste vakken. Dit om het spel makkelijk uitbreidbaar te maken. Bij het opbouwen van het spelbord wordt een vak zijn type ingelezen uit het xml file. bv een afgrond dan wordt dit object @runtime geload via een classloader en gecast naar een vak object.
Dit werkt perfect! Het bordt en alle nodige gegevens worden perfect opgebouwd en weer gegeven. Maar vanaf ik een spelbord wil doorzenden op het netwerk om de clients dit bord te laten ontvangen (het object bord bestaande uit de @runtime geladen vakken) loopt het mis.
Het verzenden is geen probleem maar vanaf een client het spelbord ontvangt en de "stream" wilt omzetten naar het object spelbord loopt het mis. Dan wil deze via (denk ik) een classloader de vakken weer loaden. Hier krijgt hij dan een probleem en krijg ik een ClassNotFoundException. Nu de client heeft (op de dezelfde manier als de server) de nodige class files van de vakken staan. Het probleem is dat de classloader denk ik geen idee heeft waar hij deze moet zoeken.
Ik weet totaal niet hoe ik dit probleem zou moeten oplossen en ben dus op zoek naar hulp :)

de serverkant, hier gaat het goed
code:
1
2
3
4
5
6
7
8
9
10
11
    /**
     * Stuur een spelbord naar alle clients.
     * 
     * @param SpelBord spelbord
     */
    public void stuurSpelbord(SpelBord spelbord){
        ClientServerPakket pakket = new ClientServerPakket();
        pakket.setObj(spelbord);
        pakket.setType(ClientServerPakket.SPELBORD);
        connectie.stuurPakketNaarClient(pakket,null);
    }


client kant hier loopt het mis
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
     * De run() procedure bewaakt de socket voor inkomende objecten.
     * Als er een object binnenkomt wordt dit verpreid over de verschillende peers.
     */
    public void run(){
        try{
            
            while(true){
                try{
                    in = new ObjectInputStream(socket.getInputStream());
                    //hieronder loopt het mis
                    pakket = (ClientServerPakket)(in.readObject());
                }
                catch(java.io.IOException ioe){
                    System.out.println("Socket problemen aan de serverzijde");
                    break;
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                if(pakket != null){
                    model.verdeelOverPeers(pakket);
                }
            }
        }

[ Voor 29% gewijzigd door Tyf op 28-12-2005 11:25 ]


Verwijderd

Het is handig als je de relevante code past hoe jij een 'pakket' in elkaar flanst :) Zijn de objecten die je verstuurt wel serializable? Als dat niet zo is moet je die klasse Serializable laten implementeren.

  • Tyf
  • Registratie: December 2002
  • Laatst online: 28-11-2025
Alles Serializable anders ging het versturen zelf niet gaan.
Packet is niet meer dan het object (spelbord) en een string met die ik op clientside gebruik om de juiste opdracht uit te voeren. Hier is allemaal niks mee. Het is puur de ontvangende kant die zo'n @runtime gemaakte class wilt inlezen en deze niet kent. Ik zoek dus iets waarmee ik kan zeggen als je een class load en je vind hem niet zoek deze dan in deze map.

  • bodiam
  • Registratie: December 2001
  • Laatst online: 31-12-2024
Misschien dat je een eigen classloader kunt maken? Of dat je al je objecten in 1 keer overstuurt, verpakt in een jar ofzo? (Tja, ik zeg ook maar wat...)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:43

Janoz

Moderator Devschuur®

!litemod

Probeer eens te achterhalen wat het type van het object dan wel is.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Serialisatie van java objecten gebeurt alleen op basis van de data binnen de class. De class zelf wordt niet meegestuurd! Als op een server dus een bepaalde object instantie aanwezig is, en je wilt dat de client over deze instantie (waar hij de class ook niet van heeft) beschikking krijgt, dan zul je zowel de class als de inhoud moeten versturen.

De vraag is trouwens of je dit wilt. Ik weet eerlijk gezegd niet wat voor problemen er op gaan treden mbt classloaden. En verder heb je natuurlijk te maken met allerlei veiligheids aspecten (wie garandeerd de client dat hij niet een of andere trojan binnenhaalt). Verder is het vanuit synchronisatie oogpunt vaak handiger om alle state op de server bij te houden (de client state kan mbv incrementele update gesynchroniseerd worden met de server). Maar echte intelligentie zou ik toch centraal op de server houden.

Verder zal er ook een bepaalde gemeenschappelijke basis moeten zijn. Je kunt niet ineens een SchaakVakje naar een client sturen en verwachten dat de client ineens goed met zo`n class om kan gaan. Zo`n class zal toch ergens in een of ander framework achtig iets moeten hangen.

[ Voor 31% gewijzigd door Alarmnummer op 29-12-2005 12:17 ]


  • Tyf
  • Registratie: December 2002
  • Laatst online: 28-11-2025
@Alarmnummer
De clients hebben ook een copy staan van de class van van het object die hij wil inladen. Maar de "interne classloader" die een stream naar het object omzet ken de plaats van die class files niet (zitten in dir ergens).
Nu heb ik het zo opgelost dat ik het bord genereer op client en server tegelijk inplaats van op server en die het dan te laten doorzenden.
Veiligheid is totaal geen probleem hier. Het is een schoolproject waarbij uw programma structuur belangrijkste is.

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 15:32

Robtimus

me Robtimus no like you

Janoz schreef op donderdag 29 december 2005 @ 11:55:
Probeer eens te achterhalen wat het type van het object dan wel is.
Het is geen foute casting, dan zou het een ClassCastException zijn en geen ClassNotFoundException.

Basic vraagje, maar staat je classpath op de client wel goed?

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Tyf
  • Registratie: December 2002
  • Laatst online: 28-11-2025
client en server zijn voorlopig zelfde pc. Ik start client op zelfde pc als server beide op zelfde manier.
Ik heb het nu voorlopig (?) opgelost met het spelbord te laten opbouwen (xml parsen) op server en op client. Ik wou dit infeite op server alleen doen en deze dan het bord laten doorzenden.
Nu dit gaat ook, werkt zelf goed. Zou alleen graag mijn fout bij de vorige oplossing willen oplossen. Al is het puur om de educatieve waarde ervan :p

[ Voor 64% gewijzigd door Tyf op 30-12-2005 10:26 ]

Pagina: 1