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

Java Discussion :

Problème avec OpenJDK


Sujet :

Java

  1. #21
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 472
    Par défaut
    Citation Envoyé par hwoarang Voir le message
    Est ce que tu peux poster le code de memory.lecteur.LecteurMP3 qui apparaissent dans les traces ?
    En particulier les lignes qui posent probleme et l'initialisation des classes utilisées sur ces lignes ?
    Est-ce que je viens de poster suffit ? Je peux aussi mettre toute la classe. Ce projet utilise beaucoup le projet javazoom et tritonus. cependant vu les problèmes que j'ai rencontré j'ai récupéré toutes les sources de ces deux projets et garder seulement les classes nécessaires.

    Citation Envoyé par joel.drigo Voir le message
    La classe memory.lecteur.LecteurMP3 est bien une classe à toi ?

    On voit que l'appel de la méthode stop de org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLine appelée par ta méthode memory.lecteur.LecteurMP3.pausePlayback() est en deadlock avec l'appel de write de la classe org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLin appelée par run() de ta classe memory.lecteur.LecteurMP3.run(LecteurMP3.java:636).

    Les objets sur lesquels on a le synchrinized qui cause le deadlock sont l'instance de org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLine et une instance d'Object.
    Où se trouvent les indications qui permettent de comprendre que c'est la méthode stop qui est en cause ? J' avais bien trouvé que c'était la méthode run() et en particulier semble-t'il la ligne : this.sortieSon.write(abData, 0, nBytesRead);
    qui posait problème mais je n'avais pas vu le problème de la méthode stop().

  2. #22
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Le problème vient probablement de synchronized (this.audioInputStream). Je suppose qu'il s'agit d'une instance de org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLin

    Citation Envoyé par Patrice Henrio Voir le message
    Où se trouvent les indications qui permettent de comprendre que c'est la méthode stop qui est en cause ?
    Found one Java-level deadlock:
    =============================
    "Lecteur MP3":
      waiting to lock monitor 0x8b00b218 (object 0xa934cae8, a org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLine),
      which is held by "AWT-EventQueue-0"
    "AWT-EventQueue-0":
      waiting to lock monitor 0x8b00a534 (object 0x93c39970, a java.lang.Object),
      which is held by "Lecteur MP3"
     
    Java stack information for the threads listed above:
    ===================================================
    "Lecteur MP3":
    	at org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLine.write(PulseAudioSourceDataLine.java:183)
    	- waiting to lock <0xa934cae8> (a org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLine)
    	- locked <0x93c39970> (a java.lang.Object)
    	at memory.lecteur.LecteurMP3.run(LecteurMP3.java:636)
    	- locked <0xa921fa98> (a memory.lecteur.javazoom.spi.mpeg.sampled.convert.DecodedMpegAudioInputStream)
    	at java.lang.Thread.run(Thread.java:724)
    "AWT-EventQueue-0":
    	at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.stop(PulseAudioDataLine.java:386)
    	- waiting to lock <0x93c39970> (a java.lang.Object)
    	- locked <0xa934cae8> (a org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLine)
    	at org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLine.stop(PulseAudioSourceDataLine.java:51)
    	at memory.lecteur.LecteurMP3.pausePlayback(LecteurMP3.java:381)
    	at memory.lecteur.LecteurMP3.pause(LecteurMP3.java:841)
    	at memory.chants.JLecteurMP3.pauseChant(JLecteurMP3.java:409)
    	at memory.chants.JLecteurMP3.actionPerformed(JLecteurMP3.java:336)
    	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    
    ...
    
    Found 1 deadlock.
    
    Ce n'est pas les méthode stop() ou write() qui sont en cause, ce sont tes méthodes pausePlayback() et run() qui le sont, dans la manière d'appeler les méthodes de PulseAudioSourceDataLine et synchroniser sur l'instance de cette classe.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #23
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Et "sortieSon" ? Il est initialisé comment ?

    Pour préciser, meme si on ne peut pas écarter un bug du jdk, il est plus probable que tu appelles des fonctions dans un ordre ou de maniere non prévue (par exemple dans un thread particulier ou bien dans un mauvais état).

  4. #24
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 472
    Par défaut
    Citation Envoyé par hwoarang Voir le message
    Et "sortieSon" ? Il est initialisé comment ?

    Pour préciser, meme si on ne peut pas écarter un bug du jdk, il est plus probable que tu appelles des fonctions dans un ordre ou de maniere non prévue (par exemple dans un thread particulier ou bien dans un mauvais état).
    Voici l'initialisation de la sortie son
    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
     
    	/**
             * Créer la sortie son
             * @throws LineUnavailableException les erreurs sur la sortie son
             */
    	private void createLine() throws LineUnavailableException
    	{
    		if (this.sortieSon == null)
    		{
    			// récupérer le format de la source
    			AudioFormat sourceFormat = this.audioInputStream.getFormat();
     
    			// pour les fichiers MP3 choisis nSampleSizeInBits = 16;
    			AudioFormat targetFormat = new AudioFormat(
    					AudioFormat.Encoding.PCM_SIGNED,
    					sourceFormat.getSampleRate(), 16,
    					sourceFormat.getChannels(),
    					2 * sourceFormat.getChannels(),
    					sourceFormat.getSampleRate(), false);
    			// garder une référence sur le flux audio pour la progression de la
    			// lecture
    			// encodedAudioInputStream est le format encodé de départ (IO)
    			// audioInputStream sera le format décodé (système audio)
    			this.encodedAudioInputStream = this.audioInputStream;
    			// Créer le flux décodé
    			// this.audioInputStream =
    			// AudioSystem.getAudioInputStream(targetFormat,
    			// this.audioInputStream);
    			MpegFormatConversionProvider mfcp = new MpegFormatConversionProvider();
    			this.audioInputStream = mfcp.getAudioInputStream(targetFormat,
    					this.audioInputStream);
     
    			// this.audioInputStream = getAudioInputStream();
    			//
    			// if (this.url != null) initAudioInputStream(url);
    			// else if (this.source != null) initAudioInputStream(this.source);
    			// else if (this.inputStream != null)
    			// initAudioInputStream(inputStream);
    			//
    			// this.audioInputStream = lecteur.getAudioInputStream(targetFormat,
    			// this.audioInputStream);
    			// récupérer le format décodé
    			AudioFormat audioFormat = this.audioInputStream.getFormat();
    			// Informer la sortie son
    			DataLine.Info info = new DataLine.Info(SourceDataLine.class,
    					audioFormat, AudioSystem.NOT_SPECIFIED);
    			this.sortieSon = (SourceDataLine) AudioSystem.getLine(info);
    		}
    	}
    avec la déclaration de la sortieSon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // la sortie son (AudioSystem)
    	private SourceDataLine				sortieSon;
    Sous sunJDK SourceDataLine renvoie à
    public interface SourceDataLine extends DataLine du package package javax.sound.sampled;

    Par contre sous openJDK il ne trouve pas la source (je n'ai pas réussi à localiser les sources ni de icedtea ni de openJDK ... ce qui est quand même un comble pour un paquetage qui n'existe que parce que sunJDK est considéré comme non libre).

  5. #25
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 472
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Le problème vient probablement de synchronized (this.audioInputStream). Je suppose qu'il s'agit d'une instance de org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLin

    Ce n'est pas les méthode stop() ou write() qui sont en cause, ce sont tes méthodes pausePlayback() et run() qui le sont, dans la manière d'appeler les méthodes de PulseAudioSourceDataLine et synchroniser sur l'instance de cette classe.
    pour sunJDK
    audioInputStream est une instance de
    public class AudioInputStream extends InputStream
    du package package javax.sound.sampled;

    pareil pour openJDK sauf que je n'ai pas accès aux sources ... comme expliqué précédemment.

  6. #26
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 472
    Par défaut
    J'ai fini par trouver où se cachaient les sources de openJDK. Je vais pouvoir aller plus loin dans ma recherche.

  7. #27
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 472
    Par défaut
    Comme on me l'a signalé, le problème vient surement de l'ordre de déclenchement des méthodes et aussi d'un problème se synchronized.

    J'ai un attribut de la classe LecteurMP3 qui est un Thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	private Thread						thread					= null;
    Lorsque je démarre un chant, si le lecteur est à l'arrêt je réinitialise le flux audio d'entrée.
    Ensuite je vérifie que le lecteur est en lecture.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	private void startPlayback() throws LecteurException
    	{
    		if (this.etat == LecteurEvent.STOPPED) initAudioInputStream();
    		if (this.etat == LecteurEvent.OPENED)
    		{
    .../...
    		}
    	}
    Ensuite je regarde si le thread est "vivant"
    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
     
    // ATTENTION : le thread précédent est peut-être encore en lecture
    if ((this.thread != null) && (this.thread.isAlive()))
    {
    	int cnt = 0;
    	while (this.etat != LecteurEvent.OPENED)
    	{
    		try
    		{
    			if (this.thread != null)
    			{
    				cnt++;
    				Thread.sleep(1000);
    				if (cnt > 2) this.thread.interrupt();
    			}
    		}
    		catch (InterruptedException e)
    		{
    			throw new LecteurException(LecteurException.WAITERROR,e);
    		}
    	}
    }
    Une fois que je suis sûr que le thread a fini de travailler, j'initialise la ligne son, le thread
    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
     
    	try
    	{
    		initLine();
    	}
    	catch (LineUnavailableException e)
    	{
    		throw new LecteurException(LecteurException.CANNOTINITLINE, e);
    	}
    	this.thread = new Thread(this, "Lecteur MP3");
    	this.thread.start();
     
    	if (this.sortieSon != null)
    	{
    		this.sortieSon.start();
    		this.etat = LecteurEvent.PLAYING;
    	}
    J'ai l'impression que je ne fais ce qu'il faut déjà dans cette méthode. la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.thread = new Thread(this, "Lecteur MP3");
    est-elle nécessaire ?

  8. #28
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 472
    Par défaut
    Bon j'ai trouvé comment contourner le problème (mais pas pourquoi le problème existe sous OpenJDK et pas sous SunJDK).
    Pour utiliser l'audio sous Java il faut recueillir les fournisseurs de tables de mixage de la machine java installée. La méthode qui permet de les récupérer est la même il s'agit de
    AudioSystem.getMixerProviders()

    Sous OpenJDK cette méthode getMixerProviders() renvoie
    org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider
    com.sun.media.sound.DirectAudioDeviceProvider
    com.sun.media.sound.PortMixerProvider

    Sous SunJDK cette même méthode renvoie
    com.sun.media.sound.DirectAudioDeviceProvider
    com.sun.media.sound.PortMixerProvide

    Comme on renvoie le premier fournisseur de table de mixage adapté, sous OpenJDK on récupère PulseAudioMixerProvider qui semble ne pas gérer de la même façon que le suivant les sources MP3.
    Il suffit de créer une version perso de AudioSystem.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. VC++ Direct3D8, problème avec LPD3DXFONT et LPD3DTEXTURE8
    Par Magus (Dave) dans le forum DirectX
    Réponses: 3
    Dernier message: 03/08/2002, 12h10
  2. Problème avec [b]struct[/b]
    Par Bouziane Abderraouf dans le forum CORBA
    Réponses: 2
    Dernier message: 17/07/2002, 11h25
  3. Problème avec le type 'Corba::Any_out'
    Par Steven dans le forum CORBA
    Réponses: 2
    Dernier message: 14/07/2002, 19h48
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 17h10

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