加载 jar 中包含的资源

2022-09-02 00:39:35

在我的应用程序中,我以这种方式加载资源:

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

有没有办法解决这个问题?

我将使用“存储库”dir名称来创建以下内容:

ConfigurationContext ctx = (ConfigurationContext) ConfigurationContextFactory.createConfigurationContextFromFileSystem(repositoryString, null);

以同样的方式,我将获得一个文件名(而不是dir),我将以这种方式使用它:

System.setProperty("javax.net.ssl.trustStore", fileNameString)

答案 1

听起来好像您正在尝试使用或类似的东西来加载资源。不要这样做:不要调用 ,而是调用 getResourceAsStream 并从中读取数据。FileInputStreamgetResource

(您可以改为从 URL 加载资源,但调用会更方便一些。getResourceAsStream

编辑:看到更新的答案后,似乎其他代码位依赖于文件系统中物理单个文件中的数据。因此,答案是首先不要将其捆绑在jar文件中。您可以检查它是否在单独的文件中,如果没有将其提取到临时文件中,但这是相当棘手的IMO。


答案 2

使用 运行代码时,java 仅使用 JAR 文件清单中定义的类路径(即 属性)。如果类位于 中,或者该类位于 JAR 清单的属性中设置的类路径中,则可以使用以下代码段加载该类,其中 的 是完全限定的类名。java -jar app.jarClass-Pathapp.jarClass-PathclassName

final String classAsPath = className.replace('.', '/') + ".class";
final InputStream input = ClassLoader.getSystemResourceAsStream( path/to/class );

现在,如果类不是 JAR 的一部分,并且不在清单的 中,则类装入器将无法找到它。相反,您可以谨慎使用 ,来处理 Windows 和 Unix/Linux/MacOSX 之间的差异。Class-PathURLClassLoader

// 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 );

在这两个示例中,您都需要处理异常,以及输入流是在找不到资源的情况下的事实。另外,如果你需要进入一个,你可以使用Apache的共享资源。而且,如果您随后想要 一个 ,则可以使用类装入器的方法,该方法接受 .nullInputStreambyte[]IOUtils.toByteArray(...)ClassdefineClass(...)byte[]

您可以在 Diffusive 源代码的 ClassLoaderUtils 类中找到此代码,该源代码可以在 SourceForge 上找到,github.com/robphilipp/diffusive

以及一种从 RestfulDiffuserManagerResource.createJarClassPath(...) 中的相对和绝对路径为 Windows 和 Unix/Linux/MacOSX 创建 URL 的方法。


推荐