Skip to content

[OPENJPA-2962] Do not create a broker to obtain a class loader - #177

Open
rzo1 wants to merge 1 commit into
masterfrom
OPENJPA-2962
Open

[OPENJPA-2962] Do not create a broker to obtain a class loader#177
rzo1 wants to merge 1 commit into
masterfrom
OPENJPA-2962

Conversation

@rzo1

@rzo1 rzo1 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

The four schema management methods each built a Broker through newBrokerImpl() only to call getClassLoader() on it. That loader was always null: BrokerImpl assigns it in initialize(), which newBrokerImpl() never reaches, so the broker was asked a question it structurally could not answer and then dropped.

They now pass the thread context class loader, which is the value initialize() would have assigned, and which postCreationCallback() already passes for the same synchronizeMappings() calls.

Closing the broker instead was not available: close() runs free(), which dereferences a cache an uninitialized broker has not got, so a finally { broker.close(); } would have turned four working methods into four that throw. Nothing heavyweight leaked either — without initialize() there is no store manager, no connection and no registration with the factory; the cost was a finalizable object per call whose finalizer threw and was discarded.

The only behaviour that changes is that a class loader now reaches MappingTool, so a custom openjpa.Sequence class resolves where it previously fell back to the bootstrap loader.

Routing through getClassResolverInstance() was considered and rejected: where OpenJPA's own loader differs from the context loader it returns a MultiClassLoader that is then re-resolved downstream against a different context class, producing a nesting an initialized broker would never produce.

The ticket also names dropPersistenceStrucuture and validatePersistenceStruture; cbb19f7 has since corrected both spellings.

The four schema management methods each built a Broker through
newBrokerImpl() only to call getClassLoader() on it. That loader was always
null: BrokerImpl assigns it in initialize(), which newBrokerImpl() does not
reach, so the broker answered a question it could not answer and was then
dropped. They now pass the thread context class loader, which is the value
initialize() would have assigned and which postCreationCallback() already
passes for the same synchronizeMappings() calls.

Closing the broker instead was not an option: close() runs free(), which
dereferences a cache that an uninitialized broker has not got, so it throws.
Nothing heavyweight leaked, though, since without initialize() there is no
store manager, no connection and no registration with the factory; what the
call cost was a finalizable object per invocation whose finalizer threw and
was discarded.

The only behaviour that changes is that a class loader now reaches
MappingTool, so a custom openjpa.Sequence class resolves where it
previously fell back to the bootstrap loader.

The ticket also names dropPersistenceStrucuture and
validatePersistenceStruture; cbb19f7 has since corrected both spellings.
@rzo1 rzo1 self-assigned this Sep 2, 2026
@rzo1
rzo1 requested review from cristof and solomax September 2, 2026 19:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants