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

Wildfly/JBoss Java Discussion :

appel d'un remote ejb stateless qui n'a pas le comportement attendu


Sujet :

Wildfly/JBoss Java

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    728
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 728
    Points : 250
    Points
    250
    Par défaut appel d'un remote ejb stateless qui n'a pas le comportement attendu
    Bonjour,

    je travaille sous eclipse LUNA et ai créé un projet Entreprise Application Project. J'ai ajouté un serveur JBOSS eap 6.2

    Voici la structure de mon projet

    Nom : Forum_Projet_EJB_2014-09-27_à_17.54.04.png
Affichages : 548
Taille : 86,4 Ko


    J'ai créé un remote EJB stateless dans le module EJBTutorialEJB

    LibrarySessionBeanRemote.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
     
    package com.tutorialspoint.sessionbean.stateless;
     
    import java.util.List;
     
    import javax.ejb.Remote;
     
    @Remote
    public interface LibrarySessionBeanRemote {
     
    	void addBook(String bookname);
     
    	List<String> getBooks();
    }
    LibrarySessionBean.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
     
    package com.tutorialspoint.sessionbean.stateless;
     
    import java.util.ArrayList;
    import java.util.List;
     
    import javax.ejb.Stateless;
     
    /**
     * Session Bean implementation class LibrarySessionBean
     */
    @Stateless
    public class LibrarySessionBean implements LibrarySessionBeanRemote {
     
    	private List<String> bookShelf;
     
    	/**
             * Default constructor.
             */
    	public LibrarySessionBean() {
    		// TODO Auto-generated constructor stub
    		bookShelf = new ArrayList<String>();
    	}
     
    	public void addBook(String bookname) {
    		bookShelf.add(bookname);
    	}
     
    	public List<String> getBooks() {
    		return bookShelf;
    	}
     
    }
    Dans le module EJBTutorialClient, j'ai une classe main qui appelle cet EJB remote stateless

    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.List;
    import java.util.Properties;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    import com.tutorialspoint.sessionbean.stateless.LibrarySessionBeanRemote;
    
    public class Main {
    
    	BufferedReader brConsoleReader = null;
    	Properties jndiProperties = new Properties();
    	Context ctx = null;
    
    	public void initializeStandardJNDIContext() {
    		// Context.URL_PKG_PREFIXES = "java.naming.factory.url.pkgs"
    		jndiProperties.put(Context.URL_PKG_PREFIXES,"org.jboss.ejb.client.naming");
    		// Context.INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial"
    		jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");
    		// Context.PROVIDER_URL = "java.naming.provider.url"
    		jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
    		jndiProperties.put("jboss.naming.client.ejb.context", true);
    		try {
    			ctx = new InitialContext(jndiProperties);
    		} catch (NamingException ex) {
    			ex.printStackTrace();
    		}
    	}
    
    
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Main ejbTester = new Main();
    
    		ejbTester.initializeStandardJNDIContext();
    		ejbTester.testStatelessEjb();
    	}
    
    
    
    	/*
    	 * (non-Java-doc)
    	 *
    	 * @see java.lang.Object#Object()
    	 */
    	public Main() {
    		super();
    		brConsoleReader = new BufferedReader(new InputStreamReader(System.in));
    	}
    
    	private void showGUI() {
    		System.out.println("**********************");
    		System.out.println("Welcome to Book Store");
    		System.out.println("**********************");
    		System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
    	}
    
    	private void testStatelessEjb() {
    		try {
    			int choice = 1;
    			String viewClassName = LibrarySessionBeanRemote.class.getName();
    			LibrarySessionBeanRemote libraryBean = (LibrarySessionBeanRemote) ctx.lookup("EJBTutorial/EJBTutorialEJB//LibrarySessionBean!"+ viewClassName);
    			while (choice != 2) {
    				String bookName;
    				showGUI();
    				String strChoice = brConsoleReader.readLine();
    				choice = Integer.parseInt(strChoice);
    				if (choice == 1) {
    					System.out.print("Enter book name: ");
    					bookName = brConsoleReader.readLine();
    					libraryBean.addBook(bookName);
    				} else if (choice == 2) {
    					break;
    				}
    			}
    			List<String> booksList = libraryBean.getBooks();
    			System.out.println("Book(s) entered so far: " + booksList.size());
    			for (int i = 0; i < booksList.size(); ++i) {
    				System.out.println((i + 1) + ". " + booksList.get(i));
    			}
    
    			LibrarySessionBeanRemote libraryBean1 = (LibrarySessionBeanRemote) ctx
    					.lookup("EJBTutorial/EJBTutorialEJB//LibrarySessionBean!"
    							+ viewClassName);
    			List<String> booksList1 = libraryBean1.getBooks();
    			System.out.println("***Using second lookup to get library stateless object***");
    			System.out.println("Book(s) entered so far: " + booksList1.size());
    			for (int i = 0; i < booksList1.size(); ++i) {
    				System.out.println((i + 1) + ". " + booksList1.get(i));
    			}
    		} catch (Exception e) {
    			System.out.println(e.getMessage());
    			e.printStackTrace();
    		} finally {
    			try {
    				if (brConsoleReader != null) {
    					brConsoleReader.close();
    				}
    				ctx.close();
    			} catch (IOException | NamingException ex) {
    				System.out.println(ex.getMessage());
    			}
    		}
    
    	}
    
    }
    Quand Je fais un "run as Java Application" sur la classe Main, il y a plusieurs comportement innatendu

    Voici ce qu'il y a en console

    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
     
    INFO: JBoss EJB Client version 1.0.24.Final-redhat-1
    **********************
    Welcome to Book Store
    **********************
    Options 
    1. Add Book
    2. Exit 
    Enter Choice: 1
    Enter book name: La source et le delta
    **********************
    Welcome to Book Store
    **********************
    Options 
    1. Add Book
    2. Exit 
    Enter Choice: 1
    Enter book name: Struts
    **********************
    Welcome to Book Store
    **********************
    Options 
    1. Add Book
    2. Exit 
    Enter Choice: 2
    Book(s) entered so far: 2
    1. La source et le delta
    2. Struts
    ***Using second lookup to get library stateless object***
    Book(s) entered so far: 2
    1. La source et le delta
    2. Struts
    sept. 27, 2014 6:04:26 PM org.jboss.naming.remote.protocol.v1.RemoteNamingStoreV1$MessageReceiver handleEnd
    ERROR: Channel end notification received, closing channel Channel ID 8d6f21a9 (outbound) of Remoting connection 65694ee6 to localhost/127.0.0.1:4447
    sept. 27, 2014 6:04:26 PM org.jboss.ejb.client.remoting.ChannelAssociation$ResponseReceiver handleEnd
    INFO: EJBCLIENT000016: Channel Channel ID a531a3da (outbound) of Remoting connection 65694ee6 to localhost/127.0.0.1:4447 can no longer process messages
    sept. 27, 2014 6:04:26 PM org.jboss.remoting3.spi.SpiUtils safeHandleClose
    ERROR: Close handler threw an exception
    java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@241f0670 rejected from java.util.concurrent.ThreadPoolExecutor@70dfb596[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]
    1) premièrement je rentre 2 livres: "La source et le delta" et "Struts"
    Quand je choisis Exit ensuite il y a un comportement attendu au départ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Book(s) entered so far: 2
    1. La source et le delta
    2. Struts
    Jusqu'ici, tout va bien
    Seulement après, il m'affiche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ***Using second lookup to get library stateless object***
    Book(s) entered so far: 2
    1. La source et le delta
    2. Struts
    Et là ça ne va pas car cette liste est obtenu à l'aide d'un nouveau lookup (LibrarySessionBeanRemote libraryBean1 = (LibrarySessionBeanRemote) ctx.lookup("EJBTutorial/EJBTutorialEJB//LibrarySessionBean!"+ viewClassName)

    Comme j'ai un stateless remote Bean, la liste des 2 livre que j'ai rentré auparavant ne devrait pas être stocké et retrouvé avec ce nouveau lookup. J'en profite pour vous demander la chose suivante (à mon avis je dirais oui): est-ce que quand on fait un lookup, cela crée une nouvelle session ?

    2) deuxièmement: quand j'essaye de fermer mon context (en bleu à la fin de ma classe main), il y a l'erreur suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    sept. 27, 2014 6:04:26 PM org.jboss.naming.remote.protocol.v1.RemoteNamingStoreV1$MessageReceiver handleEnd
    ERROR: Channel end notification received, closing channel Channel ID 8d6f21a9 (outbound) of Remoting connection 65694ee6 to localhost/127.0.0.1:4447
    Je ne comprends pas quelle est l'erreur.


    Merci d'avance pour vos réponses
    Images attachées Images attachées  

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Le context est une ressource gérée par le serveur, tu n'as pas besoin de le fermer.

    Pour ton problème de session bean, il ne faut pas utiliser de variable d'instance. Ton serveur d'application crée un pool d'ejb qui sont réutilisés en fonction des besoins, pour ne pas avoir à en créer un nouveau à chaque fois.

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    728
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 728
    Points : 250
    Points
    250
    Par défaut
    Bonjour fr1man et merci pour ta réponse

    Je ne suis pas le seul à avoir utilisé cette méthode. En fait j'essaye de refaire le tutoriel à l'adresse suivante:
    http://www.tutorialspoint.com/ejb/ej...pplication.htm

    Le context est une ressource gérée par le serveur, tu n'as pas besoin de le fermer.
    Tu veux dire que mon client ne peux pas fermer un contexte car cela est réservé au container JBoss ?

    Pour ton problème de session bean, il ne faut pas utiliser de variable d'instance.
    Et pourquoi pas ? un stateless bean peut avoir un attribut

    Ton serveur d'application crée un pool d'ejb qui sont réutilisés en fonction des besoins, pour ne pas avoir à en créer un nouveau à chaque fois.
    Je suis d'acord avec ce que tu dis, mais un client EJB doit quand même faire un lookup pour récupérer un des EJB session dans le pool

    En fait je me demande si il n'y a pas un seul session bean créé dans le pool que le client redemande à chaque fois

  4. #4
    Membre habitué
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

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

    Informations forums :
    Inscription : Novembre 2008
    Messages : 88
    Points : 154
    Points
    154
    Par défaut
    Comme j'ai un stateless remote Bean, la liste des 2 livre que j'ai rentré auparavant ne devrait pas être stocké et retrouvé avec ce nouveau lookup. J'en profite pour vous demander la chose suivante (à mon avis je dirais oui): est-ce que quand on fait un lookup, cela crée une nouvelle session ?
    Je répond par la définition du site: A stateless session bean as per its name does not have any associated client state, but it may preserve its instance state. EJB Container normally creates a pool of few stateless bean's objects and use these objects to process client's request.

    Un stateless session bean n'est pas lié à la session utilisateur et donc n'a pas à être détruit ou recréé à chaque connexion et déconnection d'un utilisateur. Une même instance peut être réutilisée par un nombre infini d'utilisateurs, jusqu'au redémarrage du serveur qui va les recréer à nouveau et donc perdre leus états.
    Il est utile pour gérer les accès concurrent à la base de donnée car il n'a pas à être recréé à chaque nouvelle session d'utilisateur ou Lookup et il prend peut de mémoire.

    Un Statefull sesion bean doit être recréé pour chaque nouvelle session, ainsi chaque utilisateur est associé à son propre Statefull Session bean, c'est utilise par exemple pour gérér la connexion des utilisateur à un site web.

    Quand le serveur utilise un pool de taille 2 ou plus, lors du lookup pour un stateless bean on n'est pas sûr de l'instance obtenue et de l'état des variables d'instance.
    Dans ton cas, je pense que le serveur utilise un pool de taille 1 donc il ne crée qu'une seule instance pour chaque session bean.

    Tu veux dire que mon client ne peux pas fermer un contexte car cela est réservé au container JBoss ?
    Evidemment, un context est géré par le serveur d'application, tu ne fait qu'obtenir une référence vers ce contexte à travers JNDI.
    L'objectif des serveurs d'application et de EJB en particulier et de concentrer le programmeur dans sa tâche d'implémenter la logique métier sans ce préoccuper d'instancier ou de fermer ou de supprimer les composants JEE.

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    728
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 728
    Points : 250
    Points
    250
    Par défaut
    Merci pour ta réponse velocity, c'est clair

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 09/10/2014, 18h53
  2. Réponses: 2
    Dernier message: 27/09/2013, 09h40
  3. [EJB3] Un Ejb Stateless qui se comporte comme unEjb Stateful
    Par clem_alain dans le forum Java EE
    Réponses: 5
    Dernier message: 04/02/2011, 12h00
  4. [EJB] Les méthodes des ejb stateless ne s'exécutent pas
    Par methodman225 dans le forum Java EE
    Réponses: 3
    Dernier message: 04/08/2010, 11h52
  5. [MySQL] requête qui n'insère pas les valeurs attendues
    Par mimi83 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 12/06/2008, 03h07

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