Pyjnius: méthodes de superclasse non accessibles en 1.2.1

Créé le 13 déc. 2019  ·  20Commentaires  ·  Source: kivy/pyjnius

arraylist = autoclass("java.util.ArrayList")()
arraylist.iterator()
arraylist.stream()

Cela fonctionne pour la 1.2.0 mais pas pour la 1.2.1.

AttributeError                            Traceback (most recent call last)
<ipython-input-7-5e67e1c90388> in <module>()
----> 1 arraylist.stream()

AttributeError: 'java.util.ArrayList' object has no attribute 'stream'

Bloc-notes reproductible sur https://colab.research.google.com/drive/1F9u2jVQR5JFw_mk5Bq--VH1Ki91Xe5x3

stream() est défini par défaut dans la super-interface.

Nous avons également eu des problèmes d'accès aux méthodes dans les interfaces qui étendaient java.util.List.

Commentaire le plus utile

J'observe le même problème, les méthodes des superclasses ne sont pas accessibles en 1.2.1 mais tout fonctionne en 1.2.0. C'est un bogue assez méchant, ne pensez-vous pas qu'il est logique de supprimer la version 1.2.1 ou de la marquer d'une manière ou d'une autre comme inutilisable ?

Tous les 20 commentaires

Je peux le reproduire localement, voyons si cela se produit également en CI, je chercherai un correctif quand j'aurai un peu de temps.

CI a échoué, mais je ne vois pas comment nous l'avons cassé dans 1.2.1. Je peux voir que getDeclaredMethods() n'inclut pas les méthodes qui sont des implémentations par défaut. (Ils ne sont pas déclarés dans la classe ou ses supertypes).

Il y a une discussion dans https://blog.jooq.org/2018/03/28/correct-reflective-access-to-interface-default-methods-in-java-8-9-10/ - Je ne pense pas à cela est pertinent.

La solution consiste-t-elle également à parcourir toutes les interfaces et leurs interfaces parentes en ajoutant des méthodes par défaut ? (On pourrait ajouter les méthodes abstraites, mais cela semble superflu car elles doivent être implémentées par l'objet concret).

Ceci est le plus fil stackoverflow pertinent , j'ai trouvé: https://stackoverflow.com/questions/28400408/what-is-the-new-way-of-getting-all-methods-of-a-class-including-inherited- par défaut

il semble qu'il puisse y avoir des différences dans les différentes implémentations JVM...

Cela fonctionne si je lance d'abord sur java.util.Collection, mais cela ne devrait pas être nécessaire… :/

Je pense aussi que c'est à cause de l'utilisation de getDeclaredMethods au lieu de getMethods, j'ai essayé de parcourir toutes les interfaces mais d'une manière ou d'une autre, il ne trouvait pas l'interface Collection dans getInterfaces()…

hm, cela semble fonctionner… pas tout à fait sûr pourquoi.
https://github.com/kivy/pyjnius/pull/466/files#diff-06f2b31838f083623d82353f734d644a

edit: euh, sauf pour une erreur de segmentation… https://github.com/kivy/pyjnius/runs/348651345
j'ai réessayé de courir au cas où c'était un problème, s'est écrasé à nouveau sur ubuntu, python3.8, java 10…
edit2 : très confus, toutes les combinaisons actuelles ont fonctionné lorsque j'ai exclu 3.8/java10/ubuntu ensemble, puis j'ai activé Java 9 et 11, et j'ai eu le même plantage avec 3.7/11/ubuntu… au moins je peux installer openjdk-11-jdk sur mon ubuntu et tester avec python3.7 facilement… … et ça marche. grmbl.

https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=100815&view=logs&j=696704cc-6fef-57a3-ea36-f27779b8cd5e&t=06421391-4b55-523d-a804-5e108a5bff
incidemment, il semble que la construction de conda-forge sur linux ait également des erreurs de segmentation sur 1.2.1, donc le problème aurait pu être présent avant mon changement.

le patch fonctionne pour moi en collaboration

bosse polie. Ce serait bien de fusionner celui-ci. J'ai ajouté un commentaire au diff suggérant un commentaire de code.

Désolé de laisser cela s'attarder, je n'ai vraiment aucune idée de ce qui empêche le CI de passer, et je n'aime pas vraiment désactiver une partie des cibles juste pour faire taire une erreur incompréhensible, je suis d'accord pour laisser ce bitrot n'est pas mieux mais je ' Je ne sais pas comment aller de l'avant à partir de cela.

Je m'étais demandé s'il s'agissait d'un problème de simultanéité selon # 480, mais je ne pense pas que pytest soit simultané par défaut.

J'ai essayé de reproduire localement, mais je n'ai pas réussi à reproduire #480. Voici ma commande - c'est une image basée sur Debian :

docker run -i continuumio/anaconda3 /bin/bash <<EOF

cat /etc/os-release
apt-get update
mkdir /usr/share/man/man1
apt-get -y install openjdk-11-jdk-headless gcc ant

conda create -y -n pyjnius python=3.7.5
conda activate pyjnius

git clone https://github.com/kivy/pyjnius.git
cd pyjnius/
python -m pip install -U setuptools cython
python setup.py bdist_wheel
pip install --timeout=120 .[dev,ci]
ant all
cd tests/
CLASSPATH="../build/test-classes:../build/classes" PYTHONPATH=/opt/conda/envs/pyjnius/lib/python3.7/site-packages/ pytest -v
cd ../
git checkout -b issue_465 origin/issue_465

python setup.py bdist_wheel
pip install --timeout=120 .[dev,ci]
ant all
cd tests/
CLASSPATH="../build/test-classes:../build/classes" PYTHONPATH=/opt/conda/envs/pyjnius/lib/python3.7/site-packages/ pytest -v

EOF

Tous les tests passés sur le maître et sur la branche.

J'observe le même problème, les méthodes des superclasses ne sont pas accessibles en 1.2.1 mais tout fonctionne en 1.2.0. C'est un bogue assez méchant, ne pensez-vous pas qu'il est logique de supprimer la version 1.2.1 ou de la marquer d'une manière ou d'une autre comme inutilisable ?

Désolé de laisser cela s'attarder, je n'ai vraiment aucune idée de ce qui empêche le CI de passer, et je n'aime pas vraiment désactiver une partie des cibles juste pour faire taire une erreur incompréhensible, je suis d'accord pour laisser ce bitrot n'est pas mieux mais je ' Je ne sais pas comment aller de l'avant à partir de cela.

Puis-je suggérer de réexécuter les tests CI ? Pouvons-nous essayer de réduire cela - est-ce un problème dans ce patch, ou un problème avec une version précédente ?

Pour y revenir :

Je ne pense pas que mélanger getDeclaredMethods() et getMethods() soit la solution. getMethods() est suffisant.

Mes cas de test pour cela sont:

 def test_super_interface(self):
        LinkedList = autoclass('java.util.LinkedList')
        words = LinkedList()
        words.add('hello')
        words.add('world')
        q = cast('java.util.Queue', words)
        self.assertEqual(2, q.size())
        self.assertIsNotNone(q.iterator())

    def test_super_object(self):
        LinkedList = autoclass('java.util.LinkedList')
        words = LinkedList()
        words.hashCode()

    def test_super_interface_object(self):
        LinkedList = autoclass('java.util.LinkedList')
        words = LinkedList()
        q = cast('java.util.Queue', words)
        q.hashCode()

Divers échouent lorsque nous utilisons uniquement getDeclaredMethods().

Mon seul problème avec getMethods() est que test_inheritance.py échoue. Ceci n'est que marginalement problématique - la méthode statique newInstance() org.jnius.Child remplace la méthode newInstance() org.jnius.Parent. Ce qui se passe, c'est que getMethods() voit les deux méthodes newInstance() , donc construit un JavaMultipleMethod. C'est faux : Child.newInstance() devrait cacher Parent.newInstance() - voir https://www.java67.com/2012/08/can-we-override-static-method-in-java.html. J'ai également vérifié cela en utilisant Jshell :

jshell> org.jnius.Child.newInstance()
$3 ==> org.jnius.Child<strong i="24">@506c589e</strong>

Salut @tshirtman, je vois que tu as commis getMethods(). Je recommanderais également les cas de test supplémentaires ci-dessus.
Je ne savais pas trop comment résoudre la méthode statique masquant que Child.newInstance () devrait masquer Parent.newInstance (). Je pense que vous devriez réorganiser l'itération des classes et des interfaces dans autoclass() - parcourir l'arbre pour obtenir les classes, puis les appliquer dans l'ordre inverse, c'est-à-dire en commençant à java.lang.Object.

hm, en effet, l'ajout de ce test montre qu'actuellement l'objet converti en java.util.Queue autoclass n'a pas d'attribut size , ce qui est faux.
Je suis d'accord avec votre analyse, la recherche inversée, le remplacement des méthodes parentes par une signature identique au lieu de créer une JavaMultipleMethod, cela semble être une bonne stratégie.

501 ont réussi tous les tests. Clôturer ce problème. (Être prier).

Les champs protégés manquent toujours !

Changer cette ligne de public à protected échoue le test.

Il y a une discussion sur #500 pour savoir si les méthodes/champs privés/protégés devraient être exposés.

je pense que c'est différent, actuellement nous sommes censés avoir tout, et avec votre correctif, cela semble être vrai pour les méthodes, mais apparemment ce n'est pas (et peut-être jamais ?) vrai pour les champs, donc je pense que c'est un bogue à résoudre en premier , si nous décidons ensuite d'autoriser le filtrage des méthodes/champs que nous souhaitons voir en fonction de leur niveau de confidentialité. Comme ce bogue est fermé, il est logique pour moi d'en ouvrir un nouveau pour ce cas.

cela semble être vrai pour les méthodes, mais apparemment ce n'est pas (et peut-être jamais ?) vrai pour les champs

Cela a fonctionné pour <1.2.1, donc je m'attendrais à ce que cela fonctionne dans >1.2.1, <2.0 aussi même si cela n'aurait dû fonctionner pour aucune version.

Cette page vous a été utile?
0 / 5 - 0 notes