VIP创新项目1课程总结2021-2022学年第1学期(1)

简介: 文章目录VIP创新项目1课程总结2021-2022学年第1学期1. Java基础1.1 Java代码是如何执行的1.2Java打包案例1.带package的jar包——直接输出hello

VIP创新项目1课程总结2021-2022学年第1学期

1. Java基础

1.1 Java代码是如何执行的

Java执行过程如下图:


  1. 在指定目录下,编写Java代码,Hello.java源代码如下:
class Hello{ 
public static void main(String[] agrs){ 
     System.out.println("hello"); 
  } 
}

编译java源代码

当java源程序编码结束后,就需要编译器编译。

安装好jdk后,我们打开jdk目录,有两个.exe文件,即javac.exe(编译源代码,xxx.java文件) 和 java.exe(执行字节码,xxx.class文件).



用命令行进入到该目录下,编译这个文件javac Hello.java

F:\你的工程所在路径>javac Hello.java
  1. 将编译后的Hello.class文件打成jar包
    jar -cvf hello.jar Hello.class
    c表示要创建一个新的jar包,v表示创建的过程中在控制台输出创建过程的一些信息,f表示给生成的jar包命名
 F:\你的工程所在路径> jar -cvf hello.jar Hello.class
 已添加清单
 正在添加: Hello.class(输入 = 409) (输出 = 280)(压缩了 31%)
  1. 运行jar包
    java -jar hello.jar 这时会报如下错误 hello.jar中没有主清单属性
F:\你的工程所在路径>java -jar hello.jar
hello.jar中没有主清单属性
  • 解决办法1:java -classpath hello.jar Hello
  • 解决办法2:添加Main-Class属性

最后一样一定要回车,空一行,不然无法识别最后一行的配置。


Manifest-Version、Main-Class和Class-Path后面跟着一个英文的冒号,冒号后面必须跟着一个空格,然后才是版本号、类和ClassPath。


Class-Path中的各项应使用空格分隔,不是逗号或分号。


Class-Path中如果有很多项,写成一行打包的时候会报错line too long,这时需要把Class-Path分多行写。注意:从第二行开始,必须以两个空格开头,三个以上我没试过,不过不用空格开头和一个空格开头都是不行的,我已经试过了。


Class-Path写完之后最后一定要有一个空行。


jar包内有些配置文件想放在jar包外面,比如文件config.properties:如果这个文件是以路径方式载入的,比如new file("./config/config.properties"),那么将config.properties放在jar包相同目录下的config目录下即可,也就是说“./”路径等价于jar包所在目录;如果这个文件是以ClassPath下的文件这种方式载入的,比如在Spring中载入classpath:config.properties,则在MF文件的配置文件的ClassPath中添加“./”,然后将这个配置文件与jar包放在同一个目录即可,当然也可以在MF文件的配置文件的ClassPath中添加“./config/”,然后把配置文件都放在jar包相同目录下的config目录下。

用压缩软件打开hello.jar,会发现里面多了一个META-INF文件夹,里面有一个MENIFEST.MF的文件,用记事本打开

    Manifest-Version: 1.0
    Created-By: 1.8.0_121 (Oracle Corporation)
    Main-Class: Hello

在第三行的位置写入 Main-Class: Hello (注意冒号后面有一个空格,整个文件最后有一行空行),保存

再次运行

java -jar hello.jar

此时成功在控制台看到 hello ,成功


备注:

.jar分2种,有一种只是当作调用包;另外一种是可以直接执行,类似.exe。

但是一般可直接执行的*.jar文件,用winrar等解压软件打开会发现都有一个META-INF的文件夹,这个文件夹中必须有个MANIFEST.MF文件,这个文件主要是用来描述可执行的*.jar的执行入口文件(通常是含有main()方法的类文件),格式大体如下:

Manifest-Version: 1.0
Created-By: 1.4.2_08 (Sun Microsystems Inc.)
Main-Class: Main

这边Main既是运行类,含有main()方法的一个类文件,名字为Main.class。

1.2Java打包案例

1.带package的jar包——直接输出hello

方法步骤

(0)创建目录F:\Example_Project

(1)创建edu.hncj.vip目录,用记事本写一个Hello.java的文件

package edu.hncj.vip;
class Hello{
     public static void main(String[] agrs){
         System.out.println("hello");
     }
}

(2)用命令行进入到该目录下,编译这个文件javac -d . Hello.java

F:\Example_Project\edu\hncj\vip>javac -d . Hello.java

javac -d . 中 -d参数:编译时,同时由系统自动生成package目录 .参数:指定Hello.java类的包名 将要生成在哪个目录下,.表示当前目录,可以任意指定

(3)将编译后的Hello.class文件打成jar包

jar -cvf hello.jar edu\hncj\vip\
F:\Example_Project\edu\hncj\vip>jar -cvf hello.jar edu\hncj\vip\
已添加清单
正在添加: edu/hncj/vip/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: edu/hncj/vip/Hello.class(输入 = 422) (输出 = 292)(压缩了 30%)

c表示要创建一个新的jar包,v表示创建的过程中在控制台输出创建过程的一些信息,f表示给生成的jar包命名

(4)运行jar包

   java -jar hello.jar

这时会报如下错误 hello.jar中没有主清单属性

用压缩软件打开hello.jar,会发现里面多了一个META-INF文件夹,里面有一个MENIFEST.MF的文件,用记事本打开

添加Main-Class属性

Manifest-Version: 1.0
Created-By: 1.8.0_181 (Oracle Corporation)
Main-Class: edu.hncj.vip.Hello

在第三行的位置写入 Main-Class: Hello (注意冒号后面有一个空格,整个文件最后有一行空行),保存

再次运行 java -jar hello.jar ,此时成功在控制台看到 hello ,成功

2.含有两个类的jar包——通过调用输出hello

(0)创建目录F:\Example_Project\两个类的jar>

(1)用记事本写一个Hello.java和一个Student.java的文件

目的是让Hello调用Student的speak方法

class Hello{
     public static void main(String[] agrs){
         //System.out.println("hello");
     Student.speak();
     }
}
class Student{
    public static void speak(){
        System.out.println("hello,I'm 20级学生 ");
    }
}

(2)编译: javac -encoding UTF-8 Hello.java


此时Hello.java和Student.java同时被编译,因为Hello中调用了Student,在编译Hello的过程中发现还需要编译Student

F:\Example_Project\两个类的jar>javac -encoding UTF-8 Hello.java

(3)打jar包


在F:\Example_Project\两个类的jar>下创建META-INF文件夹


F:\Example_Project\两个类的jar>mkdir META-INF


在META-INF下创建MANIFEST.MF


F:\Example_Project\两个类的jar>type nul>META-INF\MANIFEST.MF

这次我们换一种方式直接定义Main-Class。


Manifest-Version: 1.0
Created-By: 1.8.0_121 (Oracle Corporation)
Main-Class: Hello


事先准备好上述的MANIFEST.MF文件,并存放在META-INF文件夹下,此时打jar包的命令如下

F:\Example_Project\两个类的jar> jar -cvfm hello.jar META-INF\MANIFEST.MF Hello.class Student.class
已添加清单
正在添加: Hello.class(输入 = 293) (输出 = 223)(压缩了 23%)
正在添加: Student.class(输入 = 408) (输出 = 308)(压缩了 24%)

jar -cvfm hello.jar META-INF\MANIFEST.MF Hello.class Student.class命令解释如下:

表示用第一个文件当做MENIFEST.MF文件,hello.jar作为名称,将Hello.class和Student.class打成jar包。其中多了一个参数m,表示要定义MANIFEST文件

(4)运行 java -jar hello.jar ,此时成功在控制台看到 hello ,成功

F:\Example_Project\两个类的jar> java -jar hello.jar
hello,I'm 20级学生

3.有目录结构的jar包——通过引包并调用输出hello

(0)创建文件夹

F:\Example_Project\有目录结构的两个类jar(1)我们将上一个稍稍变化一下,将Student这个类放在edu.hncj.vip包下,Hello放在com包下

修改Hello.java文件

package com;
import edu.hncj.vip.Student;
class Hello{
     public static void main(String[] agrs){
         //System.out.println("hello");
     Student.speak();
     }
}

修改Student.java文件,注意需要修改为public公共类

package edu.hncj.vip;
public class Student{
    public static void speak(){
        System.out.println("hello,I'm 20级学生 ");
    }
}

查看当前目录结构

F:\Example_Project\有目录结构的两个类jar>tree .  /f  /a
卷 工作 的文件夹 PATH 列表
卷序列号为 00000057 5296:88B3
F:\EXAMPLE_PROJECT\有目录结构的两个类JAR
+---com
|       Hello.java
|
\---edu
    \---hncj
        \---vip
                Student.java

方法步骤

(1)编译Hello.java

javac -encoding UTF-8 -d . com\Hello.java

编译Hello.java时,自动编译Student.java文件

(2)打jar包,同样准备好MANIFEST文件

在F:\Example_Project\两个类的jar>下创建META-INF文件夹

F:\Example_Project\有目录结构的两个类jar>mkdir META-INF

在META-INF下创建MANIFEST.MF

F:\Example_Project\有目录结构的两个类jar>type nul>META-INF\MANIFEST.MF

这次我们换一种方式直接定义Main-Class。注意后面的空行

Manifest-Version: 1.0
Created-By: 1.8.0_121 (Oracle Corporation)
Main-Class: com.Hello
此处有空行

事先准备好上述的MANIFEST.MF文件,并存放在META-INF文件夹下,此时打jar包的命令如下

jar -cvfm hello.jar META-INF\MANIFEST.MF com\Hello.class edu\hncj\vip
F:\Example_Project\有目录结构的两个类jar>jar -cvfm hello.jar META-INF\MENIFEST.MF com\Hello.class edu\hncj\vip
已添加清单
正在添加: com/Hello.class(输入 = 310) (输出 = 238)(压缩了 23%)
正在添加: edu/hncj/vip/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: edu/hncj/vip/Student.class(输入 = 421) (输出 = 319)(压缩了 24%)
正在添加: edu/hncj/vip/Student.java(输入 = 146) (输出 = 130)(压缩了 10%)

输出信息表示已经把哪些文件打包在hello.jar中

(3)运行 java -jar hello.jar ,此时成功在控制台看到 hello ,成功

4.制作含有jar文件的jar包

我们将场景稍稍变得复杂一点,看看jar包中需要引入其他jar包的场景


1、两个jar包间相互调用——调用jar外的jar输出hello


最终生成的jar包结构


hello.jar

tom.jar


方法步骤


(0)生成student.jar


准备:创建Student.java文件

public class Student{
    public static void speak(){
        System.out.println("hello,I'm 20级学生 ");
    }
}

在Student.java同级目录下打开cmd

执行如下命令编译java文件


javac -encoding UTF-8 Student.java


执行jar -cvf student.jar Student.class 命令生成jar包


F:\Example_Project\两个jar相互调 用>javac -encoding UTF-8 Student.java
F:\Example_Project\两个jar相互调 用>jar -cvf student.jar Student.class
已添加清单
正在添加: Student.class(输入 = 408) (输出 = 307)(压缩了 24%)

(1)编写一个Hello.java并将其编译成Hello.class,注意,由于Hello里面引用了Student类的speak方法,因此在打jar包时应使用-cp参数,将student.jar包引入


Hello.java文件内容:
class Hello{
     public static void main(String[] agrs){
         //System.out.println("hello");
   Student.speak();
     }
}

执行 javac命令编译Hello.java

如果直接编译Hello.java会提示如下错误


F:\Example_Project\两个jar相互调用>javac  Hello.java
Hello.java:5: 错误: 找不到符号
                Student.speak();
                ^
符号:   变量 Student
位置: 类 Hello
 1 个错误

可以在编译Hello.java的同时,把依赖的jar放在classpath下


 F:\Example_Project\两个jar相互调 用>javac -cp student.jar Hello.java

这里的 -cp 表示 -classpath,指的是把student.jar加入classpath路径下

(2)将hello.class达成jar包

创建META-INF目录,创建MANIFEST.MF 文件,注意末尾的空行

Manifest-Version: 1.0
Created-By: 1.8.0_181 (Oracle Corporation)
Main-Class: Hello
这里有空行

达成jar包,执行jar -cvfm hello.jar META-INF/MANIFEST.MF hello.class


F:\Example_Project\两个jar相互调 用>jar -cvfm hello.jar META-INF/MANIFEST.MF Hello.class
已添加清单
正在添加: Hello.class(输入 = 293) (输出 = 223)(压缩了 23%)

目前可以顺利的达成jar包,但运行时会出错,如下。

(3)此时运行 java -jar 发现报错 ClassNotFoundException:Student

F:\Example_Project\两个jar相互调 用>java -jar hello.jar
Exception in thread "main" java.lang.NoClassDefFoundError: Student
        at Hello.main(Hello.java:5)
Caused by: java.lang.ClassNotFoundException: Student
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 1 more

原因很简单,引入jar包需要在MENIFEST.MF文件中配置一个新属性:Class-Path,路径指向你需要的所有jar包

现在打开hello.jar中MENIFEST.MF文件,添加Class-Path。应该变成

Manifest-Version: 1.0
Created-By: 1.8.0_121 (Oracle Corporation)
Main-Class: Hello
Class-Path: student.jar

(4)好了,修改这个文件,再次运行,发现成功在控制台输出 hello


tips:引入多个jar包,中间用空格隔开


至此,我们可以总结出,命令变化如下


javac -cp xxx.jar 要编译的文件 -d 目标位置


jar -cvfm 命名 MENIFEST文件 要打包的文件1 要打包的文件2


5.jar包中含有jar包——调用jar内的jar输出hello

当项目中我们把所需要的第三方jar包也打进了我们自己的jar包中时,如果仍然按照上述操作方式,会报找不到Class异常。原因就是jar引用不到放在自己内部的jar包。

这种情况的具体实现细节比较复杂,可以先参考这篇文章:


http://www.cnblogs.com/adolfmc/archive/2012/10/07/2713562.html


引用方法1:使用AppClassloader来加载


引用方法2:也可以把需要加载的jar都扔到%JRE_HOME%/lib/ext下面,这个目录下的jar包会在Bootstrap Classloader工作完后由Extension Classloader来加载。非常方便,非常省心。


(1)本部分使用AppClassloader加载


在F:\Example_Project\jar包内含有jar包 的目录下创建edu.hncj.vip.Student.java

package edu.hncj.vip;
public class Student{
    public static void speak(){
        System.out.println("hello,I'm 20级学生 ");
    }
}

(2)生成student.jar文件

编译Student.java文件,执行 javac -d . -encoding UTF-8 edu/hncj/vip/Student.java命令

F:\Example_Project\jar包内含有jar包>javac -d . -encoding UTF-8 edu/hncj/vip/Student.java

生成student.jar包,jar -cvf student.jar edu\hncj\vip\

F:\Example_Project\jar包内含有jar包>jar -cvf student.jar edu\hncj\vip\
已添加清单
正在添加: edu/hncj/vip/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: edu/hncj/vip/Student.class(输入 = 421) (输出 = 319)(压缩了 24%)
正在添加: edu/hncj/vip/Student.java(输入 = 146) (输出 = 130)(压缩了 10%)

在 F:\Example_Project\jar包内含有jar包 目录下创建lib目录,把student放置在lib目录下



相关文章
|
10月前
|
JavaScript 安全 前端开发
【实训项目】精点考研
【实训项目】精点考研
105 0
|
3月前
|
存储 JavaScript 前端开发
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)
|
4月前
|
SQL 安全 调度
网安预习课程笔记(九到十节)
本文是一篇关于渗透测试案例的分享,案例主要包括弱口令、SQL注入、内网渗透等多个环节,详细描述了渗透测试工作者如何通过一系列步骤获取不同服务器和系统的管理员权限。提到了一些关键的IP地址、数据库和服务器的发现,以及利用这些漏洞如何获取的权限。文章最后讨论了漏洞报告的组成部分,强调了报告的规范性和清晰度对于有效沟通和解决问题的重要性。 请注意,由于原始内容包含多个图片和链接,摘要中并未包含这些元素。
56 11
|
机器学习/深度学习 人工智能 安全
IT专业报考指南:选择正确的学校和课程
随着高考的技术,男怕入错行,女怕嫁错郎,专业的选择也是至关重要的,当准备报考IT专业时,选择适合自己的学校和课程是至关重要的一步。随着信息技术的快速发展和应用范围的不断扩大,IT行业的就业前景变得更加广阔。然而,在众多学校和课程中做出明智的选择并不容易。这就是为什么一个全面的报考指南对于帮助你确定正确的学校和课程至关重要。
72 0
|
Dubbo Java 应用服务中间件
VIP创新项目1课程总结2021-2022学年第1学期(3)
文章目录 VIP创新项目1课程总结2021-2022学年第1学期 1. Java基础 1.1 Java代码是如何执行的 1.2Java打包案例 1.带package的jar包——直接输出hello
VIP创新项目1课程总结2021-2022学年第1学期(3)
|
SQL 存储 分布式计算
Hadoop大数据技术课程总结2021-2022学年第1学期(下)
文章目录 Hadoop大数据技术课程总结 1.大数据概述 1.1大数据时代的4V 1.2大数据时代的三次浪潮
Hadoop大数据技术课程总结2021-2022学年第1学期(下)
|
存储 SQL 分布式计算
Hadoop大数据技术课程总结2021-2022学年第1学期(上)
文章目录 Hadoop大数据技术课程总结 1.大数据概述 1.1大数据时代的4V 1.2大数据时代的三次浪潮
Hadoop大数据技术课程总结2021-2022学年第1学期(上)
|
SQL 分布式计算 资源调度
Hadoop大数据技术课程总结2021-2022学年第1学期(中)
文章目录 Hadoop大数据技术课程总结 1.大数据概述 1.1大数据时代的4V 1.2大数据时代的三次浪潮
Hadoop大数据技术课程总结2021-2022学年第1学期(中)
|
运维 前端开发 小程序
自己学校里的实训做笔记
自己学校里的实训做笔记
自己学校里的实训做笔记
|
网络安全 Windows
千峰课程网安笔记(1)
1如何使两台虚拟机在同一局域网下互Ping以及关于单方面ping通的解决办法
108 0
千峰课程网安笔记(1)