返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
Java

深入Jar包:Gradle构建可执行jar包与访问jar包中文件夹与文件

前言 Java的跨平台功能听起来很诱人可口,号称“Write Once,Run Everywhere”,实际上是“Run Once,Debug Everywhere”... 在实际开发过程中还是会遇到各种各样的坑的,刚刚解决了一系列问题,特地写个文章总结一下。 使用Gradle构建Jar包 感谢万能的Gradle,极大提高了Java开发的生产力~ 在Gradle中生成jar包可以使用官方的插件:a

曦远 (DealiAxy)约 9 分钟
目录6 个章节

前言

Java的跨平台功能听起来很诱人可口,号称“Write Once,Run Everywhere”,实际上是“Run Once,Debug Everywhere”... 在实际开发过程中还是会遇到各种各样的坑的,刚刚解决了一系列问题,特地写个文章总结一下。

使用Gradle构建Jar包

感谢万能的Gradle,极大提高了Java开发的生产力~ 在Gradle中生成jar包可以使用官方的插件:application 来简单生成Jar包,同时还有多种不同的配置可以自定义,了解详情请参照Gradle官方文档。

我这里使用的是一个叫做 shadow 的Gradle插件,把构建jar包的配置都安排得明明白白了,非常的方便! 官方文档:https://imperceptiblethoughts.com/shadow/configuration/#configuring-output-name

下面是 build.gradle 配置参考:

plugins {
    id 'com.github.johnrengelman.shadow' version '4.0.3'

    // Apply the java plugin to add support for Java
    id 'java'

    // Apply the application plugin to add support for building an application
    id 'application'
}

dependencies {
    implementation 'com.github.jengelman.gradle.plugins:shadow:4.0.3'
}

// Output to build/libs/name.jar
shadowJar {
    baseName = 'name'
    classifier = null
    version = null
}

apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'java'

具体的配置要依照项目的实际需要来配置~ 设置完 shadow 插件之后,执行 gradle build 就可以在 build/libs/ 文件夹下面生成你的可执行jar包了,超级方便。 需要更多功能可以查看shadow官网文档,写的很清楚。

访问jar包中的资源

虽然jar包中有各种目录结构,但是jar包本质仍然是一个文件,所以不可以用传统的方法去访问,像 File 类,Class 对象的 getResouce 方法都不行的。 应该使用 ClassLoader 的 getResourceStream 方法直接获取资源文件的输入流。 例如:

InputStream is=this.getClass().getResourceAsStream("/resource/res.txt");
InputStream is=this.getClass().getClassLoader().getResourceStream("/resource/res.txt");

注意:Class对象和ClassLoader对象的getResourceStream方法也是有不同的,具体的不同可以查看这个笔记:正确获取Java项目资源

访问Jar包中的文件夹

当jar包中的资源文件很多的时候,不可能一个个输入名字去获取,这也太hack了吧,肯定要用自动化的方式来提高生产力。 事实上,访问jar包中的文件夹是挺麻烦的,不过还是找到了取巧的方法,试了一下还是挺好用的。 (不过最好做一下缓存)

代码如下:

String path = getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
JarFile localJarFile = new JarFile(new File(path));

Enumeration<JarEntry> entries = localJarFile.entries();
while (entries.hasMoreElements()) {
      JarEntry jarEntry = entries.nextElement();
      String innerPath = jarEntry.getName();
      System.out.println(innerPath);
}

使用getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); 来获取当前jar包的路径,如果代码不在jar包中运行的话,获取到的就是当前class文件所在路径。所以在使用之前最好做一下判断,看看程序是否在jar包中运行。

关于JavaFX的Media资源问题

JavaFX可以播放音乐,但是和其他Image、Font资源不同的是,Media对象的构造函数只能接受一个String参数(即文件URL),所以没办法使用getResourceStream方法把文件输入流传入对象。

我查了一下官网,找到了解决办法,把文件URL换成JarURL就可以了,文档:https://docs.oracle.com/javase/6/docs/api/java/net/JarURLConnection.html。

简单示例:

String path = String.format("jar:file:%s!/%s", jarPath, relativePath);
Media media = new Media(path);

注意:relativePath的形式是 media/hello.wav 这样的。

欢迎交流

程序设计实验室专注于互联网热门新技术探索与团队敏捷开发实践,在公众号「程序设计实验室」后台回复 linux、flutter、c#、netcore、android、kotlin、java、python 等可获取相关技术文章和资料,同时有任何问题都可以在公众号后台留言~

_EOF_

深入Jar包:Gradle构建可执行jar包与访问jar包中文件夹与文件

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

在Linux-Ubuntu上配置开发JavaFx程序-(更新)

前言 不清楚什么原因,网络上关于JavaFx的中文资料很少,并且都很老,所以建议大家有兴趣学习JavaFx还是看官方文档比较好,而且貌似部分人不看好JavaFx。 关于Swing的资料倒是要多很多。我觉得挺奇怪的,从设计上来将,还是JavaFx高明一些嘛。 PS:经过近一周的折腾和探索,发现OpenJDK使用JavaFX真的好多坑~ OpenJDK 和 Oracle JDK的配置是有差别的,这里推

2022-05-27 · Java · 约 1 分钟

Spring-Boot:创建第一个应用

简介 Spring Boot 是一个轻量级框架,可以完成基于 Spring 的应用程序的大部分配置工作。在本教程中,将学习如何使用 Spring Boot 的 starter、特性和可执行 JAR 文件结构,快速创建能直接运行的基于 Spring 的应用程序。 本文使用IDEA作为开发工具,Gradle作为构建工具,创建一个简单的SpringBoot应用,暂时不涉及数据库的配置。 使用IDEA创建

2022-05-27 · Java · 约 1 分钟

2020年第一次用上Struts2框架做Web开发的体验

SliiyStruts2 又名 sb-struts2,因为struts真的太难用了(也许在很多年前是很好用的,但是现在看来,被其他框架秒成渣) 前言 想不到我还是得和这struts框架打交道啊,从一开始学web的时候就十分抵制这类古老,使用反人类的框架,不过为了帮女朋友做个学校的作业,还是得搞一下,然而,半小时就写好的业务代码,因为我不熟悉这个框架和Java的这套体系,调试了半天才成功run起来…

2022-06-17 · Java · 约 1 分钟

Java开发:JDK安装和环境配置

前言 环境配置是开发中最基础的部分,不过最近有很多新入坑的同学,都在问怎么安装JDK和配置环境,索性写一篇。 这里要注意一下,在Windows平台和Linux平台下做开发是不同的,Windows平台开发Java需要自己手动配置JDK的环境变量,而大多数Linux都是不需要的,安装了OpenJDK就可以了(可能很多发行版都自带了OpenJDK),这点是比较方便的。 下载Java JDK Window

2023-02-08 · Java · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…