You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus Native构建中如何正确声明MyFaces扩展的ResourceBundle?

自定义ResourceBundle类在Native构建中无法加载的解决方法

问题场景

尝试在faces-config.xml中配置自定义Java类作为Resource Bundle,配置如下:

<application>
    <resource-bundle>
        <base-name>app.LanguageBundle</base-name>
        <var>msg</var>
    </resource-bundle>
</application>

自定义类已添加@RegisterForReflection注解,但Native构建后仍无法加载,抛出MissingResourceException:

java.util.MissingResourceException: Can't find bundle for base name app.LanguageBundle, locale de_DE
    at java.base@21.0.5/java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:2059)
    at java.base@21.0.5/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1697)
    at java.base@21.0.5/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1600)
    at java.base@21.0.5/java.util.ResourceBundle.getBundle(ResourceBundle.java:1283)
    at org.apache.myfaces.application.ApplicationImpl.getResourceBundle(ApplicationImpl.java:417)
    at org.apache.myfaces.application.ApplicationImpl.getResourceBundle(ApplicationImpl.java:381)
    at jakarta.faces.application.ApplicationWrapper.getResourceBundle(ApplicationWrapper.java:263)
    at jakarta.faces.application.ApplicationWrapper.getResourceBundle(ApplicationWrapper.java:263)
    at org.apache.myfaces.el.resolver.ResourceBundleResolver.getResourceBundle(ResourceBundleResolver.java:212)
    at org.apache.myfaces.el.resolver.ResourceBundleResolver.getValue(ResourceBundleResolver.java:132)
    at jakarta.el.CompositeELResolver.getValue(CompositeELResolver.java:136)
    at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:94)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:137)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190)
    at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getValue(ContextAwareTagValueExpression.java:100)
    at org.apache.myfaces.view.facelets.el.ELText$ELTextVariable.writeText(ELText.java:238)
    at org.apache.myfaces.view.facelets.compiler.TextInstruction.write(TextInstruction.java:45)
    at org.apache.myfaces.view.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:46)
    at org.apache.myfaces.view.facelets.compiler.UILeaf.encodeAll(UILeaf.java:362)

自定义ResourceBundle类实现(属性存储在非.properties文件中):

@RegisterForReflection
public class LanguageBundle extends ResourceBundle {

    @Override
    protected Object handleGetObject(String key) {
        // 自定义属性获取逻辑
    }
}

解决步骤

1. 完善自定义ResourceBundle类

Native构建下,ResourceBundle的实例化需要标准构造方法,补充必要的构造方法和getKeys()实现:

@RegisterForReflection
public class LanguageBundle extends ResourceBundle {

    // 无参构造
    public LanguageBundle() {
        super();
    }

    // 带Locale参数的构造
    public LanguageBundle(Locale locale) {
        setLocale(locale);
    }

    @Override
    protected Object handleGetObject(String key) {
        // 自定义属性获取逻辑
        return null;
    }

    @Override
    public Enumeration<String> getKeys() {
        // 根据你的数据源返回所有key的枚举,示例返回空枚举
        return Collections.emptyEnumeration();
    }
}

2. 添加GraalVM反射元数据配置

在src/main/resources/META-INF/native-image/目录下创建reflect-config.json,显式注册自定义Bundle类,确保GraalVM在Native构建时保留该类的反射信息:

[
  {
    "name": "app.LanguageBundle",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true
  }
]

3. 显式指定ResourceBundle加载逻辑

可以在应用启动阶段,通过自定义ResourceBundle.Control来强制加载你的Bundle类,避免Native模式下的类查找失败:

@PostConstruct
public void initResourceBundle() {
    ResourceBundle.getBundle("app.LanguageBundle", Locale.getDefault(), new ResourceBundle.Control() {
        @Override
        public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
            return new LanguageBundle(locale);
        }
    });
}

4. 替换faces-config.xml配置为框架属性(Quarkus场景)

如果使用Quarkus+MyFaces,建议通过application.properties配置ResourceBundle,确保Native构建时能正确识别:

quarkus.myfaces.resource-bundle.msg.base-name=app.LanguageBundle

内容的提问来源于stack exchange,提问作者Oleh Astappiev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:26:04