Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我要在Kotlin中运行这个特殊的Cucumber步骤来获得ArrayIndexOutOfBoundsException?_Kotlin_Bdd_Cucumber Jvm_Cucumber Java_Picocontainer - Fatal编程技术网

为什么我要在Kotlin中运行这个特殊的Cucumber步骤来获得ArrayIndexOutOfBoundsException?

为什么我要在Kotlin中运行这个特殊的Cucumber步骤来获得ArrayIndexOutOfBoundsException?,kotlin,bdd,cucumber-jvm,cucumber-java,picocontainer,Kotlin,Bdd,Cucumber Jvm,Cucumber Java,Picocontainer,我正在运行一个Cucumber JVM特性文件,使用Java8和PicoContainer。我已经把这些台阶剥去了,所以它们是空的,但我仍然得到一个错误。以下是我的特色: Feature: Full Journey Scenario: Can load a typical JIRA csv and calculate the distribution from it Given a typical JIRA export "/closed_only_JIRA.csv" When I impo

我正在运行一个Cucumber JVM特性文件,使用Java8和PicoContainer。我已经把这些台阶剥去了,所以它们是空的,但我仍然得到一个错误。以下是我的特色:

Feature: Full Journey

Scenario: Can load a typical JIRA csv and calculate the distribution from it

Given a typical JIRA export "/closed_only_JIRA.csv"
When I import it into Montecarluni
Then I should see the distribution
"""
6, 15, 3, 14, 2, 5, 6, 8, 5, 10, 15, 4, 2, 1
"""
When I copy it to the clipboard
Then I should be able to paste it somewhere else
(是的,这是一个完整的过程,而不是BDD场景。)

无论出于何种原因,在Kotlin中运行此步骤都会导致错误:

import cucumber.api.java8.En

class ClipboardSteps(val world : World) : En {
    init {
        When("^I copy it to the clipboard$", {
            // Errors even without any code here 
        })
    }
}
虽然该Java类运行良好:

import cucumber.api.java8.En;

public class JavaClipboardSteps implements En {

    public JavaClipboardSteps(World world) {
        When("^I copy it to the clipboard$", () -> {
            // Works just fine with code or without
        });
    }
}
我完全困惑不解,尤其是因为Kotlin steps类中的“Then”运行得非常完美,而另一个步骤运行时没有错误:

import cucumber.api.java8.En

class FileImportSteps(val world: World) : En {
    init {
        // There's a Given here

        When("^I import it into Montecarluni$", {
            // There's some code here
        })
    }
}
跑步者,为了完成:

import cucumber.api.CucumberOptions
import cucumber.api.junit.Cucumber
import org.junit.runner.RunWith

@RunWith(Cucumber::class)
@CucumberOptions(
    format = arrayOf("pretty"),
    glue = arrayOf("com.lunivore.montecarluni.glue"),
    features = arrayOf("."))
class Runner {
}
Stacktrace是:

cucumber.runtime.CucumberException: java.lang.ArrayIndexOutOfBoundsException: 52

at cucumber.runtime.java.JavaBackend.addStepDefinition(JavaBackend.java:166)
at cucumber.api.java8.En.Then(En.java:280)
at com.lunivore.montecarluni.glue.DistributionSteps.<init>(DistributionSteps.kt:8)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.picocontainer.injectors.AbstractInjector.newInstance(AbstractInjector.java:145)
at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:342)
at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:678)
at cucumber.runtime.java.picocontainer.PicoFactory.getInstance(PicoFactory.java:40)
at cucumber.runtime.java.JavaBackend.buildWorld(JavaBackend.java:131)
at cucumber.runtime.Runtime.buildBackendWorlds(Runtime.java:141)
at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:38)
at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:102)
at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
at cucumber.api.junit.Cucumber.runChild(Cucumber.java:95)
at cucumber.api.junit.Cucumber.runChild(Cucumber.java:38)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at cucumber.api.junit.Cucumber.run(Cucumber.java:100)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Caused by: java.lang.ArrayIndexOutOfBoundsException: 52
at jdk.internal.org.objectweb.asm.Type.getArgumentTypes(Type.java:358)
at cucumber.runtime.java8.ConstantPoolTypeIntrospector.getGenericTypes(ConstantPoolTypeIntrospector.java:32)
at cucumber.runtime.java.Java8StepDefinition.getParameterInfos(Java8StepDefinition.java:54)
at cucumber.runtime.java.Java8StepDefinition.<init>(Java8StepDefinition.java:44)
at cucumber.runtime.java.JavaBackend.addStepDefinition(JavaBackend.java:162)
... 44 more
cucumber.runtime.CucumberException:java.lang.ArrayIndexOutOfBoundsException:52
位于cucumber.runtime.java.JavaBackend.addStepDefinition(JavaBackend.java:166)
在cumber.api.java8.En.Then(En.java:280)
位于com.lunivore.montecarluni.glue.DistributionSteps.(DistributionSteps.kt:8)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:423)
位于org.picocontainer.injectors.AbstractInjector.newInstance(AbstractInjector.java:145)
位于org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:342)
在org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicdDependencyGuard.observe上(AbstractInjector.java:270)
位于org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
位于org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
位于org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
位于org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
位于org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
位于org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
位于org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:678)
在cucumber.runtime.java.picocontainer.picofacory.getInstance(picofacory.java:40)中
位于cucumber.runtime.java.JavaBackend.buildWorld(JavaBackend.java:131)
在cucumber.runtime.runtime.buildBackendWorlds(runtime.java:141)
在cucumber.runtime.model.cucumbersecenario.run(cucumbersecenario.java:38)
在cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:102)中
在cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)中
在cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)中
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:363)
运行(FeatureRunner.java:70)
cumber.api.junit.cumber.runChild(cumber.java:95)
cumber.api.junit.cumber.runChild(cumber.java:38)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:363)
位于cumber.api.junit.cumber.run(cumber.java:100)
位于org.junit.runner.JUnitCore.run(JUnitCore.java:137)
位于com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
位于com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
位于com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
位于com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
原因:java.lang.ArrayIndexOutOfBoundsException:52
位于jdk.internal.org.objectweb.asm.Type.getArgumentTypes(Type.java:358)
在cucumber.runtime.java8.ConstantPoolTypeIntrospector.getGenericTypes(ConstantPoolTypeIntrospector.java:32)
位于cucumber.runtime.java.Java8StepDefinition.GetParameterInfo(Java8StepDefinition.java:54)
在cucumber.runtime.java.Java8StepDefinition.(Java8StepDefinition.java:44)
位于cucumber.runtime.java.JavaBackend.addStepDefinition(JavaBackend.java:162)
... 44多
发生什么事了


当前使用Kotlin步骤签入的所有源代码都已注释掉。(请原谅这种混乱,因为我对我正在使用的很多东西都是新手;从最初的峰值开始重构正在进行。)

这似乎是Kotlin编译匿名代码块的优化之间的一种不幸的交互,Cumber假设JVM如何存储对lambda的引用,Cucumber使用了一些不应该接近的JVM内部构件

由于各种(不同)原因,您的系统不会触发错误

简单地说,如果Kotlin可以实现一个块或lambda作为一个静态单例,那么它可以实现,大概是出于性能原因。这会干扰magic Cumber执行的一些非常规反射(详情如下)

修复方法是在Cucumber代码中添加一个额外的检查,尽管可以说更好的修复方法是重写Cucumber代码以供使用

解决方法是确保Kotlin不会通过包含对包含实例的引用来优化lambda。即使是像引用
这样简单的内容

When("^I import it into Montecarluni$") {
    this
    // your code
}
足以说服Kotlin不要进行优化

细节 Cucumber在中添加带有lambda的步骤定义时,例如。