Puzzling problem with latest Groovy stable release - testing

I just started a new Gradle project. In my previous build.gradles I had been putting this:
compile 'org.codehaus.groovy:groovy-all:2.4.15'
testCompile 'org.spockframework:spock-core:1.1-groovy-2.4'
... and also these dependencies:
testCompile 'net.bytebuddy:byte-buddy:1.6.11'
testCompile 'org.objenesis:objenesis:2.6'
By a process of trial and error I had found that Groovy 2.4.15 with these Bytebuddy and Objensis dependencies enabled me to mock BufferedReader. This proved useful in a console application where I wanted to mock user input to the console. The "console handler" class thus has the following field/property:
def br = new BufferedReader( new InputStreamReader(System.in, 'UTF-8' ))
used as follows in the app class to get user console input:
String response = br.readLine().trim()
... meaning that Spock tests can do this sort of thing:
def 'prompt should show help on entering H'() {
given:
consoleHandler.br = Mock( BufferedReader )
consoleHandler.br.readLine() >> 'h'
i.e. simulate the entry of the letter h at the console.
... but it doesn't work with Groovy 2.5.3 and its matching Spock dependency: for this new project I put:
compile 'org.codehaus.groovy:groovy-all:2.5.3'
testCompile 'org.spockframework:spock-core:1.2-groovy-2.5'
... with the same ByteBuddy and Objenisis dependencies. I get the following test failure:
java.lang.IllegalArgumentException: Could not create type at
net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:140) at
net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:346)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:161) at
net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:355)
at
org.spockframework.mock.runtime.ByteBuddyMockFactory.createMock(ByteBuddyMockFactory.java:41)
at
org.spockframework.mock.runtime.ProxyBasedMockFactory.create(ProxyBasedMockFactory.java:42)
at
org.spockframework.mock.runtime.JavaMockFactory.createInternal(JavaMockFactory.java:58)
at
org.spockframework.mock.runtime.JavaMockFactory.create(JavaMockFactory.java:38)
at
org.spockframework.mock.runtime.CompositeMockFactory.create(CompositeMockFactory.java:42)
at
org.spockframework.lang.SpecInternals.createMock(SpecInternals.java:46)
at
org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:294)
at
org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:284)
at
org.spockframework.lang.SpecInternals.MockImpl(SpecInternals.java:100)
at core.FirstSpec.setup(first_tests.groovy:20)Caused by:
java.lang.NoSuchMethodError:
net.bytebuddy.dynamic.loading.ClassInjector$UsingLookup.isAvailable()Z
at
org.spockframework.mock.runtime.ByteBuddyMockFactory.determineBestClassLoadingStrategy(ByteBuddyMockFactory.java:103)
at
org.spockframework.mock.runtime.ByteBuddyMockFactory.access$300(ByteBuddyMockFactory.java:27)
at
org.spockframework.mock.runtime.ByteBuddyMockFactory$1.call(ByteBuddyMockFactory.java:54)
at
org.spockframework.mock.runtime.ByteBuddyMockFactory$1.call(ByteBuddyMockFactory.java:43)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:138)
Any Groovy über-geeks out there?

You have to upgrade byte-buddy:
testCompile 'net.bytebuddy:byte-buddy:1.8.21'
Spock version 1.1-groovy-2.4 was depending on byte-buddy:1.6.5 - https://mvnrepository.com/artifact/org.spockframework/spock-core/1.1-groovy-2.4
Spock version 1.2-groovy-2.5 depends on byte-buddy:1.8.21 - https://mvnrepository.com/artifact/org.spockframework/spock-core/1.2-groovy-2.5

Related

Why am I getting "java.lang.NoClassDefFoundError: Could not initialize class io.mockk.impl.JvmMockKGateway" when using quarkusDev task in IntelliJ?

I am using Gradle 7.5, Quarkus 2.12.3 and mockk 1.13.3. When I try to run quarkusDev task from command line and then start continuous testing (by pressing r), then all tests pass OK.
However, when I do the same as from IntelliJ (as gradle run configuration), all tests fail with error:
java.lang.NoClassDefFoundError: Could not initialize class io.mockk.impl.JvmMockKGateway
How can I fix that?
Masked thrown exception
After much debugging I found the problem. The thrown exception actually originates in HotSpotVirtualMachine.java and is thrown during attachment of ByteBuddy as a java agent. Here is the relevant code;
// The tool should be a different VM to the target. This check will
// eventually be enforced by the target VM.
if (!ALLOW_ATTACH_SELF && (pid == 0 || pid == CURRENT_PID)) {
throw new IOException("Can not attach to current VM");
}
Turning check off
So the check can be turned off by setting ALLOW_ATTACH_SELF constant to true. The constant is set from a system property named jdk.attach.allowAttachSelf:
String s = VM.getSavedProperty("jdk.attach.allowAttachSelf");
ALLOW_ATTACH_SELF = "".equals(s) || Boolean.parseBoolean(s);
So, in my case, I simply added the following JVM argument to my gradle file and tests started to pass:
tasks.quarkusDev {
jvmArgs += "-Djdk.attach.allowAttachSelf"
}

Jacoco Test Coverage Verification not getting executed

I am trying to add test coverage verification in my kotlin gradle project. I added a super high minimum value (0.99) to fail my build but this task is not getting executed.
tasks.jacocoTestCoverageVerification {
violationRules {
rule {
limit {
minimum = "0.99".toBigDecimal()
}
}
}
}
The test coverage report is generated successfully from the coverageReport task (details not in the post)
tasks.withType<Test> {
finalizedBy(coverageReport) // report is always generated after tests run
}
According to jacoco violation rules official documentation
Any violation of the declared rules would automatically result in a failed build when executing the check task.
So I am under the assumption that the test coverage verification should be auto triggered?
So I expected that the jacocoTestCoverageVerification would execute without I having to call it. I also added the following to the jacocoTestCoverageVerification task but still doesn't fail so not writing all the rules is not a likely issue.
rule {
isEnabled = true
element = "CLASS"
includes = listOf("org.gradle.*")
limit {
counter = "LINE"
value = "TOTALCOUNT"
maximum = "0.99".toBigDecimal()
}
}
I also tried :
tasks.jacocoTestCoverageVerification {
violationRules {
rule {
classDirectories.setFrom(sourceSets.main.get().output.asFileTree.matching {
})
isEnabled = true
limit {
minimum = "0.99".toBigDecimal()
}
}
}
}
Can anyone please help me catch what I am missing?
EDIT:
Gradle version
bin/gradle --version
------------------------------------------------------------
Gradle 7.6
------------------------------------------------------------
Kotlin: 1.7.10
Groovy: 3.0.13
Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM: 17.0.5 (Eclipse Adoptium 17.0.5+8)
OS: Mac OS X 13.2 aarch64
The gradle build command:
bin/gradle build
Build logs
Execution optimizations have been disabled for task ':codeCoverageReport' to ensure correctness due to the following reasons:
- Gradle detected a problem with the following location: '/Users/Development/myrepo/build/reports/jacoco/codeCoverageReport/codeCoverageReport.xml'. Reason: Task ':validateDependenciesKtFile' uses this output of task ':codeCoverageReport' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.6/userguide/validation_problems.html#implicit_dependency for more details about this problem.
- Gradle detected a problem with the following location: '/Users/Development/myrepo/build/reports/jacoco/codeCoverageReport/html'. Reason: Task ':validateDependenciesKtFile' uses this output of task ':codeCoverageReport' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.6/userguide/validation_problems.html#implicit_dependency for more details about this problem.
These indicate that the optimizations are disabled so doesnt seem like a red flag?

UnsupportedOperationException when using enum in Java 11, works fine in Java 8

I am porting an existing application Java 7 to Java 11 (Drools 7.42.0). The application works as expected if I compile as Java 1.8 and deploy on Java 11 container (Weblogic 14). But if I compile the same code in Java 11, I get the following error. The only change between 1.8 and 11 is the java compiler level in Maven pom.
I have ASM7 as a dependency in Maven.
Caused by: java.lang.UnsupportedOperationException: This feature requires ASM7
at org.mvel2.asm.ClassVisitor.visitNestMember(ClassVisitor.java:236)
at org.mvel2.asm.ClassReader.accept(ClassReader.java:651)
at org.mvel2.asm.ClassReader.accept(ClassReader.java:391)
at org.drools.core.util.asm.ClassFieldInspector.processClassWithByteCode(ClassFieldInspector.java:107)
at org.drools.core.util.asm.ClassFieldInspector.processClassWithByteCode(ClassFieldInspector.java:114)
at org.drools.core.util.asm.ClassFieldInspector.<init>(ClassFieldInspector.java:86)
at org.drools.core.util.asm.ClassFieldInspector.<init>(ClassFieldInspector.java:74)
at org.drools.core.base.ClassFieldAccessorFactory.getClassFieldInspector(ClassFieldAccessorFactory.java:157)
at org.drools.core.base.ClassFieldAccessorFactory.getFieldType(ClassFieldAccessorFactory.java:141)
at org.drools.core.base.ClassFieldAccessorStore.getFieldType(ClassFieldAccessorStore.java:295)
at org.drools.compiler.rule.builder.PatternBuilder.getValueType(PatternBuilder.java:1079)
at org.drools.compiler.rule.builder.PatternBuilder.normalizeExpression(PatternBuilder.java:1047)
at org.drools.compiler.rule.builder.PatternBuilder.buildExpression(PatternBuilder.java:965)
at org.drools.compiler.rule.builder.PatternBuilder.buildCcdDescr(PatternBuilder.java:942)
at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:767)
at org.drools.compiler.rule.builder.PatternBuilder.processConstraintsAndBinds(PatternBuilder.java:620)
at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:187)
at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:154)
at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:136)
at org.drools.compiler.rule.builder.GroupElementBuilder.build(GroupElementBuilder.java:66)
at org.drools.compiler.rule.builder.RuleBuilder.build(RuleBuilder.java:107)
at org.drools.compiler.builder.impl.KnowledgeBuilderImpl.internalAddRule(KnowledgeBuilderImpl.java:1183)
at org.drools.compiler.builder.impl.KnowledgeBuilderImpl.addRule(KnowledgeBuilderImpl.java:1178)
at org.drools.compiler.builder.impl.KnowledgeBuilderImpl.lambda$null$3(KnowledgeBuilderImpl.java:1134)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290)
at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
I noticed while debugging that this was caused by an "enum" in our code. Drools works fine if we remove the enum and use constants. The error seems to suggest that this could happen to any nested classes. Is there a better way to handle this other than changing our code to remove nested classes and enums?
I see that in the class org.drools.core.util.asm.ClassFieldInspector, the API is set to ASM5, but MVEL is expecting ASM7. But not sure why it would work in Java 8 and not in Java 11. Any suggestions?
ClassFieldVisitor(final Class< ? > cls,
final boolean includeFinalMethods,
final ClassFieldInspector inspector) {
super(Opcodes.ASM5);
this.clazz = cls;
this.includeFinalMethods = includeFinalMethods;
this.inspector = inspector;
}
Disclaimer: I'm one of the Drools developers
That's interesting as we might not emit valid ASM code.
Please file a bug on https://issues.redhat.com so that we can fix it
Thank you very much

Kotlin script unable to instantiate class

Attempt at Kotlin Cookbook by Ken Kousen -- 1.5 Executing a Kotlin Script produces 'unable to instantiate class' error.
$ cat southpole.kts
import java.time.*
val instant = Instant.now()
val southPole = instant.atZone(ZoneId.of("Antarctica/South_Pole"))
val dst = southPole.zone.rules.isDaylightSavings(instant)
println("It is ${southPole.toLocalTime()} (UTC${southPole.offset}) at the South Pole")
println("The South Pole ${if (dst) "is" else "is not"} on Daylight Savings Time")
$ kotlinc -script southpole.kts
OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
error: unable to instantiate class Southpole (southpole.kts): java.lang.NoClassDefFoundError: kotlin/script/templates/standard/ScriptTemplateWithArgs
kotlin version 1.3.50
In order to work, println(...) needs a kotlin runtime which has to be added manually.
This issue is described here https://discuss.kotlinlang.org/t/possible-kts-bug/10162
..., it (script) takes dependencies from the module, so you need to include kotlin-script-runtime to the module dependencies explicitly.
(...) Unfortunately, it is not very obvious. We’re thinking about possible solutions.
This seems to be improved in the upcoming Kotlin 1.3.60 release
https://youtrack.jetbrains.com/issue/KT-33529
As as a work-around, use:
$ sdk use kotlin 1.3.41

Cannot register new CQ query on Apache Geode

I stuck in place while trying to register cq query with ClientCache. Still getting this exception:
CqService is not available.
java.lang.IllegalStateException: CqService is not available.
at org.apache.geode.cache.query.internal.cq.MissingCqService.start(MissingCqService.java:171)
at org.apache.geode.cache.query.internal.DefaultQueryService.getCqService(DefaultQueryService.java:777)
at org.apache.geode.cache.query.internal.DefaultQueryService.newCq(DefaultQueryService.java:486)
The client cache is created as follow:
def client(): ClientCache = new ClientCacheFactory()
.setPdxPersistent(true)
.setPdxSerializer(new ReflectionBasedAutoSerializer(false, "org.geode.importer.domain.FooBar"))
.addPoolLocator(ConfigProvider.locator.host, ConfigProvider.locator.port)
.setPoolSubscriptionEnabled(true)
.create()
and suggested solution does not help. Actual library version is:
"org.apache.geode" % "geode-core" % "1.0.0-incubating"
You will have to pull in geode-cq as a dependency. In gradle
compile 'org.apache.geode:geode-cq:1.0.0-incubating'