用JDK制作可能运行的JAR

一、前言

对于C来说,我们可以通过编译,连接,然后制作成一个exe文件,这样我们双击制作好的文件就可以直接运行我们的程序了。对于JAVA来说,我们也可以把我们的程序制作成一个JAR文件来运行。网上有很多说JAVA制作成JAR文件来运行的,但还是有一些小地方没有说明,并且大部分例子都是一个简单的Hello World,且不带有包。本文以一个两层包结构为例 org.happymzw.printChoseFileName。程序主要功能是打印一人文件夹及其子文件夹下的所有文件的路径,并且输出到一个result.txt的文件中。

JAVA JAVAC JAR的一些参数

153412_NaOR_1461287.png

153432_w0fH_1461287.png

153449_aW3X_1461287.png

 

二、JAVA 类文件

package org.happymzw;

import java.io.File;
import java.io.FileWriter;
import java.util.Scanner;

/**
 * @author victor.min
 *
 */
public class PrintChoseFileName {

    public static void main(final String[] args) {

        System.out.println("1. print xml name");
        System.out.println("2. print module name");
        System.out.println("3. print sql name");
        System.out.println("4. print full name");
        final Scanner scanner = new Scanner(System.in);

        System.out.print("  -- please input number(1, 2, 3, 4): ");
        final int index = scanner.nextInt();

        System.out.print("  -- please input root folder path: ");
        final String path = scanner.next();

        FileWriter writer = null;
        try {
            final String result = printFileName(new File(path), index);
            final String destPath = path + File.separator + "result.txt";
            writer = new FileWriter(destPath);
            writer.write(result);
            writer.flush();
            System.out.println("==> successful <==\n");
        } catch (final Exception e) {
            System.out.println("==> error occured. <==");
            e.printStackTrace();
        }
    }

    private static String printFileName(final File file, final int type) {
        String result = "";
        if (file.isFile()) {
            final String path = file.getAbsolutePath();
            System.out.println(" --> find file: " + path);
            if (type == 1 && (path.substring(path.lastIndexOf(".")).equalsIgnoreCase(".xml"))) {
                result += path + "\n";
            } else if (type == 2 && (path.substring(path.lastIndexOf(".")).equalsIgnoreCase(".xlsx"))) {
                result += path.substring(path.lastIndexOf(File.separator) + 1, path.lastIndexOf(".")) + "\n";
            } else if (type == 3 && (path.substring(path.lastIndexOf(".")).equalsIgnoreCase(".sql"))) {
                result += "@@" + path + "\ncommit;\n";
            } else if(type == 4) {
                result += path + "\n";
            }
        } else if (file.isDirectory()) {
            for (final File f : file.listFiles()) {
                result += printFileName(f, type);
            }
        }
        return result;
    }
}

 

三、具体操作

1、

编译JAVA文件,本示例路径 C:\Users\victor.min\Desktop\printFileName\PrintChoseFileName.java

cd C:\Users\victor.min\Desktop\printFileName
javac *.java

 

154313_gVv9_1461287.png

154330_8g1m_1461287.png

154341_10pL_1461287.png

这时在C:\Users\victor.min\Desktop\printFileName 路径下会多出一些 class文件

154443_jZ4r_1461287.png

2、创建相应的层结构图

本文中的包为 org.happymzw.PrintChoseFileName

所以创建一个文件夹  src/org/happymzw/, 然后再把刚才编译好的 PrintChoseFileName.class文件放入到src/org/happymzw/中,最后的层结构 为 src/org/happymzw/PrintChoseFileName.class

3,编写相就的manifest.mf 文件,这个很重要,对于可执行JAR来说

155031_J2c8_1461287.png

155111_iZKx_1461287.png

manifest.mf文件中的 main-class: org.happymzw.PringChoseFileName

注:main-class 冒号后面有一个空格,其次,类要包括包名,不然运行的时候会提示找不到,最后必须有一个换行键,也就是说最后要空一行出来。这只是一个简单的示例,所以只要有一个main-class就可以了,比如还有version, classPath等等

然后 cd 到 C:\Users\victor.min\Desktop\printFileName\src 下, 运行 jar cvfm test.jar manifest.mf ./*

test.jar: 名字为导出后的jar名字,可以自己随便取

manifest.mf: 就是刚才有main-class的文件

./*:指打包当前文件夹下子文件夹中所有的class文件,这个路径可以根据自己的需要写

cd C:\Users\victor.min\Desktop\printFileName\src
jar cvfm test.jar manifest.mf ./*

 

155946_H1e1_1461287.png

155955_63MM_1461287.png

4、执行JAR

运行 java -jar test.jar

java -jar test.jar

 

160134_ZodY_1461287.png

可以看出程序已启动。

 

四、后记

本文只做了一些简单的介绍,但有许多的地方不足:

1、制作出来的JAR文件不能双击运行,这个目前我也不知道哪里出错了,解JAR JDK中自带的双击可运行JAR,也没有发现哪里不同,这个很蛋疼。网上有人说有时候可以,有时候就不行了。。。

2、编译很蛋疼,如果有很多个JAVA文件,并且不是在一个包中的时候,这时候可能需要我们自己写一个BAT命令来执行。比如有这样的包结构: org.happymzw.com.XXX,org.happymzw.core.XXX,org.happymzw.util.XXX。。。这时编译就很麻烦了

3、创建层结构,这个也比较麻烦,我们要一个一个文件夹创建,然后把相应的Class文件放入到相应的文件夹中。按理说JAVAC是应该可以自动为我们创建层结构的,这个待我去研究下再来补上,同时欢迎各位指出方法,共同学习,共同进步。

 

修改一: 

1、针对后记中的(2)(3)两点提出解决方案。

2、程序中引入第三方包

不同之处:

1、对于(2),我们可以用一个文件列出我们所需要编译的类文件

sources.txt 文件可以用windows的命令 dir /b/s/a-d *.java生成

094805_e3sO_1461287.jpg

 

2、层结构问题

095058_h1yU_1461287.jpg

095058_0lR5_1461287.jpg

 

输入命令:

javac -encoding utf-8 -cp lib/*.jar -d classes @sources.txt

命令介绍:javac 编译java文件成为class文件,如: abc.java --> abc.class

-encoding utf8,采用utf-8编码,没有这个option的话就可能出现如上图所示的错误

-cp lib/*.jar,即指定编译时所需要的第三方jar包的位置,-cp 也可以写成 -classpath

-d classes,指定class文件生成后存放的位置,说明:classes文件夹必须自己手动创建,不然会提示找不到文件夹。在生成的classes文件夹中已经帮我们自动创建好了层结构

@sources.txt,即编译sources.txt中指出的类文件

3、打成可执行的jar文件

102228_ObNZ_1461287.jpg

命令:

jar -cvfm test.jar ../MANIFEST.MF org

命令介绍:

1、jar:把文件打成jar 文件

2、 -cvfm:  c:创建文件,v:显示说情,f:生成后的文件名,m指定自己的MANIFEST.MF文件

3、test.jar:生成出来后的jar文件名

4、../MANIFEST.MF:自己的MANIFEST.MF文件路径,文件名可以任意,只要内容是按标准格式来写的就可以了,这个这里简单提示一下里面自己踩过的坑:a、最后要有一行空白行,b、每个冒号后面要加一个空格,如:Main-Class(冒号)(空格)(你要执行的类文件名,注意要加上包路径),c、class-path中如果要引入多个第三方jar文件,那么每个jar 文件用空格隔开,不能用逗号或者分号

5、org:这个是表示要打包的文件

 

4、执行生成的jar文件

103200_DryU_1461287.jpg

java -jar test.jar
##这个命令就不解释了,一看就懂了

注意:要把第三方jar文件放到MANIFEST.MF中class-path指定的位置处, class-path中一般用的是相对路径,这个相对路径是相对最后生成的test.jar文件来说的:如class-path中写的是 lib/1.jar,那么在执行test.jar的时候,在和他同级目录下必须要有一个lib文件夹,里面有一个1.jar,不然运行程序的时候就会出现 java.lang.ClassNotFoundException

 

后续解决掉第一版中的第一个问题后再后续更新,现在正在研究怎么自己精简JDK,然后直接打包到一个文件夹里,到时候在一台没有安JDK的机器上直接双击就可以运行程序

 

^0^

 

 

转载于:https://my.oschina.net/happymzw/blog/362732

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值