[
https://issues.apache.org/jira/browse/JCR-5095?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18103190#comment-18103190
]
Sylwester Lachiewicz commented on JCR-5095:
-------------------------------------------
[~reschke] Good question, and the direction of the argument is worth spelling
out, because it cuts against the hypothesis rather than for it.
The clock facts. On Windows, System.currentTimeMillis() is bound to the system
timer tick — ~15.6 ms by default, ~1 ms only while some process has raised the
global timer resolution via timeBeginPeriod. On Linux/macOS it is derived from
a microsecond-resolution clock and truncated, so consecutive calls genuinely
differ. Worth noting for your earlier ISO8601.format(long) idea: moving off
Calendar would not have bought precision on Windows either — even
Clock.systemUTC()/Instant.now() is coarse there, since JDK-8180466
(https://bugs.openjdk.org/browse/JDK-8180466) ("Clock.systemUTC has low
resolution on Windows", asking for GetSystemTimePreciseAsFileTime) was closed
Won't Fix. And TokenProvider truncates to milliseconds anyway
(ISO8601.format(creation), trunk L153–157
(https://github.com/apache/jackrabbit/blob/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/token/TokenProvider.java#L153)),
so sub-ms clock precision never reaches the node name on any platform.
So yes — if colliding token node names were the mechanism, a ~15 ms tick would
make collisions roughly an order of magnitude more likely, and Windows should
be the platform where this fails most. You see it seldom. That is a point
against the timestamp hypothesis, not for it — consistent with your UUID
experiment (aa2789a8
(https://github.com/apache/jackrabbit/commit/aa2789a8c621a50e20db434835ba79b1094cb3da))
having no effect, and with what I described above: the conflict is on the
shared .tokens parent losing the child node entry, which unique names cannot
prevent. The exception text supports that too — has no child entry for <uuid>
is a missing entry; an actual duplicate name would surface as
ItemExistsException or SNS index handling, not this.
One caveat on the evidence itself: "seldom on Windows" is not a clean clock
signal in either direction. You already named the confounder in this ticket —
test execution order differs by platform, and the repository is reused across
tests, so what ran before TokenBasedLoginTest differs on your machine. Core
count and disk speed also move the width of the race window far more than the
clock granularity does. So I would not read your Windows observation as
measuring the clock at all; it just fails to show the effect the hypothesis
predicted.
Net: I don't think there is anything platform-specific to chase here. The
mitigation in PR #368 (https://github.com/apache/jackrabbit/pull/368) addresses
the parent conflict directly and is orthogonal to the timestamp.
_Claude Opus based response_
> TokenBasedLoginTest is flaky
> ----------------------------
>
> Key: JCR-5095
> URL: https://issues.apache.org/jira/browse/JCR-5095
> Project: Jackrabbit Content Repository
> Issue Type: Bug
> Components: core
> Reporter: Konrad Windszus
> Priority: Major
>
> The Jenkins build is failing sometimes due to that
> ([https://ci-builds.apache.org/job/Jackrabbit/job/jackrabbit-trunk/).]
> The logs shows
> {code:java}
> [ERROR]
> org.apache.jackrabbit.core.security.authentication.token.TokenBasedLoginTest.testConcurrentLogin
> – Time elapsed: 2.463 s <<< FAILURE!junit.framework.AssertionFailedError:
> javax.jcr.LoginException: Failed to commit: failed to build path of
> b7a136a5-5247-460d-bd74-4e191872ca92: 18765f8a-895a-49c4-831b-dc5119faaacd
> has no child entry for b7a136a5-5247-460d-bd74-4e191872ca92
> at junit.framework.Assert.fail(Assert.java:57)
> at junit.framework.TestCase.fail(TestCase.java:223)
> at
> org.apache.jackrabbit.core.security.authentication.token.TokenBasedLoginTest.testConcurrentLogin(TokenBasedLoginTest.java:275)
> at
> java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
> at java.base/java.lang.reflect.Method.invoke(Method.java:580)
> at junit.framework.TestCase.runTest(TestCase.java:177)
> at junit.framework.TestCase.runBare(TestCase.java:142)
> at junit.framework.TestResult$1.protect(TestResult.java:122)
> at junit.framework.TestResult.runProtected(TestResult.java:142)
> at junit.framework.TestResult.run(TestResult.java:125)
> at org.apache.jackrabbit.test.JCRTestResult.run(JCRTestResult.java:75)
> at junit.framework.TestCase.run(TestCase.java:130)
> at org.apache.jackrabbit.test.AbstractJCRTest.run(AbstractJCRTest.java:476)
> at junit.framework.TestSuite.runTest(TestSuite.java:241)
> at junit.framework.TestSuite.run(TestSuite.java:236)
> at junit.framework.TestSuite.runTest(TestSuite.java:241)
> at junit.framework.TestSuite.run(TestSuite.java:236)
> at
> org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90)
> at
> org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:316)
> at
> org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:240)
> at
> org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:214)
> at
> org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:155)
> at
> org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
> at
> org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
> at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
> at
> org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495){code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)