Десериализация класса — различия между Jython и Java

Мне удалось сериализовать пользовательский JFrame в базу данных, и я хотел бы его десериализовать.
К сожалению, во время предполагаемой десериализации у меня возникла ошибка, которую я не могу устранить.

import sys

from java.io import *
from java.lang import Class
from java.sql import *
from methods import *


class MyFrame(JFrame):
    def __init__(self):
        self._title = 'Frame di prova'
        self.setTitle(self._title)
        c = self.getContentPane()

        self._insertN = JTextField(20)
        nameLabelPane, nameFieldPane = incidentPanels(
            JLabel("Nome"), [self._insertN])

        firstBlock = (nameLabelPane, nameFieldPane)

        firstPane = gridPane(firstBlock)

        if self._title.startswith('Modifica'):
            saveBtn = JButton('Modifica')
        else:
            saveBtn = JButton('Salva')

        globalPane = JPanel()
        gridBagger(globalPane, (firstPane, saveBtn))
        c.add(JScrollPane(globalPane))

        self.pack()


SQL_CREATE_TABLE = "create table if not exists serialized_java_objects (object_name varchar(1000), serialized_object blob)"
SQL_SERIALIZE_OBJECT = "INSERT INTO serialized_java_objects(object_name, serialized_object) VALUES (?, ?)"
SQL_DESERIALIZE_OBJECT = "SELECT serialized_object FROM serialized_java_objects limit 1"


def createTable(connection):
    connection.createStatement().executeUpdate(SQL_CREATE_TABLE)

def serializeJavaObjectToDB(connection, objectToSerialize):
    pstmt = connection.prepareStatement(SQL_SERIALIZE_OBJECT)

    pstmt.setString(1, 'Frame di prova')
    pstmt.setObject(2, objectToSerialize)
    pstmt.executeUpdate()
    pstmt.close()

def deSerializeJavaObjectFromDB(connection):
    pstmt = connection.prepareStatement(SQL_DESERIALIZE_OBJECT)
    rs = pstmt.executeQuery()
    rs.next()

    buf = rs.getBytes(1)
    objectIn = None
    if (buf != None):
        objectIn = ObjectInputStream(ByteArrayInputStream(buf))

    deSerializedObject = objectIn.readObject()

    rs.close()
    pstmt.close()

    return deSerializedObject


def getMySqlConnection():
    mysqlConn = None

    mysqlLog_server = "localhost"
    mysqlLog_username = "root"
    mysqlLog_password = ""
    mysqlLog_database = "tuttle"

    properties = Properties()
    properties.put("user", mysqlLog_username)
    properties.put("password", mysqlLog_password)

    url = "jdbc:mysql://" + mysqlLog_server + "/" + mysqlLog_database + \
        "?user=" + mysqlLog_username + "&password=" + mysqlLog_password

    mysqlConn = DriverManager.getConnection(url)
    return mysqlConn


def main(args):
    frame = MyFrame()
    Class.forName("com.mysql.jdbc.Driver")
    connection = getMySqlConnection()
    createTable(connection)

    serializeJavaObjectToDB(connection, frame)
    objFromDatabase = deSerializeJavaObjectFromDB(connection)

    objFromDatabase.setVisible(True)


if __name__ == '__main__':
    main(sys.argv)

Ошибка на строке objFromDatabase = deSerializeJavaObjectFromDB(connection), в частности на deSerializedObject = objectIn.readObject() и она следующая:

Traceback (most recent call last):
  File "provaSerializzazione.py", line 119, in <module>
    main(sys.argv)
  File "provaSerializzazione.py", line 113, in main
    objFromDatabase = deSerializeJavaObjectFromDB(connection)
  File "provaSerializzazione.py", line 74, in deSerializeJavaObjectFromDB
    deSerializedObject = objectIn.readObject()
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at java.io.ObjectInputStream.resolveClass(Unknown Source)
        at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
        at java.io.ObjectInputStream.readClassDesc(Unknown Source)
        at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
        at java.io.ObjectInputStream.readObject0(Unknown Source)
        at java.io.ObjectInputStream.readObject(Unknown Source)
        at java.io.ObjectInputStream.readObject(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
java.lang.ClassNotFoundException: java.lang.ClassNotFoundException: org.python.proxies.__main__$MyFrame$3

Любопытно, что при замене строки frame = MyFrame() на frame = JFrame() функция сериализуется корректно, без ошибок.
Похоже, что функция десериализации не принимает класс Python (который, в свою очередь, расширяет JFrame). Что мне делать, чтобы десериализовать мой класс MyFrame на языке jython? Заранее спасибо!


person Memmo    schedule 04.09.2020    source источник
comment
Это не похоже на проблему десериализации. Похоже, ваш класс MyFrame не существует в пути к классам.   -  person Onur Baştürk    schedule 09.09.2020
comment
@OnurBaştürk Так что бы ты посоветовал мне сделать?   -  person Memmo    schedule 09.09.2020
comment
Ну, я не использую Python. Поэтому я не знаю, как вы импортируете объекты Java в проект Python. Может быть, вы можете объяснить структуру вашего проекта и механизм импорта, тогда я попытаюсь найти способ. Позвольте мне сначала спросить. Является ли MyFrame объектом Java? я думаю это не   -  person Onur Baştürk    schedule 09.09.2020
comment
Вы говорите, что можете сериализовать пользовательский объект JFrame в базу данных. Я думаю, что этот пользовательский объект - это MyFrame, верно? И как выглядят данные в базе? Это в формате JSON или sth. еще?   -  person Onur Baştürk    schedule 09.09.2020
comment
Тип данных в базе данных — BLOB, так как это сериализованный объект. Он спасен, и я очень горжусь этим. Ошибка возникает во время десериализации. class MyFrame(JFrame) — это класс Python/Jython, который расширяет класс JFrame Java, и это, вероятно, не подходит для десериализатора (Java). На самом деле, если бы я объявил JFrame, например, с f = JFrame(), при выполнении всей программы не было бы проблем! Но мне нужно расширение класса...   -  person Memmo    schedule 09.09.2020
comment
Да, я вижу это. Возможно, вы могли бы вставить данные в формате JSON, а затем преобразовать их в свой объект MyFrame после выбора его в виде строки. Я думаю, что в Jython будет какая-то библиотека для десериализации JSON. В Java есть библиотека Джексона, и я вижу, что есть библиотека python-javaobj. думаю такой подход сработает   -  person Onur Baştürk    schedule 09.09.2020


Ответы (1)


Вам нужно использовать org.python.util.PythonObjectInputStream вместо java.io.ObjectInputStream.

person Anar Sultanov    schedule 10.09.2020