在我的应用程序中,我以这种方式加载资源:
WinProcessor.class.getResource("repository").toString();
这给了我:
file:/root/app/repository (and I replace "file:" with empty string)
当我从IDE运行我的应用程序时,这工作正常,但是当我运行我的应用程序的jar时:
java -jar app.jar
路径变成:
jar:/root/app.jar!/repository
有什么方法可以解决这个问题吗?
我将使用"repository"目录名称来创建:
ConfigurationContext ctx = (ConfigurationContext) ConfigurationContextFactory.createConfigurationContextFromFileSystem(repositoryString, null);
以同样的方式,我将获得一个文件名(而不是一个目录),我将以这种方式使用它:
System.setProperty("javax.net.ssl.trustStore", fileNameString)
Jon Skeet.. 35
听起来你正在尝试使用FileInputStream
类似的东西来加载资源.不要这样做:而不是呼叫getResource
,调用getResourceAsStream
和读取数据.
(您可以从URL加载资源,但调用getResourceAsStream
更方便.)
编辑:看到你的更新答案后,似乎其他代码依赖于文件系统中物理单个文件中的数据.因此,答案不是首先将其捆绑在jar文件中.你可以检查它是否在一个单独的文件中,如果没有将它提取到一个临时文件,但这是非常hacky IMO.
听起来你正在尝试使用FileInputStream
类似的东西来加载资源.不要这样做:而不是呼叫getResource
,调用getResourceAsStream
和读取数据.
(您可以从URL加载资源,但调用getResourceAsStream
更方便.)
编辑:看到你的更新答案后,似乎其他代码依赖于文件系统中物理单个文件中的数据.因此,答案不是首先将其捆绑在jar文件中.你可以检查它是否在一个单独的文件中,如果没有将它提取到一个临时文件,但这是非常hacky IMO.
使用代码运行时java -jar app.jar
,java仅使用JAR文件清单中定义的类路径(即Class-Path
属性).如果该类所在app.jar
,或者该类位于Class-Path
JAR清单属性中设置的类路径中,则可以使用以下代码片段加载该类,其中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
进入a byte[]
,你可以使用Apache的公共资源IOUtils.toByteArray(...)
.而且,如果你想要一个Class
,你可以使用类加载器的defineClass(...)
方法,它接受byte[]
.
您可以ClassLoaderUtils
在Diffusive源代码中的类中找到此代码,您可以在SourceForge上找到该代码,网址为github.com/robphilipp/diffusive
以及从相对和绝对路径为Windows和Unix/Linux/MacOSX创建URL的方法 RestfulDiffuserManagerResource.createJarClassPath(...)
构造一个URL
,然后可以使用该openStream
方法加载资源(甚至在jar文件中).