【问题标题】:Serialized files don't work when project is converted to executable jar?将项目转换为可执行 jar 时,序列化文件不起作用?
【发布时间】:2013-04-11 16:47:52
【问题描述】:

我使用 eclipse 中的 export to jar 选项将我的 java 项目变成了一个可执行的 jar。 jar 按预期运行,只是它不使用任何序列化文件。我可以从 GUI 清楚地看到这一点。这个问题可能是什么原因,我该如何解决?

我看到了这个相关的问题 - Why does my JAR file not create a serialization?

但它并没有确切地告诉我如何解决这个问题。看起来您无法将文件夹打包到 jar 中。为什么 ?因为代码可能会意外/故意继续向该文件夹添加数据并使整个 jar 占用硬盘?

如何创建某种结构来打包我的可执行 jar 及其序列化文件夹?

【问题讨论】:

  • 在这里查看第二个答案:stackoverflow.com/questions/3369794/….
  • 代码在哪里?您希望这段未知代码做什么,它会做什么?
  • 这些序列化文件在哪里?连同你在 jar 中的类?
  • @DenisTulskiy - 这些文件位于我的项目文件夹内的单独/独立文件夹中,而不是 bin、src 或 lib 文件夹中。
  • 如果您的文件夹在 eclipse 项目目录中,那么它会在导出到 jar 时显示它。它不适合您吗?

标签: java eclipse jar


【解决方案1】:

回答这个问题:

如何创建某种结构来打包我的可执行 jar 及其序列化文件夹?

一种常见的方法是有一个明确定义的位置来存储序列化文件、设置等,这与程序执行的位置无关。通常它是用户的主目录,或者在 windows 的情况下是应用程序数据。我使用此代码来存储我的应用程序设置:

    String home = System.getenv("APPDATA");
    if (StringUtils.isEmpty(home)) {
        home = System.getProperty("user.home");
    }
    CONFIG_HOME = new File(home, ".myProgram").getAbsoluteFile();
    CONFIG_HOME.mkdirs();

因此在 Windows 上它将使用 AppData,而在 *nix 系统上它将使用用户的家。 myProgram 前面的点是让它在 *nix 平台上隐藏,这是一种常见的做法。

编辑对于您评论中的问题:

在我的 linux 机器上没有 APPDATA 环境变量,所以这段代码将创建一个目录/home/myUser/.myProgram。在 Windows 上,它将类似于 c:/Users/myUser/AppData/Local/.myProgram。在 MacOSX 上,不知道。

【讨论】:

  • Denis 请逐步解释代码在做什么。保存设置、序列化文件等的文件夹名称是什么?
【解决方案2】:

您需要您的 JAR 使用与 eclipse 中的代码相同的路径来读取序列化文件。

因此,您创建了一个属性文件,其中包含带有序列化对象的目录。 然后,这对于您的 JAR 和我们的项目都是一样的。

另请参阅:http://www.mkyong.com/java/java-properties-file-examples/

【讨论】:

    【解决方案3】:

    你可以使用

    AClass.class.getResource(String str);
    //or
    AClass.class.getResourceAsStream(String str);
    

    AClass:你的一个类。

    str:要读取的文件位置。

    例如;

    如果您的类层次结构如下所示:

    +src
        +-com
             +-test
                 |-AClass.java
                 +-util
                     +-PrintUtil.java
                 +-resources
                     |-Bouble.png
                     |-Mouse.png
                     +-Ocean.png
    

    对于阅读“Mouse.png”图像,您可以通过多种方式进行:

    AClass.class.getResource("/resources/Mouse.png");
    //or
    PrintUtil.class.getResource("../resources/Mouse.png");
    ...
    

    【讨论】:

      【解决方案4】:

      在使用/运行 jar 文件时,不能在 jar 文件中写入内容。当您将 jar 文件放在类路径中或直接从 jar 运行程序时,该 jar 将被您的 jvm 锁定,因此它不允许您更新当前使用的同一 jar 文件。


      如果您的类位于文件夹中,而不是存档(您正在使用)中,则人们给出的解决方案将资源用作流将起作用。


      作为存档,您不能直接更新它,您需要执行以下步骤(自己或通过 3rd 方 api),
      在临时位置提取
      更新文件
      重新存档

      现在由于 jar 文件被锁定,您将无法进行第三次操作,这甚至是不安全的。例如,当您运行 jar 文件时,尝试重命名它,它不会发生,如果发生,jar 文件尚未被 jvm 锁定,每当您调用 jar 内的类时,它就会被锁定文件。
      为了更好、更安全的序列化和文件保存,请查看:java.util.prefs.Preferences

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-09
        • 2018-01-28
        • 2020-03-22
        • 1970-01-01
        • 1970-01-01
        • 2022-11-24
        相关资源
        最近更新 更多