在netbeans中正确包装可运行的Jar项目

时间:2017-05-21 17:00:49

标签: java netbeans jar

所以我的任务是创建一个小程序,显示一个媒体文件列表,并分别使用默认的OS媒体播放器运行这些媒体文件。

我目前的解决方案是创建一个包含所有媒体文件的包,例如:

-com.media
       |_a.mp4
       |_b.mp4

以下代码将所选mp4复制到临时目录,然后运行默认的os媒体播放器:

public File copyTempMedia(File tempAppFolder, String videoName) {

    URL f = getClass().getResource(String.format("%s/%s", Constants.MEDIA_LOCATION, videoName));
    File from = new File(f.getPath());
    File to = new File(tempAppFolder.getAbsolutePath());

    try {
        FileUtils.copyFileToDirectory(from, to);
    } catch (IOException ex) {
        Logger.getLogger(MediGUIModel.class.getName()).log(Level.SEVERE, null, ex);
    }
    System.out.println("Temp video copied: "  +  to.getAbsolutePath() + "/" + to.getName());
    return to;
}

public void triggerMediaPlayer(String fileLocation) {
    System.out.println("Triggering media player: " + fileLocation);
    try {
        if (OPERATIN_SYSTEM.contains("Linux")) {
            Runtime.getRuntime().exec("sh -c " + fileLocation);
        } else if (OPERATIN_SYSTEM.contains("Windows")) {

            Runtime.getRuntime().exec("cmd /c " + fileLocation);
        }
    } catch (IOException ex) {
        Logger.getLogger(MediGUIModel.class.getName()).log(Level.SEVERE, null, ex);
        ex.printStackTrace();
    }
}

当我通过Netbeans运行程序时,它按预期工作,但当我执行clean/build运行从构建创建的.jar时,媒体文件似乎不会被读取,所以我的问题是:

  1. 为什么它通过Netbeans而不是通过构建.jar?
  2. 这是解决这个问题的最佳方法吗?
  3. 我应该以不同方式打包媒体吗?
  4. 提前致谢。

    修改

    因此在通过控制台而不是双击jar后,在我读取文件的行中得到一个空指针异常:

    URL f = getClass().getResource(String.format("%s/%s", Constants.MEDIA_LOCATION, videoName));
    

    为什么它在Netebeans中有效,而在build / jar上却没有?

    jar中是否有另一个地方可以放置媒体文件,以便通过getResource或getResourceAsStream读取它们没有问题?

4 个答案:

答案 0 :(得分:3)

在NetBeans中运行项目时,它没有像java -jar yourproject.jar那样运行可执行jar。相反,它将类路径设置为类似java -cp build/classes com.media.YourMainClass的构建/类。这意味着您的视频文件是位于您的项目/ build / classes / com / media中的实际文件,它们可以作为文件系统中的普通文件进行访问,并像普通文件一样进行复制。当您从jar运行时,文件将打包在jar文件中,并且无法使用简单的文件复制命令进行复制。

不要通过致电getClass().getResource()来获取网址,而是通过致电InputStream来获取getClass().getResourceAsStream()。然后,您可以编写一个简单的循环来将输入流中的字节复制到临时文件中。

答案 1 :(得分:2)

此代码段可能会有所帮助:

    BufferedInputStream result = (BufferedInputStream) getClass().getResourceAsStream("/com/media/a.mp4");
    byte[] bytes = new byte[4098];
    try {
        result.read(bytes);
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println(new String(bytes));

你需要读取循环中的字节或其他东西,但这应该可以工作而不需要单独的jar。

答案 2 :(得分:2)

我认为将媒体文件放在jar中并不是一个好主意,因为如果你想更改一个并且jar大小会增长,你需要重建项目。

使用:

File from = new File(String.format("%s/%s", Constants.MEDIA_LOCATION,videoName));

从与jar相同的文件夹加载文件。

如果要将媒体保留在jar中,请创建一个Maven项目并将mp4放在src / main / resources中。 使用maven创建一个胖jar,src / main / resources将包含在jar中。 请参阅' maven-shade-plugin'配置pom.xml和https://www.mkyong.com/maven/create-a-fat-jar-file-maven-shade-plugin/

然后你可以使用其他maven的伟大属性!

请参阅Reading a resource file from within jar

修改

经过一些尝试后,我无法通过“getResource”'从罐子里。 你在jar中获得的路径如下:file:/C:/.../JavaApplication4/dist/JavaApplication4.jar!/test.txt 并且未被识别为有效的文件系统路径。

您可以使用' getResourceAsStream'并将文件从jar复制到本地文件夹。

InputStream in;
OutputStream out;
IOUtils.copy(in,out);
in.close();
out.close();

答案 3 :(得分:1)

好的,我找到了解决方案:

  1. 使用media.*.mp4创建单独的项目。
  2. 导出为Jar库。
  3. 将库导入桌面应用程序。
  4. 确保库位于类路径中。
  5. 这个解决方案对我有用......

    如果有人有更好的解决方案,很高兴听到,希望在赏金之前:)