I have a application client that performs the following actions using my application running on GlassFish 4.1.2:
- Creates a new person JPA entity.
- Calls a create method on server an passes new person.
- Note: Server creates a person and person2 entity.
- Retrieves person2 JPA Entity from server.
- Adds a note to the person2.notes List property.
- Calls an update method on server and passes the updated entity.
The server updates the person2 entity correctly and does not report any errors. The client however reports the following error when running the update method.
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
The following is the application client code that creates the person and person2 entity.
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);
}
The following is the application client code that updates the person2 entity.
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);
}
The following is the server code that updates 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;
}
If I comment out all the code except the return line in the updatePerson2 method, the application client does not report any issues, so something in the updatePerson2 method is corrupting the stream.
It turns out that the root cause of this issue was that my EntityState class was not serializable. I added an "implements Serializable" to the EntityState class definition and my problems disappeared.
Interestingly, I stumbled across this solution because I thought maybe I need to add some dummy history on the client side before requesting the update. When I added the event with EntityState to the history on the client side and called the updatePerson2 method on the server, the client immediately reported that EntityState is not serializable.