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

Tomcat et TomEE Java Discussion :

Data Source et ClassLoader


Sujet :

Tomcat et TomEE Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 41
    Par défaut Data Source et ClassLoader
    Bonjour à tous,

    J'utilise Tomcat dans une configuration en cluster. Le driver d'accès à la base Oracle est positionné dans common/lib et toutes les applications y ont accès. Une de mes appli souhaiterait utiliser une version différente de ce driver. Pour cela je lui ai demandé de mettre son driver dans son war, pensant qu'il serait chargé en priorité par le classloader, mais en fait pas du tout :-(
    Cette application utilise une datasource définie dans son fichier server.xml.

    Non seulement le driver utilisé n'est pas celui embarqué par l'application mais même quand je supprime celui dans common/lib je prends un NoClassFound exception...

    J'ai relu les règles concernant les classloader dans la doc Tomcat et j'avoue ne pas très bien comprendre. Je pensais que c'était les classes dans WEB-INF/lib qui étaient chargées en priorité (je n'ai pas de delegate à true dans ma conf).

    Comment puis je indiquer dans la conf Tomcat de cette application de privilégier le chargement du driver fourni par l'application ?

    J'espère avoir été clair, merci d'avance pour vos réponses.

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    alors d'abord les drivers, c'est particulier. En effet, tu ne charge jamais directement une connection avec un driver. C'est le driver qui s'enregistre auprès de jdbc. Ensuite quand jdbc recois une string de connection (genre jdbc:oracle:thin:blablabla), il regarde dans tous les drivers enregistrés lequel peut charger la connection. Le classloader n'interviens pas là dedans. Ce qui explique que ton war n'a pas priorité dans ce cas là. En réalité c'est le dernier driver enregistré qui gagne. C'est pour ca qu'il ne faut jamais mettre les driver dans le war. Sinon le war se retrouve enregistré auprès de jdbc et au final, c'est le driver du war 1 qui pourrais se retrouvé utilisé par le war2, bonjour le meli melo .

    Maintenant, le deuxième problème, les datasource gérées par tomcat, elle sont chargée à un niveau server et non pas à un niveau web. Ce qui fait qu'elle n'ont pas accès au classloader de ton war, et donc pas au driver, et donc impossible de charger le driver pour qu'il s'enregistre auprès de jdbc => NoClassDefFound.

    Donc t'as pas le choix, faudra le mettre dans common/lib.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 41
    Par défaut
    Merci pour ta réponse claire et complète.

    Donc si je comprends bien dans une configuration en cluster, toutes les applications sont obligées de partager le même driver, ce dernier devant se trouver dans common/lib. Je trouve ce fonctionnement assez rigide et je suis assez surpris qu'il n'existe aucune solution pour contourner ce problème. Mais bon si c'est comme ça que ça fonctionne !


    Citation Envoyé par tchize_ Voir le message
    alors d'abord les drivers, c'est particulier. En effet, tu ne charge jamais directement une connection avec un driver. C'est le driver qui s'enregistre auprès de jdbc. Ensuite quand jdbc recois une string de connection (genre jdbc:oracle:thin:blablabla), il regarde dans tous les drivers enregistrés lequel peut charger la connection. Le classloader n'interviens pas là dedans. Ce qui explique que ton war n'a pas priorité dans ce cas là. En réalité c'est le dernier driver enregistré qui gagne. C'est pour ca qu'il ne faut jamais mettre les driver dans le war. Sinon le war se retrouve enregistré auprès de jdbc et au final, c'est le driver du war 1 qui pourrais se retrouvé utilisé par le war2, bonjour le meli melo .

    Maintenant, le deuxième problème, les datasource gérées par tomcat, elle sont chargée à un niveau server et non pas à un niveau web. Ce qui fait qu'elle n'ont pas accès au classloader de ton war, et donc pas au driver, et donc impossible de charger le driver pour qu'il s'enregistre auprès de jdbc => NoClassDefFound.

    Donc t'as pas le choix, faudra le mettre dans common/lib.

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    En réalité, je t'ai donné la version simplifiée. Il est possible d'avoir plusieurs drivers pour une même db avec les drivermanager de jdbc. Celui-ci, lorsqu'on lui demande un driver, va toujours regarder quelle classloader est demandeur et va retourner le driver dépendant de ce classloader là. Cependant, ca supposerais, si tu met ton driver dans WEB-INF/lib, que l'appelant est le classloader du WAR. Or, avec tomcat, les ressources du context.xml sont chargées par le classloader du serveur. On pourrais théoriquement donc envisager que d'autres serveur J2EE supporte le modèle "1 driver par war / ear". A chercher. De plus ca pose toujours de problèmes de memory leak de charger ces driver depuis le war.

  5. #5
    Membre Expert
    Avatar de hasalex
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2009
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2009
    Messages : 879
    Par défaut
    Peut-être avec une datasource intégrée avec l'application ? cf. c3p0

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 41
    Par défaut
    J'ai résolu mon problème en modifiant le fichier catalina.properties. Dans ce fichier on configure notamment les répertoires utilisés par chaque classloader. Comme tu le disais la datasource étant défini au niveau server, c'est le classloader Common qui est sollicité pour récupérer la classe du driver (dans common/lib notamment). J'ai finalement rajouté le nouveau driver dans le répertoire CATALINA_BASE/shared/lib de l'appli qui voulait un driver spécifique et j'ai rajouté ce répertoire en tête de liste.

    J'obtiens le résultat souhaité, vois-tu une contre-indication à cette solution ?

  7. #7
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    oui, pourquoi le mettre dans shared lib et modifier profondément le comportement de tomcat alors que common/lib fait le boulot?

    shared/lib est un répertoire supposé contenir des librairies ajoutées à chaque webapp comme si elles étaient dans WEB-INF/lib. Et là t'as fait remonter ce répertoire au niveau de common/lib par ta bidouille!

Discussions similaires

  1. Réponses: 2
    Dernier message: 10/07/2006, 16h10
  2. [DataSource] Data-source SQL Server
    Par Eric Schmitz dans le forum Struts 1
    Réponses: 10
    Dernier message: 28/06/2006, 08h40
  3. Erreur data-source/socket
    Par dali20022 dans le forum Struts 1
    Réponses: 9
    Dernier message: 16/06/2006, 09h12
  4. [Data-sources] Questions de conception
    Par xfacq dans le forum Général Java
    Réponses: 1
    Dernier message: 02/06/2006, 01h32
  5. [WSAD5][DATA SOURCE][MYSQL]
    Par scape dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 02/02/2005, 10h50

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