NoSuchFieldExpression when Debbugging - kotlin

Since a while I got the following Exception, when running my tests in Debugging Mode.
java.lang.NoSuchFieldException: serialPersistentFields
at java.base/java.lang.Class.getDeclaredField(Class.java:2642)
at java.base/java.io.ObjectStreamClass.getDeclaredSerialFields(ObjectStreamClass.java:1634)
at java.base/java.io.ObjectStreamClass.getSerialFields(ObjectStreamClass.java:1608)
at java.base/java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:398)
at java.base/java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:384)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
at java.base/java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:384)
at java.base/java.io.ObjectStreamClass$Caches$1.computeValue(ObjectStreamClass.java:110)
at java.base/java.io.ObjectStreamClass$Caches$1.computeValue(ObjectStreamClass.java:107)
at java.base/java.io.ClassCache$1.computeValue(ClassCache.java:73)
at java.base/java.io.ClassCache$1.computeValue(ClassCache.java:70)
at java.base/java.lang.ClassValue.getFromHashMap(ClassValue.java:228)
at java.base/java.lang.ClassValue.getFromBackup(ClassValue.java:210)
at java.base/java.lang.ClassValue.get(ClassValue.java:116)
at java.base/java.io.ClassCache.get(ClassCache.java:84)
at java.base/java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:363)
at java.base/java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:246)
at org.junit.platform.launcher.TestIdentifier.<clinit>(TestIdentifier.java:51)
at com.intellij.junit5.JUnit5IdeaTestRunner.<clinit>(JUnit5IdeaTestRunner.java:72)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:383)
at java.base/java.lang.Class.forName(Class.java:376)
at com.intellij.rt.junit.JUnitStarter.getAgentClass(JUnitStarter.java:244)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:225)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
I am already, found the following links:
NoSuchFieldException when field exists
I also created a Bug Report at:
https://youtrack.jetbrains.com/issue/IDEA-300566
Even running a simpleTest like:
package com.example.package
import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test
class SampleTest {
#Test
fun someTest(){
//Arrange
val a = 5
val b = 10
//Act
val res = a + b
//Assert
res.shouldBe(15)
}
}
causes the Exception shown above.
Does anyone got this problem alread and found a solution for it.
I am not serializing anything. I can't even debug the most simple Test, printing Hello World.
I a other project it's still possible.
After this exception there are coming a lot more and if I disable the Breakpoints the test is excecuted without problems.

Found out that disabling exception breakpoints fix the problem for the moment.
Hope that there will be a better solution than this in the future.
The exceptions seem not to disturb the functionality of the Unit Test, so after all exceptions thrown the Breakpoints inside the code are visited again.

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

Sleep in Spock's Mock waits when run by CompletableFuture

When I separately run the runAsyncWithMock test, it waits for 3 seconds until the mock's execution is finalised, rather than get terminated like the other 2 tests.
I was not able to figure out why.
It is interesting that:
When multiple Runnables are executed by CompletableFuture.runAsync in a row in the runAsyncWithMock test, only the first one waits, the others not.
When having multiple duplicated runAsyncWithMock tests, each and every of them runs for 3s when the whole specification is executed.
When using Class instance rather than a Mock, the test is finalised immediately.
Any idea what I got wrong?
My configuration:
macOS Mojave 10.14.6
Spock 1.3-groovy-2.4
Groovy 2.4.15
JDK 1.8.0_201
The repo containing the whole Gradle project for reproduction:
https://github.com/lobodpav/CompletableFutureMisbehavingTestInSpock
The problematic test's code:
#Stepwise
class SpockCompletableFutureTest extends Specification {
def runnable = Stub(Runnable) {
run() >> {
println "${Date.newInstance()} BEGIN1 in thread ${Thread.currentThread()}"
sleep(3000)
println "${Date.newInstance()} END1 in thread ${Thread.currentThread()}"
}
}
def "runAsyncWithMock"() {
when:
CompletableFuture.runAsync(runnable)
then:
true
}
def "runAsyncWithMockAndClosure"() {
when:
CompletableFuture.runAsync({ runnable.run() })
then:
true
}
def "runAsyncWithClass"() {
when:
CompletableFuture.runAsync(new Runnable() {
void run() {
println "${Date.newInstance()} BEGIN2 in thread ${Thread.currentThread()}"
sleep(3000)
println "${Date.newInstance()} END2 in thread ${Thread.currentThread()}"
}
})
then:
true
}
}
This is caused by the synchronized methods in https://github.com/spockframework/spock/blob/master/spock-core/src/main/java/org/spockframework/mock/runtime/MockController.java when a mock is executed it delegates through the handle method. The Specification also uses the synchronized methods, in this case probably leaveScope, and is thus blocked by the sleeping Stub method.
Since this is a thread interleaving problem I guess that additional closure in runAsyncWithMockAndClosure moves the execution of the stub method behind the leaveScope and thus changes the ordering/blocking.
Oh, just now after writing my last comment I saw a difference:
You use #Stepwise (I didn't when I tried at first), an annotation I almost never use because it creates dependencies between feature methods (bad, bad testing practice). While I cannot say why this has the effect described by you only when running the first method, I can tell you that removing the annotation fixes it.
P.S.: With #Stepwise you cannot even execute the second or third method separately because the runner will always run the preceding one(s) first, because - well, the specification is said to be executed step-wise. ;-)
Update: I could briefly reproduce the problem with #Stepwise, but after recompilation now it does not happen anymore, neither with or without that annotation.

WebSphere wsadmin testConnection error message

I'm trying to write a script to test all DataSources of a WebSphere Cell/Node/Cluster. While this is possible from the Admin Console a script is better for certain audiences.
So I found the following article from IBM https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/txml_testconnection.html which looks promising as it describles exactly what I need.
After having a basic script like:
ds_ids = AdminConfig.list("DataSource").splitlines()
for ds_id in ds_ids:
AdminControl.testConnection(ds_id)
I experienced some undocumented behavior. Contrary to the article above the testConnection function does not always return a String, but may also throw a exception.
So I simply use a try-catch block:
try:
AdminControl.testConnection(ds_id)
except: # it actually is a com.ibm.ws.scripting.ScriptingException
exc_type, exc_value, exc_traceback = sys.exc_info()
now when I print the exc_value this is what one gets:
com.ibm.ws.scripting.ScriptingException: com.ibm.websphere.management.exception.AdminException: javax.management.MBeanException: Exception thrown in RequiredModelMBean while trying to invoke operation testConnection
Now this error message is always the same no matter what's wrong. I tested authentication errors, missing WebSphere Variables and missing driver classes.
While the Admin Console prints reasonable messages, the script keeps printing the same meaningless message.
The very weird thing is, as long as I don't catch the exception and the script just exits by error, a descriptive error message is shown.
Accessing the Java-Exceptions cause exc_value.getCause() gives None.
I've also had a look at the DataSource MBeans, but as they only exist if the servers are started, I quickly gave up on them.
I hope someone knows how to access the error messages I see when not catching the Exception.
thanks in advance
After all the research and testing AdminControl seems to be nothing more than a convinience facade to some of the commonly used MBeans.
So I tried issuing the Test Connection Service (like in the java example here https://www.ibm.com/support/knowledgecenter/en/SSEQTP_8.5.5/com.ibm.websphere.base.doc/ae/cdat_testcon.html
) directly:
ds_id = AdminConfig.list("DataSource").splitlines()[0]
# other queries may be 'process=server1' or 'process=dmgr'
ds_cfg_helpers = __wat.AdminControl.queryNames("WebSphere:process=nodeagent,type=DataSourceCfgHelper,*").splitlines()
try:
# invoke MBean method directly
warning_cnt = __wat.AdminControl.invoke(ds_cfg_helpers[0], "testConnection", ds_id)
if warning_cnt == "0":
print = "success"
else:
print "%s warning(s)" % warning_cnt
except ScriptingException as exc:
# get to the root of all evil ignoring exception wrappers
exc_cause = exc
while exc_cause.getCause():
exc_cause = exc_cause.getCause()
print exc_cause
This works the way I hoped for. The downside is that the code gets much more complicated if one needs to test DataSources that are defined on all kinds of scopes (Cell/Node/Cluster/Server/Application).
I don't need this so I left it out, but I still hope the example is useful to others too.

How to propagate exceptions from a Job?

From What is the difference between launch/join and async/await in Kotlin coroutines:
launch is used to fire and forget coroutine. It is like starting a new thread. If the code inside the launch terminates with exception, then it is treated like uncaught exception in a thread -- usually printed to stderr in backend JVM applications and crashes Android applications. join is used to wait for completion of the launched coroutine and it does not propagate its exception. However, a crashed child coroutine cancels its parent with the corresponding exception, too.
If join doesn't propagate the exception, is there a way to wait for completion of a Job which does?
E.g. suppose that some library method returns a Job because it assumed its users wouldn't want to propagate exceptions, but it turns out there is a user who does want it; can this user get it without modifying the library?
Please use join + invokeOnCompletion method
Code will be like this:
suspend fun awaitError(job: Job): Throwable? {
val errorAwaiter = CompletableDeferred<Throwable?>();
job.invokeOnCompletion { errorAwaiter.complete(it) }
require(job.IsActive) {
"Job was completed for too fast, probably error is missed"
}
val errorRaised = errorAwaiter.await();
return when(errorRaised) {
is CancellationException -> null
else -> errorRaised
}
}
Please note, that code will raise error for the fast jobs, so please be carefully. Possible it is better just to return null in this case (in my example).

org.xml.sax.SAXException: Invalid element in com.rallydev.webservice.v1_28.domain.OperationResult - Object

I've built an integration with Rally using the SOAP API so that when I target a bug in bugzilla, a user story is created and scheduled in the proper release. It also work in update, so if I just update the target the US will be associated to the specified release in Rally.
It has been working for a while, but now it seems not to work anymore.
I get the following error:
org.xml.sax.SAXException: Invalid element in com.rallydev.webservice.v1_28.domain.OperationResult - Object
at org.apache.axis.encoding.ser.BeanDeserializer.onStartChild(BeanDeserializer.java:258)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1035)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:236)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2467)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at com.rallydev.webservice.v1_28.service.RallyServiceSoapBindingStub.update(RallyServiceSoapBindingStub.java:1166)
I updated to the latest API, but not luck.
Stefano,
This is a known issue in Rally and we expect it will be corrected this Saturday (3Dec11). If you need to get the code running right away, you can catch the thrown exception by editing the generated code.
As long as the SAX exception is caught, it does not prevent updates from actually succeeding. A couple customers have been able to workaround the mismatched return value by wrapping the update code and/or calls to the Rally service in a try/catch block similar to an example here on a Task:
try {
OperationResult operationResult = rallyService.update(myTask);
} catch (Exception e) {
System.out.println("Rally SAX Exception encountered");
}
Sorry for the inconvenience.
Mark