[
https://issues.apache.org/jira/browse/XMLBEANS-636?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18132640#comment-18132640
]
François Rajotte commented on XMLBEANS-636:
-------------------------------------------
I saw activity in the mailing about a problem I thought was similar to this
one: XMLBEANS-661
Although it turned out to be unrelated, I did spend some more time on this
problem and thought I'd share some of the things I found.
I now believe that the regression with regards to multi-schema bean factory
methods was specifically introduced by this commit:
https://github.com/apache/poi-xmlbeans/commit/7a6f8e3159c897335aa1c96fac9b64f813ba2b53#diff-d6b1647188c1a397a29bdd622f14cc9e51fe2f9f63a8532bc2e96ac6584a90cf
In this commit, the SchemaTypeCodePrinter that is used to build the generated
java classes was updated. The generated Factory classes were changed to use the
SchemaTypeSystem (held by the TypeSystemHolder) rather than the context type
loader (XmlBeans.getContextTypeLoader).
With this change, the convenience Factory classes are now unable to resolve
types that are outside their own type system.
There are still remnants of the old behavior that remain documented in the
javadoc such as this comment here that mentions that the context type loader is
used by the convenient factory methods:
https://github.com/apache/poi-xmlbeans/blob/fd4458788634baa390de13796a09942a0ffa0a53/src/main/java/org/apache/xmlbeans/SchemaTypeLoader.java#L48-L57
Types that span multiple type systems are not really tested by the existing
tests. However, I did find one minor side effect that could have been observed
at the time.
In the ElementRestriction test, an element that was previously of concrete type
XmlString became a more generic XmlAnyType. This regression was found later
during the migration from maven to gradle and was addressed by changing the
test:
https://github.com/apache/poi-xmlbeans/commit/df29cd7d19ad683db5ca596b69155aa8625e3361#diff-33f73d05d94355392159e6d40f52d45d813a08f6f84ed29b63dc58992cd3dde6L82-R83
The reason why this regression had not been found sooner is because a previous
refactor (XMLBEANS-532) had disabled the test classes that did not end in
Test.java or Tests.java:
https://github.com/apache/poi-xmlbeans/blob/258e01096ca3f85cb4e71bfbb0828d6159dac6f8/build.xml#L418-L419
In any case, this small side effect is probably undefined behavior. But I
thought it was interesting to mention nonetheless.
I am not sure of the rationale of moving the Factory methods away from the
context type loader. It seems to have been somehow related to enhancements
related to java9 support. And I'm not sure what kind of issues we would have if
we brought back the context Type Loader by default for Factory classes.
If we were to revisit the Factory type loaders, I believe it would have to be
in the ElementFactory class. The getTypeLoader() method
(https://github.com/apache/poi-xmlbeans/blob/fd4458788634baa390de13796a09942a0ffa0a53/src/main/java/org/apache/xmlbeans/impl/schema/ElementFactory.java#L36-L38)
could be updated to return a different type loader.
However, there are a few problems with such a change.
One problem is that the getTypeLoader() method is public and therefore exposed
in the generated beans. Despite its name, this method's signature forces the
return type to be of SchemaTypeSystem rather than the more generic
SchemaTypeLoader. Changing the return type to match the method name would
introduce backwards-compatibility issues with the generated beans. To work
around this limitation, we could introduce a new package-private method that
returns a SchemaTypeLoader, for internal use and update all the factory classes
to use it rather than getTypeLoader().
If, for some reason, we still want to prefer looking up types in the local
schema type system before interrogating the context type loader (for
performance reasons perhaps?), we could build a TypeLoader union (similar to
this:
https://github.com/apache/poi-xmlbeans/blob/fd4458788634baa390de13796a09942a0ffa0a53/src/main/java/org/apache/xmlbeans/XmlBeans.java#L407-L414)
which checks the local type system first before checking the context type
loader.
I've worked on some prototypes of these changes and it appears to solve the
issue at first glance. But I'm a bit worried because I don't fully understand
why we moved away from the context type loader in the first place.
> Incorrect processing of abstract XML types defined in multiple schema files
> ---------------------------------------------------------------------------
>
> Key: XMLBEANS-636
> URL: https://issues.apache.org/jira/browse/XMLBEANS-636
> Project: XMLBeans
> Issue Type: Bug
> Affects Versions: Version 4.0.0, Version 5.1.1
> Reporter: François Rajotte
> Priority: Major
> Attachments: AbstractType_xmlbeans-3.0.0.log,
> AbstractType_xmlbeans-5.1.1.log
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> We have observed a regression when upgrading XMLBeans from version 3.0.0 to
> 5.1.1.
> The issue is related to how concrete and abstract types are handled in
> XMLBeans when they are defined in different schema files.
> I have enhanced the existing "AbstractTypes" sample provided in the XMLBeans
> repository to show the regression. You can find the code in my private branch
> here:
> [https://github.com/JeSuisAbraham/xmlbeans/tree/AbstractTypes/samples/AbstractTypes]
> The "AbstractTypes" sample consists of two schema files.
> The abstractBase.xsd schema defines the document root, which contains
> abstract "figures".
> The myfigures.xsd schema contains concrete implementations of these abstract
> figures: a "square" and a "circle".
> Three tests are performed:
> * buildDocument: builds a document "top-down". Creates a document, adds
> abstract objects and specializes them into concrete objects.
> * buildDocument2: builds a document "down-top". Creates a document, creates
> the concrete objects and adds them to the document.
> * parseDocument: parses a document containing concrete types.
> All of these tests are broken in XMLBeans 4.+ whereas they worked in XMLBeans
> 3.x.
> I have attached the output of this test program when ran against XMLBeans
> 3.0.0 and XMLBeans 5.1.1 for comparison.
> The differences between v3.0.0 and v5.1.1 are:
> * buildDocument: In v5.1.1, the test throws a ClassCastException when trying
> to coerce an abstract object down to a concrete implementation.
> * buildDocument2: In v5.1.1, the document output does not contain the
> xsi:type attributes. The resulting document is not schema-valid.
> * parseDocument: In v5.1.1, the concrete objects are not recognized as such.
> They remain of the abstract type. The parsed document object in not
> schema-valid.
>
> Using a debugger, we've found the following differences between v3.0.0 and
> v5.1.1:
> The concrete types are resolved here using a SchemaTypeLoader:
> [https://github.com/apache/xmlbeans/blob/fb3f015826f1378b10178b7d4fe71bfe133c30ca/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java#L937]
> In 3.x.x, the schema type loader is of type "SchemaTypeLoaderImpl", and will
> fetch both locally in its own schema and in other schema type systems loaded
> into the system:
> [https://github.com/apache/xmlbeans/blob/a7cdcb1a37319d69eeef31a90badf9d2bb02de81/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderImpl.java#L372]
> In 5.x.x, the schema type loader is of type "TypeSchemaHolder", defined in
> the bean jar itself, and extends "SchemaTypeSystemImpl". This schema type
> loader only looks for types into its own schema:
> [https://github.com/apache/xmlbeans/blob/a7cdcb1a37319d69eeef31a90badf9d2bb02de81/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java#L1009]
> This change in behavior seems related to XMLBEANS-536.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]