Skip to content

fix: suppress SLF4J startup warning in Tycho test runtime#1299

Draft
joaodinissf wants to merge 2 commits intodsldevkit:masterfrom
joaodinissf:fix/slf4j-suppress-warning
Draft

fix: suppress SLF4J startup warning in Tycho test runtime#1299
joaodinissf wants to merge 2 commits intodsldevkit:masterfrom
joaodinissf:fix/slf4j-suppress-warning

Conversation

@joaodinissf
Copy link
Copy Markdown
Collaborator

Stacked on #1280.

What

Suppress the SLF4J(W): No SLF4J providers were found warning during Tycho Surefire test execution by setting -Dslf4j.internal.verbosity=ERROR in the test JVM arguments.

Why

SLF4J 2.x discovers providers via java.util.ServiceLoader, which does not work across OSGi bundle classloaders — slf4j.api's classloader cannot see META-INF/services/org.slf4j.spi.SLF4JServiceProvider inside the separate slf4j.nop bundle. The warning is cosmetic: SLF4J defaults to NOP regardless, which is the desired behaviour for a plugin test suite.

The slf4j.internal.verbosity system property (available since SLF4J 2.0.10) is the documented mechanism for controlling SLF4J's internal reporting level. Setting it to ERROR suppresses WARN-level diagnostics while preserving error messages.

Downstream RCP products

For projects assembling DDK plugins into an Eclipse RCP product, the proper fix is configuring start levels in the .product file so that Apache Aries SPI Fly (the OSGi Service Loader Mediator, shipped with Eclipse Platform) bridges ServiceLoader across bundle boundaries:

<plugin id="org.apache.aries.spifly.dynamic.bundle" autoStart="true" startLevel="2" />
<plugin id="slf4j.nop" autoStart="true" startLevel="2" />

This approach was tested in the Tycho Surefire context but does not fully work there — SPI Fly's asynchronous bundle scanning completes after the first LoggerFactory.getLogger() call, producing the warning before the provider is registered. The .product configuration does not have this timing issue because the product launch sequence ensures proper ordering.

Why not fix it in OSGi directly?

The only way to make ServiceLoader work without SPI Fly would be packaging slf4j.nop as a fragment of slf4j.api (shared classloader). This is an upstream Eclipse Orbit packaging decision. See investigation details in #1280.

References

joaodinissf and others added 2 commits April 2, 2026 01:17
Add slf4j.nop 2.0.17 from Eclipse Orbit aggregation 4.39.0 to the DDK
target platform. This makes the SLF4J NOP binding available to the OSGi
runtime, though due to classloader isolation in OSGi the startup warning
cannot be fully suppressed — slf4j.nop is a standalone bundle (not a
fragment of slf4j.api), so ServiceLoader-based provider discovery does
not find it before SLF4J's first initialization. This is a known
limitation shared by Eclipse Platform itself.

References:
- qos-ch/slf4j#427
- https://github.com/orgs/eclipse-orbit/discussions/24

Also removes unused Import-Package: org.slf4j from three test bundle
manifests where no source file references org.slf4j:
- com.avaloq.tools.ddk.check.ui.test
- com.avaloq.tools.ddk.xtext.test
- com.avaloq.tools.ddk.xtext.test.core

Retains org.slf4j in com.avaloq.tools.ddk.test.ui — its SwtBot wrapper
classes directly use org.slf4j.Logger.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Set -Dslf4j.internal.verbosity=ERROR in the Tycho Surefire argLine to
suppress the "No SLF4J providers were found" warning during OSGi test
execution.

Why this warning occurs:

SLF4J 2.x discovers providers via java.util.ServiceLoader, which does
not work across OSGi bundle classloaders — slf4j.api's classloader
cannot see META-INF/services in the separate slf4j.nop bundle. This is
a known limitation shared by Eclipse Platform itself (qos-ch/slf4j#427,
eclipse-platform#588). The warning is cosmetic: SLF4J defaults to NOP
regardless, which is the desired behaviour for a plugin test suite.

Why this approach:

The official fix for Eclipse RCP products is to configure start levels
in the .product file so that the OSGi Service Loader Mediator (Apache
Aries SPI Fly) bridges ServiceLoader across bundle boundaries:

    <plugin id="org.apache.aries.spifly.dynamic.bundle"
            autoStart="true" startLevel="2" />
    <plugin id="slf4j.nop"
            autoStart="true" startLevel="2" />

Downstream projects assembling DDK plugins into an RCP product should
add these entries to their .product Configuration tab. This wires the
NOP provider properly at the product level.

For the Tycho Surefire test runtime (which has no .product file), the
start-level approach was tested but does not fully work — SPI Fly's
asynchronous bundle scanning completes after the first
LoggerFactory.getLogger() call, producing the warning before the
provider is registered. The slf4j.internal.verbosity system property
(available since SLF4J 2.0.10) is the documented way to control
SLF4J's internal reporting level, suppressing WARN-level diagnostics
while preserving ERROR-level messages.

References:
- https://www.slf4j.org/faq.html (slf4j.internal.verbosity)
- qos-ch/slf4j#427
- https://github.com/orgs/eclipse-orbit/discussions/24
- eclipse-platform/eclipse.platform.releng.aggregator#588

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@joaodinissf
Copy link
Copy Markdown
Collaborator Author

This PR is stacked on #1280 (which adds slf4j.nop to the target platform and cleans up stale org.slf4j imports). See #1280 for the full investigation into why the SLF4J warning occurs in OSGi and why it cannot be resolved at the bundle level.


🤖 Claude Code

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