命令行下Jar包打包小结

  • jar包打包实现

    • 第一种简单的打包方式
    • 第二种打包方式
    • MANIFEST文件介绍
  • 小结

jar包打包实现

jar包打包可以使用jar指令实现打包,在命令行中输入jar可以查看jar指令的内容

从最后显示的两个示例看出存在两种打包的方法,两者的区别就是是否使用自己定义的MANIFEST清单文件。第一个示例没有使用MANIFEST文件进行打包,所以最终生成的jar包中MANIFEST文件为默认文件,这种方式适用于比较简单的jar包结构,不存在其他jar包依赖以及生成的jar包不需要可执行。这种方式生成的jar包不能使用java -jar XXX.jar命令执行,因为MANIFEST文件中未指定程序入口。而第二个实例是比较常用的打包方式,即是使用自定义的MANIFEST文件参与打包,这样能够实现往包中添加依赖,并且可以指定程序入口,实现java -jar XXX.jar 直接运行jar包。

第一种简单的打包方式

最简单的就是在当前文件夹下将编译的class字节码文件进行打包输出。示例如下:

编写三个java文件,test1.java test2.java 以及Main.java

public class test1
{
    public static void main(String[] args)
    {
    }
    public void display()
    {
        System.out.println("this is class test1");
    }
}

以及test2.java 文件

public class test2
{
    public static void main(String[] args)
    {
    }
    public void display()
    {
        System.out.println("this is class test2");
    }
}

Main.java

public class Main
{
    public static void main(String[] args)
    {
        for(String a:args)
        {
            System.out.println("给定的参数"+a);
        }
        test1 t1 = new test1();
        t1.display();
        test2 t2 = new test2();
        t2.display();
    }
}

命令行下将这三个文件进行编译,使用javac命令实现编译。

用jar指令将编译的class文件打包

打包过程中有显示已添加清单。用解压工具打开生成的test.jar包,可以看到如下的结构:

除了编译的三个class文件外多了一个META-INF文件夹,里面有一个MANIFEST.MF(清单文件)的文件,这个文件的作用非常重要,后面说明。我们先看它里面的内容

非常简单的清单,只包含清单版本与java版本。

这个时候执行java -jar test.jar有如下效果:

没有主清单属性报错。这是因为我们使用第一种方法生成jar使用了默认的清单,默认清单没有指定程序入口,所以出错。

可以直接更改jar包中的MANIFEST文件(解压工具打开,更改后保存),改成如下效果:

再一次执行java -jar test.jar 后程序输入正确内容:

在MANIFEST文件中添加了Main-Class属性指定了程序入口,实现了直接执行jar文件。

所以说使用默认的MANIFEST是不能直接执行jar文件,要么使用自己定义的MANIFEST文件打包,要么更改包中的MANIFEST文件。

第二种打包方式

第二种打包方式更加通用,一般情况下java文件第一行都是package XXX;即是包名,也决定了编译后的class文件存在的路径。当有多个java文件要编译打包并且他们存在不同的包名时,如果还是按照第一种方法打包时一个文件一个文件的写非常不现实,所以有了第二种方法。将所有要打包的class文件存在的目录以及依赖的jar包全部放在一个根文件夹里面(比如是foo),然后编写MANIFEST清单文件,指定程序入口以及其他添加的依赖的jar包。在执行指令:

注意 上面的指令中foo/ 文件夹后面有一个空格还有一个点

下面看一个例子

同样还是test1.java与test2.java以及Main.java 但是各自有自己的包名。

package cn.mytest1;
public class test1
{
    public static void main(String[] args)
    {
    }
    public void display()
    {
        System.out.println("this is class test1");
    }
}
package cn.mytest2;
public class test2
{
    public static void main(String[] args)
    {
    }
    public void display()
    {
        System.out.println("this is class test2");
    }
}
package cn.mymain;
import cn.mytest1.test1;
import cn.mytest2.test2;
public class Main
{
    public static void main(String[] args)
    {
        for(String item:args)
        {
            System.out.println("传递参数"+item);
        }
        test1 t1 = new test1();
        test2 t2 = new test2();
        t1.display();
        t2.display();
    }
}

同样使用javac 指令编译,三个class文件存在于不同的路径下,因为他们包名不一样。把编译号的含有class文件的文件夹全部放在foo文件夹下:

然后在foo 外面写一个MANIFEST文件:

MANIFEST内容如下:

注意:MANIFEST 文件最后一行是空行。

命令行下执行指令:jar cvfm test.jar MANIFEST.MF -C foo/ .

在命令行下测试jar包是否能够直接运行了,使用指令java -jar test.jar

正确打包,成功运行jar.

MANIFEST文件介绍

通过上面的两个例子,可以看到MANIFEST文件对于jar打包都是必须的。MANIFEST文件描述了打包后的jar文件的详细信息,存在于打包后的META-INF 的文件夹.一个简单的MANIFEST文件主要内容如下:

主要就是Manifest-Version Main-Class Class-Path这三个属性在制作jar包时非常重要.Manifest-Version 是版本号,照着写就行。Main-Class则是jar包的入口程序,指定运行的类的全称(一定要包含包名),这样可以使用java -jar name.jar直接运行jar包。第三个Class-Path是指的打包时需要依赖的其他jar包,打包的时候自己的程序中也可能含有其他的jar包所以要添加依赖。

注意每个MANIFEST属性冒号与内容之间都有一个空格,并且写完后最后还要留有一行空行,不然运行时还是出现找不到主清单属性的错误

小结

jar文件打包容易出错的地方就是Manifest清单文件的编写,容易出一些格式上的错误比如属性的冒号和内容之间少空格,Class-Path中添加依赖之间没有空格,依赖文件过多,多行书写的时候每行开头没加空格,文件最后一行没有空行等等。写MANIFEST文件的时候注意这些关键的地方就不会在打包上面耗费太多的时间。

时间: 2024-10-14 17:03:01

命令行下Jar包打包小结的相关文章

Java 命令行运行jar包

nohup  java -jar XX.jar >temp.text & nohup 客户端关闭,后台继续运行 & 客户端关闭,后台停止运行 temp.text 是存控制台文件 , 使用  tail -f temp.text 实时查看

java命令行引入jar包

编译: E:/>javac -cp e:/jdom.jar test1.java 执行: E:/>java -classpath e:/jdom.jar; test1

ubuntu命令行下java工程编辑与算法(第四版)环境配置

ubuntu命令行下java工程编辑与算法(第四版)环境配置 java 命令行 javac java 在学习算法(第四版)中的实例时,因需要安装配套的java编译环境,可是在编译java文件的时候总是出各种错误,特在此总结一下. ubuntu下java环境配置 由于网上教程比较多,而且也较全面,特此摆放一个链接,跟着此教程总就可以配置好oracle的java jdk,如果想更加省事,直接在命令行下键入java,会提示安装各种开源java jdk,只需要一个命令即可: sudo apt-get i

JNI之——在cmd命令行下编译执行C/C++源文件

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46604269 一直用java来敲代码,java配置好jre路径之后.在cmd下编译执行.非常方便. 刚好要给一个舍友改下C程序,想到可不能够像java一样在环境变量里配置好C的编译路径呢? 于是上网搜了一下,得到例如以下结果: 一.假设装有VC,那就简单了,由于VC带有C的编译器,能够将此路径设置进环境变量. Windows系统下编译连接源码方法: cl -GX test.c -

在命令行执行带包名的Java程序

之前关于如何在命令行运行带包名的java文件的问题,一直搞不懂,直到今天终于明白了是怎么一回事. 以下是我的程序代码 package bonn.thread; import java.sql.SQLOutput; /** * Created by Lin-953 on 2016/1/15. */ public class TestThread { public static void main(String[] args) { Runner r = new Runner(); Thread t

【Python】iichats —— 命令行下的局域网聊天程序

转载请声明出处:http://www.cnblogs.com/kevince/p/3941728.html   ——By Kevince ii系列工具第三弹,命令行下的局域网聊天程序 原理: 程序启动时向全网(255.255.255.255)BACKPORT端口广播自己的主机名以及状态(上线). 如果接受收到的上线状态,则将其加入通信列表,同时返还一个数据包,使自己也将对面加入其通信列表. 程序退出时向全网广播自己的下线状态,如果收到该下线状态则将其从自己的通信列表中删除 为了防止在输入过程中被

JNI之——在cmd命令行下编译运行C/C++源文件

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46604269 一直用java来写程序,java配置好jre路径之后,在cmd下编译运行,很方便. 刚好要给一个舍友改下C程序,想到可不可以像java一样在环境变量里配置好C的编译路径呢? 于是上网搜了一下,得到如下结果: 一.如果装有VC,那就简单了,因为VC带有C的编译器,可以将此路径设置进环境变量. Windows系统下编译连接源代码方法: cl -GX test.c -GX

Maven配置、第三方依赖jar包打包以及Profiles多环境配置

由一次打包部署失败引发的深入探索┑( ̄▽  ̄)┍ 一.Maven配置 1.概览 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/

oracle官网下载老版本jdk + 如何命令行下wget下载jdk

一.文章由来 1.前天有人再去你咨询如何下载jdk的老版本,在oracle官网上找了老半天,找不到相应的选项~ 2.等待问题解决了之后,又抛出来一个新的问题,如何wget直接下载,毕竟百十来兆的文件,下载下来再上传对于我们这种蜗牛带宽来说也是一件苦逼的事情~ 二.如何下载jdk的历史版本 1.访问http://www.oracle.com 2.点击Downloads---->Java for Developers 3.在弹出的的页面中,下拉页面到最下面,点击历史归档 4.点击进去,同意协议,然后