tomcat 部署战争中的资源包未按预期工作

发布于 2025-01-10 09:25:09 字数 6387 浏览 1 评论 0原文

我遇到一个与加载资源包相关的奇怪问题。经过一些调试后,我能够找出问题的原因,因为资源包按预期顺序加载。但是,我想知道是什么原因造成的。 我有如下命名的资源包。

core_cs.properties
core_de.properties
core_en_GB.properties
core_en_US.properties
core_en.properties
core_fr.properties

当 Spring 配置加载资源包时,基本名称应该是

../core
../core_en

但是,这会导致

../core_en
../core

由于这个原因,每个语言环境都显示来自 core_en 资源包的翻译值。 在项目中,我将 core.jar 添加为我的 Web 项目中的依赖项。

目前的行为。

found == META-INF/resourcebundles/core_en for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en_GB.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_cs.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_de.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_es.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_fr.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_hu.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_it.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_nl.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_pl.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_sl.properties
found == META-INF/resourcebundles/core_en for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en_US.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en.properties

预期加载应该是

found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_cs.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_de.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en.properties
found == META-INF/resourcebundles/core_en for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en_GB.properties
found == META-INF/resourcebundles/core_en for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en_US.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_es.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_fr.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_hu.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_it.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_nl.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_pl.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_sl.properties

我正在使用 springframework 中的 PathMatchingResourcePatternResolver 来解析类路径配置中的路径

    <bean id="messageSource" class="com.company.core.spring.support.ClasspathResourceBundleMessageSource">
        <property name="basename" value="classpath*:/META-INF/resourcebundles/**/*.properties"/>  
    </bean>

ClasspathResourceBundleMessageSource 正在扩展 springframework 中的 ResourceBundleMessageSource

public void setBasenames(final String... basenames) {
        List<String> basenamesList = new ArrayList<>();
        try {

            for (String basename : basenames) {
                LOGGER.info("==\t Base Name configured {}", basename);
                Resource[] resources = (new PathMatchingResourcePatternResolver()).getResources(basename);
                for (Resource resource : resources) {
                    LOGGER.info("==\t Name of resource found {}", resource.getURI());
                    String filename = resource.getURI().toString();
                    String newBasename = transformToBasename(filename);
                    if (newBasename != null && !basenamesList.contains(newBasename)) {
                        LOGGER.info("Adding resource bundle basename {}", newBasename);
                        basenamesList.add(newBasename);
                    }
                }
            }

            // Add the basenames found
            LOGGER.info("Resource bundle path:{}", basenamesList);
            String[] basenamesArray = basenamesList.toArray(new String[]{});
            super.setBasenames(basenamesArray);
        } catch (Exception ex) {
            LOGGER.error("Error setting base names", ex);
        }
    }

另一种见解是,如果我在本地构建存档战争它有效。但是,当构建服务器(jenkins)构建存档时,它无法按预期工作。

I am experiencing a strange issue related to loading of resource bundles. After some debugging, i am able to find out the cause of the issue as resource bundles are loading in expected order. But, I query is what is causing it.
I have resource bundles named as below.

core_cs.properties
core_de.properties
core_en_GB.properties
core_en_US.properties
core_en.properties
core_fr.properties

When resource bundles are loaded by spring configuration, then base name should be

../core
../core_en

But, it is resulting in

../core_en
../core

Due to this, every locale is showing translated value from core_en resource bundle.
In project, i am adding core.jar as dependency in my web project.

Current Behaviour.

found == META-INF/resourcebundles/core_en for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en_GB.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_cs.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_de.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_es.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_fr.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_hu.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_it.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_nl.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_pl.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_sl.properties
found == META-INF/resourcebundles/core_en for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en_US.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en.properties

Expected loading should be

found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_cs.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_de.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en.properties
found == META-INF/resourcebundles/core_en for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en_GB.properties
found == META-INF/resourcebundles/core_en for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_en_US.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_es.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_fr.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_hu.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_it.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_nl.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_pl.properties
found == META-INF/resourcebundles/core for file jar:file:/D:/Tomcat/WebProject/webapps/demo/WEB-INF/lib/core-SNAPSHOT.jar!/META-INF/resourcebundles/core_sl.properties

I am using PathMatchingResourcePatternResolver from springframework to resolve the path from classpath configuration

    <bean id="messageSource" class="com.company.core.spring.support.ClasspathResourceBundleMessageSource">
        <property name="basename" value="classpath*:/META-INF/resourcebundles/**/*.properties"/>  
    </bean>

ClasspathResourceBundleMessageSource is extending ResourceBundleMessageSource from springframework

public void setBasenames(final String... basenames) {
        List<String> basenamesList = new ArrayList<>();
        try {

            for (String basename : basenames) {
                LOGGER.info("==\t Base Name configured {}", basename);
                Resource[] resources = (new PathMatchingResourcePatternResolver()).getResources(basename);
                for (Resource resource : resources) {
                    LOGGER.info("==\t Name of resource found {}", resource.getURI());
                    String filename = resource.getURI().toString();
                    String newBasename = transformToBasename(filename);
                    if (newBasename != null && !basenamesList.contains(newBasename)) {
                        LOGGER.info("Adding resource bundle basename {}", newBasename);
                        basenamesList.add(newBasename);
                    }
                }
            }

            // Add the basenames found
            LOGGER.info("Resource bundle path:{}", basenamesList);
            String[] basenamesArray = basenamesList.toArray(new String[]{});
            super.setBasenames(basenamesArray);
        } catch (Exception ex) {
            LOGGER.error("Error setting base names", ex);
        }
    }

Another insight is that, if i build archive war locally it works. But, when archive is build by build server (jenkins), then it is not working as expected.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ゝ杯具 2025-01-17 09:25:09

我发现 java.util.jar.JarFile 中的 JarFile.entries() 方法以未排序的顺序返回文件列表。我用一个小程序测试了一下。

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class JarFileTest {

    public static void main(String[] args) {

        File correctJarFile = new File("D:\\target\\budget.jar");
        File wrongJarFile = new File("D:\\target\\budget2.jar");
     
        try (JarFile jar = new JarFile(correctJarFile )) {
            for (Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); ) {
                JarEntry entry = entries.nextElement();
                String entryPath = entry.getName();
                if (entryPath.endsWith(".properties")) {
                    System.out.println(entryPath);
                }
            }
        }catch (IOException e) {
        }
        System.out.println("\n============ 2");
        try (JarFile jar = new JarFile(wrongJarFile)) {
            for (Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); ) {
                JarEntry entry = entries.nextElement();
                String entryPath = entry.getName();
                if (entryPath.endsWith(".properties")) {
                    System.out.println(entryPath);
                }
            }
        }catch (IOException e) {
        }
    }
}

上面的程序产生下面的输出。

META-INF/resourcebundles/core_cs.properties
META-INF/resourcebundles/core_de.properties
META-INF/resourcebundles/core_en.properties
META-INF/resourcebundles/core_en_GB.properties
META-INF/resourcebundles/core_en_US.properties
META-INF/resourcebundles/core_fr.properties

============ 2
META-INF/resourcebundles/core_en_GB.properties
META-INF/resourcebundles/core_cs.properties
META-INF/resourcebundles/core_de.properties
META-INF/resourcebundles/core_fr.properties
META-INF/resourcebundles/core_en_US.properties
META-INF/resourcebundles/core_en.properties

这与 Java8 Stream API 相同

        try (JarFile jar = new JarFile(jarFile)) {
            jar.stream().filter(entry -> entry.getName().endsWith(".properties")).forEach(System.out::println);
        } catch (IOException e) {
        }
        System.out.println("\n============ 0");
        try (JarFile jar = new JarFile(jarFile2)) {
            jar.stream().filter(entry -> entry.getName().endsWith(".properties")).forEach(System.out::println);
        } catch (IOException e) {
        }

因此,我应用了自定义排序来修复 ZipFile 中的排序,如此 stackoverflow 问题中所述

I found that JarFile.entries() method from java.util.jar.JarFile is returning list of files in unsorted order. I tested it with a small program.

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class JarFileTest {

    public static void main(String[] args) {

        File correctJarFile = new File("D:\\target\\budget.jar");
        File wrongJarFile = new File("D:\\target\\budget2.jar");
     
        try (JarFile jar = new JarFile(correctJarFile )) {
            for (Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); ) {
                JarEntry entry = entries.nextElement();
                String entryPath = entry.getName();
                if (entryPath.endsWith(".properties")) {
                    System.out.println(entryPath);
                }
            }
        }catch (IOException e) {
        }
        System.out.println("\n============ 2");
        try (JarFile jar = new JarFile(wrongJarFile)) {
            for (Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); ) {
                JarEntry entry = entries.nextElement();
                String entryPath = entry.getName();
                if (entryPath.endsWith(".properties")) {
                    System.out.println(entryPath);
                }
            }
        }catch (IOException e) {
        }
    }
}

Above program result in below output.

META-INF/resourcebundles/core_cs.properties
META-INF/resourcebundles/core_de.properties
META-INF/resourcebundles/core_en.properties
META-INF/resourcebundles/core_en_GB.properties
META-INF/resourcebundles/core_en_US.properties
META-INF/resourcebundles/core_fr.properties

============ 2
META-INF/resourcebundles/core_en_GB.properties
META-INF/resourcebundles/core_cs.properties
META-INF/resourcebundles/core_de.properties
META-INF/resourcebundles/core_fr.properties
META-INF/resourcebundles/core_en_US.properties
META-INF/resourcebundles/core_en.properties

This is same with Java8 Stream API

        try (JarFile jar = new JarFile(jarFile)) {
            jar.stream().filter(entry -> entry.getName().endsWith(".properties")).forEach(System.out::println);
        } catch (IOException e) {
        }
        System.out.println("\n============ 0");
        try (JarFile jar = new JarFile(jarFile2)) {
            jar.stream().filter(entry -> entry.getName().endsWith(".properties")).forEach(System.out::println);
        } catch (IOException e) {
        }

So, I have applied custom sorting to fix ordering in ZipFile as mentioned in this stackoverflow question

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文