Pyjnius: métodos de superclase no accesibles en 1.2.1

Creado en 13 dic. 2019  ·  20Comentarios  ·  Fuente: kivy/pyjnius

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

Esto funciona para 1.2.0 pero no para 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'

Cuaderno reproducible en https://colab.research.google.com/drive/1F9u2jVQR5JFw_mk5Bq--VH1Ki91Xe5x3

stream () se define en la superinterfaz de forma predeterminada.

También tuvimos problemas para acceder a métodos en interfaces que extendían java.util.List.

Comentario más útil

Observo el mismo problema, los métodos de superclase no son accesibles en 1.2.1 pero todo funciona en 1.2.0. Este es un error bastante desagradable, ¿no crees que tiene sentido eliminar la versión 1.2.1 o marcarla como inutilizable de alguna manera?

Todos 20 comentarios

Puedo reproducirlo localmente, veamos si también sucede en CI, buscaré una solución cuando tenga algo de tiempo.

CI falló, pero no puedo ver cómo lo rompimos en 1.2.1. Puedo ver que getDeclaredMethods () no incluye métodos que son implementaciones predeterminadas. (No se declaran en la clase ni en sus supertipos).

Hay algo de discusión en https://blog.jooq.org/2018/03/28/correct-reflective-access-to-interface-default-methods-in-java-8-9-10/ - No _think_ this es relevante.

¿La solución también es recorrer todas las interfaces y sus interfaces principales agregando métodos predeterminados? (Podríamos agregar los métodos abstractos, pero esto parece superfluo ya que deben ser implementados por el objeto concreto).

Este es el hilo de stackoverflow más relevante que encontré: https://stackoverflow.com/questions/28400408/what-is-the-new-way-of-getting-all-methods-of-a-class-including-inherited- defau

parece que podría haber algunas diferencias en diferentes implementaciones de JVM ...

Funciona si primero lanzo a java.util.Collection, pero no debería ser necesario…: /

También creo que es debido al uso de getDeclaredMethods en lugar de getMethods, intenté recorrer todas las interfaces pero de alguna manera no encontré la interfaz de Colección en getInterfaces () ...

hm, esto parece funcionar ... no estoy completamente seguro de por qué.
https://github.com/kivy/pyjnius/pull/466/files#diff -06f2b31838f083623d82353f734d644a

editar: uh, salvo por una segfault ... https://github.com/kivy/pyjnius/runs/348651345
intenté ejecutar de nuevo en caso de que fuera un problema técnico, se bloqueó nuevamente en ubuntu, python3.8, java 10 ...
edit2: muy confuso, toda la combinación actual funcionó cuando excluí 3.8 / java10 / ubuntu juntos, luego habilité java 9 y 11, y obtuve el mismo bloqueo con 3.7 / 11 / ubuntu ... bueno, al menos puedo instalar openjdk-11-jdk en mi ubuntu y prueba con python3.7 fácilmente ... ... y funciona. 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-5c1901a5b
Incindentalmente, parece que conda-forge build en Linux también tiene algunos segfaults en 1.2.1, por lo que el problema podría haber estado presente antes de mi cambio.

el parche funciona para mí en collab

golpe educado. Sería bueno fusionar este. Agregué un comentario al diff sugiriendo un comentario de código.

Perdón por dejar que esto se demore, realmente no tengo idea de qué impide que pase el CI, y no me gusta deshabilitar parte de los objetivos solo para silenciar un error incomprensible, estoy de acuerdo en dejar que este bitrot no sea mejor, pero yo ' No estoy seguro de cómo seguir adelante con esto.

Me preguntaba si se trataba de un problema de concurrencia según # 480, pero no creo que pytest sea concurrente de forma predeterminada.

Intenté reproducirlo localmente, pero no logré reproducir el # 480. Aquí estaba mi comando, es una imagen basada en 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

Todas las pruebas pasaron en el maestro y en la rama.

Observo el mismo problema, los métodos de superclase no son accesibles en 1.2.1 pero todo funciona en 1.2.0. Este es un error bastante desagradable, ¿no crees que tiene sentido eliminar la versión 1.2.1 o marcarla como inutilizable de alguna manera?

Perdón por dejar que esto se demore, realmente no tengo idea de qué impide que pase el CI, y no me gusta deshabilitar parte de los objetivos solo para silenciar un error incomprensible, estoy de acuerdo en dejar que este bitrot no sea mejor, pero yo ' No estoy seguro de cómo seguir adelante con esto.

¿Puedo sugerir que se vuelvan a ejecutar las pruebas de CI? ¿Podemos intentar reducir esto? ¿Es un problema en este parche o un problema con una versión anterior?

Para volver a esto:

No creo que mezclar getDeclaredMethods() y getMethods() sea ​​la respuesta. getMethods() es suficiente.

Mis casos de prueba para esto son:

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

Varios fallan cuando solo usamos getDeclaredMethods ().

Mi único problema con getMethods() es que test_inheritance.py falla. Esto es solo un poco problemático: el método newInstance() estático newInstance() org.jnius.Child anula el método org.jnius.Parent getMethods() ve ambos métodos newInstance() , por lo que construye un JavaMultipleMethod. Esto es incorrecto: Child.newInstance() debería ocultar Parent.newInstance() ; consulte https://www.java67.com/2012/08/can-we-override-static-method-in-java.html. También verifiqué esto usando Jshell:

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

Hola @tshirtman , veo que comprometiste getMethods (). También recomendaría los casos de prueba adicionales anteriores.
No estaba seguro de cómo resolver el método estático que oculta que Child.newInstance () debería ocultar Parent.newInstance (). Creo que tendrías que reordenar la iteración de clases e interfaces en autoclass (): recorrer el árbol para obtener las clases y luego aplicarlas en orden inverso, es decir, comenzando en java.lang.Object.

hm, de hecho, agregar esta prueba muestra que actualmente el objeto convertido como java.util.Queue autoclass no tiene un atributo size , lo cual es incorrecto.
Estoy de acuerdo con su análisis, búsqueda inversa, reemplazando los métodos principales con una firma idéntica en lugar de hacer un JavaMultipleMethod, que parece una buena estrategia.

501 pasó todas las pruebas. Cerrando este tema. (Alabado sea).

¡Aún faltan campos protegidos!

Cambiar esta línea de public a protected falla en la prueba.

Hay una discusión sobre el n. ° 500 sobre si los métodos / campos privados / protegidos deben exponerse en absoluto.

Creo que eso es diferente, actualmente se supone que tenemos todo, y con su solución, parece ser cierto para los métodos, pero aparentemente no es (¿y posiblemente nunca lo fue?) cierto para los campos, así que creo que es un error que debe resolver primero. , si luego decidimos permitir el filtrado de los métodos / campos que queremos ver en función de su nivel de privacidad. Como este error está cerrado, para mí tiene sentido abrir uno nuevo para ese caso.

parece ser cierto para los métodos, pero aparentemente no lo es (¿y posiblemente nunca lo fue?) cierto para los campos

Funcionó para <1.2.1, por lo que esperaría que funcione en> 1.2.1, <2.0 también, incluso si no debería haber funcionado para ninguna versión.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Hukuta picture Hukuta  ·  5Comentarios

hanslovsky picture hanslovsky  ·  3Comentarios

stania picture stania  ·  6Comentarios

tom19952000 picture tom19952000  ·  15Comentarios

apalala picture apalala  ·  7Comentarios