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

Maven Java Discussion :

Maven théorie et pratique


Sujet :

Maven Java

  1. #1
    Membre chevronné
    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 : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut Maven théorie et pratique
    Bonjour,

    Je travaille dans un très gros projet avec énormément de modules, hiérarchisés avec des dépendances héritées... Tout ça manipulé par des tas de gens répartis d'un bout du monde à l'autre, donc c'est un contexte assez complexe.

    Je développe avec IntelliJ en court-circuitant tout ce qui est Maven et en laissant les autres se débrouiller. Ce n'est pas bien me direz-vous (même si ça marche).

    Situation théorique:
    - soit une librairie A en version 1.1
    - un Module M dépend de A 1.1
    - mon code dépend de M mais veut utiliser des nouveautés de A 1.2

    Quelqu'un saurait-il m'indiquer ce que je peux mettre dans mes dépendances M et A1.2 ?
    Avec le degré de complexité de nos dépendances, ceci ne fonctionne pas ! C'est encore plus "amusant" s'il n'y a pas compatibilité ascendante entre A 1.1 et A 1.2, Hibernate en l'occurrence.

    Autre difficulté, à l'exécution je n'ai pas le même ordre de dépendances de librairies entre les exécutions avec Maven ou sans Maven -> la recherche de Ressources ne donne donc pas le même résultat !

    Merci d'avance pour votre aide.
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    Situation théorique:
    - soit une librairie A en version 1.1
    - un Module M dépend de A 1.1
    - mon code dépend de M mais veut utiliser en propre des nouveautés de A 1.2

    Je mets quoi dans mes dépendances: M et A1.2 ? ....
    Oui, la librairies en 1.2 que tu définis dans ton pom a priorité sur la dépendance héritée de M

    Citation Envoyé par professeur shadoko Voir le message
    Avec le degré de complexité de nos dépendances ceci ne fonctionne pas ! C'est encore plus "amusant" s'il n'y a pas compatibilité ascendante entre A 1.1 et A 1.2, Hibernate en l'occurrence.
    Envoie le pom.xml du projet en question, le résultat de mvn dependency:tree pour ton projet et le résultat de help:effective-pom

    Le premier c'est ta configuration, le deuxième c'est ton arbre de dépendances effectif, le troisième c'est comment maven voit ton projet en incluant tout ce qui viens du parent

    Aussi, définir "ne marche pas" -> message d'erreur?

    Citation Envoyé par professeur shadoko Voir le message
    Autre difficulté: à l'exécution je n'ai pas le même ordre de dépendances de librairies entre les exécution Maven ou sans-Maven -> la recherche de Ressources ne donne donc pas le même résultat!
    Si tu as des ressources multiples avec le même nom, la jvm ne garantis pas l'ordre des énumérations qui en sortent. L'ordre des dépendance ne dois pas influencer ton programme. Si elle l'influence c'est que tu as des conflits à gérer, genre deux versions d'une librairie présente. Ceci peut arriver quand un librairie "déménage" dans le repository entre deux versions, maven ne vois pas qu'il s'agit de la même version.

  3. #3
    Membre chevronné
    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 : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Oui, la librairies en 1.2 que tu définis dans ton pom a priorité sur la dépendance héritée de M
    c'est ce que dit la doc ... sauf que j'ai eu des exemples (avec des héritages très compliqués) où ce n'est pas ce qui se passait.
    + dans les cas où ça marche comme ça que fait le code de A qui dépend d'une librairie qui n'est pas en compatibilité ascendante : il plante (ça m'est arrivé hier avec Hibernate).
    (il faudrait que je retrouve les cas exacts où ça se produit: mais avec plus de 70 modules sur un très gros projet les fois où j'ai envoyé des copies ça a effrayé la maintenance ... en faisant des essais/erreurs on arrive à réparer mais j'ai toujours pas compris comment être sûr de son coup)

    Aussi, définir "ne marche pas" -> message d'erreur?
    c'est purement applicatif: le code exécuté n'est pas le code attendu ... ça peut être une exécution qui ne donne pas le résultat attendu (typiquement un "vieux" comportement pas le nouveau attendu avec version 1.2, ou une exception applicative)

    Si tu as des ressources multiples avec le même nom, la jvm ne garantis pas l'ordre des énumérations qui en sortent. L'ordre des dépendance ne dois pas influencer ton programme. Si elle l'influence c'est que tu as des conflits à gérer, genre deux versions d'une librairie présente. Ceci peut arriver quand un librairie "déménage" dans le repository entre deux versions, maven ne vois pas qu'il s'agit de la même version.
    Oops ... je crains qu'on ne se comprenne pas là:
    une resource au sens de getResource() est dépendante des ClassLoaders , tu peux masquer une ressource par une autre : par exemple la ressource par défaut est définie dans la librairie mais ton jar peut masquer avec tes propres valeurs.
    Si ça n'était pas le cas le principe même des ressources serait en cause. donc si M est hiérarchiquement celui qui démarre son jar doit être situé avant dans la hierarchie vue par le loader. les IDE ne s'y trompent pas quand ils t'emballent un lancement de programme ... mais si Maven se trompe alors plus rien ne marche normalement.
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

  4. #4
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Je n'ai qu'un mot à dire : Dependancy Management.

    Maven ne "tolère" qu'une version par artefact (groupId, artifactId, type, ???). Par défaut, la première trouvée est la première servie. Sous Eclipse tu as une vue "Dependancy Hierarchy" où tu peux voir l'arbre de dépendance avec les dépendances ignorées (cf. artefact + version).

    Le "Dependancy Management" permet justement de spécifier une version (et même un scope minimal) particulière à appliquer pour une dépendance. Autrement, il est également possible d'exclure une dépendance qui ne te convient pas. C'est particulièrement utile pour les dépendances dont tu veux utiliser une version plus récente mais dont le groupId/artifactId à changer entre temps.

    Pour le problème d'ordre, je n'ai jamais eu à traiter ce soucis. Néanmoins je pense qu'une exclusion devrait pouvoir traiter le problème ? Sinon la solution est peut-être également dans un fonctionnement différent pour gérer les ressources ? Par exemple, un système similaire aux "Profiles" de Spring ?
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  5. #5
    Membre chevronné
    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 : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    maintenant revons un peu:
    je développe en vitesse mon code qui dépend de la version 1.2
    je ne me pose pas de question et j'utilise le module M dont je ne sais rien (et en particulier qu'il utilise 1.1 de A)
    étant donné que 1.2 et 1.1 ne sont pas compatibles (pour différentes raisons)
    pourrais-je faire marcher mon programme de façon à ce que mon code utilise 1.2 et le code de M (que j'appelle) utilise 1.1 ?

    même question si M est invoqué dans un autre ClassLoader managé par mon code ?
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

  6. #6
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Si tu veux exécuter deux versions d'une même librairie dans un même runtime, sache que Java n'est pas fait pour cela à la base. Ce n'est donc pas Maven qui viendra t'aider.

    Penche plus sur OSGi dans ce cas. Néanmoins, si tu veux faire du A1.2 -> M -> A1.1, il faudra nécessairement une compatibilité. Il faut traiter A1.2 et A1.1 comme des modules C et D. M ne voit statiquement qu'une seule version de la classe (pour faire simple) A. Donc statiquement, les éléments doivent avoir une "interface" (API) commune tout comme il te faudrait une interface (mot clé) commune pour faire fonctionner C et D à travers M.

    Donc la seule solution que je vois, supprimer la dépendance statique de M vers A ou alors le faire dépendre d'un sous-groupe compatible, un module B par exemple.

    En OSGi, il est commun que le module appelant passe toutes les références nécessaires pour que le module appelé fasse des callbacks. Le module appelé n'a alors pas de responsabilité qu'à la construction des objets. Après sans plus de concret sur le fonctionnement (même très abstrait du module) on pourra pas te donner de réponse moins abstraite.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Si tu ne fournis pas d'exemple concret, on ne va pas pouvoir t'aider. De toute ma carrière avec maven, je ne l'ai jamais pris en défaut dans une situation où il ne respectait pas l'ordre de dépendance tel que documenté.

    Le cas que tu présente pourrait avoir lieu comme ça
    -> signifie "dépend de"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    A v2 
           -> B v1
           -> C v2
    B v1 
           -> C v1
    ==> A vois donc B v1, C v2 et pas C v1

    Dépendances calculées:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Av2
     -> Bv1
       -> Cv1 (conflit, supprimé)
     -> Cv2
    Ensuite

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    D v2 
           -> B v1
           -> A v2
    Au niveau de D on a réellement un problème: B v1 lui dit qu'il faut amener C v1, A v2 lui dit qu'il faut amener C v2. C v1 et C v2 sont sur un même niveau dans l'arbre de dépendance donc la règle de "nearest definition" ne s'applique pas comme elle existait dans A! Maven, depuis maven 2.0.9, applique alors la règle du premier déclaré premier servis. Ici Bv1 est déclaré en premier, et sa dépendance a donc priorité. Ce qui nous donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Dv2
      -> Bv1
        -> Cv1
      -> Av2
        -> Bv1 
          -> Cv1 
        -> Cv2 (conflit, supprimé)
    Et c'est peut être ça que tu as expérimenté. Autrement le "FIX" que tu fais dans A de forcer une version ne tiens pas la route si celui qui utilise A amène aussi explicitement la dépendance problématique par un autre chemin. D'où mon point de vue qu'il vaut mieux résoudre à la base le problème en ayant un gestion décidée des versions du projet, en dehors même de l'existance de l'outil maven




    Citation Envoyé par professeur shadoko Voir le message
    dans les cas où ça marche comme ça que fait le code de A qui dépend d'une librairie qui n'est pas en compatibilité ascendante : il plante (ça m'est arrivé hier avec Hibernate).
    Maven n'est pas là pour résoudre le fait que dans ton projet tu essaie de faire cohabiter deux librairies qui entrent en conflit de par leur nécessité chacune de dépendre d'une version spécifique d'une libriarie tierce non compatible. Tu veux utiliser A et B, mais A utilise C et B utilise D hors C et D ne peuvent pas être présents en même temps et ne peuvent pas se substituer. Ce n'est pas le rôle de maven de gérer ça, c'est un problème soit de gestion du projet: rester cohérent dans vos choix de librairies et mettez vous d'accord, soit dans la structure du projet: de gros truc comme eclipse, où ces conflits sont inévitables, utilisent des technique comme Osgi pour mettre chaque module en isolation.


    une resource au sens de getResource() est dépendante des ClassLoaders , tu peux masquer une ressource par une autre : par exemple la ressource par défaut est définie dans la librairie mais ton jar peut masquer avec tes propres valeurs.
    Si ça n'était pas le cas le principe même des ressources serait en cause. donc si M est hiérarchiquement celui qui démarre son jar doit être situé avant dans la hierarchie vue par le loader. les IDE ne s'y trompent pas quand ils t'emballent un lancement de programme ... mais si Maven se trompe alors plus rien ne marche normalement.
    Tu es occupé de supposer que ta hierarchie de dépendance maven se traduit pas une hierarchie de classloader. Ce n'est pas le cas et n'est même pas envisageable. Maven a un arbre de dépendances, la hierarchie de classloader, c'est une chaine simple qui va de ton application au bootstrap. Ton application n'a qu'un seul classloader au final, l'URLClassloader, qui regroupe tous les jars. La notion de hierarchie pour le chargement des ressources ne s'applique qu'à la hierarchie de classloader, et la javadoc dit le contraire de ce que tu dis: on va d'abord chercher dans le classloader parent. Selon moi là tu es occupé d'imaginer des comportements qui n'existent pas dans la JVM et sont basés sur ton expérience en utilisant des effets de bord de l'URLClassloader (notament le fait qu'il va regarder les jar dans l'ordre de sa liste interne)


    L'IDE est un cas particulier, car il va effectivement lancer l'application avec les paramères -cp:./target:./librairie1.jar,.....

    Mais c'est juste "le hasard" (l'effet de bord) qui fait que l'URLClassLoader lise d'abord les ressources dans target/ puis dans librairie1.jar. Ce n'est documenté nulle part.

  8. #8
    Membre chevronné
    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 : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Si tu ne fournis pas d'exemple concret, on ne va pas pouvoir t'aider. De toute ma carrière avec maven, je ne l'ai jamais pris en défaut dans une situation où il ne respectait pas l'ordre de dépendance tel que documenté.
    comme souvent quand on a un bug (ou ce qu'on pense être un bug et qui n'en est pas) il faudrait que je prenne le temps de faire un équivalent qui synthétise le problème (là je ne peux vraiment pas essayer de reconstituer une situation qui s'est produite il y a déjà quelques temps dans un projet aussi complexe).
    mais ma question restait donc plus au niveau de principes.

    merci pour les explications
    Tu es occupé de supposer que ta hierarchie de dépendance maven se traduit pas une hierarchie de classloader. ......
    et la javadoc dit le contraire de ce que tu dis: on va d'abord chercher dans le classloader parent. Selon moi là tu es occupé d'imaginer des comportements qui n'existent pas dans la JVM
    on ne doit pas parler de la même chose (ou je me suis mal exprimé) car je n'imagine rien du tout: la gestion des ressources par les ClassLoaders est cablée de manière précise dans Java .
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    comme souvent quand on a un bug (ou ce qu'on pense être un bug et qui n'en est pas) il faudrait que je prenne le temps de faire un équivalent qui synthétise le problème (là je ne peux vraiment pas essayer de reconstituer une situation qui s'est produite il y a déjà quelques temps dans un projet aussi complexe).
    L'avantage avec maven c'est qu'il y a pas besoin de reconsituer un équivalent. Envoie le pom, le dependency tree et le effective pom, ça aidera déjà pas mal

    Citation Envoyé par professeur shadoko Voir le message
    on ne doit pas parler de la même chose (ou je me suis mal exprimé) car je n'imagine rien du tout: la gestion des ressources par les ClassLoaders est cablée de manière précise dans Java .
    Alors effectivement, je ne sais pas de quoi tu parle. Tout ce que je peux te dire c'est que maven crée un URLClassloader et y fourre tous les jars sans ordre particulier. Autrement dit exactement le même comportement que tu as dans une conteneur J2EE par exemple, où il n'y a pas de priorité entre les différents jars présents dans le WEB-INF/lib. Bref tu ne peux pas supposer que la ressource présente dans tel ou tel jar aura priorité sur un autre jar. Où alors je me demande bien par quelle magie, parce qu'il n'y a rien dans les jar qui permette à la jvm d'établir une telle hierarchie. Et rien dans la javadoc qui suppose cela.

    Ceci dit, si l'ordre des .jar dans le classpath est important pour toi, il y a ceci, introduit dans maven 2.0.9 qui peut t'être utile:

    MNG-1412 / MNG-3111 introduced deterministic ordering of dependencies on the classpath. In the past, natural set ordering was used and this lead to odd results. The ordering is now preserved from your pom, with dependencies added by inheritence added last. In builds that had conflicting or duplicate dependencies, this may introduce a change to the output. In short, if you have weird issues with 2.0.9, take a look at the dependencies to see if you have conflicts somewhere.
    Mais pour moi ça reste une mauvaise idée, tu es dépendant d'une implémentation précise du classloader. Quand ton module tournera sur un conteneur J2EE ou dans un conteneur tomcat, ou via JNLP, le comportement peut être complètement différent.

  10. #10
    Membre chevronné
    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 : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Mais pour moi ça reste une mauvaise idée, tu es dépendant d'une implémentation précise du classloader.
    là je ne suis pas d'accord: ce n'est pas une question d'implémentation c'est une question d'ordre dans le classPath.
    (correctif : je me trompe effectivement l'implantation du ClassLoader peut changer ça )

    Le système de ressources (standard) est précisément conçu de cette manière: un librairie X peut fournir une ressource par défaut et ton jar (situé "devant" X) en fournit une version modifiée. Si on n'a pas ça la gestion des ressources (locales, distantes, etc...) devient liée à des codes spécifiques (qui 9 fois sur 10 ne marchent pas correctement lorsqu'on fait des déploiements particuliers - bon ici aussi je ferais mieux de ne pas être aussi affirmatif : voir Spring-). Ici "devant" peut signifier un classLoader parent ou un jar situé en priorité dans le classPath utilisé par le loader courant. Je découvre maintenant que ça a été pris en compte par Maven (à partir de 2.09) pour cette raison précise (à moi de faire attention)

    edit: maintenant si le ClassLoader peut changer sa façon d'opérer, je me demande comment il fait avec getResource ....
    j'ai constamment des librairies qui fournissent une ressource par défaut et quand je fournit la mienne (avec le même path de ressource) ces librairies prennent ma ressource.... Il y a des ClassLoaders qui voient les choses différemment?
    Dans le ClassLoader standard l'ordre des jars est important quand on est au même niveau. (et je ne sais pas ce que Maven faisait mais les ressources modifiées et donc prioritaires n'étaient pas prises en compte ... erreur de description sans doute)
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    edit: maintenant si le ClassLoader peut changer sa façon d'opérer, je me demande comment il fait avec getResource ....
    j'ai constamment des librairies qui fournissent une ressource par défaut et quand je fournit la mienne (avec le même path de ressource) ces librairies prennent ma ressource.... Il y a des ClassLoaders qui voient les choses différemment?
    Il y a la possibilité que la librairie utilise getResources plutot que getResource, ce qui permet de tout lister et éventuellement de repérer le sien pour l'éjecter. Log4j est bien plus compliqué car il joue avec son classloader, avec le classloader du thread et avec le system classloader et jongle avec tout ça. Sans parlé des version modifiées pour fonctionner avec tel ou tel conteneur en ayant des Logger différents en fonction de chaque webapplication

    Il suffit de penser conteneur web. Quand j'ai 200 librairies dans le WEB-INF/lib, comment est gérer cette priorité? Quel jar passe devant? Facile, c'est l'ordre retourné par le filesystem. Autrement dit c'est peu prédictible. La seule chose à peu près certaine, WEB-INF/classes a tendance à passer devant, mais j'attends de voir une spec qui dit que c'est le comportement voulu.

  12. #12
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Tu peux également récupérer la liste des ressources. C'est par exemple le fonctionnement de ServiceLoader.

    Soit c'est un problème de classes, auquel cas seul OSGi pourra t'aider, soit un problème de ressources, auquel cas je pense qu'il est plus prudent de revoir le système de chargement des ressources. Par exemple, à l'aide de Handler/Factory chargé avec un ServiceLoader.
    Ou sinon plus simple (dans le principe mais bcp moins vrai d'un point de vue architectural), l'injection.

    Une solution que j'ai déjà utilisée inspirée des ServiceLoader, c'est d'avoir des fichiers de ressources qui contiennent une liste de package avec une priorité. Les ressources sont ensuite chargés relativement au chemin du package avec la plus haute priorité.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  13. #13
    Membre chevronné
    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 : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Bon je suis à des années-lumières de JavaEE .

    Mais pour ne pas mourir idiot dites moi :
    - j'ai des librairies (que je n'ai pas écrites) qui font des getResource (hein c'est pas moi) et qui fournisse une ressource par défaut
    - "on" m'a dit (quel farceur ce "on" ) que la politique des classLoaders était de prendre les choses dans l'ordre du classpath
    - et donc "on" (encore lui!) m'a dit que la politique standard de Java était d'avoir des jars dans l'ordre pour remplacer une ressource de librairie par la mienne.

    "on" m'aurait menti ?
    Donc ceci s'applique aux classes et pas aux ressources:
    "Specification order
    The order in which you specify multiple class path entries is important. The Java interpreter will look for classes in the directories in the order they appear in the class path variable
    ."

    vous faites comment quand vous récupérez une librairie (étrangère) qui fait getResource pour lui dire je veux ci et pas ça?
    et donc il n'y aurait pas de standard sur la recherche/manipulation des ressources? Chacun son truc quand on établir une librairie?

    ServiceLoader est une autre histoire: on peut recueillir l'ensemble des objets qui implantent un service ...

    Quand à Maven je reviendrais plus tard sur le sujet avec des exemples.
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    The Java interpreter will look for classes in the directories in the order they appear in the class path variable[/I]."
    Toutes les exécutions java n'impliquent pas nécessairement la présence de cette variable.
    Citation Envoyé par professeur shadoko Voir le message
    vous faites comment quand vous récupérez une librairie (étrangère) qui fait getResource pour lui dire je veux ci et pas ça?
    On ne fait pas. Pour reprendre l'exemple de librairies existantes, log4j charge log4j.properties. Tu notera qu'ils se sont abstenu de fournir un log4j.properties à la racine de leur jar, pour éviter ce genre de conflit.

    Si une librairies A veux fournir un fichier par défaut et un fichier customizable par l'application, en général, je vois plusieurs possibilités:

    • lui fournir programmatiquement: TaLibrairie.loadConfig("/laOuJeVeux.properties");
    • Jouer avec plusieurs localisations de fichier: je cherche "/maConfig.properties" et si je ne trouve pas, je cherche "/META-INF/malib/maConfig.properties"
    • Avoir une libriarie capable de collater plusieurs configurations et de les réunir, en utilisant getResources(). Exemple: lorsque spring scanne le classpath à la recherche de librairies additionnelles pour son spring.xml



    Et il est vrai que quand des librairies réutilisable fournissent un log4j.properties d'elles même ou un truc similaires, c'est le bordel, d'expérience. J'ai déjà du sur un projet faire un petit main qui listait toutes les ressources d'un nom précis pour trouver le coupable qui passait devant les autres. Heureusement il s'agissait d'une erreur d'un dev interne, on a pu corriger. Quand la librairie viens de dehors, c'est le monde sauvage...

    Je crois que le +- standard c'est de dire que ce n'est pas à la librairies X de configurer la librairies Y, mais a l'application finale de le faire, et uniquement à elle. Exemple: on ne met pas une config hibernate dans un module réutilisable, on met des fichiers de mapping et seulement dans l'application final, on charge tous ces fichiers de mapping dans le hibernate.cfg.xml.

  15. #15
    Membre chevronné
    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 : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Je crois que le +- standard c'est de dire que ce n'est pas à la librairies X de configurer la librairies Y, mais a l'application finale de le faire, et uniquement à elle. .
    cas N°1 : une librairie met dans sa doc où et quoi mettre comme conf mais il n'y a pas de conf par défaut (mais c'est attrapé par un getResource)
    cas N° 2: une librairie met dans sa doc comment modifier une conf par défaut (qui est dans ses propres ressources) OU permet un rechargement complet de la conf (toujours par getResource qui trouve un path prioritaire)
    cas N°3: toutes les confs exotiques qu'on peut imaginer (lire soigneusement la doc)

    j'ai essentiellement les deux premières dans celles que j'utilise (mais je ne suis nullement dans JEE) ... mais je vais dire à "on" qu'il n'y a apparemment pas d'accord sur ce qui est standard.
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

  16. #16
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    En sus des cas déjà listé par tchize_, log4j (et d'autres librairies) permettent de surcharger le chemin par défaut à l'aide d'une propriété système. Ce qui permet d'assurer la ressource utilisée.

    Après si tu travailles avec des librairies (et des équipes) qui n'ont pas conscience (et ne prennent pas en compte) la variété d'intégration possible, c'est sûr que tu seras limité dans les possibilités. Et jouer avec l'ordre des ressources tient plus du hack que d'un choix de design/architecture.

    tchize_ > Concernant WEB-INF/classes en premier, cela est indiqué dans la "Java Servlet Specification - 10.5 Directory Structure" :
    Citation Envoyé par Java Servlet Specification - 10.5 Directory Structure
    The Web application class loader must load classes from the WEB-INF/classes
    directory first, and then from library JARs in the WEB-INF/lib directory. Also, except
    for the case where static resources are packaged in JAR files, any requests from the
    client to access the resources in WEB-INF/ directory must be returned with a
    SC_NOT_FOUND(404) response.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Logan Mauzaize Voir le message

    tchize_ > Concernant WEB-INF/classes en premier, cela est indiqué dans la "Java Servlet Specification - 10.5 Directory Structure" :
    Merci

Discussions similaires

  1. Etude, théorie et pratique du controle winsock
    Par Ramdoulou dans le forum VB 6 et antérieur
    Réponses: 57
    Dernier message: 13/11/2008, 18h56
  2. [MySQL] théorie et pratique script football
    Par jackbauer33 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 10/06/2008, 15h39
  3. De la théorie à la pratique
    Par CoGnos8 dans le forum Approche théorique du décisionnel
    Réponses: 3
    Dernier message: 05/06/2008, 19h55
  4. Index : théorie et pratique
    Par schlitters dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 11/01/2006, 19h02
  5. [Architecture] De la théorie à la pratique ...
    Par JMLJ dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 24/06/2005, 10h46

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