当前位置: 首页 > 知识库问答 >
问题:

纯模式下的GraalVM Quarkus区域设置

扈昀
2023-03-14

在本机构建时,我对可用区域设置有一个意想不到的行为。在纯模式下,我只有一个区域设置可用。

我的应用程序很简单:

@ApplicationPath("/api")
public class ApplicationPathConfiguration extends Application {
}

@Path("/locales")
public class LocaleController {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Locale[] get() {
        return Locale.getAvailableLocales();
    }

}

签出后,如果我在开发模式下启动应用程序:

mvn quarkus:dev

您可以调用endpoint:http://localhost:8080/api/locales

curl http://localhost:8080/api/locales

此endpoint返回许多区域设置:

["","nn","ar_JO","bg","kea","nds","zu","am_ET","fr_DZ","ti_ET","bo_CN","hsb","qu_EC","ta_SG","lv","en_NU","zh_SG_#Hans","en_MS","en_GG","en_JM","vo","kkj","sr_ME","sv_SE","es_BO","dz_BT","mer","sah","en_ZM","fr_ML","br","ha_NG","ar_SA","fa_AF","dsb_DE","sk","os_GE","ml","en_MT","en_LR","ar_TD","en_GH","en_IL","sv","cs","el","tzm_MA","af","sw_UG","ses_ML","smn","tk_TM","sr_ME_#Cyrl","ar_EG","dsb","lkt_US","vai_LR_#Latn","ji_001","yo_NG","se_NO","khq","sw_CD","vo_001","en_PW","pl_PL","fil_PH","it_VA","sr_CS","ne_IN","es_PH","es_ES","es_CO","bg_BG","ji","ar_EH","bs_BA_#Latn","en_VC","nds_DE","nb_SJ","es_US","agq","hsb_DE","en_US_POSIX","en_150","ar_SD","en_KN","ha_NE","pt_MO","ebu","ro_RO","zh__#Hans","lb_LU","sr_ME_#Latn","es_GT","so_KE","dje_NE","bas_CM","fr_PM","ar_KM","fr_MG","no_NO_NY","es_CL","mn","agq_CM","kam_KE","teo","tr_TR","eu","fa_IR","en_MO","wo","shi__#Tfng","en_BZ","sq_AL","ar_MR","es_DO","ru","twq_NE","az","nmg_CM","fa","kl_GL","en_NR","nd","kk","az__#Cyrl","en_MP","en_GD","tk","hy","shi__#Latn","en_BW","en_AU","en_CY","kab_DZ","kde_TZ","ta_MY","ti_ER","nus_SS","en_RW","nd_ZW","sv_FI","ksb","luo","lb","ne","en_IE","zh_SG","ln_CD","en_KI","nnh_CM","om_ET","no","ja_JP","my","ka","ar_IL","mgh","or_IN","fr_MF","shi","kl","en_SZ","rwk_TZ","zh","es_PE","mgh_MZ","saq","az__#Latn","ta","en_GB","lag","zh_HK_#Hant","ar_SY","ksf_CM","bo","kk_KZ","es_PA","tt_RU","om_KE","ar_PS","en_AS","fr_VU","zh_TW","bez","kln","fr_MC","kw","pt_MZ","fr_NE","vai__#Latn","ksb_TZ","ksh","ur_IN","ln","en_JE","gsw_CH","ln_CF","en_CX","luy_KE","pt","en_AT","gl","kkj_CM","sr__#Cyrl","yue_CN_#Hans","es_GQ","kn_IN","ar_YE","to","en_SX","ga","qu","ru_KZ","en_TZ","et","en_PR","mua","ko_KP","in","ps","sn","nl_SR","rof","en_BS","km","zgh","fr_NC","be","gv","es","dua","gd_GB","jgo","nl_BQ","fr_CM","gsw","uz_UZ_#Cyrl","pa_IN_#Guru","en_KE","guz","mfe","asa_TZ","teo_UG","ja","fr_SN","or","brx","fr_MA","pt_LU","fr_BL","en_NL","mgo_CM","ln_CG","te","sl","ko_KR","el_CY","mr_IN","ha","es_MX","lrc_IR","gsw_FR","es_HN","hu_HU","ff_SN","sbp","sq_MK","sr_BA_#Cyrl","fi","uz","bs__#Cyrl","et_EE","sr__#Latn","en_SS","sw","bo_IN","fy_NL","ar_OM","tr_CY","nmg","rm","en_MG","fr_BI","uz_UZ_#Latn","bn","dua_CM","de_IT","lrc_IQ","vai__#Vaii","kn","fr_TN","sr_RS","de_CH","bn_BD","nnh","fr_PF","en_ZA","gu","pt_GQ","vun_TZ","jmc_TZ","en_TV","lo","fr_FR","en_PN","en_MH","fr_BJ","zh__#Hant","cu_RU","zh_HK_#Hans","nl_NL","sah_RU","en_GY","ps_AF","bs__#Latn","ky","mas","dyo_SN","os","bs_BA_#Cyrl","nl_CW","ar_DZ","sk_SK","pt_CH","fr_GQ","ff_CM","am","en_NG","fr_CI","ki_KE","en_PK","zh_CN","en_LC","rw","brx_IN","wo_SN","iw","gv_IM","mk_MK","en_TT","dav","sl_SI","fr_HT","te_IN","nl_SX","lrc","ses","ce","fr_CG","fr_BE","jgo_CM","mt_MT","es_VE","mg","mr","mer_KE","ko","nds_NL","en_BM","nb_NO","ak","seh","kde","dz","kea_CV","mgo","vi_VN","en_VU","en_US","to_TO","mfe_MU","seh_MZ","fr_BF","pa__#Guru","it_SM","fr_YT","gu_IN","ii_CN","pa_PK_#Arab","ast","fr_RE","fi_FI","yue__#Hans","ca_FR","sr_BA_#Latn","bn_IN","fr_GP","pa","zgh_MA","uk_UA","fr_DJ","rn","tg","rwk","hu","fr_CH","en_NF","twq","ha_GH","sr_XK_#Cyrl","bm","ar_SS","en_GU","nl_AW","de_BE","en_AI","en_CM","xog_UG","cs_CZ","tr","ca_ES","cgg","rm_CH","nyn_UG","ru_MD","ms_MY","ta_LK","ksf","en_TO","cy","en_PG","fr_CF","pt_TL","sq","fr","tg_TJ","en_ER","qu_PE","sr_BA","es_PY","de","es_EC","kok_IN","lg_UG","zu_ZA","fr_TG","sr_XK_#Latn","en_PH","ig_NG","fr_GN","prg_001","cgg_UG","zh_MO_#Hans","ksh_DE","lg","ru_RU","se_FI","ff","en_DM","en_CK","sd","ar_MA","ga_IE","en_BI","en_AG","fr_TD","en_WS","fr_LU","ebu_KE","bem_ZM","xog","ewo_CM","fr_CD","so","rn_BI","en_NA","ar_ER","kab","ms","nus","sn_ZW","prg","iw_IL","ug","es_EA","th_TH_TH_#u-nu-thai","hi","fr_SC","ca_IT","lag_TZ","en_SL","teo_KE","no_NO","ca_AD","zh_MO_#Hant","en_SH","vai","qu_BO","haw_US","vi","fr_CA","de_LU","sq_XK","dyo","en_KY","mt","it_CH","de_DE","si_LK","luo_KE","en_DK","yav","so_DJ","lt_LT","it_IT","eo","kam","ar_SO","en_ZW","ro","eo_001","ee","en_UM","nn_NO","fr_MU","pl","se_SE","en_TK","en_SI","mua_CM","ur","uz__#Arab","vai_LR_#Vaii","saq_KE","se","pt_GW","lo_LA","chr","ar_LB","af_ZA","ms_SG","ee_TG","ln_AO","be_BY","ff_GN","yue__#Hant","in_ID","es_BZ","ar_AE","hr_HR","luy","as","rof_TZ","it","pt_CV","ks_IN","uk","my_MM","ur_PK","mn_MN","da_DK","en_FM","es_PR","wae_CH","mzn","en_BE","ii","tt","fr_WF","ru_BY","mzn_IR","naq","fo_DK","en_SG","ee_GH","ar_BH","kln_KE","tzm","fur","om","hi_IN","en_CH","asa","yo_BJ","fo_FO","ast_ES","fr_KM","bez_TZ","fr_MQ","en_SD","es_AR","en_MY","ja_JP_JP_#u-ca-japanese","es_SV","pt_BR","ml_IN","sbp_TZ","fil","en_FK","uz__#Cyrl","is_IS","yue_HK_#Hant","hy_AM","en_GM","en_DG","fo","ne_NP","hr","pt_ST","ak_GH","lt","uz_AF_#Arab","fur_IT","ta_IN","ccp","en_SE","fr_GF","lkt","zh_CN_#Hans","is","es_419","si","pt_AO","en_001","en","guz_KE","gsw_LI","ccp_BD","es_IC","ca","ru_KG","fr_MR","ar_TN","ks","zh_TW_#Hant","bm_ML","kw_GB","ug_CN","as_IN","es_BR","zh_HK","khq_ML","sw_KE","en_SB","th_TH","rw_RW","chr_US","shi_MA_#Tfng","ar_IQ","nyn","yue","jmc","en_MW","naq_NA","mk","en_IO","ar_QA","en_DE","pa__#Arab","en_CC","bs","ro_MD","en_FI","pt_PT","fy","az_AZ_#Cyrl","th","dav_KE","ckb_IQ","shi_MA_#Latn","es_CU","ar","en_SC","en_VI","haw","eu_ES","en_UG","en_NZ","dje","es_UY","bas","mas_KE","ru_UA","sg_CF","el_GR","yav_CM","uz__#Latn","sg","da_GL","en_FJ","de_LI","en_BB","km_KH","smn_FI","hr_BA","de_AT","ckb_IR","nl","lu_CD","ca_ES_VALENCIA","ar_001","so_SO","lv_LV","ckb","es_CR","fr_GA","ar_KW","sr","ar_LY","sr_RS_#Cyrl","bem","en_MU","da","wae","gl_ES","en_IM","az_AZ_#Latn","en_LS","ig","en_HK","en_GI","ce_RU","en_CA","gd","ka_GE","fr_SY","sw_TZ","fr_RW","so_ET","nl_BE","ar_DJ","mg_MG","cy_GB","en_VG","cu","os_RU","sr_RS_#Latn","en_TC","ky_KG","sv_AX","af_NA","vun","en_IN","lu","ki","yo","es_NI","nb","ff_MR","sd_PK","mas_TZ","ti","kok","ewo","ms_BN","ccp_IN","br_FR"]

如果在纯模式下执行相同操作:

mvn clean package -Pnative && ./target/QuarkusLocale-1.0-SNAPSHOT-runner

我只获得一个区域设置:

["fr_US"]

如何获取所有可用的区域设置?

而且,由于这种行为,我还有另一个问题。如您所见,如果我试图开发一个需要使用Locale服务。区域设置未使用,无法应用货币格式。为了演示这一点,我开发了CurrencyController。

@Path("/currency")
public class CurrencyController {

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public String get(String localeString) {
        String[] localeArray = localeString.split("-");
        Locale locale = new Locale(localeArray[0], localeArray[1]);

        NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale);
        numberFormat.setCurrency(Currency.getInstance("USD"));
        return numberFormat.format(1337);
    }

}

你可以用curl来调用它:

curl -X POST http://localhost:8080/api/currency -H "Content-Type: application/json" -d "en-GB"
> US$1,337.00

curl -X POST http://localhost:8080/api/currency -H "Content-Type: application/json" -d "en-US
> $1,337.00

如果在纯模式下执行相同操作:

curl -X POST http://localhost:8080/api/currency -H "Content-Type: application/json" -d "en-GB"
> US$1,337.00

curl -X POST http://localhost:8080/api/currency -H "Content-Type: application/json" -d "en-US
> US$1,337.00
  • 在GraalVM 19.3.1CE版上运行Quarkus本机映像插件
  • 夸克1.4.1.final

共有1个答案

谷梁鸣
2023-03-14

这是Graalvm上一个非常知名的问题。目前,绕过它的唯一方法是创建在运行时扫描所有区域设置的功能:

  1. 添加maven依赖项
        <dependency>
            <groupId>org.graalvm.nativeimage</groupId>
            <artifactId>svm</artifactId>
            <version>19.3.1</version>
        </dependency>
package org.example;

import com.oracle.svm.core.annotate.AutomaticFeature;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;

import java.util.Locale;

@AutomaticFeature
public class NativeLanguageFeature implements Feature {

    @Override
    public void beforeAnalysis(BeforeAnalysisAccess access) {
        ImageSingletons.lookup(RuntimeClassInitializationSupport.class).initializeAtBuildTime(SupportedLocales.class, "__");

        final Locale[] availableLocales = Locale.getAvailableLocales();
        final SupportedLocales supportedLocales = new SupportedLocales();
        supportedLocales.locales = availableLocales;
        ImageSingletons.add(SupportedLocales.class, supportedLocales);
    }

    public static class SupportedLocales {
        public Locale[] locales;
    }
}
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Locale[] get() {
        if(ImageSingletons.contains(NativeLanguageFeature.SupportedLocales.class)){
            final NativeLanguageFeature.SupportedLocales lookup = ImageSingletons.lookup(NativeLanguageFeature.SupportedLocales.class);
            return lookup.locales;
        }
        return Locale.getAvailableLocales();
    }

你可能也需要用钱做同样的事情。

 类似资料:
  • 我有一个有多个模块的Quarkus项目。 在公共模块中,我添加了以下依赖项(遵循本指南 https://quarkus.io/guides/rest-client)。 子模块将公共模块作为依赖项。 以及我在子模块中使用的代码片段。 并从另一个ApplicationScoped类调用它: 当在纯模式下运行应用程序时,它会抛出。 我偶然发现了这个(https://quarkus.io/guides/l

  • 我想强制我的Symfony 2.5应用程序的区域设置为。我希望这个区域设置用于strftime()函数。 我的: 我正在我的一个控制器中使用以下代码来调试: 当这样执行时,它显示:。 但是,当第一行未注释时,它会显示:,因此区域设置已安装在系统中并正常工作。 我如何使Symfony始终使用配置中指定的语言环境? $locale-a:

  • 正在学习期末考试,并决定构建一个利用纯虚拟函数和多态性的程序。我陷入了一个非常奇怪的错误,也许我错过了什么。 这是形状抽象类 形状。cpp实施文件 Circle头文件 循环. cpp实现文件 我在抽象的“shape”类中声明了两个纯虚函数,并且正在访问circle头文件中shape类的public,如果我在circle类中声明纯虚函数,它将使其抽象。。。错误表示“GetPermiture的越界定义

  • 我正在开发一个应用程序,我显式地将应用程序的语言环境设置为阿拉伯语。然而,我想收集英语的电话号码。我如何才能将EditText和TextView的语言环境显式地设置为美国英语。 下面是我如何设置应用程序区域设置的。我有一门助手课 在我的活动中,我在中使用这个助手,如下所示: 如何分别为我们设置EditText或TextView的区域设置?

  • 创建了一个读/写数据库,使用Mac下的Neo4j Desktop(V1.1.8)和3.4.5作为数据库引擎。 仅用几个节点填充它 停止,设置并重新启动 在最后一步,服务器日志显示错误:“UnsupportedOperationException:不能在只读模式下创建索引写入器”并关闭。那么,这种选择真的(仍然)有效吗?