简体   繁体   English

Java Jar 文件:使用资源错误:URI 不分层

[英]Java Jar file: use resource errors: URI is not hierarchical

I have deployed my app to jar file.我已将我的应用程序部署到 jar 文件。 When I need to copy data from one file of resource to outside of jar file, I do this code:当我需要将数据从一个资源文件复制到 jar 文件之外时,我执行以下代码:

URL resourceUrl = getClass().getResource("/resource/data.sav");
File src = new File(resourceUrl.toURI()); //ERROR HERE
File dst = new File(CurrentPath()+"data.sav");  //CurrentPath: path of jar file don't include jar file name
FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dst);
 // some excute code here

The error I have met is: URI is not hierarchical .我遇到的错误是: URI is not hierarchical this error I don't meet when run in IDE.在 IDE 中运行时我没有遇到这个错误。

If I change above code as some help on other post on StackOverFlow:如果我更改上面的代码作为 StackOverFlow 上其他帖子的一些帮助:

InputStream in = Model.class.getClassLoader().getResourceAsStream("/resource/data.sav");
File dst = new File(CurrentPath() + "data.sav");
FileOutputStream out = new FileOutputStream(dst);
//....
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) { //NULL POINTER EXCEPTION
  //....
}

You cannot do this你不可以做这个

File src = new File(resourceUrl.toURI()); //ERROR HERE

it is not a file!它不是一个文件! When you run from the ide you don't have any error, because you don't run a jar file.当您从 ide 运行时,您没有任何错误,因为您没有运行 jar 文件。 In the IDE classes and resources are extracted on the file system.在 IDE 中,类和资源被提取到文件系统上。

But you can open an InputStream in this way:但是你可以通过这种方式打开一个InputStream

InputStream in = Model.class.getClassLoader().getResourceAsStream("/data.sav");

Remove "/resource" .删除"/resource" Generally the IDEs separates on file system classes and resources.通常,IDE 将文件系统类和资源分开。 But when the jar is created they are put all together.但是当 jar 被创建时,它们被放在一起。 So the folder level "/resource" is used only for classes and resources separation.所以文件夹级别"/resource"仅用于类和资源分离。

When you get a resource from classloader you have to specify the path that the resource has inside the jar, that is the real package hierarchy.当您从类加载器获取资源时,您必须指定资源在 jar 中的路径,即真正的包层次结构。

如果由于某种原因你真的需要创建一个java.io.File对象来指向 Jar 文件中的资源,答案在这里: https : //stackoverflow.com/a/27149287/155167

File f = new File(getClass().getResource("/MyResource").toExternalForm());

Here is a solution for Eclipse RCP / Plugin developers:这是 Eclipse RCP/插件开发人员的解决方案:

Bundle bundle = Platform.getBundle("resource_from_some_plugin");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
   URL resolvedFileURL = FileLocator.toFileURL(fileURL);

   // We need to use the 3-arg constructor of URI in order to properly escape file system chars
   URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null);
   File file = new File(resolvedURI);
} catch (URISyntaxException e1) {
    e1.printStackTrace();
} catch (IOException e1) {
    e1.printStackTrace();
}

It's very important to use FileLocator.toFileURL(fileURL) rather than resolve(fileURL) , cause when the plugin is packed into a jar this will cause Eclipse to create an unpacked version in a temporary location so that the object can be accessed using File.使用FileLocator.toFileURL(fileURL)而不是resolve(fileURL)非常重要,因为当插件被打包到 jar 中时,这将导致 Eclipse 在临时位置创建一个解压版本,以便可以使用 File 访问该对象。 For instance, I guess Lars Vogel has an error in his article - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/例如,我猜 Lars Vogel 在他的文章中有一个错误 - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/

While I stumbled upon this problem myself I'd like to add another option (to the otherwise perfect explanation from @dash1e):虽然我自己偶然发现了这个问题,但我想添加另一个选项(来自@dash1e 的完美解释):

Export the plugin as a folder (not a jar) by adding:通过添加以下内容将插件导出为文件夹(而不是 jar):

Eclipse-BundleShape: dir

to your MANIFEST.MF .到您的MANIFEST.MF

At least when you export your RCP app with the export wizard (based on a *.product ) file this gets respected and will produce a folder.至少当您使用导出向导(基于*.product )导出 RCP 应用程序时,这会得到尊重并生成一个文件夹。

In addition to the general answers, you can get "URI is not hierarchical" from Unitils library attempting to load a dataset off a .jar file.除了一般答案之外,您还可以从Unitils库尝试从.jar文件加载数据集时获得“URI 不是分层的”。 It may happen when you keep datasets in one maven submodule, but actual tests in another.当您将数据集保存在一个 Maven 子模块中,而将实际测试保存在另一个子模块中时,可能会发生这种情况。

There is even a bug UNI-197 filed.甚至还有一个错误 UNI-197提交。

I got a similiar issues before, and I used the code:我之前遇到过类似的问题,我使用了代码:

new File(new URI(url.toString().replace(" ","%20")).getSchemeSpecificPart());

instead of the code :而不是代码:

new File(new URI(url.toURI())

to solve the problem解决问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM