加载包含在一个罐子里
在我的应用程序以这种方式加载资源的资源:加载包含在一个罐子里
WinProcessor.class.getResource("repository").toString();
,这给了我:
file:/root/app/repository (and I replace "file:" with empty string)
,当我从IDE运行我的应用程序也能正常工作,但是当我运行我的应用程序的罐子:
java -jar app.jar
的路径变为:
jar:/root/app.jar!/repository
有没有什么办法可以解决这个问题?
我会为了创建这个使用“仓库”目录名称:
ConfigurationContext ctx = (ConfigurationContext) ConfigurationContextFactory.createConfigurationContextFromFileSystem(repositoryString, null);
以同样的方式,我会得到一个文件名(而不是目录),我将使用它是这样的:
System.setProperty("javax.net.ssl.trustStore", fileNameString)
听起来好像你正试图加载资源使用FileInputStream
或类似的东西。不要这样做:不要拨打getResource
,请拨打getResourceAsStream
并从中读取数据。
(你可以加载从网址,而不是资源,但调用getResourceAsStream
更方便一点。)
编辑:在看到更新后的答案,似乎其他代码位依赖于一个数据是文件系统中的物理单个文件。因此,答案不是首先将它捆绑在一个jar文件中。你可能检查它是否在一个单独的文件,如果不提取它到一个临时文件,但这是相当hacky IMO。
构建一个URL
,那么你可以加载资源(即使是在一个jar文件)使用openStream
方法。
这就是`getResourceAsStream`所做的。 – 2016-07-12 14:20:56
当使用java -jar app.jar
运行代码时,java仅使用JAR文件清单中定义的类路径(即Class-Path
属性)。如果该类在app.jar
中,或者该类在JAR清单的Class-Path
属性中设置的类路径中,则可以使用以下代码片段加载该类,其中className
是完全限定的类名。
final String classAsPath = className.replace('.', '/') + ".class";
final InputStream input = ClassLoader.getSystemResourceAsStream(path/to/class);
现在,如果类不是JAR的一部分,它是不是在清单的Class-Path
,那么类装载器将无法找到它。相反,你可以使用URLClassLoader
,小心处理windows和Unix/Linux/MacOSX之间的差异。
// the class to load
final String classAsPath = className.replace('.', '/') + ".class";
// the URL to the `app.jar` file (Windows and Unix/Linux/MacOSX below)
final URL url = new URL("file", null, "///C:/Users/diffusive/app.jar");
//final URL url = new URL("file", null, "/Users/diffusive/app.jar");
// create the class loader with the JAR file
final URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { url });
// grab the resource, through, this time from the `URLClassLoader` object
// rather than from the `ClassLoader` class
final InputStream input = urlClassLoader.getResourceAsStream(classAsPath);
在你需要处理异常两个例子,而事实上,输入流是null
如果资源不能被发现。另外,如果您需要将InputStream
转换为byte[]
,则可以使用Apache的公共区域IOUtils.toByteArray(...)
。而且,如果您想要Class
,则可以使用类加载程序的defineClass(...)
方法,该方法接受byte[]
。
您可以在扩散源代码,你可以在github.com/robphilipp/diffusive
和一种方法找到SourceForge上为Windows和Unix/Linux创建URL找到一个ClassLoaderUtils
类的代码/从相对和绝对路径的MacOSX RestfulDiffuserManagerResource.createJarClassPath(...)
同意。每当你不能100%肯定地说你会处理物理单个文件(java web start for one)时,你应该总是用流编码。 – 2009-02-22 12:16:38