使用布局方言时 Thymeleaf 和 Micronaut 视图错误

问题描述 投票:0回答:3

我们正在使用 Thymeleaf 视图和布局方言运行 Micronaut(我们通过覆盖 Micronaut 的

ThymeleafFactory
来手动添加它)。以下是依赖项(Micronaut 版本为 3.2.7):

implementation 'io.micronaut.views:micronaut-views-core:3.1.2'
implementation 'io.micronaut.views:micronaut-views-thymeleaf:3.1.2'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.0.0'

有问题的代码是这样的:

<html layout:decorate="~{/layout-top}">

使用

./gradlew run
运行时似乎工作正常,但使用
java -jar ...
从胖(阴影)罐子运行时会崩溃。这将指向类路径问题,但我们无法弄清楚这些问题是什么。

运行shadow jar时的错误消息如下:

Caused by: groovy.lang.MissingMethodException: No signature of method: io.micronaut.views.thymeleaf.WebEngineContext.getOrCreate() is applicable for argument types: (String, nz.net.ultraq.thymeleaf.layoutdialect.context.extensions.IContextExtensions$_getPrefixForDialect_closure1) values: [DialectPrefix::org.thymeleaf.standard.StandardDialect, nz.net.ultraq.thymeleaf.layoutdialect.context.extensions.IContextExtensions$_getPrefixForDialect_closure1@26b0c4d0]
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:70)
    at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
    at nz.net.ultraq.thymeleaf.layoutdialect.context.extensions.IContextExtensions.getPrefixForDialect(IContextExtensions.groovy:54)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke(ReflectionMetaMethod.java:54)
    at org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod.invoke(NewInstanceMetaMethod.java:54)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:247)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
    at nz.net.ultraq.thymeleaf.layoutdialect.models.extensions.IProcessableElementTagExtensions.equalsIgnoreXmlnsAndWith(IProcessableElementTagExtensions.groovy:60)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke(ReflectionMetaMethod.java:54)
    at org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod.invoke(NewInstanceMetaMethod.java:54)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:247)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
    at nz.net.ultraq.thymeleaf.layoutdialect.decorators.DecorateProcessor.doProcess(DecorateProcessor.groovy:103)
    at org.thymeleaf.processor.element.AbstractAttributeModelProcessor.doProcess(AbstractAttributeModelProcessor.java:77)

我们对此进行了调试并隔离了

nz.net.ultraq.thymeleaf.layoutdialect.context.extensions.IContextExtensions
中的失败代码:

    static String getPrefixForDialect(IContext self, Class<IProcessorDialect> dialectClass) {
        return self.getOrCreate(DIALECT_PREFIX_PREFIX + dialectClass.name) { ->
            def dialectConfiguration = self.configuration.dialectConfigurations.find { dialectConfig ->
                return dialectClass.isInstance(dialectConfig.dialect)
            }
            return dialectConfiguration?.prefixSpecified ?
                    dialectConfiguration?.prefix :
                    dialectConfiguration?.dialect?.prefix
        }
    }

似乎

IContext
的说法并不是应该的,但我们无法真正找到其根本原因。也不知道为什么运行相同代码的两种不同方法会有不同的行为。

thymeleaf micronaut
3个回答
5
投票

经过进一步调查,我们发现这与shadow jar插件中的这个错误有关:https://github.com/johnrengelman/shadow/issues/490

图书馆

thymeleaf-layout-dialect
正在使用
nz.net.ultraq.extensions:groovy-extensions:1.1.0
反过来,它通过
META-INF/services/org.codehaus.groovy.runtime.ExtensionModule

注册一些 Groovy 扩展

shadow jar 插件不能正确处理这些(它只处理

META-INF/groovy/...
路径)。

根据此处的票证评论https://github.com/johnrengelman/shadow/issues/490,有一个解决方法,但它非常令人不快。


0
投票

我通过升级 Gradle 版本修复了它

./gradlew wrapper --gradle-version 7.6.4

(您可能需要 7.6.4 以外的版本,但对我来说这是最可行的)


0
投票

使用 Thymeleaf 布局方言时,我收到“没有方法签名:org.thymeleaf.context.EngineContext.getOrCreate”。我试图使用 Maven 程序集插件将项目的所有类打包到一个可执行的 jar 中。我最终不得不放弃,而是生产了 2 罐。一个是一个带有我的非百里香布局依赖项的罐子。另一个是百里香布局方言罐子。我将两个 jar 添加到我的类路径中并指定了我的主类,它开始工作

© www.soinside.com 2019 - 2024. All rights reserved.