【问题标题】:Runnable Jar cannot find Resources and Other LibrariesRunnable Jar 找不到资源和其他库
【发布时间】:2012-12-09 00:18:31
【问题描述】:

我创建了一个桌面应用程序,但在生成的可运行 jar 中遇到了问题。在 Eclipse 环境中一切正常,但是当我生成 jar 时,它只显示swtcomponents(菜单、选项卡等)。 其他库的位置是空白区域(生成图库的库)。同样不出现set ToolBar(含带图片的按钮),GoogleMap.html不出现。

如何正确生成包含这些外部源的可执行 jar?

工具栏图片加载代码:

folderSearchIcon = new Image(display, this.getClass().getResourceAsStream("images/search_folder.png"));

GoogleMap.html 加载代码:

File mapFile = new File("resources/GoogleMap.html");        
if(!mapFile.exists()) {
    System.out.println("File doesn't exist! " + mapFile.getAbsolutePath()); 
    return;
}

生成可运行的 jar:

我在 Eclipse 中的应用结构和生成的 jar 结构:

生成的清单:

Manifest-Version: 1.0
Rsrc-Class-Path: ./ swt.jar commons-imaging-1.0-SNAPSHOT.jar org.eclip
  se.nebula.widgets.gallery_0.5.3.201210262156.jar xmpcore.jar metadata
  -extractor-2.6.3.jar
Class-Path: .
Rsrc-Main-Class: geotagger.AppInit
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader

【问题讨论】:

  • 通过runnable jar运行应用时,后台有没有异常?
  • 您确定资源确实包含在 jar 中吗?只需使用存档软件打开并检查即可。
  • 所以 lib 文件夹不包含在 jar 中,对吗?只需使用 Eclipse 将它们添加到构建路径
  • @NikolayKuznetsov 从清单和第二个屏幕截图中可以看出,库在 jar 中被引用
  • @unixhead 根据您的屏幕截图,您的 jar 不包含 resources 文件夹,但您使用它来访问 .html 文件。

标签: java eclipse swt executable-jar


【解决方案1】:

对于工具栏图像,您需要添加一个斜杠,即,而不是

this.getClass().getResourceAsStream("images/search_folder.png")

你需要

this.getClass().getResourceAsStream("/images/search_folder.png")

这是因为,as explained in the JavaDocsClass.getResourceAsStream 会针对相关类的包解析相对路径,因此如果thiscom.example.Foo,那么getResourceAsStream("images/search_folder.png") 将在您的JAR 中查找com/example/images/search_folder.png。在斜线前面添加它会使其查找 images/search_folder.png,而这正是您的屏幕截图所暗示的。

您需要对 GoogleMap.html 使用类似的技巧 - 您不能使用 java.io.File 从 JAR 中加载项目,但您可以使用 this.getClass().getResource("/GoogleMap.html") 获取指向 HTML 文件的 java.net.URL在您的 JAR 中。

【讨论】:

  • 感谢它的工作!可运行的 jar 显示了应用程序的全部内容,但 GoogleMap.html 未在 SWT 浏览器中加载(在 Eclipse 中有效)但浏览器与网络连接,GoogleMap.html 加载代码:try { URL mapFile = getClass().getResource("/GoogleMap.html"); browserMap = new Browser(compositeTabItemMap, SWT.NONE); browserMap.setUrl(mapFile.toString()); } catch(NullPointerException e) { e.printStackTrace(); }
  • @unixhead 在这种情况下,您可能必须自己将 HTML 加载到字符串中并使用 setText 而不是 setUrl。 SWT Browser 是原生浏览器的包装器,可能无法加载特定于 Java 的 URL 方案。
  • 那么没有其他方法可以在 jar 中执行*.html 文件吗?它更容易,更清楚:(
  • 我试过这个:InputStream getHtml = getClass().getResourceAsStream("/GoogleMaps.html"); Scanner htmlScanner = new Scanner(getHtml); StringBuffer htmlBuffer = new StringBuffer(); while(htmlScanner.hasNextLine()) { htmlBuffer.append(htmlScanner.nextLine()); } browserMap = new Browser(compositeTabItemMap, SWT.NONE); browserMap.setText(htmlBuffer.toString()); 但是谷歌地图在 Eclipse 中没有加载.. 我创建了简单的 html 文件并做了同样的事情.. 在这种情况下它在 Eclipse 中工作但在可运行的 jar 中仍然是与 GoogleMap.html 相同的情况
  • 简单解决方案:):java 无法从 jar 文件加载 html 文件,因为它必须解压缩到文件 sys.xml 中的临时文件。位置,所以我将.html 更改为.txt 并且我在append 方法中添加了\n 以正确验证javascript代码,它工作得很好
【解决方案2】:

我在同一个问题上浪费了很多时间。如果您使用 Eclipse 中的“导出”功能中的选项创建了可运行的 jar,那么它将无法正常工作。至少它不适合我。无论我尝试了多少选项,都没有任何效果。尝试读取资源时,resourceUrl 将返回 null。最后,我决定使用 Maven 创建可运行的 jar,而将 Eclipse 的帮助放在一边。我需要将依赖的 jars 放在一个单独的 lib 文件夹中。我按照http://www.mkyong.com/maven/how-to-create-a-manifest-file-with-maven/ 中的说明创建了可运行的 jar,该解决方案对我有用。不知何故,当 Eclipse 创建可运行的 jar 包时,无法读取资源,即使它们存在于 jar 文件中。希望这对其他人有帮助。

【讨论】:

  • 我也无法让它工作。但是,我确实注意到将资源文件夹复制到可运行 jar 的同一文件夹中是有效的......也许这对其他人有帮助
【解决方案3】:

如您所见:

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getResourceAsStream(java.lang.String)

getResourceAsStream() 在与调用它的类相同的包中查找文件。因此它将在 JAR 中查找名为“com/whatever/more/images/search_folder.png”的文件,该文件当然不会存在,因为“resources”目录的内容直接放在JAR 导出器的 JAR 文件。

请改用http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResourceAsStream(java.lang.String)

第二部分:当你加载 HTML 时将永远无法工作。您尝试在您的 java 程序进程的工作目录中查找名为“resources/GoogleMap.html”的文件,但它会在 JAR 之外查找。您应该再次使用前面的函数来加载 HTML:

http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResourceAsStream(java.lang.String)

【讨论】:

  • 所以在看到上述似乎对我来说很好的解决方案后,我最终尝试了这个。不知道为什么这对于 Runnable Jars 来说如此晦涩难懂。我将资源放在我的资源目录中,我已将其添加为 Eclipse ClassLoader.getSystemClassLoader().getResourceAsStream("file.txt"); 的类路径的一部分
【解决方案4】:

由于导出到可运行的 jar 实质上会创建一个文件,因此使用 FileReader 无法再找到资源文件夹中的文件/图像/资源,因为文件位置现在不存在..

从使用 FileReader fr = new FileReader(resource_file_path) 更改为使用 InputStream、InputStream is = getClass().getResourceAsStream(resource_file_path) 加载,然后使用 InputStreamReader 实际使用其他位置的资源。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2014-03-22
    • 2012-02-04
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多