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

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"
}

Related

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?

How to define multiple errors for -XX:AbortVMOnException

I am depending on libraries that hang for certain errors, which I cannot fix! The offenders are currently StackOverflowError and OutOfMemoryError but there might be more.
I am trying to upgrade the unrecoverable hang to an exit/abort. However, I cannot figure out how to pass multiple different errors to the -XX:AbortVMOnException as only the latest argument is active in:
JAVA_OPTS="-XX:+UnlockDiagnosticVMOptions -XX:AbortVMOnException=java.lang.StackOverflowError -XX:java.lang.OutOfMemoryError" foo
There can be only one value for AbortVMOnException option.
JVM does a substring search when checking if the exception class matches AbortVMOnException value. E.g. -XX:AbortVMOnException=Error will cause the VM to abort on any throwable with Error in its name: java.lang.StackOverflowError, java.lang.OutOfMemoryError, java.lang.NoClassDefFoundError, etc.
To add a custom callback on the desired exception types, you may use the JVM TI approach described in this answer. You'd only need to replace
if (strcmp(class_name + 1, fatal_error_class) == 0) {
with
if (strstr(fatal_error_class, class_name + 1) != NULL) {
and then it will be possible to specify multiple exceptions types that cause VM exit:
java -agentpath:/path/to/libabort.so=java/lang/StackOverflowError,java/lang/OutOfMemoryError ...

How to fail Velocity template processing with tracable message

Having:
Velocity template or macro
some object
How to validate the object (#if) and fail (stop further processing) in a way that is easily tracable to the place of failure (like throwing exception in Java).
I am looking for something like this:
#if ( ! $context.treasureMap.containsKey('gold'))
#fail('no golden treasure here')
#end
Background
I am writing a maven site page. The velocity context is injected by maven and contains POM information. I want to test existence of some information from effective pom. When the information is not available, I want to fail.
Requirements
fail Velocity processing > fail site generation > fail maven build.
error message should lead to the place of failure so the site should be fixed
preferably no configuration (no extensions, just constructs/tools contained in plain Velocity)
Tried
Strict Reference Mode
Unwanted configuration, do not want to fail on every occasion.
#evaluate('#end') aka syntax error
(Chose #end as most descriptive to my intent) Basically what I want. Fails the processing and maven build but the error message does not lead back to failure location:
ParseException: Encountered "#end" at line 1, column 1..
You need to make a method call which produce exception.See explanation:
The only place where one could run into trouble within Velocity is if there is a call to a method which throws an exception during runtime. For example, this VTL defines a String $foo and then attempts to call its substring() method on it would throw an IndexOutOfBoundsException:
#set ($foo = "bar")
#set ($bar = $foo.substring(0,10))
When the exception is thrown, the parser will stop processing and throw that exception up the stack tree where it can be caught in the method that caused the parser to execute. At that point, the exception can be handled gracefully.

Writing Codeception CLI test; want to throw exception but not have it fail the test

I forked Codeception/Codeception and added a Command module check that throws an exception.
When testing, this exception causes the test to fail but I'm running a test to force the exception and failure, to make sure it catches it.
Here's the edit to src/Codeception/Command/GenerateSuite.php
if ($this->containsInvalidCharacters ($suite)) {
throw new \Exception("Suite name '{$suite}' contains invalid characters. ([A-Za-z0-9_]).");
}
When updating tests/cli/GenerateSuiteCept.php when I run the command $I->executeCommand('generate:suite invalid-suite'); it fails because I'm throwing the exception in src/Codeception/Command/GenerateSuite.php in the first place.
Here is the addition to tests/cli/GenerateSuiteCept.php:
$I->executeCommand('generate:suite invalid-dash-suite');
When I run it, it says it failed. However, I want it to pass because I'm deliberately adding the dash to verify it catches invalid characters. What is the best way to do that? I'm wary of a try/catch block in these tests. I'm not sure if that is the best way to do that.
After looking at the other Codeception tests, I found this to be a better way than throwing an exception:
if ($this->containsInvalidCharacters ($suite)) {
$output->writeln("<error>Suite name '{$suite}' contains invalid characters. ([A-Za-z0-9_]).</error>");
return;
}
So I modified the test to:
$I->expect ('suite is not created due to dashes');
$I->executeCommand('generate:suite invalid-dash-suite');
$I->seeInShellOutput('contains invalid characters');

How to have a run script with display_trace() in it for debug purposes

I have a typical sort of "run" script (below).
When I want to debug the scenario, I use VLAB GUI ... and in this instance I want the trace window open, so I have display_trace() at the end of the run script.
However, often I just want to run this scenario in batch as part of a regression test. The problem is that VLAB throws an exception on display_trace() when in batch mode.
I don't really like the idea of
try:
display_trace()
except:
pass
(or even catching the specific error that is thrown) ... it just feels "messy". What if there is a valid exception upon display_trace() that I miss?
Is there some way not to call display_trace() at all if I'm in batch mode?
run script:
from vlab import *
import os
image_path = os.path.join('o5e', 'bin','o5e_dbg.elf')
load('ecu.sim', args=['--testbench=testbench_o5e',"--image=%s" % image_path] + __args__)
# First set up MMU
add_sw_execute_breakpoint(get_address("BamExit"))
run(blocking=True)
# Then we can set breakpoints in user code space
add_sw_execute_breakpoint(get_address("init_variables"))
run(blocking=True)
# Trace stuff
vtf_sink = trace.sink.vtf("o5e.vtf")
add_trace("+src:ecu.core_system.Core0.InstrTraceMsg", sink=vtf_sink)
add_trace(get_ports("ecu.core_system.Core0", kind="bus"), sink=vtf_sink)
display_trace(vtf_sink)
The "interface_mode" session property can be used to query whether VLAB was launched in "graphical" mode, where the VLAB IDE is displayed, or in "text" mode.
You could use this property to conditionally call vlab.display_trace():
in_graphical_mode = vlab.get_properties()["interface_mode"] == "graphical"
if in_graphical_mode:
vlab.display_trace()