一、制作只含有字节码文件的jar包
1、最简单的jar包——直接输出hello
2、含有两个类的jar包——通过调用输出hello
3、有目录结构的jar包——通过引包并调用输出hello

二、制作含有jar文件的jar包
1、两个jar包间相互调用——调用jar外的jar输出hello
2、jar包中含有jar包——调用jar内的jar输出hello

三、制作含有资源文件的jar包
1、资源文件在jar包内部——读取jar内的文件
2、资源文件在另一个jar包内部——读取另一个jar内的文件
3、资源文件在jar包外部——读取jar外的文件

正文:

一、制作只含有字节码文件的jar包

我们先来看只含有字节码文件,即只含有class文件的jar包怎么制作,这是最简单的形式

1、最简单的jar包——直接输出hello

最终生成的jar包结构

META-INF
Hello.class

方法步骤

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

1 class Hello{
2 public static void main(String[] agrs){
3 System.out.println("hello");
4 }
5 }

(2)用命令行进入到该目录下,编译这个文件

   javac Hello.java

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

   jar -cvf hello.jar Hello.class

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

(4)运行jar包

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

  添加Main-Class属性

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

1 Manifest-Version: 1.0
2 Created-By: 1.8.0_121 (Oracle Corporation)
3

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

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

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

最终生成的jar包结构

META-INF
Tom.class
Hello.class

方法步骤

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

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

1 class Hello{
2 public static void main(String[] agrs){
3 Tom.speak();
4 }
5 }
1 class Tom{
2 public static void speak(){
3 System.out.println("hello");
4 }
5 }

(2)编译: javac Hello.java

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

(3)打jar包,这次我们换一种方式直接定义Main-Class。

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

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

   jar -cvfm hello.jar META-INF\MENIFEST.MF Hello.class Tom.class

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

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

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

最终生成的jar包结构

META-INF
com
 Tom.class
Hello.class

  我们将上一个稍稍变化一下,将Tom这个类放在com包下,源文件目录结构变成

    com
     Tom.java
    Hello.java

  同时Tom.java需要在第一行声明自己的包名

package com;

  Hello.java需要引入Tom这个类,同样要在第一行进行import

import com.Tom;

方法步骤

(1)编译Hello.java

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

   jar -cvfm hello.jar META-INF\MENIFEST.MF Hello.class com

  注意,最后一个com表示把com这个文件夹下的所有文件都打进jar包

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

(4)优化过程

  我们注意到,com包下是有Tom.java源文件的,也被打进了jar包里,这样不太好,能不能优化一下javac命令,使所有的编译后文件编译到另一个隔离的地方呢,答案是可以的。

  在编译Hello.java时,先新建一个target文件夹。然后我们用如下命令

     javac Hello.java -d target

  该命令表示,将所有编译后的文件,都放到target文件夹下。

  将META-INF文件夹也复制到target目录下,进入这个目录,输入如下命令

     jar -cvfm hello.jar META-INF\MENIFEST.MF *

  注意最后一个位置变成了*,表示把当前目录下所有文件都打在jar包里

  优化完毕

至此,我们可以总结出,制作一个只含有class字节码文件的jar包,以下命令足以

javac 要编译的文件 -d 目标位置

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

二、制作含有jar文件的jar包

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

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

最终生成的jar包结构

hello.jar
tom.jar

方法步骤

准备:将上述一中写好的那个不带包的tom.jar复制过来(目的是调用里面的speak方法)

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

    javac -cp tom.jar Hello.class

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

(2)将hello.class达成jar包,步骤略

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

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

  现在MENIFEST.MF这个文件应该变成

1 Manifest-Version: 1.0
2 Created-By: 1.8.0_121 (Oracle Corporation)
3 Main-Class: Hello
4 Class-Path: Tom.jar
5

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

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

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

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

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

2、jar包中含有jar包——调用jar内的jar输出hello

最终生成的jar包结构

META-INF
Hello.class
tom.jar

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

  这种情况的具体实现细节比较复杂,我会在后一篇介绍一些知名的java应用是如何加载jar包的,来说明这种情况。实现方式的简单说明,可以先参考这篇文章:

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

三、制作含有资源文件的jar包

1、资源文件在jar包内部——读取jar内的文件

最终生成的jar包结构

META-INF
Hello.class
text.txt

方法步骤

 1 import java.io.InputStream;
2 import java.io.BufferedReader;
3 import java.io.InputStreamReader;
4
5 class Hello{
6 public static void main(String[] args) throws Exception{
7 Hello hello = new Hello();
8 InputStream is = hello.getClass().getResourceAsStream("text.txt");
9 print(is);
10 }
11
12 /**
13 * 读取文件,输出里面的内容,通用方法
14 */
15 public static void print(InputStream inputStream) throws Exception {
16 InputStreamReader reader = new InputStreamReader(inputStream, "utf-8");
17 BufferedReader br = new BufferedReader(reader);
18 String s = "";
19 while ((s = br.readLine()) != null)
20 System.out.println(s);
21 inputStream.close();
22 }
23 }

2、资源文件在另一个jar包内部——读取另一个jar内的文件

最终生成的jar包结构

hello.jar
resource.jar
 text.txt

方法步骤

同1一样,只不过需要在MENIFEST文件中将resource.jar加入classpath

 1 import java.io.InputStream;
2 import java.io.BufferedReader;
3 import java.io.InputStreamReader;
4
5 class Hello{
6 public static void main(String[] args) throws Exception{
7 Hello hello = new Hello();
8 InputStream is = hello.getClass().getResourceAsStream("text.txt");
9 print(is);
10 }
11
12 /**
13 * 读取文件,输出里面的内容,通用方法
14 */
15 public static void print(InputStream inputStream) throws Exception {
16 InputStreamReader reader = new InputStreamReader(inputStream, "utf-8");
17 BufferedReader br = new BufferedReader(reader);
18 String s = "";
19 while ((s = br.readLine()) != null)
20 System.out.println(s);
21 inputStream.close();
22 }
23 }

3、资源文件在jar包外部——读取jar外的文件

最终生成的jar包结构

hello.jar
text.txt

方法步骤

 1 import java.io.InputStream;
2 import java.io.BufferedReader;
3 import java.io.InputStreamReader;
4 import java.io.FileInputStream;
5
6 class Hello{
7 public static void main(String[] args) throws Exception{
8 Hello hello = new Hello();
9 InputStream is = new FileInputStream("text.txt");
10 print(is);
11 }
12
13 /**
14 * 读取文件,输出里面的内容,通用方法
15 */
16 public static void print(InputStream inputStream) throws Exception {
17 InputStreamReader reader = new InputStreamReader(inputStream, "utf-8");
18 BufferedReader br = new BufferedReader(reader);
19 String s = "";
20 while ((s = br.readLine()) != null)
21 System.out.println(s);
22 inputStream.close();
23 }
24 }

如何打jar包的更多相关文章

  1. spring各jar包作用(转载)

     除了spring.jar文件,Spring还包括有其它13个独立的jar包,各自包含着对应的Spring组件,用户可以根据自己的需要来选择组合自己的jar包,而不必引入整个spring.jar的所有 ...

  2. Maven中安装本地Jar包到仓库中或将本地jar包上传

    摘要 maven install 本地jar 命令格式 mvn install:install-file -DgroupId=<group_name> -DartifactId=<a ...

  3. 不显示cmd窗口运行jar包

    今天,打开导出的jar包,发现并不能运行,查看jar包中的META-INF文件夹下的MANIFEST.MF文件,发现MANIFEST.MF中并没有Main-Class,于是,就手动添加相应的信息,本项 ...

  4. 由提交storm项目jar包引发对jar的原理的探索

    序:在开发storm项目时,提交项目jar包当把依赖的第三方jar包都打进去提交storm集群启动时报了发现多个同名的文件错误由此开始了一段对jar包的深刻理解之路. java.lang.Runtim ...

  5. 第三方开源库和jar包的区别

    jar包和第三方开源库的根本区别在于,开源库的功能比jar包功能更强大,通过引入库项目可以访问java文件以及该开源库项目下的资源文件,例如图片,layout等文件 jar包中只能放class文件 引 ...

  6. 在 CentOS7 上将自定义的 jar 包注册为 linux 服务 service

    在 CentOS7 上将自定义的 jar 包注册为 linux 服务 service 1.在 /etc/rc.d/init.d/ 目录下创建一个名字和服务名完全相同的 shell 脚本文件 joyup ...

  7. java 执行 jar 包中的 main 方法

    java 执行 jar 包中的 main 方法 通过 OneJar 或 Maven 打包后 jar 文件,用命令: java -jar ****.jar执行后总是运行指定的主方法,如果 jar 中有多 ...

  8. maven 打包含有第三方依赖的 jar 包

    maven 打包含有第三方依赖的 jar 包:mvn assembly:assembly

  9. 使用maven给spring项目打可直接运行的jar包(配置文件内置外置的打法)

    从网上看过许多打jar包的例子,大多是将配置文件打进jar包的.经过本人一番研究,终于搞清楚了怎样将jar包的配置文件外置. 废话不说,直接上spring的pom.xml的配置文件. <proj ...

  10. struts2中各个jar包作用

    Struts2.3.4 所需的Jar包及介绍 Jar包的分类 jar包名称 jar包版本 jar包 文件名 jar包 的作用 jar包内包含的主要包路径及主要类 依赖的自有jar包名称 依赖的第三方j ...

随机推荐

  1. String类、常量池、字符串比较

    String类.常量池.字符串比较 一:String类           1.String类又称作不可变字符序列           2.String位于java.lang包中,Java程序默认导入 ...

  2. centos7上安装cacti监控

     简介 在企业网络运维过程中,管理员必须时刻关注服务器的运行状态,如CPU.内存.磁盘空间使用情况等.为了能够及时的发现问题,尽量减少故障的发生.当网络中的设备,服务器等数量较多时,可以部署一套监控系 ...

  3. Tools - OpenSSL

    OpenSSL http://www.openssl.org/ OpenSSL is an open source project that provides a robust, commercial ...

  4. python 开发环境配置

    上篇文章配置了虚机基础环境,本篇文章介绍配置python开发环境 配置YUM源 使用国内yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos ...

  5. Nginx+apache/Tomcat实现反向代理与动静分离

    其实本人比较喜欢nginx跑静态和做负载反向代理,动态php还是交给apache处理比较稳定,jsp就交给tomcat.resin或jboss.nginx跑静态的能力是无与伦比的,是目前web服务器里 ...

  6. 用DDD模拟案例分析

    之前我写了几篇关于DDD的介绍和一些小例子说明,我想这对于介绍DDD还是有些模糊,甚至还不知道怎么用DDD来分析设计.昨天和园友讨论也发现没有例子很难说明,所以今天我模拟了一个案例,同时这个案例也是真 ...

  7. 我是如何利用Github Pages搭建起我的博客,细数一路的坑

    1.前言 其实早在这之前我就一直想过写博客,但由于种种原因一直没有去学习这方面的知识,最近半个月(从开始动手到搭建好)一直陆陆续续的在着手这方面的工作.从开始到搭建完成的过程中遇到了很多困难,因为在这 ...

  8. SignalR 中使用 MessagePack 序列化提高 WebSocket 通信性能

    It's like JSON.but fast and small. MessagePack is an efficient binary serialization format. It lets ...

  9. Spring Framework简介

    作者关于此主题早期文章 Spring框架快速入门 起源 要谈Spring的历史,就要先谈J2EE.J2EE应用程序的广泛实现是在1999年和2000年开始的,它的出现带来了诸如事务管理之类的核心中间层 ...

  10. leetcode — longest-palindromic-substring

    import java.util.Arrays; /** * Source : https://oj.leetcode.com/problems/longest-palindromic-substri ...