ultraq / thymeleaf-layout-dialect

A dialect for Thymeleaf that lets you build layouts and reusable templates in order to improve code reuse
https://ultraq.github.io/thymeleaf-layout-dialect/
Apache License 2.0
701 stars 111 forks source link

No signature of method: org.thymeleaf.engine.Model.first() is applicable for argument types: () values: [] #241

Closed tbee closed 1 week ago

tbee commented 2 weeks ago

I'm using thymeleaf-layout-dialect 3.3.0 and thymeleaf 3.1.2.RELEASE, AFAIK is exactly the version of thymeleaf that this version of thymeleaf-layout-dialect expects. The application runs fine from the IDE, but in an UberJar I get:

2024-04-28 22:05:02,144 ERROR [org.thy.TemplateEngine] (executor-thread-1) [THYMELEAF][executor-thread-1] Exception processing template "templates/connect.html": Error during execution of processor 'nz.net.ultraq.thymeleaf.layoutdialect.decorators.DecorateProcessor' (template: "templates/connect.html" - line 2, col 74): org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'nz.net.ultraq.thymeleaf.layoutdialect.decorators.DecorateProcessor' (template: "templates/connect.html" - line 2, col 74)
        at org.thymeleaf.processor.element.AbstractAttributeModelProcessor.doProcess(AbstractAttributeModelProcessor.java:134)
        at org.thymeleaf.processor.element.AbstractElementModelProcessor.process(AbstractElementModelProcessor.java:98)
        at org.thymeleaf.util.ProcessorConfigurationUtils$ElementModelProcessorWrapper.process(ProcessorConfigurationUtils.java:649)
        at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1510)
        at org.thymeleaf.engine.OpenElementTag.beHandled(OpenElementTag.java:205)
        at org.thymeleaf.engine.Model.process(Model.java:282)
        at org.thymeleaf.engine.Model.process(Model.java:290)
        at org.thymeleaf.engine.GatheringModelProcessable.process(GatheringModelProcessable.java:78)
        at org.thymeleaf.engine.ProcessorTemplateHandler.handleCloseElement(ProcessorTemplateHandler.java:1640)
        at org.thymeleaf.engine.CloseElementTag.beHandled(CloseElementTag.java:139)
        at org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:136)
        at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:661)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1103)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
        at org.tbee.spotifyDanceInfoQrks.Thymeleaf$ThymeleafRenderable.render(Thymeleaf.java:62)
        at org.jboss.resteasy.plugins.providers.html.HtmlRenderableWriter.writeTo(HtmlRenderableWriter.java:72)
        at org.jboss.resteasy.plugins.providers.html.HtmlRenderableWriter.writeTo(HtmlRenderableWriter.java:34)
        at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.lambda$writeTo$1(ServerWriterInterceptorContext.java:74)
        at org.jboss.resteasy.plugins.server.servlet.Servlet3AsyncHttpRequest$Servlet3ExecutionContext.executeBlockingIo(Servlet3AsyncHttpRequest.java:373)
        at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:73)
        at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.syncProceed(AbstractWriterInterceptorContext.java:224)
        at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.getStarted(AbstractWriterInterceptorContext.java:161)
        at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.lambda$getStarted$0(ServerWriterInterceptorContext.java:68)
        at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.aroundWriteTo(ServerWriterInterceptorContext.java:87)
        at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.getStarted(ServerWriterInterceptorContext.java:68)
        at org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$3(ServerResponseWriter.java:166)
        at org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:365)
        at org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:243)
        at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:100)
        at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:73)
        at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:518)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:458)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:240)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:154)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:321)
        at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:157)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:229)
        at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:222)
        at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.service(ResteasyFilter.java:70)
        at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.sendError(ResteasyFilter.java:76)
        at io.undertow.servlet.handlers.DefaultServlet.doGet(DefaultServlet.java:189)
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527)
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
        at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
        at io.quarkus.resteasy.runtime.ResteasyFilter.doFilter(ResteasyFilter.java:31)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
        at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63)
        at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
        at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
        at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:67)
        at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133)
        at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
        at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65)
        at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
        at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
        at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
        at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:247)
        at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:56)
        at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:111)
        at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:108)
        at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
        at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
        at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$9$1.call(UndertowDeploymentRecorder.java:630)
        at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)
        at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:152)
        at io.undertow.server.handlers.CanonicalPathHandler.handleRequest(CanonicalPathHandler.java:49)
        at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$1.handleRequest(UndertowDeploymentRecorder.java:126)
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:284)
        at io.undertow.server.DefaultExchangeHandler.handle(DefaultExchangeHandler.java:18)
        at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$5$2.run(UndertowDeploymentRecorder.java:445)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:599)
        at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: groovy.lang.MissingMethodException: No signature of method: org.thymeleaf.engine.Model.first() is applicable for argument types: () values: []
Possible solutions: print(java.io.PrintWriter), print(java.lang.Object), find(), find(groovy.lang.Closure), is(java.lang.Object), write(java.io.Writer)
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:72)
        at org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.unwrap(IndyGuardsFiltersAndSignatures.java:163)
        at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
        at nz.net.ultraq.thymeleaf.layoutdialect.decorators.DecorateProcessor.doProcess(DecorateProcessor.groovy:102)
        at org.thymeleaf.processor.element.AbstractAttributeModelProcessor.doProcess(AbstractAttributeModelProcessor.java:77)
        ... 87 more

This seems to me thymeleaf-layout-dialect is assuming a first() method exists in Thymeleaf's Model class. It does not. My code does not invoke any 'first' method, so I assume it is something internal. I'm unclear in why it works from the IDE and not from the UberJar; there is only one Thymeleaf dependency in the tree (see the at the bottom).

org.tbee.spotifyDanceInfo:spotifydanceinfoqrks:jar:1.1.2
+- org.tbee.spotifyDanceInfo:spotifyDanceInfoShared:jar:1.1.2:compile
|  +- org.tbee.tecl:tecl:jar:1.7.1:compile
|  |  +- org.antlr:antlr4:jar:4.13.0:compile
|  |  |  +- org.antlr:antlr4-runtime:jar:4.13.0:compile
|  |  |  +- org.antlr:antlr-runtime:jar:3.5.3:compile
|  |  |  +- org.antlr:ST4:jar:4.3.4:compile
|  |  |  +- org.abego.treelayout:org.abego.treelayout.core:jar:1.0.3:compile
|  |  |  \- com.ibm.icu:icu4j:jar:72.1:compile
|  |  \- org.apache.commons:commons-text:jar:1.11.0:compile
|  +- com.opencsv:opencsv:jar:5.9:compile
|  |  +- org.apache.commons:commons-lang3:jar:3.14.0:compile
|  |  +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
|  |  |  +- commons-logging:commons-logging:jar:1.2:compile
|  |  |  \- commons-collections:commons-collections:jar:3.2.2:compile
|  |  \- org.apache.commons:commons-collections4:jar:4.4:compile
|  +- org.apache.poi:poi:jar:5.2.5:compile
|  |  +- commons-codec:commons-codec:jar:1.16.1:compile
|  |  +- org.apache.commons:commons-math3:jar:3.6.1:compile
|  |  +- com.zaxxer:SparseBitSet:jar:1.3:compile
|  |  \- org.apache.logging.log4j:log4j-api:jar:2.23.1:compile
|  +- org.apache.poi:poi-ooxml:jar:5.2.5:compile
|  |  +- org.apache.poi:poi-ooxml-lite:jar:5.2.5:compile
|  |  +- org.apache.xmlbeans:xmlbeans:jar:5.2.0:compile
|  |  +- org.apache.commons:commons-compress:jar:1.26.1:compile
|  |  \- com.github.virtuald:curvesapi:jar:1.08:compile
|  +- se.michaelthelin.spotify:spotify-web-api-java:jar:9.0.0-RC1:compile
|  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.17.0:compile
|  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.17.0:compile
|  |  |  +- com.fasterxml.jackson.core:jackson-core:jar:2.17.0:compile
|  |  |  \- net.bytebuddy:byte-buddy:jar:1.14.11:compile
|  |  +- com.google.code.gson:gson:jar:2.10.1:compile
|  |  +- com.neovisionaries:nv-i18n:jar:1.29:compile
|  |  \- org.apache.httpcomponents.client5:httpclient5-cache:jar:5.3:compile
|  |     \- org.apache.httpcomponents.client5:httpclient5:jar:5.3:compile
|  |        +- org.apache.httpcomponents.core5:httpcore5:jar:5.2.4:compile
|  |        \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.2.4:compile
|  \- com.github.LabyStudio:java-spotify-api:jar:1.2.0:compile
|     +- net.java.dev.jna:jna:jar:5.8.0:runtime
|     \- net.java.dev.jna:jna-platform:jar:5.8.0:runtime
+- io.quarkus:quarkus-resteasy:jar:3.9.4:compile
|  +- io.quarkus:quarkus-vertx-http:jar:3.9.4:compile
|  |  +- io.quarkus:quarkus-security-runtime-spi:jar:3.9.4:compile
|  |  +- io.quarkus:quarkus-credentials:jar:3.9.4:compile
|  |  +- io.quarkus:quarkus-mutiny:jar:3.9.4:compile
|  |  |  +- io.quarkus:quarkus-smallrye-context-propagation:jar:3.9.4:compile
|  |  |  |  \- io.smallrye:smallrye-context-propagation:jar:2.1.0:compile
|  |  |  |     +- io.smallrye:smallrye-context-propagation-api:jar:2.1.0:compile
|  |  |  |     \- io.smallrye:smallrye-context-propagation-storage:jar:2.1.0:compile
|  |  |  \- io.smallrye.reactive:mutiny-smallrye-context-propagation:jar:2.5.8:compile
|  |  +- io.smallrye.common:smallrye-common-vertx-context:jar:2.3.0:compile
|  |  |  \- io.smallrye.common:smallrye-common-constraint:jar:2.3.0:compile
|  |  +- io.quarkus:quarkus-vertx:jar:3.9.4:compile
|  |  |  +- io.quarkus:quarkus-netty:jar:3.9.4:compile
|  |  |  |  \- com.aayushatharva.brotli4j:brotli4j:jar:1.16.0:compile
|  |  |  |     +- com.aayushatharva.brotli4j:service:jar:1.16.0:compile
|  |  |  |     \- com.aayushatharva.brotli4j:native-windows-x86_64:jar:1.16.0:compile
|  |  |  +- io.netty:netty-codec-haproxy:jar:4.1.108.Final:compile
|  |  |  +- io.smallrye.common:smallrye-common-annotation:jar:2.3.0:compile
|  |  |  +- io.quarkus:quarkus-virtual-threads:jar:3.9.4:compile
|  |  |  +- io.quarkus:quarkus-vertx-latebound-mdc-provider:jar:3.9.4:compile
|  |  |  +- io.smallrye.reactive:smallrye-mutiny-vertx-core:jar:3.11.0:compile
|  |  |  |  +- io.smallrye.reactive:smallrye-mutiny-vertx-runtime:jar:3.11.0:compile
|  |  |  |  \- io.smallrye.reactive:vertx-mutiny-generator:jar:3.11.0:compile
|  |  |  |     \- io.vertx:vertx-codegen:jar:4.5.7:compile
|  |  |  \- io.smallrye:smallrye-fault-tolerance-vertx:jar:6.2.6:compile
|  |  +- io.smallrye.reactive:smallrye-mutiny-vertx-web:jar:3.11.0:compile
|  |  |  +- io.smallrye.reactive:smallrye-mutiny-vertx-web-common:jar:3.11.0:compile
|  |  |  +- io.smallrye.reactive:smallrye-mutiny-vertx-auth-common:jar:3.11.0:compile
|  |  |  +- io.smallrye.reactive:smallrye-mutiny-vertx-bridge-common:jar:3.11.0:compile
|  |  |  \- io.smallrye.reactive:smallrye-mutiny-vertx-uri-template:jar:3.11.0:compile
|  |  |     \- io.vertx:vertx-uri-template:jar:4.5.7:compile
|  |  +- io.vertx:vertx-web:jar:4.5.7:compile
|  |  |  +- io.vertx:vertx-web-common:jar:4.5.7:compile
|  |  |  +- io.vertx:vertx-auth-common:jar:4.5.7:compile
|  |  |  \- io.vertx:vertx-bridge-common:jar:4.5.7:compile
|  |  \- io.github.crac:org-crac:jar:0.1.3:compile
|  \- io.quarkus:quarkus-resteasy-server-common:jar:3.9.4:compile
|     +- io.quarkus:quarkus-resteasy-common:jar:3.9.4:compile
|     |  \- org.jboss.resteasy.microprofile:microprofile-config:jar:2.1.5.Final:compile
|     |     \- org.eclipse.microprofile.config:microprofile-config-api:jar:3.0.3:compile
|     +- org.jboss.resteasy:resteasy-cdi:jar:6.2.7.Final:compile
|     \- jakarta.validation:jakarta.validation-api:jar:3.0.2:compile
+- io.quarkus:quarkus-resteasy-multipart:jar:3.9.4:compile
|  +- org.eclipse.angus:angus-activation:jar:2.0.2:compile
|  |  \- jakarta.activation:jakarta.activation-api:jar:2.1.3:compile
|  \- org.jboss.logging:commons-logging-jboss-logging:jar:1.0.0.Final:compile
+- org.jboss.resteasy:resteasy-multipart-provider:jar:6.2.7.Final:compile
|  +- org.jboss.resteasy:resteasy-core-spi:jar:6.2.7.Final:compile
|  |  +- jakarta.ws.rs:jakarta.ws.rs-api:jar:3.1.0:compile
|  |  +- jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.2:compile
|  |  \- org.reactivestreams:reactive-streams:jar:1.0.4:compile
|  +- org.jboss.resteasy:resteasy-core:jar:6.2.7.Final:compile
|  |  \- com.ibm.async:asyncutil:jar:0.1.0:compile
|  +- org.jboss.resteasy:resteasy-jaxb-provider:jar:6.2.7.Final:compile
|  |  +- org.glassfish.jaxb:codemodel:jar:4.0.3:compile
|  |  +- org.glassfish.jaxb:jaxb-core:jar:4.0.5:compile
|  |  +- org.glassfish.jaxb:jaxb-jxc:jar:4.0.3:compile
|  |  +- org.glassfish.jaxb:jaxb-runtime:jar:4.0.5:compile
|  |  +- org.glassfish.jaxb:txw2:jar:4.0.5:compile
|  |  +- org.glassfish.jaxb:jaxb-xjc:jar:4.0.3:compile
|  |  +- org.glassfish.jaxb:xsom:jar:4.0.3:compile
|  |  +- com.sun.istack:istack-commons-runtime:jar:4.1.2:compile
|  |  +- com.sun.istack:istack-commons-tools:jar:4.1.2:compile
|  |  +- com.sun.xml.bind.external:relaxng-datatype:jar:4.0.3:compile
|  |  \- com.sun.xml.bind.external:rngom:jar:4.0.3:compile
|  +- jakarta.mail:jakarta.mail-api:jar:2.1.2:compile
|  +- org.eclipse.angus:angus-mail:jar:1.0.0:compile
|  +- org.apache.james:apache-mime4j-dom:jar:0.8.11:compile
|  |  \- org.apache.james:apache-mime4j-core:jar:0.8.11:compile
|  +- org.apache.james:apache-mime4j-storage:jar:0.8.11:compile
|  +- commons-io:commons-io:jar:2.15.1:compile
|  \- org.jboss.logging:jboss-logging:jar:3.5.3.Final:compile
+- org.jboss.resteasy:resteasy-html:jar:6.2.7.Final:compile
+- io.quarkus:quarkus-undertow:jar:3.9.4:compile
|  +- io.quarkus.security:quarkus-security:jar:2.0.3.Final:compile
|  |  \- io.smallrye.reactive:mutiny:jar:2.5.8:compile
|  +- jakarta.enterprise:jakarta.enterprise.cdi-api:jar:4.0.1:compile
|  |  +- jakarta.enterprise:jakarta.enterprise.lang-model:jar:4.0.1:compile
|  |  +- jakarta.el:jakarta.el-api:jar:5.0.1:compile
|  |  +- jakarta.interceptor:jakarta.interceptor-api:jar:2.1.0:compile
|  |  \- jakarta.inject:jakarta.inject-api:jar:2.0.1:compile
|  +- io.quarkus.http:quarkus-http-servlet:jar:5.2.1.Final:compile
|  +- jakarta.servlet:jakarta.servlet-api:jar:6.0.0:compile
|  +- jakarta.annotation:jakarta.annotation-api:jar:2.1.1:compile
|  +- io.quarkus.http:quarkus-http-vertx-backend:jar:5.2.1.Final:compile
|  |  +- io.vertx:vertx-core:jar:4.5.7:compile
|  |  |  +- io.netty:netty-common:jar:4.1.108.Final:compile
|  |  |  +- io.netty:netty-buffer:jar:4.1.108.Final:compile
|  |  |  +- io.netty:netty-transport:jar:4.1.108.Final:compile
|  |  |  +- io.netty:netty-handler:jar:4.1.108.Final:compile
|  |  |  |  \- io.netty:netty-transport-native-unix-common:jar:4.1.108.Final:compile
|  |  |  +- io.netty:netty-handler-proxy:jar:4.1.108.Final:compile
|  |  |  |  \- io.netty:netty-codec-socks:jar:4.1.108.Final:compile
|  |  |  +- io.netty:netty-codec-http2:jar:4.1.108.Final:compile
|  |  |  +- io.netty:netty-resolver:jar:4.1.108.Final:compile
|  |  |  \- io.netty:netty-resolver-dns:jar:4.1.108.Final:compile
|  |  |     \- io.netty:netty-codec-dns:jar:4.1.108.Final:compile
|  |  \- io.quarkus.http:quarkus-http-http-core:jar:5.2.1.Final:compile
|  +- io.quarkus.http:quarkus-http-core:jar:5.2.1.Final:compile
|  |  \- io.netty:netty-codec-http:jar:4.1.108.Final:compile
|  |     \- io.netty:netty-codec:jar:4.1.108.Final:compile
|  +- io.quarkus:quarkus-core:jar:3.9.4:compile
|  |  +- io.smallrye.common:smallrye-common-os:jar:2.3.0:compile
|  |  +- io.quarkus:quarkus-ide-launcher:jar:3.9.4:compile
|  |  +- io.quarkus:quarkus-development-mode-spi:jar:3.9.4:compile
|  |  +- io.smallrye.config:smallrye-config:jar:3.7.1:compile
|  |  |  \- io.smallrye.config:smallrye-config-core:jar:3.7.1:compile
|  |  |     +- io.smallrye.common:smallrye-common-classloader:jar:2.3.0:compile
|  |  |     \- io.smallrye.config:smallrye-config-common:jar:3.7.1:compile
|  |  +- org.jboss.logmanager:jboss-logmanager:jar:3.0.4.Final:compile
|  |  |  +- io.smallrye.common:smallrye-common-cpu:jar:2.3.0:compile
|  |  |  +- io.smallrye.common:smallrye-common-expression:jar:2.3.0:compile
|  |  |  |  \- io.smallrye.common:smallrye-common-function:jar:2.3.0:compile
|  |  |  +- io.smallrye.common:smallrye-common-net:jar:2.3.0:compile
|  |  |  +- io.smallrye.common:smallrye-common-ref:jar:2.3.0:compile
|  |  |  +- jakarta.json:jakarta.json-api:jar:2.1.3:compile
|  |  |  \- org.eclipse.parsson:parsson:jar:1.1.5:compile
|  |  +- org.jboss.logging:jboss-logging-annotations:jar:2.2.1.Final:compile
|  |  +- org.jboss.threads:jboss-threads:jar:3.6.1.Final:compile
|  |  +- org.jboss.slf4j:slf4j-jboss-logmanager:jar:2.0.0.Final:compile
|  |  +- org.wildfly.common:wildfly-common:jar:1.7.0.Final:compile
|  |  +- io.quarkus:quarkus-bootstrap-runner:jar:3.9.4:compile
|  |  \- io.quarkus:quarkus-fs-util:jar:0.0.10:compile
|  \- org.eclipse.microprofile.context-propagation:microprofile-context-propagation-api:jar:1.3:compile
+- io.quarkus:quarkus-arc:jar:3.9.4:compile
|  \- io.quarkus.arc:arc:jar:3.9.4:compile
|     \- jakarta.transaction:jakarta.transaction-api:jar:2.0.1:compile
+- io.quarkus:quarkus-junit5:jar:3.9.4:test
|  +- io.quarkus:quarkus-bootstrap-core:jar:3.9.4:test
|  |  +- io.quarkus:quarkus-bootstrap-app-model:jar:3.9.4:test
|  |  \- io.smallrye.common:smallrye-common-io:jar:2.3.0:compile
|  +- org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.9.0.M2:test
|  +- io.quarkus:quarkus-test-common:jar:3.9.4:test
|  |  +- io.quarkus:quarkus-core-deployment:jar:3.9.4:test
|  |  |  +- org.aesh:readline:jar:2.4:test
|  |  |  |  \- org.fusesource.jansi:jansi:jar:2.4.0:test
|  |  |  +- org.aesh:aesh:jar:2.7:test
|  |  |  +- io.quarkus.gizmo:gizmo:jar:1.8.0:test
|  |  |  |  \- org.ow2.asm:asm-util:jar:9.6:test
|  |  |  |     \- org.ow2.asm:asm-analysis:jar:9.6:test
|  |  |  +- org.ow2.asm:asm:jar:9.6:test
|  |  |  +- org.ow2.asm:asm-commons:jar:9.6:test
|  |  |  |  \- org.ow2.asm:asm-tree:jar:9.6:test
|  |  |  +- io.quarkus:quarkus-class-change-agent:jar:3.9.4:test
|  |  |  +- io.quarkus:quarkus-devtools-utilities:jar:3.9.4:test
|  |  |  +- io.quarkus:quarkus-builder:jar:3.9.4:test
|  |  |  +- org.graalvm.sdk:nativeimage:jar:23.1.2:test
|  |  |  |  \- org.graalvm.sdk:word:jar:23.1.2:test
|  |  |  \- org.junit.platform:junit-platform-launcher:jar:1.10.2:test
|  |  +- io.quarkus:quarkus-bootstrap-maven-resolver:jar:3.9.4:test
|  |  |  +- io.smallrye.beanbag:smallrye-beanbag-maven:jar:1.4.0:test
|  |  |  |  +- io.smallrye.beanbag:smallrye-beanbag-sisu:jar:1.4.0:test
|  |  |  |  |  \- io.smallrye.beanbag:smallrye-beanbag:jar:1.4.0:test
|  |  |  |  +- javax.inject:javax.inject:jar:1:test
|  |  |  |  +- org.apache.httpcomponents:httpclient:jar:4.5.14:test
|  |  |  |  +- org.apache.httpcomponents:httpcore:jar:4.4.16:test
|  |  |  |  +- org.apache.maven:maven-artifact:jar:3.9.6:test
|  |  |  |  +- org.apache.maven:maven-builder-support:jar:3.9.6:test
|  |  |  |  +- org.apache.maven:maven-model:jar:3.9.6:test
|  |  |  |  +- org.apache.maven:maven-model-builder:jar:3.9.6:test
|  |  |  |  +- org.apache.maven:maven-repository-metadata:jar:3.9.6:test
|  |  |  |  +- org.apache.maven:maven-settings:jar:3.9.6:test
|  |  |  |  +- org.apache.maven.resolver:maven-resolver-api:jar:1.9.18:test
|  |  |  |  +- org.apache.maven.resolver:maven-resolver-impl:jar:1.9.18:test
|  |  |  |  |  \- org.apache.maven.resolver:maven-resolver-named-locks:jar:1.9.18:test
|  |  |  |  +- org.apache.maven.resolver:maven-resolver-spi:jar:1.9.18:test
|  |  |  |  +- org.apache.maven.resolver:maven-resolver-util:jar:1.9.18:test
|  |  |  |  +- org.apache.maven.resolver:maven-resolver-transport-http:jar:1.9.18:test
|  |  |  |  +- org.apache.maven.wagon:wagon-provider-api:jar:3.5.3:test
|  |  |  |  +- org.apache.maven.wagon:wagon-http-shared:jar:3.5.3:test
|  |  |  |  +- org.codehaus.plexus:plexus-interpolation:jar:1.26:test
|  |  |  |  +- org.codehaus.plexus:plexus-utils:jar:3.5.1:test
|  |  |  |  +- org.codehaus.plexus:plexus-xml:jar:4.0.0:test
|  |  |  |  |  \- org.apache.maven:maven-xml-impl:jar:4.0.0-alpha-5:test
|  |  |  |  |     \- org.apache.maven:maven-api-xml:jar:4.0.0-alpha-5:test
|  |  |  |  |        \- org.apache.maven:maven-api-meta:jar:4.0.0-alpha-5:test
|  |  |  |  +- org.codehaus.plexus:plexus-cipher:jar:2.0:test
|  |  |  |  \- org.codehaus.plexus:plexus-sec-dispatcher:jar:2.0:test
|  |  |  +- org.apache.maven:maven-embedder:jar:3.9.6:test
|  |  |  |  +- org.apache.maven:maven-core:jar:3.9.6:test
|  |  |  |  |  \- org.codehaus.plexus:plexus-component-annotations:jar:2.1.0:test
|  |  |  |  +- org.apache.maven:maven-plugin-api:jar:3.9.6:test
|  |  |  |  +- org.apache.maven.shared:maven-shared-utils:jar:3.3.4:test
|  |  |  |  +- com.google.inject:guice:jar:5.1.0:test
|  |  |  |  |  \- aopalliance:aopalliance:jar:1.0:test
|  |  |  |  +- com.google.guava:guava:jar:33.0.0-jre:test
|  |  |  |  +- com.google.guava:failureaccess:jar:1.0.1:test
|  |  |  |  +- javax.annotation:javax.annotation-api:jar:1.3.2:test
|  |  |  |  +- org.codehaus.plexus:plexus-classworlds:jar:2.6.0:test
|  |  |  |  \- commons-cli:commons-cli:jar:1.5.0:test
|  |  |  +- org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.9.0.M2:test
|  |  |  +- org.apache.maven:maven-settings-builder:jar:3.9.6:test
|  |  |  +- org.apache.maven:maven-resolver-provider:jar:3.9.6:test
|  |  |  +- org.apache.maven.resolver:maven-resolver-connector-basic:jar:1.9.18:test
|  |  |  +- org.apache.maven.resolver:maven-resolver-transport-wagon:jar:1.9.18:test
|  |  |  +- org.apache.maven.wagon:wagon-http:jar:3.5.3:test
|  |  |  \- org.apache.maven.wagon:wagon-file:jar:3.5.3:test
|  |  +- io.quarkus:quarkus-bootstrap-gradle-resolver:jar:3.9.4:test
|  |  \- io.smallrye:jandex:jar:3.1.6:test
|  +- io.quarkus:quarkus-junit5-properties:jar:3.9.4:test
|  +- org.junit.jupiter:junit-jupiter:jar:5.10.2:test
|  |  +- org.junit.jupiter:junit-jupiter-api:jar:5.10.2:test
|  |  |  +- org.opentest4j:opentest4j:jar:1.3.0:test
|  |  |  +- org.junit.platform:junit-platform-commons:jar:1.10.2:test
|  |  |  \- org.apiguardian:apiguardian-api:jar:1.1.2:test
|  |  +- org.junit.jupiter:junit-jupiter-params:jar:5.10.2:test
|  |  \- org.junit.jupiter:junit-jupiter-engine:jar:5.9.2:test
|  |     \- org.junit.platform:junit-platform-engine:jar:1.10.2:test
|  \- com.thoughtworks.xstream:xstream:jar:1.4.20:test
|     \- io.github.x-stream:mxparser:jar:1.2.2:test
|        \- xmlpull:xmlpull:jar:1.1.3.1:test
+- org.thymeleaf:thymeleaf:jar:3.1.2.RELEASE:compile
|  +- ognl:ognl:jar:3.3.4:compile
|  |  \- org.javassist:javassist:jar:3.29.0-GA:compile
|  +- org.attoparser:attoparser:jar:2.0.7.RELEASE:compile
|  +- org.unbescape:unbescape:jar:1.1.6.RELEASE:compile
|  \- org.slf4j:slf4j-api:jar:2.0.6:compile
\- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:jar:3.3.0:compile
   +- org.apache.groovy:groovy:jar:4.0.14:compile
   +- nz.net.ultraq.groovy:groovy-extensions:jar:2.1.0:runtime
   \- nz.net.ultraq.thymeleaf:thymeleaf-expression-processor:jar:3.2.0:runtime
ultraq commented 2 weeks ago

This project is written in Groovy, which allows extension methods to be written for existing classes, and is how it's able to call an Model.first() without one existing in Thymeleaf. It does this with a little configuration data that normally lives in a the /META-INF/services/org.codehaus.groovy.runtime.ExtensionModule file in a JAR, which I make sure to ship when publishing this project.

This issue sounds very similar to some others in the past (#220, #223) where the tool used to create a fat/uber JAR needs to be configured to retain this information so that extension methods can continue to work. In the case of Shadow, the following configuration is required: https://imperceptiblethoughts.com/shadow/configuration/merging/#merging-groovy-extension-modules

If you're also using Shadow, then that link should help create the correct JAR for your project. If not, then I hope this info helps point you in the right direction for what's needed so that the layout dialect can continue to work when rebundled like this.

tbee commented 2 weeks ago

Ah, that explains. I've setup Thymeleaf in a Quakus server and the default UberJar packaging probably leaves that out. I'll see if that can be tuned.

tbee commented 2 weeks ago

It appears the services files contains two configurations. Need to figure out where those come from.

moduleName = thymeleaf-layout-dialect-extensions
moduleVersion = 3.3.0
extensionClasses = nz.net.ultraq.thymeleaf.layoutdialect.context.extensions.IContextExtensions,                   nz.net.ultraq.thymeleaf.layoutdialect.fragments.extensions.FragmentExtensions,                   nz.net.ultraq.thymeleaf.layoutdialect.models.extensions.IAttributeExtensions,                   nz.net.ultraq.thymeleaf.layoutdialect.models.extensions.ICloseElementTagExtensions,                   nz.net.ultraq.thymeleaf.layoutdialect.models.extensions.IModelExtensions,                   nz.net.ultraq.thymeleaf.layoutdialect.models.extensions.IProcessableElementTagExtensions,                   nz.net.ultraq.thymeleaf.layoutdialect.models.extensions.IStandaloneElementTagExtensions,                   nz.net.ultraq.thymeleaf.layoutdialect.models.extensions.ITemplateEventExtensions,                   nz.net.ultraq.thymeleaf.layoutdialect.models.extensions.ITextExtensions

# 
# Copyright 2020, Emanuel Rabina (http://www.ultraq.net.nz/)
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#     http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 

moduleName = groovy-extensions
moduleVersion = 2.1.0
extensionClasses = nz.net.ultraq.groovy.extensions.BlockingQueueExtensions,                   nz.net.ultraq.groovy.extensions.ByteArrayExtensions,                   nz.net.ultraq.groovy.extensions.ByteBufferExtensions,                   nz.net.ultraq.groovy.extensions.ExecutorServiceExtensions,                   nz.net.ultraq.groovy.extensions.FutureExtensions,                   nz.net.ultraq.groovy.extensions.MapExtensions,                   nz.net.ultraq.groovy.extensions.ObjectExtensions,                   nz.net.ultraq.groovy.extensions.SemaphoreExtensions,                   nz.net.ultraq.groovy.extensions.ShortBufferExtensions
staticExtensionClasses = nz.net.ultraq.groovy.extensions.ByteBufferStaticExtensions,                         nz.net.ultraq.groovy.extensions.MathStaticExtensions,                         nz.net.ultraq.groovy.extensions.ObjectStaticExtensions
tbee commented 2 weeks ago

Took a different approach and switched to spring boot's jar. That solves the duplicate services files conflict. Better.

tbee commented 2 weeks ago

Addendum; for some reason the spring bootable jar included jars in a folder on the file system in its classpath target/quarkus-app/quarkus to be exact, and found some generated code. This is not included in the bootable jar itself, so once you deploy that, the jar won't run. So back to resolving the uber-jar conflicts.

tbee commented 2 weeks ago

I ended up moving the quarkus build to prepare-package and then immediately an unzip of the generated jars into classes. The maven-jar-plugin then included all of them in the spring bootable jar. So for now we're testing with the bootable jar.

tbee commented 1 week ago

Bootable jar did not give the results I needed, so back to the uber-jar. By replacing the layout with thymeleaf's own fragment expressions (looks complexer than they are) this groovy related issue disappeared.