spring-bootkotlinmongock

Kotlin + Mongock for Spring Boot + Spring Data: IllegalAccessError


I have created a Kotlin application that connects to a MongoDB on Atlas to fetch some data via Spring Data JPA. For future changes to the document structure, I have experimented with Mongock. I have gone for the simplest possible integration:

@SpringBootApplication
@EnableMongock
class MyKotlinApplication
...

and declared in the application.properties

# mongock
mongock.migration-scan-package=org.foo.bar.changelogs
mongock.runner-type=applicationrunner

And created a @ChangeUnit. Mongock finds it and tries to execute it...

package org.foo.bar.changelogs

import io.mongock.api.annotations.ChangeUnit
import io.mongock.api.annotations.Execution
import io.mongock.api.annotations.RollbackExecution
import org.foo.bar.units.Unit
import org.foo.bar.units.UnitRepository

@ChangeUnit(id = "AddDispatchedBy2", order = "2", author = "Patrick")
class AddDispatchedBy2 {

    @Execution
    fun execute(unitRepository: UnitRepository) {

        val units = unitRepository.findAll().toList();
        for (it in units) {
            it.dispatchedBy = "unknown"
        }
        units.forEach { unitRepository.save(it) }

    }

    @RollbackExecution
    fun executeRollback() {

        System.out.println("oops");

    }
}

..but it fails: Method threw 'java.lang.IllegalAccessError' exception. Cannot evaluate org.foo.bar.units.UnitRepository_$$_mongock_21d_0.toString()

The UnitRepository is nothing special either:

@Repository
interface UnitRepository : CrudRepository<Unit, String>

I have understood from the docs that the application context is available because the runner takes care of that, and that Mongock somehow proxies the beans. But that doesn't seem to work...?

I have tried to declare the dependency to the UnitRepository in the constructor of the @ChangeUnit but the problem remains. Most blog articles and search hits on github show the usage of MongoTemplate but I still hope that I'd be able to use my own Repository bean.


Solution

  • It seems related to the proxy Mongock uses. It's probably something to do with the JVM version.

    If you annotate the parameter unitRepository with @NonLockGuarded, it will be probably fix it.