Hi Ofer, I don't think anything in the way that we are using the serialized CAS formats here should be considered official. This is using internal API and internal details that work nicely, but that are afaik not part of any specification and nowhere near of being officially supported. But in any case, it can be very useful from time to time ;)
When the CAS is reinitialized from a serialized CAS, depending on the serialization format, more or less all of the in-memory structures are reset/rewritten. It may be nice if (for convenience) the JCas structures would be automatically re-initialized if they had been initialized in the CAS before, but in the realm of black magic, I'd say we should be happy that it works and just live with the occasional inconvenience ;) I believe normally the JCas structures would be automatically reinitialized when you pass the CAS on to the next JCas-based analysis engine. But when you work outside of pipelines, calling jcas.getCAS().getJCas() should just do the same job nicely. My suggestion: wrap it in some static method with a proper comment and pretend the inconvenience would not exist ;) Cheers, -- Richard On 20.05.2014, at 14:12, Ofer Bronstein <[email protected]> wrote: > Hi Richard, > > First of all, my NullPointerException was because I was deserializing from > an XMI and not from a binary serialization, so I switched to the binary one. > > But then I got a new problem - I got a ClassCastException when casting the > return value of ll_getFSForRef(address) to SentenceAnnotation. This is > because the returned value was of type AnnotationImpl, which is not in the > inheritance hierarchy of Annotation (a bit misleading, but OK). And this > only happened with a deserialized JCas, a normal one created in memory > indeed returned a valid Annotation. This was solved by using your > suggestion and calling jcas.getCAS().getJCas() once after deserializing the > JCas (and before trying to resolve all addresses). > > I looked a little into it, and it seems that the problem lies here: > I create an empty JCas just before deserializing into it, using ae.newJCas(), > where ae is an AnalysisEngine object. The CAS created for the new JCas is > for some reason *different* from its svd.baseCAS. This has the effect that > deserializeCASComplete (or actually CASImpl.reinit) eventually uses the > svd.baseCAS for deserializing into, explicitly putting null in the jcas. > This null means I must afterwards call jcas.getCAS().getJCas(), otherwise > the jcas is somewhat broken. > > I don't know if this is intentional behavior or some edge case bug, and if > this happens because of the way I create the JCas and deserialized. But > this is definitely pretty weird behavior, which may be worth some > consideration. > > Ofer
