java.util.MissingResourceException-新文件()未进入jar-如何为外部库提供此文件的路径?

java.util.MissingResourceException-新文件()未进入jar-如何为外部库提供此文件的路径?,java,maven,jar,dependencies,resourcebundle,Java,Maven,Jar,Dependencies,Resourcebundle,当运行测试时,以-maven开头的问题没有正确地进入jar以获取文件夹包。但在运行一些主程序时,它确实可以正常工作 生成时运行测试的堆栈跟踪如下所示: Caused by: java.util.MissingResourceException: Can't find Not found profile: file:\C:\Users\Simon\.m2\repository\ario\TextProcessing\1.0.4-SNAPSHOT\TextProcessing-1.0.4-SNAPS

当运行测试时,以-maven开头的问题没有正确地进入jar以获取文件夹包。但在运行一些主程序时,它确实可以正常工作

生成时运行测试的堆栈跟踪如下所示:

Caused by: java.util.MissingResourceException: Can't find Not found profile: file:\C:\Users\Simon\.m2\repository\ario\TextProcessing\1.0.4-SNAPSHOT\TextProcessing-1.0.4-SNAPSHOT.jar!\lang bundle
at java.util.logging.Logger.setupResourceInfo(Logger.java:1942)
at java.util.logging.Logger.<init>(Logger.java:380)
at java.util.logging.LogManager.demandLogger(LogManager.java:554)
at java.util.logging.Logger.demandLogger(Logger.java:455)
at java.util.logging.Logger.getLogger(Logger.java:553)
at cz.techniserv.ario.tagger.TagDetect.setLangPath(TagDetect.java:126)
at cz.techniserv.ario.tagger.TagDetect.<init>(TagDetect.java:58)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
... 86 more
this.path = this.getClass().getResource("/" + aLanguageDirectoryName).getPath();
还有一个文件构造函数,它采用这个路径

在运行应用程序的情况下,它将解析为项目路径。当它运行测试时,它将解析到m2存储库中的jar,并尝试到达异常中的路径:

file:\C:\Users\Simon\.m2\repository\ario\TextProcessing\1.0.4-SNAPSHOT\TextProcessing-1.0.4-SNAPSHOT.jar!\lang

你会怎么做?您是否将resource lang文件夹复制到某个临时路径上,并为库提供这个新的非jar临时路径,以便它可以用文件构造函数打开?或者您看到了另一种更好的方法吗?

好的,那么我们所做的就是将数据临时提取到类路径并进行访问

此解决方案的问题是,如果在使用后删除文件,则每次运行时都会提取和删除数据-当每次spring初始化运行测试时都会发生这种情况,这种情况可能会发生很多次,并且会花费很多时间。但是,将数据保留在那里意味着,如果路径不是绝对路径并且在项目主干文件夹之外,SCM将拾取该路径,除非您忽略它并提交不满意的数据。另外,由于它们位于类路径上,所以在构建时会被打包到jar中,这是另一个缺点。是的,您可以使用SCM忽略该文件夹,并将maven配置为排除该文件夹,但是一些开发人员会忘记已经使用SCM忽略该文件夹,并且该文件夹已提交

我们认为提取一个不在类路径上的绝对路径是一个不好的实践——首先是因为你对项目运行的系统没有控制,所以你不能很好地猜出绝对路径——而且,由于设计不好,在你的计算机周围扔数据看起来不太好。 因此,我想最好的办法是推动每个人将数据放在光盘上的某个地方,并设置一个对每个人都相同的环境变量。这会降低项目的可移植性,需要更多的配置,但会消除前面提到的问题

我没有想出更好的办法

如果有人想做同样的事情,下面是我们的代码:

    CodeSource src = this.getClass().getProtectionDomain().getCodeSource();
    if (src == null) {
        return null;
    }
    URL jarURL = src.getLocation();
    try (JarFile jar = new JarFile(jarURL.getPath());) {
        Enumeration<JarEntry> enumEntries = jar.entries();
        while (enumEntries.hasMoreElements()) {
            JarEntry fileFromJar = (JarEntry) enumEntries.nextElement();
            File toBeCreatedFileLocally = new File(NAME_FOR_TEMPORARY_FOLDER_TO_HOLD_LANG_DATA_FROM_JAR + File.separator + fileFromJar.getName());
            if (fileFromJar.isDirectory()) {
                continue;
            }
            if (fileFromJar.getName().contains(aLanguageDirectoryName)) {
                toBeCreatedFileLocally.getParentFile().mkdirs();
                try (InputStream is = jar.getInputStream(fileFromJar); // get the input stream
                        FileOutputStream fos = new FileOutputStream(toBeCreatedFileLocally)) {
                    while (is.available() > 0) {  // write contents of 'is' to 'fos'
                        fos.write(is.read());
                    }
                }
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(TagDetect.class.getName()).log(Level.SEVERE, null, ex);
    }

此代码实际上是对此处不同答案的修改小心,该答案有一个bug,请检查注释-他们拒绝了我的编辑

尝试此mvn干净安装-U-有时在maven目标文件夹中还没有放置静态内容时会发生这种情况,这意味着还有其他问题。