Java 的 Jar 包在各个地方的作用

Java 的 Jar 包在各个地方的作用

使用记事本和命令行工具组合

  1. 先下载一个 Jar 文件用作测试

    这里选择 Gson 库,它能在 Java 对象 和 Json 字符串之间进行转换

    下载地址:Maven Repository: com.google.code.gson » gson » 2.10 (mvnrepository.com) 点击 Files 的 Jar 即可下载

  2. 打开一个文件夹,编辑一个最简单的 Java 程序

    Main.java

    import com.google.gson.Gson;
    
    public class Main {
        
        public static void main(String[] args) {
            // 创建 Gson 实例对象
            Gson gson = new Gson();
            // 实例化 Student 对象
            Student student = new Student("Wen", 22);
            // 将 Student 对象转换为 Json 字符串
            String studentStr = gson.toJson(student);
            // 将 Json 字符串转为 Student 对象
            Student studentFromJson = gson.fromJson(studentStr, Student.class);
            System.out.println("student:" + student);
            System.out.println("studentFromJson:" + studentFromJson);
            System.out.println("student.name.equales(studentFromJson.name):" + student.name.equals(studentFromJson.name));
            System.out.println("student.age == studentFromJson.age:" + (student.age == studentFromJson.age));
        }
        
        static class Student {
            
            private String name;
            
            private int age;
            
            public Student(String name, int age) {
                this.name = name;
                this.age = age;
            }
            
            public String getName() {
                return this.name;
            }
            
            public int getAge() {
                return this.age;
            }
            
            public void setName(String name) {
                this.name = name;
            }
            
            public void setAge(int age) {
                this.age = age;
            }
        }
    }
    

    PS:不会也有人企图记事本里面 sout 吧

  3. 目录结构

    Main.java
    --lib
    ----gson-2.10.jar
    
  4. 直接使用 javac Main.java 进行编译

    PS ...> javac .\Main.java
    .\Main.java:1: 错误: 程序包com.google.gson不存在
    import com.google.gson.Gson;
                          ^
    .\Main.java:7: 错误: 找不到符号
            Gson gson = new Gson();
            ^
      符号:   类 Gson
      位置: 类 Main
    .\Main.java:7: 错误: 找不到符号
            Gson gson = new Gson();
                            ^
      符号:   类 Gson
      位置: 类 Main
    3 个错误
    
  5. 使用选项(--class-path-classpath, -cp)来指定依赖库文件的路径

    PS ...> javac -cp .\lib\* .\Main.java
    PS ...> ls
    
        Directory: C:\Users\twat1\Documents\Work\other
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d----          2022/11/30    18:42                lib
    -a---          2022/11/30    18:52           1685 Main.class
    -a---          2022/11/30    18:49           1451 Main.java
    -a---          2022/11/30    18:52            661 Main$Student.class
    

    上面的 -cp .\lib* 表示当前目录 lib 文件夹下的使用 jar 或者 class 文件

  6. 然后信誓旦旦的直接 java Main

    PS ...> java Main
    Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/Gson
            at Main.main(Main.java:7)
    Caused by: java.lang.ClassNotFoundException: com.google.gson.Gson
            at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
            at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
            at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
            ... 1 more
    

    不出意外的出意外了,为什么有 NoClassDefFoundError 了呢,明明编译的时候指定了呀,很明显 javac 和 java 分家,所以在使用 java 命令时也需要指定依赖的文件路径

  7. 使用选项(--class-path, -classpath)来指定依赖库文件就好啦

    PS ...> java --class-path=".;.\lib\*" Main
    student:Main$Student@6aceb1a5
    studentFromJson:Main$Student@12bc6874
    student.name.equales(studentFormJson.name):true
    PS ...> java -classpath ".;.\lib\*" Main
    student:Main$Student@6aceb1a5
    studentFromJson:Main$Student@12bc6874
    student.name.equales(studentFormJson.name):true
    student.age == studentFromJson.age:true
    PS ...> java -cp ".;.\lib\*" Main
    student:Main$Student@6aceb1a5
    studentFromJson:Main$Student@12bc6874
    student.name.equales(studentFormJson.name):true
    student.age == studentFromJson.age:true
    

    主要这里需要使用 . java 命令在 JDK 5 开始默认是在当前目录了。但是这里指定了 classpath,所以需要另外设置一下,不然找到了 gson 库,找不到 Main 了,可以自己执行一下 java -cp ".\lib\*" Main 命令

  8. 一个最简单的记事本加上命令行的示例就结束啦,但是有什么用呢?

    在一些情况使用 SpringBoot 编译出生产运行的 Jar 包可能会上百MB,但是一般项目在进行到后期后,不会在有过多的依赖变动,那么通过将项目的依赖包提前部署在服务器上,不将依赖打包到运行的 Jar 内,在运行 Jar 程序时手动指定依赖的位置能使生产 jar 包的体积缩小的几 MB 甚至更小

使用 IDEA 进行依赖管理

注意指的是不用 Maven 和 Gradle 的情况,本文也不会涉及这两个项目构建工具

直接使用 IDEA 打开之前编辑的 Main.java 所在的文件夹,然后如果使用的 IDEA 的版本过高(🐶),那么它可能已经自动帮你识别到了 lib 文件下面的 Gson Jar 文件,并添加到了库路径

查看方法:

  • 右上角有一个 Project Structure
  • 使用快捷键 Ctrl + Shift + Alt + S

然后如果这个依赖里面有 gson 了,那就是可以直接打开 Main.java 如果直接点击绿色的箭头,或者按 Ctrl + Shift + F10 直接运行

image-20221130192700362

运行效果

C:\Users\twat1\Documents\Work\Tools\JDK\jdk-19.0.1\bin\java.exe -javaagent:C:\Users\twat1\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-0\223.7571.123\lib\idea_rt.jar=50262:C:\Users\twat1\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-0\223.7571.123\bin -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\Users\twat1\Documents\Work\other\out\production\other;C:\Users\twat1\Documents\Work\other\lib\gson-2.10.jar Main
student:Main$Student@77f03bb1
studentFromJson:Main$Student@7a92922
student.name.equales(studentFormJson.name):true
student.age == studentFromJson.age:true

怎么做到的呢?

看 IDEA 运行命令,精简一下就是

java -javaagent:... [VM Args] -classpath "...\other;...\other\lib\gson-2.10.jar" Main

java 都知道

-javaagent 是什么呢,我也不知道,好像是字节插桩(🐶等我去瞅瞅),这里不重要

-classpath 就是刚刚我们上面写过的了,不过这里没有使用 *,而是直接使用的 Jar 名,因为 IDEA 只会使用你指定了依赖,通过上面图的 + 号添加依赖

Main 程序的入口类名

注意看上图的左边的 Libraries 选项卡,这里是指定的项目的库,有时候可能模块不一定引入了,如果模块运行缺少了Jar文件,记得去上图的 Dependencies 下查看是否有对于的依赖 Jar 包

IDEA + Tomcat 组合使用

这里就不从 0 到 1 创建 Web 项目了,我们只需要知道 Tomcat 会读取 WEB-INF\lib 下面的 lib 库,所以在一般情况下,可以直接将 Jar 放入 lib 文件夹下,IDEA一般情况下会自动识别,然后提供语法高亮,但是每一个项目都要存储一个 Jar 文件,不是很方便,这个 IDEA想到了,所以只需要和上面一样,将库文件添加到模块依赖,然后在 项目结构的 Artifacts 选项卡里把对应的依赖,添加到 lib 目录下,那么IDEA 在运行 Tomcat 时,会自动将库文件夹添加到 lib 文件夹下

image-20221130195120240

所以就是如果项目运行时出现 NoClassDefFoundError,检查对应的工件 lib 有没有 Jar 或者库文件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值