(Additional) datastores broken/missing in Docker images with Jmix 2.8.6

After upgrading the Jmix BOM version from 2.8.5 to 2.8.6 for an application using two additional datastores, the application refuses starting.

app | 2026-10-07T11:08:11.206+02:00  WARN 1 --- [           main] i.j.d.i.JmixBaseEntityManagerFactoryBean : Cannot find persistence.xml for 'messagestore' store. Falling back to classpath scan for entity classes.
app | In case of problems, please make sure that the property 'jmix.core.additional-stores' is defined in application.properties and contains this store name, or that at least one entity with the '@Store(name = "messagestore")' annotation is present.
app | 2026-10-07T11:08:13.048+02:00  WARN 1 --- [           main] o.s.c.annotation.AnnotationTypeMapping   : Support for convention-based annotation attribute overrides is deprecated and will be removed in Spring Framework 7.0. Please annotate the following attributes in @javax.annotation.RegEx with appropriate @AliasFor declarations: [when]
app | 2026-10-07T11:08:14.838+02:00  WARN 1 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messagestoreEntityManagerFactory' defined in class path resource [com/layertec/app/mmc/datastore/MessagesDataStoreConfiguration.class]: Failed to read candidate component class: URL [jar:file:/app/libs/atmosphere-runtime-3.0.5.slf4jvaadin1.jar!/org/atmosphere/inject/AtmosphereRequestIntrospector.class]

The instance refusing to start is built as docker image using com.bmuschko.docker-spring-boot-application (Version 9.4.0) - it was built and running with Jmix 2.8.5 before.

When trying to rebuild locally another confusing behaviour showed up:
The following Liquibase changelog include has been removed from the main datastore changelog file:

    <include file="/io/jmix/securitydata/liquibase/changelog.xml"

Maybe that’s just subsequent error.

The image has been rebuilt by the CI environment (always clean). But I did not rebuild it clean in a local environment before.

Is the change possibly related to Unreliable entity enhancement and descriptor generation (port to 2.8) ?

Additional information: I compared the images and noticed - with Jmix 2.8.6 all *orm.xml and all *persistence.xmlfiles are missing - main and additional datastores.

Have you tried to build your app locally?

This is possible, because the location of persistence descriptors has been changed. The standard bootJar and bootBuildImage tasks work correctly, but i’m not sure about the plugin you are using. We’ll check it.

Claude has managed to build the image correctly with this plugin by adding the following to build.gradle:

// Docker image with the application jar. Build with:
//   ./gradlew -Pvaadin.productionMode=true dockerBuildImage
def dockerCopyJar = tasks.register('dockerCopyJar', Copy) {
    group = 'docker'
    doFirst {
        if (findProperty('vaadin.productionMode') != 'true') {
            throw new GradleException('Docker image must be built in Vaadin production mode: add -Pvaadin.productionMode=true')
        }
    }
    from tasks.named('bootJar')
    into layout.buildDirectory.dir('docker')
    rename { 'app.jar' }
}

def dockerCreateDockerfile = tasks.register('dockerCreateDockerfile', com.bmuschko.gradle.docker.tasks.image.Dockerfile) {
    group = 'docker'
    destFile = layout.buildDirectory.file('docker/Dockerfile')
    from 'eclipse-temurin:21-jre'
    workingDir '/app'
    copyFile 'app.jar', 'app.jar'
    exposePort 8080
    entryPoint 'java', '-jar', '/app/app.jar'
}

tasks.register('dockerBuildImage', com.bmuschko.gradle.docker.tasks.image.DockerBuildImage) {
    group = 'docker'
    dependsOn dockerCreateDockerfile, dockerCopyJar
    inputDir = layout.buildDirectory.dir('docker')
    images.add("${project.name}:${project.version}")
}
1 Like

@krivopustov Thank you for you help.

The suggested claude code solution does not exactly solve all issues but it helped finding the reason.

I’ll consider replacing the use of the plugin com.bmuschko.docker-spring-boot-application. Deploying and starting bootJar instead of extracted contents ensures a consistent build.

Thank you.

1 Like