Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE during compilation of spec while testing a method with vararg parameter #1202

Closed
tomaszstec opened this issue Jul 24, 2020 · 9 comments · Fixed by #1203
Closed

NPE during compilation of spec while testing a method with vararg parameter #1202

tomaszstec opened this issue Jul 24, 2020 · 9 comments · Fixed by #1203

Comments

@tomaszstec
Copy link

Issue description

The spock test fail to compile using gradle :test while testing method with vararg parameter. The compilation fails with the following error:

startup failed:
D:\DEV\spock-npe-bug\src\test\groovy\ABusinessClassTest.groovy: Unexpected error during compilation of spec 'ABusinessClassTest'. Maybe you have used invalid Spock syntax? Anyway, please file a bug report at http://issues.spockframework.org.

java.lang.NullPointerException
        at org.spockframework.util.AbstractExpressionConverter.convertAll(AbstractExpressionConverter.java:46)
        at org.spockframework.compiler.ConditionRewriter.visitArrayExpression(ConditionRewriter.java:391)
        at org.codehaus.groovy.ast.expr.ArrayExpression.visit(ArrayExpression.java:86)
        at org.spockframework.util.AbstractExpressionConverter.convert(AbstractExpressionConverter.java:36)
        at org.spockframework.util.AbstractExpressionConverter.convertAll(AbstractExpressionConverter.java:48)
        at org.spockframework.compiler.ConditionRewriter.visitArgumentlistExpression(ConditionRewriter.java:125)
        at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:73)
        at org.spockframework.util.AbstractExpressionConverter.convert(AbstractExpressionConverter.java:36)
        at org.spockframework.compiler.ConditionRewriter.visitMethodCallExpression(ConditionRewriter.java:93)
        at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:76)
        at org.spockframework.util.AbstractExpressionConverter.convert(AbstractExpressionConverter.java:36)
        at org.spockframework.util.AbstractExpressionConverter.convertAll(AbstractExpressionConverter.java:48)
        at org.spockframework.compiler.ConditionRewriter.visitArgumentlistExpression(ConditionRewriter.java:125)
        at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:73)
        at org.spockframework.util.AbstractExpressionConverter.convert(AbstractExpressionConverter.java:36)
        at org.spockframework.compiler.ConditionRewriter.visitMethodCallExpression(ConditionRewriter.java:93)
        at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:76)
        at org.spockframework.util.AbstractExpressionConverter.convert(AbstractExpressionConverter.java:36)
        at org.spockframework.compiler.ConditionRewriter.visitBinaryExpression(ConditionRewriter.java:213)
        at org.codehaus.groovy.ast.expr.BinaryExpression.visit(BinaryExpression.java:58)
        at org.spockframework.util.AbstractExpressionConverter.convert(AbstractExpressionConverter.java:36)
        at org.spockframework.compiler.ConditionRewriter.rewriteOtherCondition(ConditionRewriter.java:657)
        at org.spockframework.compiler.ConditionRewriter.rewriteCondition(ConditionRewriter.java:600)
        at org.spockframework.compiler.ConditionRewriter.rewriteCondition(ConditionRewriter.java:581)
        at org.spockframework.compiler.ConditionRewriter.rewriteImplicitCondition(ConditionRewriter.java:68)
        at org.spockframework.compiler.DeepBlockRewriter.handleImplicitCondition(DeepBlockRewriter.java:194)
        at org.spockframework.compiler.DeepBlockRewriter.doVisitExpressionStatement(DeepBlockRewriter.java:70)
        at org.spockframework.compiler.AbstractDeepBlockRewriter.visitExpressionStatement(AbstractDeepBlockRewriter.java:89)
        at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:40)
        at org.spockframework.compiler.StatementReplacingVisitorSupport.replace(StatementReplacingVisitorSupport.java:44)
        at org.spockframework.compiler.AbstractDeepBlockRewriter.visit(AbstractDeepBlockRewriter.java:73)
        at org.spockframework.compiler.DeepBlockRewriter.visit(DeepBlockRewriter.java:53)
        at org.spockframework.compiler.SpecRewriter.visitAnyBlock(SpecRewriter.java:325)
        at org.spockframework.compiler.model.ExpectBlock.accept(ExpectBlock.java:31)
        at org.spockframework.compiler.model.Method.accept(Method.java:70)
        at org.spockframework.compiler.model.Spec.accept(Spec.java:112)
        at org.spockframework.compiler.SpockTransform$Impl.processSpec(SpockTransform.java:78)
        at org.spockframework.compiler.SpockTransform$Impl.visit(SpockTransform.java:65)
        at org.spockframework.compiler.SpockTransform.visit(SpockTransform.java:48)
        at org.codehaus.groovy.transform.ASTTransformationVisitor.lambda$addPhaseOperationsForGlobalTransforms$4(ASTTransformationVisitor.java:337)
        at org.codehaus.groovy.control.CompilationUnit$ISourceUnitOperation.doPhaseOperation(CompilationUnit.java:880)
        at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:650)
        at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:627)
        at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:606)
        at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:275)
        at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:68)
        at org.gradle.api.internal.tasks.compile.GroovyCompilerFactory$DaemonSideCompiler.execute(GroovyCompilerFactory.java:87)
        at org.gradle.api.internal.tasks.compile.GroovyCompilerFactory$DaemonSideCompiler.execute(GroovyCompilerFactory.java:75)
        at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerWorkAction.execute(AbstractDaemonCompiler.java:128)
        at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:50)
        at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:47)
        at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:37)
        at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:98)
        at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:37)
        at org.gradle.workers.internal.IsolatedClassloaderWorker.execute(IsolatedClassloaderWorker.java:49)
        at org.gradle.workers.internal.WorkerDaemonServer.execute(WorkerDaemonServer.java:84)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.process.internal.worker.request.WorkerAction$1.call(WorkerAction.java:129)
        at org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41)
        at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:126)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
        at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.lang.Thread.run(Thread.java:748)

How to reproduce

  1. Create simple gradle project with the configuration and groovy classes taken from the gist
  2. Run the tests with
    ./gradlew :test

Link to a gist or similar

spock-npe-bug gist

Additional Environment information

Java/JDK

λ java -version
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)

Groovy version

λ groovy -version
Groovy Version: 2.5.8 JVM: 1.8.0_221 Vendor: Oracle Corporation OS: Windows 10

Build tool version

Gradle

Tested with gradlew 6.1.1 as well as my standalone gradle 5.1.1 installation

λ ./gradlew -version

------------------------------------------------------------
Gradle 6.1.1
------------------------------------------------------------

Build time:   2020-01-24 22:30:24 UTC
Revision:     a8c3750babb99d1894378073499d6716a1a1fa5d

Kotlin:       1.3.61
Groovy:       2.5.8
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          1.8.0_221 (Oracle Corporation 25.221-b11)
OS:           Windows 10 10.0 amd64
λ gradle -version

------------------------------------------------------------
Gradle 5.1.1
------------------------------------------------------------

Build time:   2019-01-10 23:05:02 UTC
Revision:     3c9abb645fb83932c44e8610642393ad62116807

Kotlin DSL:   1.1.1
Kotlin:       1.3.11
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM:          1.8.0_221 (Oracle Corporation 25.221-b11)
OS:           Windows 10 10.0 amd64

Operating System

Windows 10

Build-tool dependencies used

Gradle/Grails

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.5.8'
    testCompile group: 'org.spockframework', name: 'spock-core', version: '2.0-M3-groovy-3.0'
}
@Vampire
Copy link
Member

Vampire commented Jul 24, 2020

Without looking further, if those actually are your dependencies, you will get other problems too.
Either you have to use the groovy-2 variant with Groovy 2 or the groovy-3 variant with Groovy 3, you cannot mix them.

@Vampire
Copy link
Member

Vampire commented Jul 24, 2020

Ah, despite your dependency declaration, the conflict resolution uses Groovy 3, otherwise it would not even be valid Groovy syntax in Groovy 2 where you cannot use array initializers like new Object[]{} but have to do [] as Object[] or actually new Object[0] in both Groovy in Java. While toArray( with array argument is a deprecated usage and should be avoided anyway since Java 6 or so. But I agree that with Groovy 3 where the syntax is valid, there should not be an NPE in Spock code. :-)

@tomaszstec
Copy link
Author

Ah, that was the problem 👍 . I changed the dependency with:

testCompile group: 'org.spockframework', name: 'spock-core', version: '2.0-M2-groovy-2.5'

and replaced the line:

ABusinessClass.aMethodWithVararg([].toArray(new Object[]{})) == []

with

ABusinessClass.aMethodWithVararg([].toArray(new Object[0])) == []

and it works.

Big thanks !!!

@Vampire
Copy link
Member

Vampire commented Jul 24, 2020

Please do not close this issue, as I said, this is still a bug in the Groovy 3 variant

@Vampire
Copy link
Member

Vampire commented Jul 24, 2020

Besides that you can also simply do ABusinessClass.aMethodWithVararg() == [], there is no need to provide an array explicitly.
Or you can do ABusinessClass.aMethodWithVararg([] as Object[]) == [].

@Vampire
Copy link
Member

Vampire commented Jul 24, 2020

This is enough for reproduction actually:

class Foo extends Specification {
    def foo() {
        expect:
        new Object[]{}
    }
}

@tomaszstec
Copy link
Author

Sorry for closing the issue. I don't know the conventions. I see that you opened the corresponding ticket so I assueme it all right. Thanks for the help. Good day!

@Vampire
Copy link
Member

Vampire commented Jul 27, 2020

If you don't mind, please reopen.
I don't have permissions to re-open or close tickets.
As long as the pr is not fixed, this should stay open as the bug still exists, even if you have a work-around.

@tomaszstec
Copy link
Author

Ok, no problem. Reopened.

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 a pull request may close this issue.

2 participants