为什么我的应用程序客户端在GlassFish 4.1.2应用程序上更新JPA实体时会报告StreamCorruptedException?

时间:2017-12-16 13:00:47

标签: java-ee glassfish rmi iiop

我有一个应用程序客户端,它使用我在GlassFish 4.1.2上运行的应用程序执行以下操作:

  • 创建新人JPA实体。
  • 在服务器上调用create方法传递新人。
    • 注意:服务器会创建person and person2实体。
  • 从服务器检索person2 JPA实体。
  • 在person2.notes List属性中添加注释。
  • 在服务器上调用更新方法并传递更新的实体。

服务器正确更新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 个答案:

答案 0 :(得分:0)

事实证明,这个问题的根本原因是我的EntityState类不可序列化。我在EntityState类定义中添加了“implements Serializable”,我的问题就消失了。

有趣的是,我偶然发现了这个解决方案,因为我想在请求更新之前我可能需要在客户端添加一些虚拟历史记录。当我将具有EntityState的事件添加到客户端的历史记录并在服务器上调用updatePerson2方法时,客户端立即报告EntityState不可序列化。