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 :

Java 9 est disponible, la plateforme se met aux modules tour d'horizon des nouveautés


Sujet :

Java

  1. #41
    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
    je suis très inquiet: j'ai été dès le début un fan de Java car je trouvais que la logique interne de C++ devenait byzantine.
    Je crains que la même chose advienne à Java.

    Exemple: en Java 9 il peut y avoir une différence à l'exécution si votre code est défini dans votre classe ou si vous en héritez!
    Oui: si votre classe exécute un code par héritage il risque de ne pas marcher de la même manière que si votre code le redéfinissait localement.

    Bien que le code soit rattaché à votre classe l'exécution se passe dans le module de définition et donc il n'aura pas les mêmes droits que s'il est exécuté dans le module de la classe. Il y a une logique (tordue?) ... mais elle ne va pas rendre les codes plus clairs
    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. #42
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    ???????

    là il faut expliquer car j'ai jamais vu ça en java

    A+JYT

  3. #43
    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, bien sûr, je n'ai pas été clair.
    Une méthode dans une sous-classe ne peut pas toujours être une copie d'un code dans une super-classe
    par exemple le code de la méthode dont on va hériter va dans son contexte accéder à des données qui sont privées dans le domaine de la super-classe. Bon jusque là tout va bien.
    Là où j'ai été surpris est que le même raisonnement s'applique dans le cadre des modules.
    Si une sous-classe a accès à des données et cherche à les accéder au travers de codes hérités et bien le code se comporte comme s'il n'avait pas accès à ces données.
    On te dira ... rien de nouveau il existait des (rares) cas analogues auparavant ... sauf que là l'étendue de la chose devient réllement enquiquinante. Par exemple la réalisation d'un service qui est implantée dans un module ne peut pas hériter de codes définis dans un autre module ... et donc on recopie gentiment ces codes! Ouch!
    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. #44
    Expert confirmé Avatar de yildiz-online
    Homme Profil pro
    Architecte de domaine
    Inscrit en
    Octobre 2011
    Messages
    1 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte de domaine

    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 444
    Points : 4 563
    Points
    4 563
    Par défaut
    Tu peux donner un bout de code, et les module-infos, parce que j'utilise de l'héritage entre différents modules (API publique et implémentation séparés), et je n'ai pas rencontré ce soucis
    PXL le retro-gaming facile: Essayez-le

    Yildiz-Engine an open-source modular game engine: Website
    Yildiz-Online a 3D MMORTS in alpha: Facebook page / Youtube page

  5. #45
    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
    je vais essayer:
    on est habitué au fait que le code dans une super-classe ait des droits particuliers qui lui permettent d'accéder par exemple à des champs privés. Jusque là tout va bien!
    On n'a pas l'habitude de se rendre compte que l'inverse est aussi vrai: le code de la super-classe ne peut pas accéder à des données privées de la sous-classe. On ne le sait pas ça parce que ça n'arrive pratiquement que dans le cas de l'introspection: on demande de manipuler dynamiquement une classe qui est "accessible" par la sous-classe ...mais pas par la super-classe.

    Maintenant avec les modules les choses prennent de toutes autres proportions.
    Supposons (juste pour les besoins de la demo) qu'on ait une classe abstraite qui définisse un "service" et qui fasse ça:
    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
     
    // dans moduleA
    public abstract class DefinitionService {
         public void doIt() {
               Class clazz =this.getClass();
                System.out.println(" CLASS " +clazz);
                try {
                    Object obj = clazz.getConstructor().newInstance();
                    System.out.println("Object " + obj);
     
                } catch (Exception exc) {
                    exc.printStackTrace();
                }
        }
    }
    maintenant dans module B
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class  RendService extends DefinitionService {}
    au moment de l'exécution du service le "newInstance" va échouer si le package de RendService n'est pas "exporté" ou "ouvert".
    le super-code n'a pas accès à la classe.... vieille histoire réchauffée à une autre échelle.

    Bon là où ça devient plus difficile à comprendre c'est dans ce cas:
    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
     
    public abstract class  PropertiesProvider {
          public Properties get(String domain) {
                Class clazz =this.getClass();
                System.out.println(" CLASS " +clazz);
                 InputStream is = clazz.getResourceAsStream(domain) ;
                if (is != null) {
                    Properties props = new Properties();
                    try {
                        props.load(is);
                        return props;
                    } catch (IOException e) {
                        System.getLogger("").log(System.Logger.Level.WARNING,e) ;
                    }
                }
               return null ;
          }
    }
    Ici à l'exécution de la sous-classe qui rend le service.
    - la classe "clazz" est bien la sous-classe
    - mais getResourceAsStream s'exécute dans le contexte de la définition du service! et ne trouve pas les ressources non "ouvertes" (même quand on a passé une désignation absolue qui permettrait de retrouver la ressource dans moduleB).

    C'est loin d'être évident (pour moi ... mais encore quelques verres de bon vin et ça deviendra peut-être clair)!
    L'encapsulation à double détente du java modulaire demande pas mal d'efforts de compréhension et d'organisation.
    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. #46
    Expert confirmé Avatar de yildiz-online
    Homme Profil pro
    Architecte de domaine
    Inscrit en
    Octobre 2011
    Messages
    1 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte de domaine

    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 444
    Points : 4 563
    Points
    4 563
    Par défaut
    Ah ok, tu utilises l'introspection, dans ce cas ça n'a rien avoir avec l'héritage.

    Tu dois ouvrir ton package plutôt que l'exporter me semble-t-il, mais je n'ai pas testé

    https://stackoverflow.com/questions/...pens-in-java-9
    PXL le retro-gaming facile: Essayez-le

    Yildiz-Engine an open-source modular game engine: Website
    Yildiz-Online a 3D MMORTS in alpha: Facebook page / Youtube page

  7. #47
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    il n'y a là rien de nouveau
    en java avant 9 il est possible d'avoir plusieurs class loaders
    et les outils de type conteneur comme jEE (je par de JEE pas de conteneur de WAR comme tomcat) ou OSGi
    permettent de déployer des "modules" se rendant des "services"

    chaque module à sont propre classloader et un module ne peux étendre une classe qui est dans un autre module(provider) que si ce dernier expose le package la contenant. le module(provider) ne peux pas accéder à la classe fille ce qui est normal cela relève du respect de pattern d'héritage.

    En java avec l'introspection on peut essayer de gruger et d'accéder à des méthodes ou des attributs auquel on a pas droit. C'est de la mauvaise conception.
    la bonne façon de faire est soit d'utiliser une interface soit une classe abstraite.
    mais quelque soit le langage à objet ce n'est pas au parent d'instancier les classes filles.

    cela va même plus loin car un membre statique dans une classe pour faire un singleton ne fonctionne pas.

    supposons que nous ayons une classe S qui implémente le pattern singleton avec une méthode getInstance() un constructeur privé et un membre statique privé.
    et les modules moduleA moduleB
    le membre étant statique et privé il est lié la classe S

    le moduleA possède son propre classLoader et charge la classe S et appelle getInstance()
    dans la JVM un objet de type Class<S> est instancié et le membre privé pointe vers une instance de S

    Le moduleB charge à son tour la classe S comme il n'utilise pas le même classLoader que moduleA une autre instance de Classs<S> va être créé dans la JVM et celle ci à son membre privé à null
    lorsque le moduleB appelle getInstance() une nouvelle instance de S est crée.

    il y a donc deux instances de S
    Ce pattern singleton n'est un singleton qu'au niveau du module pas de la JVM.

    Je n'ai pas vérifié avec java9 ce qu'il en est
    A+JYT

  8. #48
    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
    ok ok les pb des ClassLoaders étaient déjà amusants (je pense en particulier à feu Jini que je regrette particulièrement)

    Le problème risque d'être stimulant quand des bibliothèques de codes font appel (en douce!) à l'introspection ou à des contrôles par "Reflection" (c'est le cas de getResourceXXX dans Class qui fait appel à jdk.internal.reflect.Reflection) ...là on va s'amuser.

    Supposons que l'on ait un outil qui fasse appel à ce genre de codes ... ce n'est pas forcément amoral hein... je pense par ex. aux outils Objet/relationnel. Du coup toutes les entités qui seront manipulées par ces outils devront faire "opens monpackage to outil" ... ah ben Oups! ici on introduit une dépendance à l'outil donc ce sera "opens monpackage" tout court ... là on va se demander alors pourquoi on modularise puisque toutes les entités doivent être lisibles par tout le monde.
    Dans monpackage tu ne peux pas faire un code de délégation qui est en portée et qui traite ton problème (ne pas compter sur l'héritage, etc...) .
    bien sûr il y a des solutions (par ex. dans les options de lancement de l'application)... mais je sens qu'on peut investir chez les fabricants d'aspirine.
    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. #49
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Je ne comprends pas trop ton problème...
    Tu as juste le contrôle sur les visibilités de ton module.

    Si un package doit être accessible de l'extérieur, tu le déclare en "export", et s'il doit être manipulé via réflection pour accéder aux éléments privés tu le déclare en "open".

    C'est justement là tout l'intérêt des modules...

  10. #50
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut OSGi et Java 9
    Bonjour
    le problème c'est qu'on ne peut plus (ou moins) tricher sur les restrictions via l'introspection et certaines lib ne s'en privaient pas.


    Depuis la venu de java 9 (avant même) beaucoup se posent des questions sur OSGi. la notion de module et de bundle est différente. et les deux ne sont pas incompatible. (c'est mon avis depuis le début)

    Mais il faut bien reconnaître qu'en l'état faire fonctionner OSGi sur java 9 ne se fait pas sans difficultés.

    L'aliance OSGi à publié un article à ce sujet le 27/02/2018.
    Il s'agit de la spécification OSGI R7 et du support de java 9

    Il est a noter que karaf (félix) se base sur la spec 6.0.0

    A+JYT

  11. #51
    Membre extrêmement actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Mars 2015
    Messages : 1 104
    Points : 2 574
    Points
    2 574
    Par défaut
    Citation Envoyé par sekaijin Voir le message
    Bonjour
    le problème c'est qu'on ne peut plus (ou moins) tricher sur les restrictions via l'introspection et certaines lib ne s'en privaient pas.
    Je n'ai jamais compris ce que sont l'introspection et la réflexivité en java, mais quelles sont les librairies susceptibles d'avoir des problèmes en java 9 ?
    "If the revolution ain't gon' be televised
    Then fuck, I'll probably miss it" - Aesop Rock

  12. #52
    Membre éclairé

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    L'introspection et la réflexion permettent à Java (et à d'autres langages) de déterminer durant l'exécution
    quelles sont les variables membres ou méthodes de leur classe, et d'agir dessus directement.

    Pour faire simple, tu pourrais écrire un programme de cette forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int mois = date.getMonth();
    System.out.println("Nous sommes le mois de " + afficheurDeMois.invoke("nomMois" + mois));
    Qui appellerait concrètement la méthode afficheurDeMois.nomMois3(), ce mois de Mars... bon ici, c'est très laid et très stigmatisé (parce que ce n'est pas tout à fait cela qu'il faut écrire), mais c'est l'idée.

    Le problème que pose Java 9, c'est qu'autant l'on peut, lorsque l'on évite cette programmation, trouver des moyens de vérifier que ses programmes vont bien se restreindre à l'emploi de quelques packages que l'on a choisi, puisqu'ils sont explicitement nommés,
    autant quand on est face à de la programmation reflexive, comment peut-on déterminer tout ce que l'on peut joindre avec ?

    Un appel fait avec :
    le_package_que_je_veux.la_classe_que_je_veux.la_methode_que_je_veux
    où les trois-là sont des variables,
    ... peut appeler théoriquement n'importe quoi, car les appels sont construits dynamiquement, et peuvent tomber partout.
    Dont à des endroits où en Java 9, il n'y aura "plus rien" au démarrage de la JVM.

  13. #53
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    Supposons que tu ais une classe MyClass avec la méthode privée aMethod

    tu as un objet de cette class
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyClass obj = new MyClass();
    et tu aimerais pouvoir écrire
    Mais comme elle est privé tu ne peux pas.
    l'introspection te permet de connaitre toutes les méthodes de ta classe, au moment de l'exécution.

    quelque chose comme ça (pseudo code)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    List<Method> lst = obj.getClass().getListOfMethods();
    for (Method m : lst) {
       system.out.println(m.getName());
    }
    sur chaque méthode tu peux connaitre son nom ses restrictions ses paramètres son type de retour
    mais tu peux surtout l'appeler. (pseudo code)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Method m = obj.getClass().getMethod("aMethod");
    system.out.println(m.invoke(obj)); //ce qui revient à faire obj.aMethod()
    Si tu fait ça tu vas obtenir une exception Illegal Access car la méthode est privé et tu n'y a pas accès.

    quand je parle de tricher c'est que java te permet tout de même de faire cet appel en passant outre les restrictions quelque chose qui ressemblerait à ça (pseudo code)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Method m = obj.getClass().getMethod("aMethod");
    system.out.println(m.invokeIgnoreRestrictions(obj)); //ce qui revient à faire obj.aMethod() alors même qu'elle est privée.
    j'appelle ça tricher car si le développeur à mis la méthode privé c'est pour qu'elle ne soit pas accessible.

    la modularisation va changer la donne en ce sens que si la classe est dans un package qui n'est pas exporté par le module
    non seulement tu ne pourras pas passer outre la restrictions mais tu ne verras même pas la méthode.

    c'est déjà vrais avec les modules OSGi
    tu définis une interface publique et une implémentation privée

    dans le jar contenant l’implémentation via l'introspection tu peux faire ce que nous venons de décrire

    mais dans un autre jar qui accède à l'implémentation via un service tu ne vois que la partie exporte (l'interface)
    si via l'introspection tu cherche à accéder à l'implémentation tu tombe sur une classe appelée Proxy qui ne contient aucune donnée et aucune autre méthodes que celles de l'interface. tu n'a donc accès à rien.

    ce qui est un gage de sécurité.

    A+JYT

  14. #54
    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 sekaijin Voir le message
    j'appelle ça tricher car si le développeur à mis la méthode privé c'est pour qu'elle ne soit pas accessible.
    je vais exprimer ici une opinion toute personnelle. La notion d'accessibilité est très ambiguë (c'est le gros problème de l'Anglais des spécifications de Java).
    Pour moi une portée "privée" signifie qu'un programmeur se réserve la responsabilité de l'usage ... il dit "attention je suis responsable de l'utilisation explicite de cette chose". est-ce une notion de "sécurité"? tout dépend de ce qu'on entend par sécurité ...
    Pour moi il n'est pas choquant d'avoir un mutateur (setXXX) privé qui indique que l'encapsulation implique des règles de gestion et donc qu'il est interdit à un programme extérieur d'invoquer explicitement cette méthode ... qui peut être quand même être invoquée dans des circonstances particulières ... par exemple lors d'une reconstitution de l'état de l'objet par un utilitaire qui lit une base de données relationnelles (une annotation est la bienvenue).
    Donc maintenant, avec les modules, ce genre d'outil va se retrouver un peu géné aux entournures ... il va falloir faire appel à un peu de sorcellerie ... mais ça va le faire.
    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)

  15. #55
    Membre extrêmement actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Mars 2015
    Messages : 1 104
    Points : 2 574
    Points
    2 574
    Par défaut
    Merci pour ces explications.

    Je comprends un peu mieux ce qu'est l'introspection, mais concrètement, à quoi ça peut servir de forcer à l'exécution l'accès à un attribut ou à une méthode à laquelle on a normalement pas accès pour raison de visibilité ?
    "If the revolution ain't gon' be televised
    Then fuck, I'll probably miss it" - Aesop Rock

  16. #56
    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 Grogro Voir le message
    Je comprends un peu mieux ce qu'est l'introspection, mais concrètement, à quoi ça peut servir de forcer à l'exécution l'accès à un attribut ou à une méthode à laquelle on a normalement pas accès pour raison de visibilité ?
    Supposons que tu aie un code comme celui-ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class CompteEnBanque {
        private BigDecimal solde ;
        private void setSolde(BigDecimal val) { ...}
        private CompteEnBanque() {}
        ..... etc, etc.
    }
    d'abord pourquoi private? et bien parce que les règles de gestion font que le modifications du solde ne peuvent passer que par des méthodes dépot, retrait; ensuite le constructeur sans paramètre ne doit pas être utilisé car cela voudrait dire que l'on pourrait manipuler un CompteEnBanque incomplet (entre parenthèses cela montre aussi pourquoi les "Java beans" sont un anti-pattern).
    par contre certains outils vont demander cela par ex. pour permettre la reconstitution d'instances à partir de données glanées dans une BDD. L'outil va utiliser, sous certaines conditions, ces éléments privés en te garantissant gentiment qu'il ne laissera pas des objets dans une état "larvaire". D'où l'introspection.

    Maintenant avec la modularité tu te trouves devant certains dilemmes:
    - pour laisser l'outil travailler tu déclares : opens com.maboite.mestrucs to org.schtroumpf.tool
    ce qui veut dire que tes trucs sont explicitement liés à l'outil schtroumpf! (ou à une liste d'outils)
    - tu dis que tout est ouvert ... mais dans ce cas pourquoi être modulaire ? ....
    - quid si toi tu veux gérer l'assemblage d'entités qui ne sont pas les tiennes (et qui ne sont pas ouvertes) avec l'outil X qui n'était pas prévu initialement? Là il va falloir faire appel à un peu de sorcellerie

    En fait on se fait des idées si on dit que "private" est synonyme de sécurité. L'intention est ailleurs: on marque une frontière de responsabilité, on interdit aux programmeurs(euses) d'utiliser explicitement ces éléments dans un code métier normal. Celui ou celle qui force le passage doit respecter des règles et savoir pourquoi il le fait. La sécurité est plus complexe que ça.
    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)

  17. #57
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    Les module vont aussi permettre de clarifier les choses
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class CompteEnBanque {
        private BigDecimal solde ;
        private void setSolde(BigDecimal val) { ...}
        private CompteEnBanque() {}
        ..... etc, etc.
    }
    voici comment on fait en osgi mais le principe est le même en java9

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    package com.mybank;
     
    public interface CompteEnBanque {
       public void depot(BigDecimal val);
       public void retrait(BigDecimal val);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    package com.mybank.private;
     
    public class CompteEnBanqueImpl implements CompteEnBanque  {
        private BigDecimal solde ;
        publicvoid setSolde(BigDecimal val) { ...}
        publicCompteEnBanque() {}
        ..... etc, etc.
    }
    Lors de la compilation le module export le package com.mybank mais il garde privé com.mybank.private

    un autre module qui utilise CompteEnBanque ne peux que faire depot et retrait
    mais la couche de persistance qui elle se trouve dans le même bundle à accès au setter de CompteEnBanqueImpl

    il n'y a donc pas besoin de faire de bricolage pour passer outre les droits dans la partie privé des implémentations privées avec des getter et setter public mais limité au module

    Dans la partie publique que les méthodes publiques
    personne ne peut depuis l'extérieur tenter d'avoir accès au méthodes de la partie privé elle sont invisible
    l'introspection ne montre que celle de l'interface publique.

    Il n'y a donc aucunement besoin de faire de vieux hack sur les accès pour pouvoir reconstruire l'objet.

    le module mybank contient la persistance de CompteEnBanqueImpl et CompteEnBanqueImpl plus éventuellement des utilitaires internes privés
    tous on accès à CompteEnBanqueImpl est donc à ses setter et getter public
    le module exporte l'interface et donc tous les autre modules on accès à l'interface et que à l'interface CompteEnBanque
    aucun getter ou setter de l'implémentation n'existe à l'extérieur. (il ne sont pas private il n'existe pas on ne les vois pas même à l'introspection)

    A+JYT

  18. #58
    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 sekaijin Voir le message
    mais la couche de persistance qui elle se trouve dans le même bundle à accès au setter de CompteEnBanqueImpl

    il n'y a donc pas besoin de faire de bricolage pour passer outre les droits dans la partie privé des implémentations privées avec des getter et setter public mais limité au module
    ....
    le module mybank contient la persistance de CompteEnBanqueImpl et CompteEnBanqueImpl plus éventuellement des utilitaires internes privés
    certes mais mon point de vue initial était qu'en faisant quelque chose qui ressemble à ça on a un couplage entre la partie "métier" et l'outil de persistance. C'est une solution qui peut se concevoir ... mais pas toujours.
    Réaliser un vrai découplage est possible mais demande des dispositifs techniques assez sophistiqués au niveau de la modularité.
    je ne maitrise pas suffisamment la notion de "strate" de modularité (module layer) en Java9 pour exposer ici un principe bien clair et propre... j'apprends ....
    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)

  19. #59
    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
    sans garantie du gouvernement (parce que j'ai pas encore testé) voici comment je vois les choses à partir de cet exemple:
    https://github.com/java9-modularity/...hapter6/lookup
    Dans un contexte de modules supposons qu'on veuille un parfait découplage entre un code "métier" et un code qui a besoin de faire de l'introspection ... à la requête du code métier (par. ex. interactions avec une BDD)

    1° le code "métier" demande un service. Ce service consomme un Lookup créé localement par le code métier.
    (dans l'exemple il y a un requires explicite du code rendant le service mais on peut passer par un service)

    2° le code métier demande au service d'opérer (dans l'exemple LoadFromDatabase avec la classe Book.class)

    3° le code qui implante le service réalise l'introspection demandée et rend l'objet. Du point de vue de la modularité c'est le code du module métier qui est initiateur de l'introspection et donc ça doit passer.

    une autre suggestion?
    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)

Discussions similaires

  1. Java 8 est disponible, la plate-forme se met aux expressions lambdas
    Par Hinault Romaric dans le forum Général Java
    Réponses: 32
    Dernier message: 24/12/2014, 14h26
  2. Quelle API Java pour un jeu de plate forme 2D ?
    Par dawadam dans le forum API graphiques
    Réponses: 0
    Dernier message: 16/06/2011, 22h25
  3. [java] Moteur de jeu de plate-forme
    Par luckyvae dans le forum Projets
    Réponses: 12
    Dernier message: 15/08/2007, 22h06
  4. Message: 'ce symbole est propre à une plate-forme'
    Par neho88 dans le forum Delphi
    Réponses: 4
    Dernier message: 18/10/2006, 15h14

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