使用JUnit运行时,Intellij IDEA不会停在Kotlin断点处

时间:2018-01-09 18:28:45

标签: java debugging intellij-idea junit kotlin

当尝试执行某些Kotlin代码时,同时也使用JUnit,Intellij IDEA将执行代码直到结束,而不是在断点处停止。

演示:

class Tester {

    @Test
    fun shouldBreakpoint() {
        //Line where threads should suspend:
        println("Should Suspend Here") //Breakpoint added to this line

        println("Shouldn't run this code unless I release above breakpoint")

    }
}

单击“Debug Tester”或“Debug shouldBreakpoint”时,没有断点可以正常工作。 enter image description here

控制台输出两条打印线,而不会在断点处停止。如果使用Java编写相同的代码,调试器将起作用:

public class Testerino {

    @Test
    public void shouldBreakpoint() {

        System.out.println("Should Suspend Here"); //Breakpoint added to this line

        System.out.println("Shouldn't run this code unless I release above breakpoint");
    }
}

在Kotlin main函数上运行时,它也能正常工作:

fun main(args: Array<String>) {
println("Should Suspend Here") //Breakpoint added to this line

println("Shouldn't run this code unless I release above breakpoint")

}

这是在Android项目上运行,build.gradle(app)文件是:

   apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
    compileSdkVersion 27
    buildToolsVersion "27.0.3"
    defaultConfig {
        applicationId "me.kerooker.visualhonk"
        minSdkVersion 19
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
         vectorDrawables.useSupportLibrary = true

    }
    buildTypes {
        release {
            minifyEnabled false
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android.txt')
        }
        debug {
            debuggable true
            minifyEnabled false // set this to false
            proguardFiles getDefaultProguardFile('proguard-android.txt')
        }
    }
}

configurations.all {
    resolutionStrategy {
        forcedModules = [
                "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version",
                "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
        ]
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:27.+'
    compile 'com.android.support.constraint:constraint-layout:+'
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

    testCompile 'io.kotlintest:kotlintest:2.0.7'
    testCompile 'junit:junit:4.12'


}
repositories {
    mavenCentral()
}

Intellij可以做些什么来正确识别并在断点处停止?

1 个答案:

答案 0 :(得分:1)

this commit开始,此错误似乎已修复。更新Intellij以获取新版本。

如果您无法更新,则解决方法是从运行过程中删除gradle aware make ,并且只在您进行更改时构建代码(而不是每次启动时都是如此)调试)

修复说明:

Hitting breakpoints in Kotlin JUnit test with an Android Gradle
project sometimes(*) does not work in Android Studio 3.1 beta.

(*) The issue is related to various threads running concurrently
with "dumb" mode background code, so the issue reproduces only
on certain configurations.

In a nutshell, the issue is as follows

* On one hand, gradle build finishes, fires an event ("buildFinished")
  that is processed "later" and that causes the IDE to enter "dumb" mode
  for a shot amount of time (about 300-500 msec on a somewhat up to date
  multi-core computer).

* On the other hand, once the JVM of the debuggee is started, breakpoints
  need to be resolved (on the debugger thread, through a call to
  com.intellij.debugger.engine.CompoundPositionManager.createPrepareRequests.
  This code calls into the "KotlinPositionManager.createPrepareRequests",
  which in turns calls into "PerFileAnalysisCache.analyze". That method
  returns "AnalysisResult.EMPTY" is the project is in dumb mode.
  This return value prevents callers from successfully resolving
  the source location into a breakpoint.

Given that the 2 code paths above execute on separate threads without
explicit synchronization, the "failed to resolve breakpoint" issue
occurs sporadically, to the point it happens 100% of the time on
certain configuration.

The fix is so wrap the kotlin breakpoint resolution code inside
a "runReadActionInSmartMode" so that the debugger thread "waits"
for "dumb" mode to terminates before trying to resolve breakpoint
locations.