Menemukan bug dengan pyjnius ketika berhadapan dengan kelas Java dengan banyak konstruktor.
Ketika saya mengeksekusi kode Java di bawah ini, metode utama akan memanggil konstruktor ke-2 dan selesai dengan anggun.
Ketika saya mengeksekusi kode python di bawah ini, itu akan melaporkan bahwa konstruktor tidak ditemukan.
(jnius.JavaException: No constructor matching your arguments, available: ['(ILjava/lang/String;)V', '(ILjava/lang/String;Ljava/lang/Object;[I)V'])
Tetapi ketika saya menghapus konstruktor pertama dalam kode Java, kode python saya dengan pyjnius dapat dengan benar menemukan satu-satunya konstruktor dan menyelesaikan dengan anggun.
Kelas Jawa
public class SampleJavaClass {
public SampleJavaClass( int arg1, String arg2, int arg3, Object arg4, int... arg5 ) {
System.out.println("arg1: " + Integer.toString(arg1));
System.out.println("arg2: " + arg2);
System.out.println("arg3: " + arg3);
System.out.println("arg3: " + arg4);
System.out.println("arg4: " + arg5.toString());
}
// the constructor plans to use
public SampleJavaClass (int arg1, String arg2, Object arg3, int... arg4) {
System.out.println("arg1: " + Integer.toString(arg1));
System.out.println("arg2: " + arg2);
System.out.println("arg3: " + arg3);
System.out.println("arg4: " + arg4.toString());
}
public static void main(String[] args) {
SampleJavaClass test = new SampleJavaClass(1, "var2", null, 4);
}
}
Kode python dengan pyjnius
import os
currentPath = os.getcwd()
classpath = currentPath + "/SampleJavaClass.class"
import jnius_config
jnius_config.set_classpath('.', classpath)
from jnius import autoclass
def main():
SampleJavaClass = autoclass("SampleJavaClass")
SampleJavaClass(1, "var2", None, 4)
print("Execution finished!")
if __name__ == "__main__":
main()
sudahkah Anda mencoba menggunakan petunjuk tanda tangan konstruktor?
Lihat https://github.com/kivy/pyjnius/blob/307659b13c1e5583fcb25603b7d3732265ffd4a0/tests/test_constructor.py#L54 untuk contoh.
Ketika pyjnius memanggil metode atau konstruktor, pertama-tama ia memeriksa apakah ada 0, 1, atau beberapa konstruktor atau metode dengan nama yang diberikan. Jika hanya ada 1 itu selalu membuat panggilan, berharap yang terbaik. Jika ada beberapa, proses penilaian ini dilakukan untuk mencoba memutuskan apakah masing-masing dapat diterima atau tidak. Mudah-mudahan satu dan hanya satu yang bisa diterima; jika tidak, itu melempar kesalahan.
Dalam hal ini, menolak keduanya karena konstruktor tidak dapat diterima. Menggunakan petunjuk tanda tangan mengatasi masalah dengan membuatnya melewati proses penilaian. Petunjuk tanda tangan adalah solusi yang baik.
Untuk masalah ini, saya melihat lebih dekat pada kode dan menemukan sebenarnya ada bug yang menyebabkan ini gagal. Dan dengan senang hati itu adalah perbaikan yang mudah. Saya akan membuat PR dengan unit test sebentar lagi.
sudahkah Anda mencoba menggunakan petunjuk tanda tangan konstruktor?
Lihat
untuk contoh.
Saya mencoba menambahkan tanda tangan seperti yang ditunjukkan oleh kode di bawah ini sekarang, tetapi itu mengeluarkan Kesalahan Pernyataan. Di mana saya mengacaukan?
Kesalahan
File "jnius/jnius_export_class.pxi", line 270, in jnius.JavaClass.__init__
File "jnius/jnius_export_class.pxi", line 319, in jnius.JavaClass.call_constructor
AssertionError
Kode python dengan pyjnius
import os
currentPath = os.getcwd()
classpath = currentPath + "/SampleJavaClass.class"
import jnius_config
jnius_config.set_classpath('.', classpath)
from jnius import autoclass
def main():
SampleJavaClass = autoclass("SampleJavaClass")
SampleJavaClass(1, "var2", None, 4, signature="(ILjava/lang/String;Ljava/lang/Object;[I)V")
print("Execution finished!")
if __name__ == "__main__":
main()
Berikut adalah kode yang relevan:
requestedDefn = kwargs.pop('signature', None)
for definition, is_varargs in definitions:
found_definitions.append(definition)
d_ret, d_args = parse_definition(definition)
if requestedDefn == definition:
assert not is_varargs
scores=[]
score=1
scores.append((score, definition, d_ret, d_args, args))
break
Mengapa petunjuk tanda tangan tidak dapat digunakan dengan argumen variabel?
Tidak apa-apa, saya menemukan jawabannya dan memiliki perbaikan untuk ini. Saya akan menambahkannya ke PR.
@enjoybeta Saya memperbaiki ini di PR, tetapi intinya, solusi petunjuk tanda tangan tidak berfungsi di rilis saat ini.
@cmacdonald , apakah ada solusi lain yang dapat mereka gunakan di sini?
Tidak ada yang di atas kepala saya - tambahkan kelas pabrik Java cepat yang memanggil konstruktor varargs?
Bagaimanapun, saya mengusulkan kita dapat menutup masalah karena rilis Jnius berikutnya akan memperbaiki bug.
Ide bagus! Metode pabrik dapat menanganinya jika mengubah kode sumber itu adalah opsi. Jika tidak, mereka dapat membuat kelas utilitas pembantu terpisah yang melakukannya untuk mereka.
Setuju, kita bisa menutup masalah ini sekarang.
Komentar yang paling membantu
Ketika pyjnius memanggil metode atau konstruktor, pertama-tama ia memeriksa apakah ada 0, 1, atau beberapa konstruktor atau metode dengan nama yang diberikan. Jika hanya ada 1 itu selalu membuat panggilan, berharap yang terbaik. Jika ada beberapa, proses penilaian ini dilakukan untuk mencoba memutuskan apakah masing-masing dapat diterima atau tidak. Mudah-mudahan satu dan hanya satu yang bisa diterima; jika tidak, itu melempar kesalahan.
Dalam hal ini, menolak keduanya karena konstruktor tidak dapat diterima. Menggunakan petunjuk tanda tangan mengatasi masalah dengan membuatnya melewati proses penilaian. Petunjuk tanda tangan adalah solusi yang baik.
Untuk masalah ini, saya melihat lebih dekat pada kode dan menemukan sebenarnya ada bug yang menyebabkan ini gagal. Dan dengan senang hati itu adalah perbaikan yang mudah. Saya akan membuat PR dengan unit test sebentar lagi.