christianAppl opened a new pull request, #158:
URL: https://github.com/apache/poi-xmlbeans/pull/158

   Two threads that touch XMLBeans for the first time at the same moment can 
deadlock in class initialization when one enters through `XmlObject.Factory` 
and the other through a generated type.
   
   - `XmlBeans.<clinit>` initializes `NO_TYPE = getNoType()`, which needs 
`BuiltinSchemaTypeSystem` and therefore its superclass `SchemaTypeLoaderBase`.
   - `SchemaTypeLoaderBase.<clinit>` initializes `USER_AGENT` from 
`XmlBeans.getVersion()` and `XmlBeans.getTitle()`, which needs `XmlBeans`.
   - A generated type initializes `SchemaTypeSystemImpl`, another subclass of 
`SchemaTypeLoaderBase`, before it reaches `XmlBeans`. So the first thread holds 
the initialization lock of `XmlBeans` and waits for `SchemaTypeLoaderBase`, 
while the second holds `SchemaTypeLoaderBase` and waits for `XmlBeans`. Neither 
returns.
   
   This is the cycle described in XMLBEANS-616. `USER_AGENT` is the only static 
reference from `SchemaTypeLoaderBase` back to `XmlBeans`, and it is only used 
when a schema is fetched over HTTP. This change builds the user agent where it 
is used, so the class initialization of `SchemaTypeLoaderBase` no longer 
depends on `XmlBeans` and the ring is gone. The header value is unchanged.
   
   The new test `misc.detailed.StaticInitializationRingTest` reproduces the 
race inside one JVM: each attempt loads XMLBeans from the test class path in a 
class loader of its own, so its classes start uninitialized, and two threads 
touch it at once, through `XmlObject.Factory` and through XMLBeans' own 
generated `SchemaDocument`.
   
   Measured against xmlbeans-5.4.1.jar (JDK 21):
   
   | | without the change | with the change |
   |---|---|---|
   | two threads, fresh JVM each, 20 runs | 15 hung | 0 hung |
   | the new test's probe, 20 attempts in one JVM | 9 hung | 0 hung |
   | the new test, 3 runs | 3 failed | 3 passed |
   
   Until a release contains this, warming XMLBeans up on one thread before 
concurrent use (as suggested in the issue) avoids the deadlock.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to