Почему мой клиент приложения сообщает об исключении StreamCorruptedException при обновлении сущности JPA в приложении GlassFish 4.1.2?

У меня есть клиент приложения, который выполняет следующие действия, используя мое приложение, работающее на GlassFish 4.1.2:

  • Создает сущность JPA нового лица.
  • Вызывает метод создания на сервере и передает нового человека.
    • Примечание. Сервер создает сущность person и person2.
  • Извлекает лицо person2 JPA с сервера.
  • Добавляет заметку в свойство списка person2.notes.
  • Вызывает метод обновления на сервере и передает обновленный объект.

Сервер корректно обновляет сущность person2 и не сообщает об ошибках. Однако клиент сообщает о следующей ошибке при запуске метода обновления.

javax.ejb.EJBException: java.rmi.MarshalException: CORBA MARSHAL 1330446347 Maybe; nested exception is: 
    org.omg.CORBA.MARSHAL: WARNING: 00810011: Exception from readValue on ValueHandler in CDRInputStream  vmcid: OMG  minor code: 11 completed: Maybe
    at com.elliottlogic.elis.ejb.person._PersonManagerRemote_Wrapper.updatePerson2(com/elliottlogic/elis/ejb/person/_PersonManagerRemote_Wrapper.java) ~[classes/:na]
    at com.elliottlogic.elis.access.Migrator.migratePeople(Migrator.java:216) ~[classes/:na]
    at com.elliottlogic.elis.access.Main.main(Main.java:152) [classes/:na]
Caused by: java.rmi.MarshalException: CORBA MARSHAL 1330446347 Maybe; nested exception is: 
    org.omg.CORBA.MARSHAL: WARNING: 00810011: Exception from readValue on ValueHandler in CDRInputStream  vmcid: OMG  minor code: 11 completed: Maybe
    at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.mapSystemException(Util.java:266) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:211) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:150) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.presentation.rmi.codegen.CodegenStubBase.invoke(CodegenStubBase.java:226) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.elliottlogic.elis.ejb.person.__PersonManagerRemote_Remote_DynamicStub.updatePerson2(com/elliottlogic/elis/ejb/person/__PersonManagerRemote_Remote_DynamicStub.java) ~[classes/:na]
    ... 3 common frames omitted
Caused by: org.omg.CORBA.MARSHAL: WARNING: 00810011: Exception from readValue on ValueHandler in CDRInputStream
    at com.sun.proxy.$Proxy19.valuehandlerReadException(Unknown Source) ~[na:na]
    at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.readRMIIIOPValueType(CDRInputStream_1_0.java:900) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:995) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.encoding.CDRInputObject.read_value(CDRInputObject.java:518) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.presentation.rmi.DynamicMethodMarshallerImpl$14.read(DynamicMethodMarshallerImpl.java:383) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.presentation.rmi.DynamicMethodMarshallerImpl.readResult(DynamicMethodMarshallerImpl.java:482) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:201) ~[glassfish-corba-orb-4.0.1.jar:na]
    ... 6 common frames omitted
Caused by: java.io.StreamCorruptedException: WARNING: ORBIO00013: Stream corrupted
    at com.sun.proxy.$Proxy70.streamCorrupted(Unknown Source) ~[na:na]
    at com.sun.corba.ee.impl.io.IIOPInputStream.inputClassFields(IIOPInputStream.java:2550) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.io.IIOPInputStream.inputObjectUsingFVD(IIOPInputStream.java:1676) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.io.IIOPInputStream.simpleReadObject(IIOPInputStream.java:405) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.io.ValueHandlerImpl.readValueInternal(ValueHandlerImpl.java:307) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.io.ValueHandlerImpl.readValue(ValueHandlerImpl.java:273) ~[glassfish-corba-orb-4.0.1.jar:na]
    at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.readRMIIIOPValueType(CDRInputStream_1_0.java:893) ~[glassfish-corba-orb-4.0.1.jar:na]
    ... 11 common frames omitted

Ниже приведен код клиента приложения, который создает сущность person и person2.

try {

    person = elis.getPersonManager().createPerson(
            person,
            ELISClientType.APPLICATION,
            "0.0.0.0",
            "Migrated Person. Originally Created: " + rs.getString("CREATED") + ", Original Creater: "
                    + convertEmployeeToELISUserName(rs.getString("CREATOR")) + ".");

} catch (AuthorizationException e) {

    logger.error("AuthorizationExcepton: ", e);

}

Ниже приведен код клиента приложения, который обновляет сущность person2.

Person2 person2 = elis.getPersonManager().readPerson2ByID(person.getId());

List<Portrait2> portrait2s = new ArrayList<Portrait2>();
List<Email> emails = new ArrayList<Email>();
List<Telephone> telephones = new ArrayList<Telephone>();
List<Postal> postals = new ArrayList<Postal>();
List<Flex> flexes = new ArrayList<Flex>();
List<EntityEvent> history = new ArrayList<EntityEvent>();

person2.setPortrait2s(portrait2s);
person2.setEmails(emails);
person2.setTelephones(telephones);
person2.setPostals(postals);
person2.setFlexes(flexes);
person2.setHistory(history);

List<EntityNote> personNotes = new ArrayList<EntityNote>();

personNotes.add(note);

person2.setNotes(personNotes);

// The following method is throwing an EJBException for some reason that can be caught and
// ignored.
try {

    person2 = elis.getPersonManager().updatePerson2(person2, ELISClientType.APPLICATION,
            "0.0.0.0", "Added note.");

} catch (EJBException e) {

    logger.error("EJBExcepton: ", e);

}

Ниже приведен код сервера, который обновляет person2:

@RolesAllowed("Initializer")
@Permission("Person2.update")
@Override
public Person2 updatePerson2(Person2 updatedPerson2, ELISClientType clientType, String ipAddress, String note)
        throws AuthorizationException {

    logger.trace("Started .updatePerson2({}, {}, {}, {}).", updatedPerson2, clientType, ipAddress, note);

    Person2 managedPerson2 = em.find(Person2.class, updatedPerson2.getId());

    if (managedPerson2 == null)
        throw new IllegalArgumentException("ID, " + updatedPerson2.getId() + ", is not associated with a Person2.");

    // Add items to detached person that are managed by system.
    updatedPerson2.setHistory(managedPerson2.getHistory());

    // Maintain Person and Portrait2s relationships.
    updatedPerson2.setPerson(managedPerson2.getPerson());
    updatedPerson2.setPortrait2s(managedPerson2.getPortrait2s());

    ELISUser user = userManager.readELISUserByName(context.getCallerPrincipal().getName());

    OffsetDateTime currentDateTime = OffsetDateTime.now();

    // Due to bug in GlassFish (GLASSFISH-21184) where @Valid @ElementCollection do not work together, I
    // have to manually validate person.
    try {

        Set<ConstraintViolation<Person2>> personCV = validator.validate(updatedPerson2);

        if (personCV.size() > 0)
            throw new ConstraintViolationException(personCV);

    } catch (ConstraintViolationException e) {

        logger.error("Caught ConstraintViolationException: {}", e.toString());

        logger.trace("Failed to complete .updatePerson().");

        throw e;
    }

    EntityEvent event = new EntityEvent();
    event.setType(EntityEventType.UPDATE);
    event.setCreated(currentDateTime);
    event.setCreater(user);
    event.setClientType(clientType);
    event.setIpAddress(ipAddress);
    event.setChanges(Historian.compare(managedPerson2, updatedPerson2));

    if (note == null || note == "")
        event.setNote("Updated person2.");
    else
        event.setNote(note);

    EntityState entityState = new EntityState();
    entityState.setVersion(managedPerson2.getVersion());
    entityState.setXmlState(convertToCharArray(managedPerson2));

    event.setEntityState(entityState);

    updatedPerson2.getHistory().add(event);

    updatedPerson2 = em.merge(updatedPerson2);

    ELISEvent elisEvent = new ELISEvent();
    elisEvent.setType(ELISEventType.ENTITY_UPDATE);

    elisEvent.setEntityClass(updatedPerson2.getClass().getCanonicalName());
    elisEvent.setEntityId(updatedPerson2.getId());
    elisEvent.setEntityVersion(updatedPerson2.getVersion());
    elisEvent.setEntityName(updatedPerson2.getPerson().getName());

    eventManager.createELISEvent(elisEvent);

    logger.trace("Finished .updatePerson2.");

    return updatedPerson2;

}

Если я закомментирую весь код, кроме строки возврата в методе updatePerson2, клиент приложения не сообщит о каких-либо проблемах, поэтому что-то в методе updatePerson2 повреждает поток.

1 ответ

Оказывается, основной причиной этой проблемы было то, что мой класс EntityState не был сериализуемым. Я добавил "реализует Serializable" в определение класса EntityState, и мои проблемы исчезли.

Интересно, что я наткнулся на это решение, потому что подумал, что, возможно, мне нужно добавить некоторую фиктивную историю на стороне клиента, прежде чем запрашивать обновление. Когда я добавил событие с EntityState в историю на стороне клиента и вызвал метод updatePerson2 на сервере, клиент сразу же сообщил, что EntityState не сериализуем.

Другие вопросы по тегам