ktlint: Logger failes to initialize when not providing the Classic Logback Logger in 0.45.0

Expected Behavior

It should work

Observed Behavior

This failure occurs (when using via Spotless)

Step 'ktlint' found problem in 'src/main/java/slack/appprofile/di/AppProfileModule.kt':
--
  | Could not initialize class com.pinterest.ktlint.core.internal.EditorConfigLoaderKt
  | java.lang.NoClassDefFoundError: Could not initialize class com.pinterest.ktlint.core.internal.EditorConfigLoaderKt
  | at com.pinterest.ktlint.core.internal.EditorConfigLoader.loadPropertiesForFile(EditorConfigLoader.kt:111)
  | at com.pinterest.ktlint.core.KtLint.prepareCodeForLinting(KtLint.kt:234)
  | at com.pinterest.ktlint.core.KtLint.format(KtLint.kt:344)
  | at com.pinterest.ktlint.core.KtLint.format(KtLint.kt:319)
  | at com.pinterest.ktlint.core.KtLint.format(KtLint.kt:315)
  | at com.diffplug.spotless.glue.ktlint.KtlintFormatterFunc.applyWithFile(KtlintFormatterFunc.java:60)
  | at com.diffplug.spotless.FormatterFunc$NeedsFile.apply(FormatterFunc.java:154)
  | at com.diffplug.spotless.FormatterStepImpl$Standard.format(FormatterStepImpl.java:78)
  | at com.diffplug.spotless.FormatterStep$Strict.format(FormatterStep.java:88)
  | at com.diffplug.spotless.Formatter.compute(Formatter.java:230)
  | at com.diffplug.spotless.PaddedCell.calculateDirtyState(PaddedCell.java:203)
  | at com.diffplug.spotless.PaddedCell.calculateDirtyState(PaddedCell.java:190)
  | at com.diffplug.gradle.spotless.SpotlessTaskImpl.processInputFile(SpotlessTaskImpl.java:92)
  | at com.diffplug.gradle.spotless.SpotlessTaskImpl.performAction(SpotlessTaskImpl.java:78)

Steps to Reproduce

Use editorconfig and ktlint 0.45.0 in a project

Your Environment

  • Version of ktlint used: 0.45.0
  • Relevant parts of the .editorconfig settings
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=true
trim_trailing_whitespace=true
indent_style=space
indent_size=4

[*.proto]
indent_size=2

[*.java]
indent_size=2

[*.json]
indent_size=2

[*.{kt,kts}]
indent_size=2
continuation_indent_size=2
disabled_rules=final-newline

[{*.yml,*.yaml}]
indent_size=2
  • Name and version (or code for custom task) of integration used (Gradle plugin, Maven plugin, command line, custom Gradle task): Spotless 6.3.0
  • Version of Gradle used (if applicable): 7.4.1
  • Operating System and version: macOS Monterey

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 5
  • Comments: 21 (5 by maintainers)

Commits related to this issue

Most upvoted comments

I think the easiest as approach would be to do RCs when you have what may be a significant change, those are easy to test. Otherwise I think it would be wise to possibly set up integration tests against known popular consuming tools like spotless and just release quickly and more frequently.

@paul-dingemans @z3d1k thanks a lot for fixing the issue. What about a new release rather than updating snapshot? 0.45.1 maybe?

I have requested a new release to be build as I can not publish it myself. It is expected to be released tomorrow by @shashachu

@paul-dingemans yes, I’ve updated it from 0.44.0

In that version cast to logback was performed only if LogLevel was set to TRACE, so it wasn’t causing any troubles in normal use.

Just checked, if I would add KTLINT_UNIT_TEST_TRACE=ON to env in the previous version - it will fail with the same error.

Yes, I was hoping for this. I am working on a fix.

Got same exception while trying to update ktlint version for maven plugin. It appears that issue is here: https://github.com/pinterest/ktlint/blob/master/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/KtLintKLoggerInitializer.kt#L38 ktlint-core assumes logger.underlyingLogger is instance of ch.qos.logback.classic.Logger, which is not the case when running it from maven plugin

Here is stacktrace

Caused by: java.lang.ClassCastException: class org.slf4j.impl.MavenSimpleLogger cannot be cast to class ch.qos.logback.classic.Logger (org.slf4j.impl.MavenSimpleLogger is in unnamed module of loader org.codehaus.plexus.classworlds.realm.ClassRealm @42f30e0a; ch.qos.logback.classic.Logger is in unnamed module of loader org.codehaus.plexus.classworlds.realm.ClassRealm @7e2f86e6)
    at com.pinterest.ktlint.core.KtLintKLoggerInitializerKt.initKtLintKLogger (KtLintKLoggerInitializer.kt:38)
    at com.pinterest.ktlint.core.internal.EditorConfigLoaderKt.<clinit> (EditorConfigLoader.kt:20)
    at com.pinterest.ktlint.core.internal.EditorConfigLoader.loadPropertiesForFile (EditorConfigLoader.kt:111)
    at com.pinterest.ktlint.core.KtLint.prepareCodeForLinting (KtLint.kt:234)
    at com.pinterest.ktlint.core.KtLint.lint (KtLint.kt:176)
    at com.pinterest.ktlint.core.KtLint.lint (KtLint.kt:152)
    at com.github.z3d1k.maven.plugin.ktlint.ktlint.KtlintWrapperKt$lintFile$1.invoke (KtlintWrapper.kt:61)
    at com.github.z3d1k.maven.plugin.ktlint.ktlint.KtlintWrapperKt$lintFile$1.invoke (KtlintWrapper.kt:48)
    at com.github.z3d1k.maven.plugin.ktlint.reports.ReporterExtensionsKt.forFile (ReporterExtensions.kt:17)

I believe that it would be better to move logback dependency from ktlint-core package to cli and introduce some kind of modifier option for the logger. This will allow tinkering with logger however needed by each ktlint-core consumer. Core package will remain logger implementation agnostic, as slf4j is intended to be, and consumers shouldn’t be affected by future changes. I can make a PR with the proposed changes.

Yeah, that would be fine by me as well. At least the idea sounds better than what I intended to do. I will post my PR anyways and have no problem with dropping it if your solution is better.