IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Erreur incompréhensible à la transmission d'un objet via Socket


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 52
    Par défaut Erreur incompréhensible à la transmission d'un objet via Socket
    Bonjour à tous,

    J'ai 2 applications Client/Serveur (donc 2 projets sous eclipse) qui communiquent via Socket TCP/IP.

    Je n'arrive pas à transmettre un objet via le Socket. L'application Client parvient à écrire l'objet dans le Socket, mais l'application Serveur n'arrive pas à lire l'objet reçu.

    L'application Client : TabletRemoteControl.java
    L'application Serveur : XroidMediaPlayer.java
    La classe qui envoi l'objet :JobWriter.java
    La classe qui reçoit l'objet : JobReader.java
    L'objet : XroidJob.java

    Nota : La classe qui définit l'objet figure dans les 2 projets.

    Mes questions :
    1. Pourquoi eclipse me dit qu'il ne trouve pas l'objet XroidJob alors qu'il figure bien dans chaque projet ?
    2. Pourquoi eclipse cherche la classe XroidJob dans com.jBidouille.Tablet.Communication.Job.XroidJob alors qu'on se trouve dans le projet côté serveur (donc Xroid) ?


    Merci d'avance pour vos lumières.


    Voici le LogCat côté Serveur (XroidMediaPlayer.java):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    I/DEBUG(224): [Xroid] <WAIT> JobReader attend l.arrivée d.un nouveau Job
    W/System.err(224): java.lang.ClassNotFoundException: com.jBidouille.Tablet.Communication.Job.XroidJob
    W/System.err(224): 	at java.lang.Class.classForName(Native Method)
    W/System.err(224): 	at java.lang.Class.forName(Class.java:237)
    W/System.err(224): 	at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:2604)
    W/System.err(224): 	at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1860)
    W/System.err(224): 	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:840)
    W/System.err(224): 	at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2080)
    W/System.err(224): 	at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:943)
    W/System.err(224): 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2299)
    W/System.err(224): 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2254)
    W/System.err(224): 	at com.jBidouille.Xroid.Communication.Job.JobReader.run(JobReader.java:64)
    W/System.err(224): 	at java.lang.Thread.run(Thread.java:1096)
    W/System.err(224): Caused by: java.lang.NoClassDefFoundError: com.jBidouille.Tablet.Communication.Job.XroidJob
    W/System.err(224): 	... 11 more
    W/System.err(224): Caused by: java.lang.ClassNotFoundException: com.jBidouille.Tablet.Communication.Job.XroidJob in loader dalvik.system.PathClassLoader@44c07938
    W/System.err(224): 	at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
    W/System.err(224): 	at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
    W/System.err(224): 	at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
    W/System.err(224): 	... 11 more
    I/DEBUG(224): [Xroid] <WAIT> JobReader attend l.arrivée d.un nouveau Job
    W/System.err(224): java.io.OptionalDataException
    W/System.err(224): 	at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:966)
    W/System.err(224): 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2299)
    W/System.err(224): 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2254)
    W/System.err(224): 	at com.jBidouille.Xroid.Communication.Job.JobReader.run(JobReader.java:64)
    W/System.err(224): 	at java.lang.Thread.run(Thread.java:1096)
    I/DEBUG(224): [Xroid] <ERR> JobReader détecte que Tablet n.écoute plus sur InputStream mais ne lève pas d.événement
    I/DEBUG(224): [Xroid] <WAIT> JobReader attend l.arrivée d.un nouveau Job
    W/System.err(224): java.io.OptionalDataException
    W/System.err(224): 	at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:966)
    W/System.err(224): 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2299)
    W/System.err(224): 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2254)
    W/System.err(224): 	at com.jBidouille.Xroid.Communication.Job.JobReader.run(JobReader.java:64)
    W/System.err(224): 	at java.lang.Thread.run(Thread.java:1096)
    I/DEBUG(224): [Xroid] <ERR> JobReader détecte que Tablet n.écoute plus sur InputStream mais ne lève pas d.événement
    I/DEBUG(224): [Xroid] <WAIT> JobReader attend l.arrivée d.un nouveau Job
    Voici la classe côté Client (Tablet) qui envoi l'objet XroidJob (JobWriter.java) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    package com.jBidouille.Tablet.Communication.Job;
     
    import java.io.IOException;
    import java.io.ObjectOutputStream;
     
    public class JobWriter implements Runnable{
     
    	private ObjectOutputStream outputStream;
    	private XroidJob writerMessage;
    	private Boolean isMessageReady = false;
    	private volatile Thread currentThread = null;		
     
    	public JobWriter(ObjectOutputStream out) {
    		this.outputStream = out;
    	}
     
    	public void doStop(){
    		currentThread.interrupt();
    	}
     
    	public void setMessage (XroidJob job){
     
    		if (job != null) {
    			writerMessage = job;
    			this.isMessageReady = true;
    		}
     
    	}
     
    	public void run() {
     
    		currentThread = Thread.currentThread();	
     
    		try{
     
    			while(!currentThread.isInterrupted()){
     
    				if (this.isMessageReady){
     
    					try {
     
    						outputStream.writeObject(writerMessage);
    						outputStream.flush();	
     
    					} catch (IOException e) {
    						e.printStackTrace();
    					}	
     
    					this.isMessageReady = false;
     
    				}
     
    				Thread.sleep(1000);
    			}
     
    		} catch (InterruptedException e){
    			e.printStackTrace();
    		}	
     
    		try {
    			outputStream.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}		
     
    	}	
     
    }
    Voici la classe côté Serveur (Xroid) qui récupère l'objet XroidJob (JobReader.java) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    package com.jBidouille.Xroid.Communication.Job;
     
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import android.util.Log;
     
    public class JobReader implements Runnable{
     
    	ObjectInputStream inputStream;
    	private XroidJob readerMessage;
    	private volatile Thread currentThread = null;
     
    	public JobReader(ObjectInputStream in){
    		this.inputStream = in;
    	}
     
    	public void doStop(){
    		currentThread.interrupt();
    	}
     
    	public void run() {
     
    		currentThread = Thread.currentThread();
     
    		try{
     
    			while(!currentThread.isInterrupted()){
     
    				try {
     
    					Log.i("DEBUG", "[Xroid] <WAIT> JobReader attend l'arrivée d'un nouveau Job");				
     
    					readerMessage = (XroidJob)inputStream.readObject();
     
    					Log.i("DEBUG", "[Xroid] JobReader a reçu le Job ID " + readerMessage.getJobID());
     
    			    } catch (IOException e) {
     
    			    	e.printStackTrace();
     
    			    	Log.i("DEBUG", "[Xroid] <ERR> JobReader détecte que Tablet n'écoute plus sur InputStream mais ne lève pas d'événement");		
     
    				} catch (ClassNotFoundException e) {
    					e.printStackTrace();
    				}
     
    				Thread.sleep(1000);
    			}
     
    		} catch (InterruptedException e){
    			e.printStackTrace();
    		}
     
    		try {
    			inputStream.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
     
    	}	
     
    }
    Le fameux objet côté Serveur (Xroid) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.jBidouille.Xroid.Communication.Job;
     
    import java.io.Serializable;
    import java.util.UUID;
     
    public class XroidJob implements Serializable{
     
    	private String jobID;
    	private int[] playList; 
    	private Boolean isRandom;
    	private Boolean isLooping;
     
    	public XroidJob(){
     
    		jobID = UUID.randomUUID().toString();
    	}
    ...
     
    }
    Le fameux objet côté Client (Tablet) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.jBidouille.Tablet.Communication.Job;
     
    import java.io.Serializable;
    import java.util.UUID;
     
    public class XroidJob implements Serializable{
     
    	private String jobID;
    	private int[] playList; 
    	private Boolean isRandom;
    	private Boolean isLooping;
     
    	public XroidJob(){
     
    		jobID = UUID.randomUUID().toString();
    	}
    ...
     
    }

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Comme je l'ai déjà dit, les deux projets doivent avoir la même classe, qui vient d'un seul et unique fichier .java
    Ça ne marche pas en utilisant deux classes de même nom.

    Pour le dire autrement, tu as besoin d'une bibliothèque partagée qui fournit les classes en question, et que ton serveur et ton client utilisent tous les deux.

    Pourquoi eclipse cherche la classe XroidJob dans com.jBidouille.Tablet.Communication.Job.XroidJob alors qu'on se trouve dans le projet côté serveur (donc Xroid) ?
    Eclipse ne décide pas, il ne fait que lancer ton programme, pour le reste c'est ton programme qui s'en occupe.
    En l'occurence, la sérialisation a généré un objet qui se trouve dans com.jBidouille.Tablet.Communication.Job.XroidJob, alors la désérialisation essaie de construire un objet com.jBidouille.Tablet.Communication.Job.XroidJob.

    Les packages ne sont pas là pour faire joli, ce sont des espaces de nom.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 52
    Par défaut
    Donc si je comprend bien :
    1. Je dois créer un unique JAR dans le quel j'intègre toutes les classes échangées entre Client et Serveur
    2. Je fais référencer chaque projet sur cette librairie externe ?


    Si c'est bien ça, j'essaye et vous dit si ok/pas ok !

    Merci.

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par elmaestro Voir le message
    1. Je dois créer un unique JAR dans le quel j'intègre toutes les classes échangées entre Client et Serveur
    2. Je fais référencer chaque projet sur cette librairie externe ?
    C'est en effet plus propre et plus "sûr" (en cela que ça évite l'erreur humaine) de faire comme cela.

    Après, la réalité, c'est qu'il suffirait de partager juste les fichiers .class correspondants dans les deux projets, ou même juste d'avoir le même fichier .java (mais exactement le même fichier .java : même nom même contenu, même taille, mêmes octets. L'un étant obtenu en copiant/collant l'autre, à chaque changement.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    une remarque très secondaire: évite de donner des noms de package avec des majuscules. Ce n'est pas au standard de nommage et , du coup, on a l'impression en lisant ta trace qu'on a affaire à une cascade de classes internes.

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 52
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    une remarque très secondaire: évite de donner des noms de package avec des majuscules. Ce n'est pas au standard de nommage et , du coup, on a l'impression en lisant ta trace qu'on a affaire à une cascade de classes internes.
    Ok la règle de nommage professeur shadoko.

    Citation Envoyé par thelvin Voir le message
    Après, la réalité, c'est qu'il suffirait de partager juste les fichiers .class correspondants dans les deux projets, ou même juste d'avoir le même fichier .java (mais exactement le même fichier .java : même nom même contenu, même taille, mêmes octets. L'un étant obtenu en copiant/collant l'autre, à chaque changement.)
    Pour aller vite et valider le principe, j'ai copier/coller le même .java avec le même nom de domaine dans chaque projet, et tout fonctionne parfaitement.

    J'essayerai plus tard de tout packager dans un JAR, histoire de faire plus propre.

    Grand merci à tous pour vos lumières.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Envoyer un Objet via Socket
    Par t4rik9 dans le forum Langage
    Réponses: 3
    Dernier message: 17/11/2014, 02h03
  2. Passage d'objet via socket
    Par kranagard dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 26/01/2014, 18h00
  3. Envoyer un objet via Socket UDP
    Par lastico21000 dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 11/02/2012, 14h58
  4. Transmission d'une ArrayList via Socket
    Par Illuminati dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 26/11/2010, 14h44
  5. Transfert d'objet via sockets
    Par benjamin-mermoz dans le forum Windows Forms
    Réponses: 5
    Dernier message: 11/12/2008, 21h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo