Pyjnius: metode superclass tidak dapat diakses di 1.2.1

Dibuat pada 13 Des 2019  ·  20Komentar  ·  Sumber: kivy/pyjnius

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

Ini berfungsi untuk 1.2.0 tetapi tidak untuk 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'

Notebook yang dapat direproduksi di https://colab.research.google.com/drive/1F9u2jVQR5JFw_mk5Bq--VH1Ki91Xe5x3

stream() didefinisikan dalam super-interface sebagai default.

Kami juga mengalami masalah dalam mengakses metode di antarmuka yang memperluas java.util.List.

Komentar yang paling membantu

Saya mengamati masalah yang sama, metode superclass tidak dapat diakses di 1.2.1 tetapi semuanya berfungsi di 1.2.0. Ini adalah bug yang cukup buruk, tidakkah menurut Anda masuk akal untuk menghapus rilis 1.2.1 atau menandainya sebagai tidak dapat digunakan?

Semua 20 komentar

Saya dapat mereproduksinya secara lokal, mari kita lihat apakah itu juga terjadi di CI, saya akan mencari perbaikan ketika saya punya waktu.

CI gagal, tapi saya tidak bisa melihat bagaimana kami memecahkannya di 1.2.1. Saya dapat melihat bahwa getDeclaredMethods() tidak menyertakan metode yang merupakan implementasi default. (Mereka tidak dideklarasikan di kelas atau supertipenya).

Ada beberapa diskusi di https://blog.jooq.org/2018/03/28/correct-reflective-access-to-interface-default-methods-in-java-8-9-10/ - I dont _think_ this relevan.

Apakah solusinya juga untuk menjalankan semua antarmuka dan antarmuka induknya menambahkan metode default? (Kita bisa menambahkan metode abstrak, tetapi ini tampaknya berlebihan karena harus diimplementasikan oleh objek konkret).

Ini adalah utas stackoverflow paling relevan yang saya temukan: https://stackoverflow.com/questions/28400408/what-is-the-new-way-of-getting-all-methods-of-a-class-termasuk-diwariskan- defau

sepertinya ada beberapa perbedaan dalam implementasi JVM yang berbeda ...

Ini berfungsi jika saya menggunakan Java.util.Collection terlebih dahulu, tetapi itu tidak perlu… :/

Saya juga berpikir itu karena menggunakan getDeclaredMethods alih-alih getMethods, saya mencoba menjalankan semua antarmuka tetapi entah bagaimana tidak menemukan antarmuka Koleksi di getInterfaces()…

hm, ini sepertinya berhasil ... tidak sepenuhnya yakin mengapa.
https://github.com/kivy/pyjnius/pull/466/files#diff -06f2b31838f083623d82353f734d644a

edit: eh, simpan untuk segfault… https://github.com/kivy/pyjnius/runs/348651345
coba jalankan lagi kalau-kalau ada kesalahan, macet lagi di ubuntu, python3.8, Java 10…
edit2: sangat bingung, semua kombinasi saat ini berfungsi ketika saya mengecualikan 3.8/java10/ubuntu bersama-sama, kemudian saya mengaktifkan Java 9 dan 11, dan mendapatkan crash yang sama dengan 3.7/11/ubuntu… setidaknya saya dapat menginstal openjdk-11-jdk di ubuntu saya dan uji dengan python3.7 dengan mudah... ...dan berhasil. 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-5e1908a5bfc
kebetulan sepertinya conda-forge build di linux juga memiliki beberapa segfault pada 1.2.1, jadi masalahnya mungkin sudah ada sebelum perubahan saya.

tambalan berfungsi untuk saya di collab

benjolan yang sopan. Akan lebih baik jika yang ini digabungkan. Saya menambahkan komentar ke diff yang menyarankan komentar kode.

Maaf karena membiarkan ini berlama-lama, saya benar-benar tidak tahu apa yang mencegah CI lewat, dan saya tidak terlalu suka menonaktifkan bagian dari target hanya untuk membungkam kesalahan yang tidak dapat dipahami, saya setuju membiarkan bitrot ini tidak lebih baik tetapi saya' m tidak yakin bagaimana untuk maju dari ini.

Saya bertanya-tanya apakah ini masalah konkurensi sesuai # 480, tetapi saya tidak berpikir pytest bersamaan secara default.

Saya mencoba mereproduksi secara lokal, tetapi tidak berhasil mereproduksi #480. Inilah perintah saya - ini adalah gambar berbasis 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

Semua tes lulus pada master dan di cabang.

Saya mengamati masalah yang sama, metode superclass tidak dapat diakses di 1.2.1 tetapi semuanya berfungsi di 1.2.0. Ini adalah bug yang cukup buruk, tidakkah menurut Anda masuk akal untuk menghapus rilis 1.2.1 atau menandainya sebagai tidak dapat digunakan?

Maaf karena membiarkan ini berlama-lama, saya benar-benar tidak tahu apa yang mencegah CI lewat, dan saya tidak terlalu suka menonaktifkan bagian dari target hanya untuk membungkam kesalahan yang tidak dapat dipahami, saya setuju membiarkan bitrot ini tidak lebih baik tetapi saya' m tidak yakin bagaimana untuk maju dari ini.

Mungkinkah saya menyarankan untuk menjalankan kembali tes CI? Bisakah kita mencoba mempersempitnya - apakah ini masalah di patch ini, atau masalah dengan versi sebelumnya?

Untuk kembali ke ini:

Saya tidak berpikir mencampur getDeclaredMethods() dan getMethods() adalah jawabannya. getMethods() sudah cukup.

Kasus pengujian saya untuk ini adalah:

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

Berbagai gagal ketika kita hanya menggunakan getDeclaredMethods().

Satu-satunya masalah saya dengan getMethods() adalah test_inheritance.py gagal. Ini hanya sedikit bermasalah - org.jnius.Child static newInstance() mengganti metode org.jnius.Parent newInstance() . Apa yang terjadi adalah getMethods() melihat kedua metode newInstance() , jadi buatlah JavaMultipleMethod. Ini salah: Child.newInstance() harus menyembunyikan Parent.newInstance() - lihat https://www.java67.com/2012/08/can-we-override-static-method-in-java.html. Saya juga memverifikasi ini menggunakan Jshell:

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

Hai @tshirtman Saya melihat Anda melakukan getMethods(). Saya akan merekomendasikan kasus uji tambahan di atas juga.
Saya tidak yakin bagaimana menyelesaikan metode statis yang menyembunyikan bahwa Child.newInstance() harus menyembunyikan Parent.newInstance(). Saya pikir Anda harus menyusun ulang iterasi kelas & antarmuka di autoclass() - berjalan di pohon untuk mendapatkan kelas, dan kemudian menerapkannya dalam urutan terbalik, yaitu mulai dari java.lang.Object.

hm, memang menambahkan tes ini menunjukkan bahwa saat ini objek yang dicor sebagai java.util.Queue autoclass tidak memiliki atribut size , yang salah.
Saya setuju dengan analisis Anda, pencarian terbalik, mengganti metode induk dengan tanda tangan yang identik alih-alih membuat JavaMultipleMethod, yang sepertinya merupakan strategi yang bagus.

501 lulus semua tes. Menutup masalah ini. (Terpujilah).

Bidang yang dilindungi masih belum ada!

Mengubah baris ini dari public menjadi protected gagal dalam pengujian.

Ada diskusi di #500 tentang apakah metode/bidang pribadi/dilindungi harus diekspos sama sekali.

saya pikir itu berbeda, saat ini kita seharusnya memiliki segalanya, dan dengan perbaikan Anda, tampaknya benar untuk metode, tetapi ternyata itu tidak (dan mungkin tidak pernah?) benar untuk bidang, jadi saya pikir ini adalah bug yang harus dipecahkan terlebih dahulu , apakah kami kemudian memutuskan untuk mengizinkan pemfilteran metode/bidang yang ingin kami lihat bergantung pada tingkat privasinya. Karena bug ini ditutup, masuk akal bagi saya untuk membuka yang baru untuk kasus itu.

tampaknya benar untuk metode, tetapi tampaknya tidak (dan mungkin tidak pernah?) benar untuk bidang

Ini berfungsi untuk <1.2.1 jadi saya berharap itu berfungsi di> 1.2.1, <2.0 juga meskipun seharusnya tidak berfungsi untuk versi apa pun.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat