Bug #3651
regression in server startup when _connect metadata is active and a database is loaded at startup
100%
History
#1 Updated by Eric Faulhaber about 8 years ago
Trunk revision 11268 introduced a server startup regression. I didn't notice it until now because it requires the combination of a database which auto-connects at startup and the use of the _connect (and _myconnection) metadata table.
At server startup, we get a stack overflow:
com.goldencode.p2j.cfg.ConfigurationException: Initialization failure
at com.goldencode.p2j.main.StandardServer.hookInitialize(StandardServer.java:1945)
at com.goldencode.p2j.main.StandardServer.bootstrap(StandardServer.java:958)
at com.goldencode.p2j.main.ServerDriver.start(ServerDriver.java:455)
at com.goldencode.p2j.main.CommonDriver.process(CommonDriver.java:444)
at com.goldencode.p2j.main.ServerDriver.process(ServerDriver.java:196)
at com.goldencode.p2j.main.ServerDriver.main(ServerDriver.java:796)
Caused by: java.lang.StackOverflowError
at java.math.BigInteger.abs(BigInteger.java:2422)
at java.math.BigInteger.pow(BigInteger.java:2219)
at java.math.BigDecimal.<init>(BigDecimal.java:934)
at java.math.BigDecimal.<init>(BigDecimal.java:872)
at com.goldencode.p2j.util.decimal.setValue(decimal.java:2130)
at com.goldencode.p2j.util.decimal.<init>(decimal.java:435)
at com.goldencode.p2j.util.datetime.<init>(datetime.java:333)
at com.goldencode.p2j.util.datetime.now(datetime.java:744)
at com.goldencode.p2j.persist.meta.ConnectTableUpdater.databaseConnected(ConnectTableUpdater.java:210)
at com.goldencode.p2j.persist.ConnectionManager.putConnected(ConnectionManager.java:3464)
at com.goldencode.p2j.persist.ConnectionManager.<init>(ConnectionManager.java:440)
at com.goldencode.p2j.persist.ConnectionManager.<init>(ConnectionManager.java:254)
at com.goldencode.p2j.persist.ConnectionManager$1.initialValue(ConnectionManager.java:271)
at com.goldencode.p2j.persist.ConnectionManager$1.initialValue(ConnectionManager.java:262)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:462)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:419)
at com.goldencode.p2j.persist.ConnectionManager.get(ConnectionManager.java:1929)
at com.goldencode.p2j.persist.BufferManager.<init>(BufferManager.java:590)
at com.goldencode.p2j.persist.BufferManager.<init>(BufferManager.java:439)
at com.goldencode.p2j.persist.BufferManager$1.initialValue(BufferManager.java:454)
at com.goldencode.p2j.persist.BufferManager$1.initialValue(BufferManager.java:451)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:462)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:419)
at com.goldencode.p2j.persist.BufferManager.get(BufferManager.java:610)
at com.goldencode.p2j.persist.Persistence$Context.<init>(Persistence.java:5044)
at com.goldencode.p2j.persist.Persistence$Context.<init>(Persistence.java:5041)
at com.goldencode.p2j.persist.Persistence$1.initialValue(Persistence.java:729)
at com.goldencode.p2j.persist.Persistence$1.initialValue(Persistence.java:726)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:462)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:419)
at com.goldencode.p2j.persist.Persistence.beginTransaction(Persistence.java:3661)
at com.goldencode.p2j.persist.meta.ConnectTableUpdater.databaseConnected(ConnectTableUpdater.java:221)
at com.goldencode.p2j.persist.ConnectionManager.putConnected(ConnectionManager.java:3464)
at com.goldencode.p2j.persist.ConnectionManager.<init>(ConnectionManager.java:440)
at com.goldencode.p2j.persist.ConnectionManager.<init>(ConnectionManager.java:254)
at com.goldencode.p2j.persist.ConnectionManager$1.initialValue(ConnectionManager.java:271)
at com.goldencode.p2j.persist.ConnectionManager$1.initialValue(ConnectionManager.java:262)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:462)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:419)
at com.goldencode.p2j.persist.ConnectionManager.get(ConnectionManager.java:1929)
at com.goldencode.p2j.persist.BufferManager.<init>(BufferManager.java:590)
at com.goldencode.p2j.persist.BufferManager.<init>(BufferManager.java:439)
at com.goldencode.p2j.persist.BufferManager$1.initialValue(BufferManager.java:454)
at com.goldencode.p2j.persist.BufferManager$1.initialValue(BufferManager.java:451)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:462)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:419)
at com.goldencode.p2j.persist.BufferManager.get(BufferManager.java:610)
at com.goldencode.p2j.persist.Persistence$Context.<init>(Persistence.java:5044)
at com.goldencode.p2j.persist.Persistence$Context.<init>(Persistence.java:5041)
at com.goldencode.p2j.persist.Persistence$1.initialValue(Persistence.java:729)
at com.goldencode.p2j.persist.Persistence$1.initialValue(Persistence.java:726)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:462)
at com.goldencode.p2j.security.ContextLocal.get(ContextLocal.java:419)
at com.goldencode.p2j.persist.Persistence.beginTransaction(Persistence.java:3661)
...
#2 Updated by Eric Faulhaber about 8 years ago
- Assignee set to Eric Faulhaber
#3 Updated by Ovidiu Maxiniuc over 7 years ago
The cause of this issue is documented in ConnectionManager.java:438:
// Query of _User table cannot be performed at this time. Calling Persistence.get()
// now will create an infinite recursion as the context has not yet finished
// its initialization.
The problem is that, with the addition of _Connect meta table, the putConnected() method will indirectly still call Persistence.get() when the ConnectTableUpdater attempts to insert a new record for the new database connection.
I temporarily avoided the infinite recursion by checking whether DatabaseManager.isInitializing() at the beginning of databaseConnected(int64). This avoid an unneeded creation of a temporary connection so that the server is starting. However, I only delayed the problem since, when a client is connecting the data structures need to be populated and this time the test will fail - evidently.
#4 Updated by Ovidiu Maxiniuc over 7 years ago
- Status changed from New to Feedback
The fix for this issue was committed in 3791b, r11299. BufferManager and ConnectionManager are initialized in 2-step process, allowing their context to be updated to a temporarily incompletely setup object. However, the objects are not returned from get() static method until their missing reference are correctly updated.
#5 Updated by Eric Faulhaber over 7 years ago
Ovidiu Maxiniuc wrote:
The fix for this issue was committed in 3791b, r11299.
Thanks for fixing this. Please move the fix to branch 3791c, which is the active, shared, fix branch. I abandoned branch 3791b and I have moved the single fix I had put there (a metadata fix) into 3791c. I am planning to archive 3791b as a dead branch.
#6 Updated by Ovidiu Maxiniuc over 7 years ago
The changes from 3791b were copied to 3791c as r11309. 3791b can be dropped.
#7 Updated by Eric Faulhaber over 7 years ago
Ovidiu Maxiniuc wrote:
The changes from 3791b were copied to 3791c as r11309. 3791b can be dropped.
There are a lot more changes than just this fix in 3791c/11309. Was this intentional?
#8 Updated by Ovidiu Maxiniuc over 7 years ago
Yes, it was the cumulative content of 3791b plus stable parts that I was intending to commit there. Since that branch is about to be abandoned, these changes will be lost or at least isolated there.
I am sorry if I misunderstood your request. I can revert the additional changes if needed.
#9 Updated by Greg Shah about 7 years ago
This is 100% complete, right?
#10 Updated by Greg Shah over 6 years ago
I see that 3791c was arched as merged on 20191025. What revision of trunk includes this change?
Can we close this?
#11 Updated by Eric Faulhaber over 6 years ago
- % Done changed from 0 to 100
- Status changed from Feedback to Closed
Greg Shah wrote:
I see that 3791c was arched as merged on 20191025. What revision of trunk includes this change?
11299
Can we close this?
Yes, I think so.