利用原始的javac手写编译脚本编译整个Java项目

如何编译一个无包结构的单个java文件,无依赖jar包,除了JDK;以及运行该文件?

在任何目录(/home/vc/javacDemo/one)下新建NoPackageClass.java文件

public class NoPackageClass {
    public static void main(String[] args) {
        System.out.println("This is no package class!");
        System.out.println("java.io.tmpdir property: "+System.getProperty("java.io.tmpdir"));
    }
}

进入改目录下执行

javac -encoding UTF-8 ./NoPackageClass.java 编译源文件,只指定了源文件源码格式为UTF-8

运行:java NoPackageClass,这里运行class文件并不需要加class文件后缀,只要java 命令后跟具有main函数的class文件名即可。

输出:

This is no package class!
java.io.tmpdir property: /tmp

如何编译一个有包结构的java文件, 无依赖jar包,除了JDK; 以及如何运行该文件

在目录/home/vc/javacDemo/two下创建下面文件,源文件并没有根据package 放置在根据package划分的目录中。

package org.vincent;

public class PackageClass {
    public static void main(String[] args) {
        System.out.println("This is package class!");
    }
}

这个时候因为源文件已经有package 进行管理了,那么需要添加一个参数-d, 用于指定编译后的class 文件存放的基目录,然后javac会根据包结构再生成相应的文件夹 。

当我们在 /home/vc/javacDemo/two java原代码所在目录下执行javac命令编译源代码时候,-d ./表示以源代码所在目录为class文件的根目录。javac -encoding UTF-8 -d ./ PackageClass.java 最后编译的class 文件所在目录为:/home/vc/javacDemo/two/org/vincent class文件根目录 + org/vincent (这个也是包结构)

运行 只能在class 文件根目录下执行,就是我们maven项目熟知的target目录

同时需要执行main方法类所在的全路径名称:java org.vincent.PackageClass
输出:This is package class!

批量编译大量java文件

新增 PackageClassTwo.java 文件

package org.vincent;

public class PackageClassTwo{
    public static void main(String[] args) {
        System.out.println("This is package class!");
    }
}

相当于现在在/home/vc/javacDemo/two 目录下有两个源文件 PackageClassTwo.java , PackageClass.java ,在当前源目录下执行javac命令编译文件,然后在当前目录下的org/vincent子目录有两个编译好的class文件

 javac -d ./ -encoding UTF-8 ./*.java

运行:java org.vincent.PackageClass, java org.vincent.PackageClassTwo文件两个命令都可以进行执行输出:This is package class!

修改 PackageClass.java文件引用PackageClassTwo类

package org.vincent;

public class PackageClass {
    public static void main(String[] args) {
        System.out.println("This is package class!");
        PackageClassTwo two=new PackageClassTwo();
        System.out.println(two.toString());
    }
}

使用 下面javac命令编译

 javac -d ./ -encoding UTF-8 ./*.java

java命令运行运行:java org.vincent.PackageClass, java org.vincent.PackageClassTwo

文件两个命令都可以进行执行输出:
java org.vincent.PackageClass 命令输出:

This is package class!
org.vincent.PackageClassTwo@15db9742

java org.vincent.PackageClassTwo 命令输出:

This is package class!

说明PackageClass 类可以引用到 PackageClassTwo类。

这个才是比较正常的项目,通过手动编写脚本使用javac编译一个完整的java项目

不用maven这些构建工具,直接把源码上传到Linux服务器手写脚本手动编译成一个可执行jar程序。

这是一个有package 管理,有依赖的简单的java程序。项目根目录下有这些东西

  • 项目根目录
    • src 源码根目录,package目录随便
    • lib 依赖包跟目录,lib 目录下一般是直接放jar文件没有在有目录,这个目录和MANIFEST.MF中Class-Path参数有关系
    • MANIFEST.MF 文件: 定义了入口main方法所在类,以及依赖包的位置


      # 重点是编译脚本
#! /bin/bash
# 此处应该是项目文件夹所在目录
cur_dir=$(pwd)
echo $cur_dir


function compile(){
        # 记录项目的根目录所在路径
        project_name=javacDemo
        project_dir=$cur_dir/$project_name
        project_src=$project_dir/src # 源代码所在根目录
        project_lib=$project_dir/lib #依赖jar所在目录
        project_class=$project_dir/target # 编译后class文件存放根目录
        echo "begin compile"
        echo $project_dir
        echo $project_src
        echo $project_lib
        echo $project_class

        # src目录下的所有java文件的名称存入到 项目根目录/src/sources.list文件中 先检查是否存在,如存在先删除 
        rm -rf $project_src/sources.list
        # $project_src -name  '*.java'表示在 $project_src目录下以及子目录下寻找以.java目录结尾的 文件 并存放到source.list临时文件
        find $project_src  -name '*.java' > $project_src/sources.list
        echo "java source file >>>"
        cat $project_src/sources.list

        # 构建存放编译好的class文件的基目录,先删除目录

        rm -rf $project_class
        mkdir $project_class

        # 组装cp参数
        # 将所有的jar文件绝对路径记录下来到lib.list文件中
        rm -rf $project_lib/lib.list
        find $project_lib  -name '*.jar' > $project_lib/lib.list
        # 将当前目录.添加进去
        cpvar=.:
        # 一行一行读取lib.list文件并去每行文件路径最终的文件名 ${line##*/}
        while read line
        do
            echo $line
            cpvar=${cpvar}${project_lib}"/"${line##*/}":"
            echo $cpvar
        done < $project_lib/lib.list

        echo "print cpvar "
        echo $cpvar
        # 删除这个中间文件
        rm -rf $project_lib/lib.list
        # 截取cpvar最后一个字符:
        # 获取cpvar字符串长度
        length=${#cpvar}-1
        # 取 0 - length 长度的字符串
        cpvar=${cpvar:0:length}
        echo $cpvar
         # 批量编译java文件 
        # 编码:-encoding utf-8
        # 依赖库以冒号:隔开 
        # -sourcepath 参数指定源码目录跟目录, @$project_src/sources.list 指定源码文件名
        javac -d $project_class -encoding UTF-8 -cp $cpvar  -g -sourcepath $project_src @$project_src/sources.list

        # 删除 sources.list零时文件
        rm -rf $project_src/sources.list

        #删除存在的jar 若编译过的话
        # rm $qddemo/qddemo.jar   
        cd $project_class
        jar -cvfm $project_class/${project_name}.jar $project_dir/MANIFEST.MF *
        chmod a+x $project_class/${project_name}.jar

        echo "将依赖包从"${project_lib}"复制到"${project_class}/lib"目录下. "
        # 将依赖jar包从$project_lib 目录 复制到 $project_target/lib目录下
        cp -r  $project_lib $project_class/lib
}
compile
exit 0

note:脚本和项目在同一目录下,也即项目文件夹和编译脚本在同级目录下 如
- 项目文件夹
- 脚本文件

注意:执行编译脚本必须在脚本所在目录执行编译脚本,因为脚本基于当前目录查找工程目录,进行编译。

MANIFEST.MF文件,放置在 项目根目录下

指定了依赖的jar包文件寻找的路径在编译后生成的jar文件所在目录下lib目录下。

Manifest-Version: 1.0
Main-Class: org.vincent.App
Class-Path: lib/commons-collections-3.2.2.jar lib/commons-lang-2.6.jar

进入target目录下执行生成的jar文件:

java -jar javacDemo.jar

输出:

start begin
true
true
start stop
Myname

利用原始的javac编译整个Java项目

Java| 命令编译Java程序以及运行class文件(javac)

java命令行构建(一)

Java基础14:离开IDE,使用java和javac构建

你可能感兴趣的:(经验分享,java-8学习记录)