【问题标题】:Creating Runnable Jar with external text and ser files included创建包含外部文本和 ser 文件的 Runnable Jar
【发布时间】:2014-10-28 03:53:37
【问题描述】:

好吧,我尝试了很多方法来创建可执行 jar,但 4 小时后我放弃了。我正在尝试使用我的项目制作可执行的 jar 文件,其中主类位于控制器中。基本上,我尝试使用具有各种选项的导出/可运行 JAR 文件,包括生成 ant 脚本。我在终端总是有类似的错误

当我用终端运行它时

java -jar fruitStore.jar

它说

    bmj@OZ:~/Documents$ java -jar fruitStoreApp.jar 
java.io.FileNotFoundException: customers.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadCustomers(Shop.java:250)
    at model.Shop.<init>(Shop.java:121)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: users.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadUsers(Shop.java:210)
    at model.Shop.<init>(Shop.java:122)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: suppliers.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadSuppliers(Shop.java:190)
    at model.Shop.<init>(Shop.java:123)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: stocks.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadStock(Shop.java:230)
    at model.Shop.<init>(Shop.java:124)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: sales.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadSales(Shop.java:150)
    at model.Shop.<init>(Shop.java:126)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
java.io.FileNotFoundException: orders.ser (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at model.Shop.loadOrders(Shop.java:170)
    at model.Shop.<init>(Shop.java:127)
    at model.Shop.getInstance(Shop.java:140)
    at model.Model.<init>(Model.java:12)
    at GUI.CustomerMainPanel.<init>(CustomerMainPanel.java:24)
    at GUI.MainMenuGUI.<init>(MainMenuGUI.java:50)
    at GUI.MainMenuGUI.getInstance(MainMenuGUI.java:35)
    at model.View.<init>(View.java:49)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: javax.imageio.IIOException: Can't read input file!
    at javax.imageio.ImageIO.read(ImageIO.java:1301)
    at GUI.WelcomeScreenGUI.<init>(WelcomeScreenGUI.java:33)
    at model.View.<init>(View.java:51)
    at model.Controller.<init>(Controller.java:42)
    at model.Controller.main(Controller.java:805)
    ... 5 more

我知道问题出在哪里。它不会将图片上的标记文件附加到 jar 中

我的问题是:如何添加这些文件?你能给我详细的答案吗?一个条件。我无法更改该文件的位置。

我阅读了一些关于 Maven 的解决方案,由于缺乏 Maven 知识,我想避免这些解决方案。

提前感谢您的快速回复

【问题讨论】:

  • 我不明白你的问题。当我通过 java -jar fruitStore.jar 在终端中运行 jar 文件时你需要代码吗?
  • 贴出抛出异常的代码
  • 这些文件是否被放置在可执行 jar 中?你的第一步是确保他们是
  • 你能显示你试图读取文件的代码吗
  • 不,这就是问题所在。我附上了一张图片,上面写着我需要哪些文件也附在 jar 上。因为那个项目不是从 jar 中运行的

标签: java jar executable-jar


【解决方案1】:

查看您的代码后,我看到您设置了文件名,并且您正在使用从文件系统读取的FileInputStream。

private String saleFile = "sales.ser";
...
public void loadSales(String inPutFile) {
    try {
        FileInputStream fileIn = new FileInputStream(inPutFile);

因此,程序将在当前工作目录中查找sale.ser。在您的 IDE 中,工作目录通常是项目根目录,这是您的文件所在的位置,这就是它工作的原因。

因此,由于您无法更改代码,因此这里有一些建议。

运行 jar 时,需要从当前工作目录运行 jar。导出 jar 时,将其导出到项目根目录。当您运行时,请确保您在 项目根目录中

可能更好的方法是编写脚本来启动程序(这很常见)。这将为您启动应用程序的方式/位置提供更大的灵活性。我不是最擅长编写脚本的,所以我只介绍最基本的,但您可能希望根据您想要启动应用程序和定位资源的方式使其更复杂。使用下面的 .bat 文件示例,.bat 文件也应该在项目根目录中

@echo off
setlocal

if "%JAVACMD%" == "" set JAVACMD=%JAVA_HOME%\bin\java.exe
if "%FRUITSTAND_HOME%" == "" set FRUITSTAND_HOME=%~dp0

cd "%FRUITSTAND_HOME%"
"%JAVACMD%" -cp "%FRUITSTAND_HOME%\lib\*" -jar "%FRUITSTAND_HOME%\fruitStoreApp.jar"
endlocal

然后您(从项目根目录)只需运行fruitStoreApp.bat。

我测试了它并且它有效。我只是为stocks.ser sales.ser 和order.ser 得到FileNotFoundException,因为...它们不存在(在您的项目中-至少不在您的github中)。

看起来您正在使用 bash,因此您将编写一个简单的 bash 脚本。我会同时创建 .bat 和 .sh 文件,这很常见,以启用 Windows 和 Unix 用户访问

【讨论】:

  • 是的,它运作良好。我想知道如何将它放在网站上并在点击后使其可供下载和运行。无论如何感谢您的帮助
  • 好吧,这对于您将无法写入文件的简单事实不起作用。无法写入 jar 中的文件。所以你可以把这个想法扔到窗外。下载一个 zip,解压缩,然后可执行文件位于 zip 主目录中的情况并不少见。您可以简单地创建一个文件夹,在与项目相同的层次结构中添加必要的文件和 jar。我看不出有什么问题。你从一开始就限制了自己。最好只是充分利用它:-)
  • 另外我输入的用户名和密码是什么登录。我不想测试一些理论。
  • 您在 UserList 文件中有登录名和密码。您的方式也可以通过 java -jar > 与终端一起使用,但是当我想用鼠标双击该 jar 时,它不起作用。你知道如何改变它吗?
【解决方案2】:

最简单的做法是提取您现有的JAR 文件,将这些文件夹包含在外部文本和ser 文件中,然后重新打包您的JAR。

  1. 在某处复制您原来的fruitStoreApp.jar,以防万一出现问题。
  2. 要从命令行提取JAR 文件,请运行jar xf fruitStoreApp.jar。
  3. 复制您的 model 文件夹(以及其他任何内容)。
  4. 删除您的旧 fruitStoreApp.jar,使其不会包含在下一个重新 jar 步骤中。
  5. 通过运行jar cf fruitStoreApp.jar * 重新压缩所有工件。

使用 ANT

如果你想用ant 试试这个,你可以像这样在你的jar 任务中包含fileset 类型:

<target name="package">
    <jar destfile="fruitStoreApp.jar" >
        <fileset dir="classes"/>
        <fileset dir="model" />
        <fileset dir="images" />
        <fileset dir="GUI" />
    </jar>
</target>

这会将classes、model、images、GUI 文件夹中的所有文件一起压缩到一个名为 fruitStoreApp.jar 的文件中。我假设您所有的 .class 文件都在 classes 文件夹中。

【讨论】:

  • 好吧,如果你知道如何用 maven 来做这件事,并且导出是不可能的,请随意发布一些东西
  • @Andrew_Dublin 您可能不需要maven,除非您需要重新编译/重新构建您的代码,这将涉及将您的项目转换为maven 项目。我已经使用命令行中的jar 命令直接使用更简单的解决方案更新了我的答案。希望这会有所帮助。
猜你喜欢
  • 1970-01-01
  • 2013-08-08
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 2021-12-28
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多