[英]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.