为什么我的Jar不运行,除非我提取文件? [英] Why my Jar doesn't run unless I extract files?

查看:182
本文介绍了为什么我的Jar不运行,除非我提取文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我运行导出的 .jar 文件,其中包含一个图像为其图标的 JFrame 该文件不运行,除非我提取文件。在编译器中它正在运行。我不想制作一个将资源包和jar文件保存在目录中的启动器。

解决方案


为什么我的Jar不运行,除非我提取文件?


这似乎是使用的行为文件到您的资源。例如

 文件文件=新文件(resources / image.png); 
图像= ImagIO.read(file);

您的项目结构(注意资源实际上应该在 src 中,以便它自动构建到jar中 - 除非你配置不同,但是为了这个说法,让我们说你在 c code code code code code code code $ > C:\
项目
resources\image.png

检查:




  • 从IDE运行 - WORKS!为什么?使用文件查找文件系统上的文件。使用相对路径,搜索将从工作目录开始,在IDE的情况下,通常是项目根目录。所以resources / image.png是一个有效的路径,相对于 ProjectRoot


  • 构建jar,说它最终在项目中的 dist 目录中。这是它的样子

      ProjectRoot 
    dist
    ProjectRoot.jar

    现在为了这个参数(实际上是正确的方式),让我们尝试打印出来的程序中的资源的URL ,所以当你运行jar时,它打印出文件的URL

      URL url = Test.class.getResource /resources/image.png); 
    System.out.println(url.toString());

    当我们运行jar C:\ProjectRoot\dist> java -jar ProjectRoot.jar 我们将看到打印输出 C:\ProjectRoot\dist\ProjectRoot.jar!\resources\image.png 。您可以看到即使当前工作目录是jar的位置,路径不再匹配,添加的jar ProjectRoot.jar!位置。


  • 那么为什么在我们提取它的时候它会工作。那么当你提取它,那么路径是正确的

      C:\ProjectRoot 
    dist
    资源/image.png //从提取的jar
    ProjectRoot.jar

    当您从 C:\ProjectRoot\dist> 资源 dir是应该在哪里。




足够解释。



因此,当您想要阅读嵌入式资源时,应从Andrew Thompson所提供的URL中读取。这个url应该是相对于调用它的类,或类加载器。以下是几种不同的方法:


  1. 如图所示

      URL url = getClass()。getResource(/ resources / image.png); 

    注意 / 。这将使我们进入类路径的根,其中资源目录将在。可以将 URL 传递给许多构造函数,如 ImageIcon(URL)或`ImageI.read(URL)


  2. 您可以使用

      InputStream is = getClass()。的getResourceAsStream( /资源/ image.png); 

    哪些将使用一个URL。您可以使用 InputStream 与许多构造函数。


  3. 还有一些方法可以使用类加载器,将从根开始,因此您不需要 /

      URL url = getClass()。getClassLoader()。getResource(resources / image.png); 


所以有几种方法可以去关于它。但是一般来说,使用嵌入式资源时,用硬编码的字符串路径读取 File 并不是个好主意。可以动态获取路径,以便您可以使用文件,但是您仍然需要使用上述技术之一,除非您真的需要一个文件将无意义,您可以使用 InputStream URL






简短描述



工作

  ProjectRoot 
src\resources\image.png

URL url = 。的getClass()的getResource( /资源/ image.png);
Image image = ImageIO.read(url);


Every time I run the exported .jar file, that contains a JFrame with an image as its icon, the file doesn't run, unless I extract the file. In the compiler it is running. I dont want to make a launcher that saves both, the resources package and the jar file, in a directory.

解决方案

"Why my Jar doesn't run unless I extract files?"

This seems to be the behavior of using File to your resources. Take for example

File file = new File("resources/image.png");
Image image = ImagIO.read(file);

And you project structure (Note the resources should actually be in the src, so that it builds into the jar automatically - unless you configure it differently. But for the sake of this argument, let's say you do confgigure it where resources is built to the jar)

C:\
   Project
        resources\image.png

Some examination:

  • Run from IDE - WORKS! Why? Using File looks for files on the file system. Using a relative path, the search will begin from the "working directory", which in the case of the IDE in generally the project root. So "resources/image.png" is a valid path, relative to ProjectRoot

  • Build jar, say it ends up in a dist dir in the project. This is what it looks like

    ProjectRoot
             dist
                ProjectRoot.jar
    

    Now for the sake of this argument (and is actually the correct way), let's try and print the URL of the resource in out program, so that when you run the jar, it prints out the URL of the file

    URL url = Test.class.getResource("/resources/image.png");
    System.out.println(url.toString());
    

    When we run the jar C:\ProjectRoot\dist> java -jar ProjectRoot.jar We will see the print out C:\ProjectRoot\dist\ProjectRoot.jar!\resources\image.png. You can obviously see even though the current working directory is the location of the jar, the paths no longer match, with the added jar ProjectRoot.jar! location.

  • So why does it work when we extract it. Well when you extract it, then the path is correct

    C:\ProjectRoot
               dist
                   resources/image.png // from extracted jar
                   ProjectRoot.jar
    

    When you run from the C:\ProjectRoot\dist >, the resource dir is where is should be.

Ok enough with the explanation.

For this reason, when you want to read embedded resources, they should be read from an URL as Andrew Thompson mentioned. This url should be relative to the class calling it, or the class loader. Here are a couple different ways:

  1. As shown already

    URL url = getClass().getResource("/resources/image.png");
    

    Notice the /. This will bring us to the root of the classpath, where the resources dir will be. URL can be passed to many constructors, like ImageIcon(URL) or `ImageI.read(URL)

  2. You can use:

    InputStream is = getClass().getResourceAsStream("/resources/image.png");
    

    Which will use an URL under the hood. You can use InputStream with many constructors also.

  3. There's also ways to use the class loader, which will start at the root, so you don't need the /

    URL url = getClass().getClassLoader().getResource("resources/image.png");
    

So there are a few ways you can go about it. But in general, reading File with hard coded string paths is never a good idea, when using embedded resources. It's possible to obtain the path dynamically so you can use File, but you will still need to use one of the aforementioned techniques, which unless you really need a File would be pointless, as you can do what you need with the InputStream or URL


To make a long story short

This would work

ProjectRoot
       src\resources\image.png

URL url = getClass().getResource("/resources/image.png");
Image image = ImageIO.read(url);

这篇关于为什么我的Jar不运行,除非我提取文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆