Pyjnius: Superklassenmethoden, die in 1.2.1 nicht zugänglich sind

Erstellt am 13. Dez. 2019  ·  20Kommentare  ·  Quelle: kivy/pyjnius

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

Dies funktioniert für 1.2.0, aber nicht für 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'

Reproduzierbares Notizbuch unter https://colab.research.google.com/drive/1F9u2jVQR5JFw_mk5Bq--VH1Ki91Xe5x3

stream() ist standardmäßig im Super-Interface definiert.

Wir hatten auch Probleme beim Zugriff auf Methoden in Schnittstellen, die java.util.List erweiterten.

Hilfreichster Kommentar

Ich beobachte das gleiche Problem, Superklassenmethoden sind in 1.2.1 nicht zugänglich, aber in 1.2.0 funktioniert alles. Dies ist ein ziemlich übler Fehler, halten Sie es nicht für sinnvoll, die Version 1.2.1 zu entfernen oder irgendwie als unbrauchbar zu markieren?

Alle 20 Kommentare

Ich kann es lokal reproduzieren, mal sehen, ob es auch in CI passiert, ich werde nach einer Lösung suchen, wenn ich etwas Zeit habe.

CI ist fehlgeschlagen, aber ich kann nicht sehen, wie wir es in 1.2.1 gebrochen haben. Ich kann sehen, dass getDeclaredMethods() keine Methoden enthält, die Standardimplementierungen sind. (Sie werden nicht in der Klasse oder ihren Supertypen deklariert).

Es gibt einige Diskussionen in https://blog.jooq.org/2018/03/28/correct-reflektive-access-to-interface-default-methods-in-java-8-9-10/ - Ich _think_ das nicht ist relevant.

Besteht die Lösung auch darin, alle Schnittstellen und ihre übergeordneten Schnittstellen zu durchlaufen, indem Standardmethoden hinzugefügt werden? (Wir könnten die abstrakten Methoden hinzufügen, aber dies erscheint überflüssig, da sie durch das konkrete Objekt implementiert werden müssen).

Dies ist der relevanteste Stackoverflow-Thread, den ich gefunden habe: https://stackoverflow.com/questions/28400408/what-is-the-new-way-of-getting-all-methods-of-a-class-inclusive-inherited- defau

es scheint, dass es einige Unterschiede in verschiedenen JVM-Implementierungen geben könnte ...

Es funktioniert, wenn ich zuerst in java.util.Collection caste, aber es sollte nicht notwendig sein… :/

Ich denke auch, dass es daran liegt, dass ich getDeclaredMethods anstelle von getMethods verwendet habe. Ich habe versucht, alle Schnittstellen zu durchlaufen, aber irgendwie wurde die Collection-Schnittstelle in getInterfaces() nicht gefunden…

hm, das scheint zu funktionieren… nicht ganz sicher warum.
https://github.com/kivy/pyjnius/pull/466/files#diff -06f2b31838f083623d82353f734d644a

edit: äh, außer für einen Segfault… https://github.com/kivy/pyjnius/runs/348651345
versuchte es erneut, falls es ein Fehler war, stürzte erneut unter Ubuntu, Python3.8, Java 10 ab…
edit2: sehr verwirrt, alle aktuellen Kombinationen haben funktioniert, als ich 3.8/java10/ubuntu zusammen ausgeschlossen habe, dann habe ich Java 9 und 11 aktiviert und den gleichen Absturz mit 3.7/11/ubuntu bekommen… auf meinem ubuntu und testen mit python3.7 einfach… …und es funktioniert. 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-5e1a5bfc1908
Übrigens scheint Conda-Forge build auf Linux auch einige Segfaults auf 1.2.1 zu haben, also könnte das Problem vor meiner Änderung vorhanden gewesen sein.

Patch funktioniert bei mir bei Collab

höflicher Stoß. Wäre gut, wenn dieser zusammengeführt wird. Ich habe dem Diff einen Kommentar hinzugefügt, der einen Codekommentar vorschlägt.

Es tut mir leid, dass ich das hier verweilen lasse, ich habe einfach keine Ahnung, was das CI am Passieren hindert, und ich mag es nicht wirklich, einen Teil der Ziele zu deaktivieren, nur um einen unverständlichen Fehler zu unterdrücken, ich stimme zu, dass es nicht besser ist, dieses Bitrot zuzulassen, aber ich Ich bin mir nicht sicher, wie ich damit weitermachen soll.

Ich hatte mich gefragt, ob dies ein Parallelitätsproblem gemäß #480 ist, aber ich glaube nicht, dass pytest standardmäßig gleichzeitig ist.

Ich habe versucht, lokal zu reproduzieren, aber es ist mir nicht gelungen, #480 zu reproduzieren. Hier war mein Befehl - es ist ein Debian-basiertes Image:

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

Alle Prüfungen am Master und am Ast bestanden.

Ich beobachte das gleiche Problem, Superklassenmethoden sind in 1.2.1 nicht zugänglich, aber in 1.2.0 funktioniert alles. Dies ist ein ziemlich übler Fehler, halten Sie es nicht für sinnvoll, die Version 1.2.1 zu entfernen oder irgendwie als unbrauchbar zu markieren?

Es tut mir leid, dass ich das hier verweilen lasse, ich habe einfach keine Ahnung, was das CI am Passieren hindert, und ich mag es nicht wirklich, einen Teil der Ziele zu deaktivieren, nur um einen unverständlichen Fehler zu unterdrücken, ich stimme zu, dass es nicht besser ist, dieses Bitrot zuzulassen, aber ich Ich bin mir nicht sicher, wie ich damit weitermachen soll.

Darf ich vorschlagen, die CI-Tests erneut durchzuführen? Können wir versuchen, dies einzugrenzen - ist es ein Problem in diesem Patch oder ein Problem mit einer früheren Version?

Um darauf zurückzukommen:

Ich glaube nicht, dass das Mischen von getDeclaredMethods() und getMethods() die Antwort ist. getMethods() ist ausreichend.

Meine Testfälle dafür sind:

 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()

Verschiedene schlagen fehl, wenn wir nur getDeclaredMethods() verwenden.

Mein einziges Problem mit getMethods() ist, dass test_inheritance.py fehlschlägt. Dies ist nur am Rande problematisch - org.jnius.Childs statische newInstance() überschreibt die org.jnius.Parent newInstance() Methode. Was passiert ist, dass getMethods() beide newInstance() Methoden sieht, also eine JavaMultipleMethod konstruiert. Das ist falsch: Child.newInstance() sollte Parent.newInstance() verbergen - siehe https://www.java67.com/2012/08/can-we-override-static-method-in-java.html. Ich habe dies auch mit Jshell überprüft:

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

Hallo @tshirtman Ich sehe, du hast getMethods() begangen. Ich würde auch die zusätzlichen Testfälle oben empfehlen.
Ich war mir nicht sicher, wie man die statische Methode löst, die verbirgt, dass Child.newInstance() Parent.newInstance() ausblenden sollte. Ich denke, Sie müssten die Iteration von Klassen und Schnittstellen in autoclass() neu anordnen - den Baum durchlaufen, um die Klassen zu erhalten, und sie dann in umgekehrter Reihenfolge anwenden, dh beginnend bei java.lang.Object.

hm, das Hinzufügen dieses Tests zeigt tatsächlich, dass das als java.util.Queue Autoklasse umgewandelte Objekt derzeit kein size Attribut hat, was falsch ist.
Ich stimme Ihrer Analyse zu, Reverse-Lookup, Ersetzen von Elternmethoden durch identische Signaturen, anstatt eine JavaMultipleMethod zu erstellen, das scheint eine gute Strategie zu sein.

501 hat alle Prüfungen bestanden. Schließen dieses Problems. (Lob sei).

Geschützte Felder fehlen noch!

Wenn Sie diese Zeile von public in protected ändern, besteht der Test nicht.

Auf #500 wird diskutiert, ob private/geschützte Methoden/Felder überhaupt offengelegt werden sollten.

Ich denke, das ist anders, derzeit sollen wir alles haben, und mit Ihrem Fix scheint es für Methoden zu gelten, aber anscheinend gilt es nicht (und war es möglicherweise nie?) für Felder, also denke ich, dass es ein Fehler ist, der zuerst gelöst werden muss , ob wir uns dann entscheiden, das Filtern der Methoden/Felder zuzulassen, die wir je nach ihrem Datenschutzniveau sehen möchten. Da dieser Bug geschlossen ist, ist es für mich sinnvoll, für diesen Fall einen neuen zu öffnen.

es scheint für Methoden zu gelten, aber anscheinend gilt es nicht (und war es möglicherweise nie?) für Felder

Es funktionierte für <1.2.1, also würde ich erwarten, dass es auch in >1.2.1,<2.0 funktioniert, auch wenn es für keine Version hätte funktionieren sollen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen