Skip to content

Deadlock in aQute.junit.Tee #7214

@amichair

Description

@amichair

The project is currently using 6.4.0, but it looks like this class hasn't been changed in years, so might be still relevant.

Tee extends PrintStream which extends FilterOutputStream which as an OutputStream out field.
Tee uses the grandparent's out field as a monitor, it's parent PrintStream uses itself as a monitor, and presumably the OutputStream may also use itself as a monitor. Some methods in Tee grab its monitor first, but some (like flush) are not implemented so are handled by the parent that grabs the second monitor first. Two monitors need to be held by println and flush, but in different order, hence the deadlock.

From thread dump:

Found one Java-level deadlock:
=============================
"main":
  waiting to lock monitor 0x00007ea640005100 (object 0x00000000fa9b3550, a java.io.PrintStream),
  which is held by "TcpConnection-Reader-org.apache.aries.rsa.discovery.tcp.TcpConnection@6350c49"
"TcpConnection-Reader-org.apache.aries.rsa.discovery.tcp.TcpConnection@6350c49":
  waiting to lock monitor 0x00007ea52c003380 (object 0x00000000fed4ebe0, a aQute.junit.Tee),
  which is held by "main"

Java stack information for the threads listed above:
===================================================
"main":
        at java.io.PrintStream.flush(java.base@11.0.30/PrintStream.java:414)
        - waiting to lock <0x00000000fa9b3550> (a java.io.PrintStream)
        at java.io.PrintStream.flush(java.base@11.0.30/PrintStream.java:417)
        - locked <0x00000000fed4ebe0> (a aQute.junit.Tee)
        at org.apache.logging.log4j.core.util.CloseShieldOutputStream.flush(CloseShieldOutputStream.java:43)
        at org.apache.logging.log4j.core.appender.OutputStreamManager.flushDestination(OutputStreamManager.java:277)
        - locked <0x00000000fc3190e8> (a org.apache.logging.log4j.core.appender.OutputStreamManager)
        at org.apache.logging.log4j.core.appender.OutputStreamManager.flush(OutputStreamManager.java:308)
        - locked <0x00000000fc3190e8> (a org.apache.logging.log4j.core.appender.OutputStreamManager)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:229)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:220)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:211)
        at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:160)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:133)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:124)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:88)
        at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:705)
        at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:663)
        at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:639)
        at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:540)
        at org.apache.logging.log4j.core.config.DefaultReliabilityStrategy.log(DefaultReliabilityStrategy.java:53)
        at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:155)
        at org.ops4j.pax.logging.log4j2.internal.PaxLoggerImpl.doLog0(PaxLoggerImpl.java:1129)
        at org.ops4j.pax.logging.log4j2.internal.PaxLoggerImpl.doLog(PaxLoggerImpl.java:1099)
        at org.ops4j.pax.logging.log4j2.internal.PaxLoggerImpl.debug(PaxLoggerImpl.java:253)
        at org.apache.felix.scr.impl.logger.ScrLogManager$ScrLoggerFacade.log0(ScrLogManager.java:195)
        at org.apache.felix.scr.impl.logger.ScrLogManager$ScrLoggerFacade.log(ScrLogManager.java:154)
        at org.apache.felix.scr.impl.Activator.debug(Activator.java:689)
        at org.apache.felix.scr.impl.AbstractExtender.createExtension(AbstractExtender.java:195)
        at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:169)
        at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:49)
        at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:490)
        at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:1)
        at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:233)
        at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:452)
        at org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:987)
        at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
        at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:151)
        at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:237)
        at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:136)
        at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:128)
        at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:232)
        at org.eclipse.osgi.container.Module.publishEvent(Module.java:534)
        at org.eclipse.osgi.container.Module.start(Module.java:518)
        at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:471)
        at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:490)
        at org.osgi.test.cases.remoteserviceadmin.junit.DiscoveryTest.testDiscoveryBasicEndpointEvents_122_6_3(DiscoveryTest.java:398)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@11.0.30/Native Method)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@11.0.30/NativeMethodAccessorImpl.java:62)
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@11.0.30/DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(java.base@11.0.30/Method.java:566)
        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 junit.framework.TestCase.run(TestCase.java:130)
        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 aQute.junit.Activator.test(Activator.java:354)
        at aQute.junit.Activator.automatic(Activator.java:266)
        at aQute.junit.Activator.run(Activator.java:188)
        at java.util.concurrent.Executors$RunnableAdapter.call(java.base@11.0.30/Executors.java:515)
        at aQute.launcher.Launcher.handleMainCallable(Launcher.java:465)
        at aQute.launcher.Launcher.launch(Launcher.java:438)
        at aQute.launcher.Launcher.run(Launcher.java:186)
        at aQute.launcher.Launcher.main(Launcher.java:162)
        at java.lang.invoke.LambdaForm$DMH/0x0000000840062c40.invokeStaticInit(java.base@11.0.30/LambdaForm$DMH)
        at java.lang.invoke.LambdaForm$MH/0x0000000840067c40.invoke(java.base@11.0.30/LambdaForm$MH)
        at java.lang.invoke.LambdaForm$MH/0x0000000840067840.invoke_MT(java.base@11.0.30/LambdaForm$MH)
        at aQute.launcher.pre.EmbeddedLauncher.executeWithRunPath(EmbeddedLauncher.java:170)
        at aQute.launcher.pre.EmbeddedLauncher.findAndExecute(EmbeddedLauncher.java:135)
        at aQute.launcher.pre.EmbeddedLauncher.main(EmbeddedLauncher.java:52)
"TcpConnection-Reader-org.apache.aries.rsa.discovery.tcp.TcpConnection@6350c49":
        at java.io.PrintStream.println(java.base@11.0.30/PrintStream.java:881)
        - waiting to lock <0x00000000fed4ebe0> (a aQute.junit.Tee)
        at aQute.junit.Tee.println(Tee.java:204)
        - locked <0x00000000fa9b3550> (a java.io.PrintStream)
        at org.osgi.test.cases.remoteserviceadmin.junit.DiscoveryTest$EndpointEventListenerImpl.endpointChanged(DiscoveryTest.java:873)
        at org.apache.aries.rsa.discovery.tcp.Interest.lambda$notifyListener$0(Interest.java:57)
        at org.apache.aries.rsa.discovery.tcp.Interest$$Lambda$335/0x000000084045fc40.accept(Unknown Source)
        at java.util.Optional.ifPresent(java.base@11.0.30/Optional.java:183)
        at org.apache.aries.rsa.discovery.tcp.Interest.notifyListener(Interest.java:54)
        at org.apache.aries.rsa.discovery.tcp.InterestManager.lambda$notifyAllListeners$2(InterestManager.java:62)
        at org.apache.aries.rsa.discovery.tcp.InterestManager$$Lambda$333/0x000000084045f040.accept(Unknown Source)
        at java.util.concurrent.ConcurrentHashMap$ValuesView.forEach(java.base@11.0.30/ConcurrentHashMap.java:4770)
        at org.apache.aries.rsa.discovery.tcp.InterestManager.notifyAllListeners(InterestManager.java:62)
        at org.apache.aries.rsa.discovery.tcp.InterestManager.addEndpoint(InterestManager.java:69)
        at org.apache.aries.rsa.discovery.tcp.TcpConnectionManager.onMessage(TcpConnectionManager.java:212)
        at org.apache.aries.rsa.discovery.tcp.TcpConnectionManager$$Lambda$257/0x0000000840381c40.accept(Unknown Source)
        at org.apache.aries.rsa.discovery.tcp.TcpConnection.readLoop(TcpConnection.java:111)
        at org.apache.aries.rsa.discovery.tcp.TcpConnection$$Lambda$263/0x000000084039f840.run(Unknown Source)
        at java.lang.Thread.run(java.base@11.0.30/Thread.java:829)

Found 1 deadlock.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions