Spring Boot 2.2 & RestAssured: MissingMethodException

I recently updated an application from Spring Boot v2.1 to v2.2. I didn’t expect it to be easy and especially due to update of Kotlin, I also had to change some code.

Nevertheless I had some strange error concerning tests that costs me some time. After simply updating Spring Boot and fixing compile errors, I executed the tests and got the following runtime error:

groovy/lang/GroovyObject
 java.lang.NoClassDefFoundError: groovy/lang/GroovyObject
     at java.base/java.lang.ClassLoader.defineClass1(Native Method)
     […]
     at io.restassured.RestAssured.(RestAssured.java:346)
     at RestAssuredTest.init(RestAssuredTest.kt:11)
     […]
 Caused by: java.lang.ClassNotFoundException: groovy.lang.GroovyObject
     at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
     at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
     at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
     … 58 more

Well, this one was the easy part: Simply adding a dependency to org.codehaus.groovy:groovy solved this error. Nevertheless I didn’t expect such an error to ocurr after a “simple” update of Spring Boot.

Now for the hard part. After adding the dependency, an even more strange exception got thrown:

groovy.lang.MissingMethodException: No signature of method: io.restassured.internal.ContentParser.parse() is applicable for argument types: (io.restassured.internal.RestAssuredResponseImpl, io.restassured.internal.ResponseParserRegistrar...) values: [io.restassured.internal.RestAssuredResponseImpl@4ee4c86b, io.restassured.internal.ResponseParserRegistrar@22029a56, ...]
Possible solutions: wait(), any(), grep()
 at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:70)
 at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:49)
 at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:151)
 at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:478)
 at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure$validate$1.call(Unknown Source)
 […]

This one costs me a lot of time. I first thought of some dependency incompatibility, e.g. Spring dependency management pulls in a library in version X but my code / another library expects the library in version Y – but this wasn’t the case. I also had a look into the source code, but that simply told me, that the call to the parse() method seemed to be correct. Even debugging and stepping through the code didn’t gave me any hint.

As I didn’t had any more ideas, I built up a completly new project without Spring and just with the necessary dependencies to run a simple RestAssured test, that would trigger the error:

class RestAssuredTest {
    
    @Before
    fun init() {
        RestAssured.port = 8080
        RestAssured.baseURI = "http://localhost"
    }

    @Test
    fun triggerTheError() {
        RestAssured
            .given()
            .`when`()
            .contentType("application/json")
            .get("/v2/api-docs")
            .then()
            .statusCode(200)
            .body("swagger", `is`("2.0"))
    }

}

After that I started to add more dependencies and Spring dependency management until I got into the same error. As the root cause for the error must have something to do with the dependencies, I executed ./gradlew dependencies and compared it to the simple setup without Spring. It still took me some time, but then I found the problem: Spring dependency management removes the transitive dependency to org.codehaus.groovy:groovy-xml of RestAssured. Manually adding this dependency solved the error.

Besides that, I don’t understand why this missing dependency causes such a strange error with a message that doesn’t contain any hint to the root cause. And additionally I don’t understand why Spring dependency management removes this transitive dependency…

Using DYS Omnibus F4 Flight Controller with Ubuntu Linux

I recently built up a FPV quadcopter model with a DYS Omnibus F4 FC (see bottom of post for full part list). Since the first time, I had some strange problems connecting to the FC as I could not connect to the flight controller sporadically using Betaflight and I had to reconnect the FC to the computer. To make it worse, I could not connect to the FC at all, after I reinstalled my system (due to another problem). Fortunately I found the caus(es) for my problems. weiterlesen…

Merging hard drives without RAID?

Some time ago, I noticed that the harddisk of my home server filled up more and more and I needed to add some more space. As this server is made to be as energy-efficient as possible, I don’t use a RAID which I can extend easily. Additionally I don’t like some facts about RAID, e.g. that I can not pull out a single drive and read the data on it on another machine – or that you need to e.g. add four drives to fulfill the requirements for your RAID level. But how can I “merge” multiple drives without a RAID transparently and without much effort? weiterlesen…

Audio dropouts / glitches / skips on Ubuntu 16.10

I recently upgraded the hardware of my home server and therefore decided to do a clean setup of the whole system, as the current one was heavily customized and I wanted it to be more clear. After installing the hardware and the newestest Ubuntu 16.10 (and lots of other programs and settings), I noticed some strange audio problems: I got random audio dropouts. weiterlesen…

Open-Xchange broken after Update to 7.8.3 Rev5

Today I updated my Open-Xchange instance to the newest version 7.8.3-5. The upgrade worked as normal, except that I had some update-conflicts in the config files, as I adjusted some values in them – but hey, this is unfortunately normal for Open-Xchange. But after the update, I could not log into Open-Xchange because of a “temporary error on the server” (LGI-0003).

weiterlesen…

Daily Scrum Timer Ball

Daily Scrum Timer BallIn our development team we (unfortunately) do not use scrum, but nevertheless we are using some scrum elements in our daily work. Besides retros, we are carry out a daily meeting at which everybody has about 2min to describe, what he has done so far, what he will do next and what blocks him. But unfortunately, we have some persons in the team, that regularily exceed their talking time…

weiterlesen…

IntelliJ Error: MissingPropertyException

Today I wanted to do some documentation on a private Java coding project. For this, I decided to use AsciiDoc as this would give me the flexibility to later publish my project e.g. on Github and have the document rendered directly on the project overview page and additionality create some PDFs for the distribution of the program as user documentation. After the first minor changes to my Gradle build-script to generate the PDFs, IntelliJ got me really strange errors when updating the Gradle structure in IntelliJ.

weiterlesen…

Roundcube: Error “Undefined index: 1.0.0.0-RC” when updating

RoundCubeI recently updated the roundcube installation of my server to the latest version. After that, I wanted to update all plugins using composer but only got the error “[ErrorException] Undefined index: 1.0.0.0-RC”. I googled around but only found some other guy with the same problem and so I decided to play around with the composer.json and hopefully find a way to fix the error. The cause of the error was sadly very simple… weiterlesen…

How to perform SQL JOINs on a sub-query in Hibernate

Hibernate is a pretty cool ORM framework with lots of features and is probably one of the frameworks, that are used most frequently in Java applications that use a relational database. With the criteria API and the hibernate query language (HQL) it offers both a programmatic and a more SQL-like approach to access data. But unfortunately, both have their limitations and are not as powerful as SQL. In this article, I will show an approach to work around one of this limitations I stumbled upon. weiterlesen…