很多朋友在做java项目的时候,会把项目打包成jar来发布,但是,如果项目涉及到img、music、ico等外来资源的时候,在工程下往往是可以的,能运行的,但打包成jar之后就不能运行了。这是为什么呢?只要您的仔细的看完本片文章,相信会对jar的资源定位方法有一个较为全面的了解。本人刚学不久,讲的不对的地方请各位大哥大姐一定多多拍砖。
大家做java项目的时候, 一般用2种方式来定位资源:相对路径资源定位和URL资源定位。
1、相对路径资源定位
这时大家在工程底下常用的方法是:
...
jframe.setIconImage(Toolkit.getDefaultToolkit().getImage( "img/1.png"));
...
systemTray = SystemTray.getSystemTray();// 获得系统托盘的实例
try {
icon = new ImageIcon(" img/1.png").getImage();
trayIcon = new TrayIcon(icon, "XXX");
systemTray.add(trayIcon);// 设置托盘的图标,img/1.png与该类文件同一目录
} catch (AWTException e) {
}
...
工程文件结构如下:
工程文件夹/src
工程文件夹/img/1.png
这样子,在工程状态下是可以运行的,打包成jar后就不能运行了。
注意:以上代码没有问题,是正确的。
解决办法:
在jar包同级目录下新建“img”文件夹,将1.png放到img文件夹内,问题解决。
文件夹结构如下:
某文件夹F/xxx.jar
某文件夹F/img/1.png
但是,我们通常不希望将资源文件和jar分开放,那样总感觉不爽,怎么办呢?这个时候this.getClass().getResource(String arg0)和this.getClass().getResourceAsStream(String arg0)就要发挥作用了。请看URL资源定位篇。
2、URL资源定位
this.getClass().getResource(String arg0)能定位当前jar内的资源路径
this.getClass().getResourceAsStream(String arg0)能获取当前jar内的资源的流,能直接读写操作该资源
这是,大家经常会将代码改成如下:
...
jframe.setIconImage(Toolkit.getDefaultToolkit().getImage( this.getClass().getResource("img/1.png")));
...
systemTray = SystemTray.getSystemTray();// 获得系统托盘的实例
try {
icon = new ImageIcon( this.getClass().getResource("img/1.png")).getImage();
trayIcon = new TrayIcon(icon, "XXX");
systemTray.add(trayIcon);// 设置托盘的图标,img/1.png与该类文件同一目录
} catch (AWTException e) {
}
...
但是,很多人在具体做的时候,还是经常出现无法定位的问题。
注意:以上代码没有问题,是正确的。
问题现象是:
this.getClass()为null,无法获得;
而this.getClass().getResource("img/1.png")就直接出错
Exception in thread "main" java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(Unknown Source)
at com.xirui.WebSrv.Gui.<init>(Gui.java:83)
at com.xirui.WebSrv.Gui.main(Gui.java:197)
解决办法:
首先,确定你使用的方法支持URL参数,因为this.getClass().getResource(String arg0)返回的是URL路径,并非正真的文件路径;还有就是img/1.png要和*.class文件放在同一目录下,而不是直接放到jar内就可以了。
解决办法的举例说明:
你有一个工程,包为 com.aa.bb;
工程结构应该是:
工程文件夹/bin/com/aa/bb/*.class
工程文件夹/bin/com/aa/bb/img/1.png
而不是
工程文件夹/bin/com/aa/bb/*.class
工程文件夹/img/1.png
jar包的结构:
你的工程打成jar包后,用rar打开(并非解压)jar包后能看到
jar/com/aa/bb/*.class
使用rar的添加文件功能,将img/1.png放入bb目录下
最后,jar文件结构如下:
jar/com/aa/bb/*.class
jar/com/aa/bb/img/1.png
而不是
jar/com/aa/bb/*.class
jar/img/1.png
这样,资源文件1.png就在jar里面了,无论你的jar包怎么放,都能引用到1.png资源
总结:
相对路径资源定位:需要将资源文件放到src文件夹或jar文件的同级目录下
URL资源定位:需要将资源文件放到*.class的同级目录下
![关于jar的资源(img、music、ico等等)定位问题 - 卡敌奴 - 幽蓝谷](https://i-blog.csdnimg.cn/blog_migrate/5db51f4b4b757183fbe922f81d93cf03.gif)
大家做java项目的时候, 一般用2种方式来定位资源:相对路径资源定位和URL资源定位。
1、相对路径资源定位
这时大家在工程底下常用的方法是:
...
jframe.setIconImage(Toolkit.getDefaultToolkit().getImage( "img/1.png"));
...
systemTray = SystemTray.getSystemTray();// 获得系统托盘的实例
try {
icon = new ImageIcon(" img/1.png").getImage();
trayIcon = new TrayIcon(icon, "XXX");
systemTray.add(trayIcon);// 设置托盘的图标,img/1.png与该类文件同一目录
} catch (AWTException e) {
}
...
工程文件结构如下:
工程文件夹/src
工程文件夹/img/1.png
这样子,在工程状态下是可以运行的,打包成jar后就不能运行了。
注意:以上代码没有问题,是正确的。
解决办法:
在jar包同级目录下新建“img”文件夹,将1.png放到img文件夹内,问题解决。
文件夹结构如下:
某文件夹F/xxx.jar
某文件夹F/img/1.png
但是,我们通常不希望将资源文件和jar分开放,那样总感觉不爽,怎么办呢?这个时候this.getClass().getResource(String arg0)和this.getClass().getResourceAsStream(String arg0)就要发挥作用了。请看URL资源定位篇。
2、URL资源定位
this.getClass().getResource(String arg0)能定位当前jar内的资源路径
this.getClass().getResourceAsStream(String arg0)能获取当前jar内的资源的流,能直接读写操作该资源
这是,大家经常会将代码改成如下:
...
jframe.setIconImage(Toolkit.getDefaultToolkit().getImage( this.getClass().getResource("img/1.png")));
...
systemTray = SystemTray.getSystemTray();// 获得系统托盘的实例
try {
icon = new ImageIcon( this.getClass().getResource("img/1.png")).getImage();
trayIcon = new TrayIcon(icon, "XXX");
systemTray.add(trayIcon);// 设置托盘的图标,img/1.png与该类文件同一目录
} catch (AWTException e) {
}
...
但是,很多人在具体做的时候,还是经常出现无法定位的问题。
注意:以上代码没有问题,是正确的。
问题现象是:
this.getClass()为null,无法获得;
而this.getClass().getResource("img/1.png")就直接出错
Exception in thread "main" java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(Unknown Source)
at com.xirui.WebSrv.Gui.<init>(Gui.java:83)
at com.xirui.WebSrv.Gui.main(Gui.java:197)
解决办法:
首先,确定你使用的方法支持URL参数,因为this.getClass().getResource(String arg0)返回的是URL路径,并非正真的文件路径;还有就是img/1.png要和*.class文件放在同一目录下,而不是直接放到jar内就可以了。
解决办法的举例说明:
你有一个工程,包为 com.aa.bb;
工程结构应该是:
工程文件夹/bin/com/aa/bb/*.class
工程文件夹/bin/com/aa/bb/img/1.png
而不是
工程文件夹/bin/com/aa/bb/*.class
工程文件夹/img/1.png
jar包的结构:
你的工程打成jar包后,用rar打开(并非解压)jar包后能看到
jar/com/aa/bb/*.class
使用rar的添加文件功能,将img/1.png放入bb目录下
最后,jar文件结构如下:
jar/com/aa/bb/*.class
jar/com/aa/bb/img/1.png
而不是
jar/com/aa/bb/*.class
jar/img/1.png
这样,资源文件1.png就在jar里面了,无论你的jar包怎么放,都能引用到1.png资源
总结:
相对路径资源定位:需要将资源文件放到src文件夹或jar文件的同级目录下
URL资源定位:需要将资源文件放到*.class的同级目录下