小工具      在线工具  汉语词典  css  js  c++  java

java命令行构建(2)

java,java,ant,jar,javac 额外说明

收录于:40天前

我们要用命令行来实现 源文件-> 可运行jar,
我们可以参考ant的打jar包脚本。

蚂蚁是如何构建的?

源文件->字节码->可执行jar
源代码和上一篇是一样的,就多了个build.xml

  • 源文件、配置和lib
│  build.xml
│
├─build
├─conf
│      log4j.xml
│
├─lib
│      log4j-1.2.17.jar
│
└─src
    └─com
        └─yp
            └─test
                │  HelloWorld.java
                │
                └─entity
                        Cat.java

  • build.xml 内容
<?xml version="1.0" encoding="UTF-8"?>
<!-- 定义一个工程,默认任务为jarFile。 -->
<project name="myh" default="jarFile" basedir=".">

    <!-- 定义属性,打成jar包的名称。 -->
    <property name="jarFileName" value="myh.jar"></property>


    <!-- 定义路径,编译java文件时用到的jar包。 -->
    <path id="project.lib">
        <fileset dir="${basedir}/lib">
            <include name="**/*.jar"/>
        </fileset>
    </path>

    <!-- 定义任务,清空任务:清空原有的class文件,创建新的build路径。 -->
    <target name="clean">
        <delete dir="${basedir}/build" />
        <mkdir dir="${basedir}/build" />
    </target>

    <!-- 定义任务,编译src文件夹中的java文件,编译后的class文件放到创建的文件夹下。 -->
    <target name="compile" depends="clean">
        <javac encoding="utf-8" srcdir="${basedir}/src" destdir="${basedir}/build" includeantruntime="false">
            <classpath refid="project.lib">
            </classpath>
        </javac>

        <copy todir="${basedir}/build">
            <fileset dir="${basedir}/conf">
                <include name="**/**.*" />
                <exclude name="**/*.java"/>   
            </fileset>
        </copy>
    </target>

    <!-- 定义默认任务,将class文件集合成jar包。 -->
    <target name="jarFile" depends="compile">
        <!-- 删除原有jar包。 -->
        <delete dir="${basedir}/${jarFileName}" />
        <!-- 建立新jar包。 -->
        <jar destfile="${basedir}/${jarFileName}" basedir = "${
    basedir}/build" includes = "**/**.*" >

           <manifest>
             <attribute name="Main-Class" value="com.yp.test.HelloWorld"/>
             <attribute name="Class-Path" value="lib/log4j-1.2.17.jar"/>
             </manifest>
        </jar>
    </target>
</project>
  • 结果将是 myh.jar
  • 运行及结果显示正常:
E:\codeplace\n_learn\java\javacmd>java -jar myh.jar
10:43:51,453 INFO  [HelloWorld] 这是log4j
hello,keyboard
  • 说明
    我们查看下jar包里面的MANIFEST.MF:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.10.0
Created-By: 1.8.0-b132 (Oracle Corporation)
Main-Class: com.yp.test.HelloWorld
Class-Path: lib/log4j-1.2.17.jar

当我们创建jar时,MANIFEST.MF必须是这样的!!为了检查并运行

现在我们使用命令行构建

我们直接用python来写这些 各种各样的命令
参考ant,会有,init,clean,compile,jar

废话不多说,我们直接上代码:

#!/usr/bin/python
#coding:UTF-8

import paramiko,datetime,os,logging
import os,shutil
import sys
import time

# 遍历文件夹
def getFiles(dir, suffix):
    res = []
    for root, directory, files in os.walk(dir):
        for filename in files:
            name, suf = os.path.splitext(filename)
            if suf == suffix:
                res.append(os.path.join(root, filename))
    return res


# init
jarFileName = "myh.jar"
basedir = os.getcwd()
mainclass = "com.yp.test.HelloWorld"


# clean
logging.error("当前工作目录:"+os.getcwd()+",清理build")
shutil.rmtree(basedir+"\\"+"build")
os.mkdir(basedir+"\\"+"build")

# compile
logging.error("开始compile")
# javac -encoding "utf8" src/com/yp/test/HelloWorld.java -sourcepath src -d build -g -cp ./lib/*.jar
# os.system("javac -encoding utf8 src/com/yp/test/HelloWorld.java -sourcepath src -d build -g -cp ./lib/*.jar")

# 把文件列表加入到sourcefiles 文件中
file=open('sourcefiles','w')
for tfile in getFiles(basedir+'/src/', '.java'):
    file.writelines (tfile+'\n')
file.close()
# 执行编译
os.system("javac -encoding utf8 -sourcepath src @sourcefiles -d build -cp ./lib/*.jar ")

# logging.error("开始copy配置文件")
os.system("cp conf/* build/")

# jar
# 用python生成清单文件
jarfile=open('manifest.mf','w')
jarfile.writelines('Class-Path: ')
for tfile in getFiles(basedir+'/lib/', '.jar'):
    tmppath,filename = os.path.split(tfile)
    tmpfilepath = 'lib/'+filename
    logging.error(tmpfilepath)
    jarfile.writelines(tmpfilepath)
jarfile.writelines('\n\n')
jarfile.close()

# 打jar包
os.chdir(basedir+"/build")
os.system("jar cvfem "+basedir+"/"+jarFileName+" "+mainclass+" "+basedir+"/manifest.mf *")
os.chdir(basedir)


# 清理
os.remove(basedir+"/manifest.mf")
os.remove(basedir+"/sourcefiles")

所需输入参数

jarFileName = “myh.jar”
mainclass = “com.yp.test.HelloWorld”

用法:

一个 python build.py 命令,一个 java -jar myh.jar

E:\codeplace\n_learn\java\javacmd>python build.py
ERROR:root:褰撳墠宸ヤ綔鐩綍:E:\codeplace\n_learn\j
ERROR:root:寮€濮媍ompile
ERROR:root:lib/log4j-1.2.17.jar
已添加清单
正在添加: com/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/yp/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/yp/test/(输入 = 0) (输出 = 0)(存储了 0
正在添加: com/yp/test/entity/(输入 = 0) (输出 = 0)(存
正在添加: com/yp/test/entity/Cat.class(输入 = 416) (
正在添加: com/yp/test/HelloWorld.class(输入 = 961) (
正在添加: log4j.xml(输入 = 1220) (输出 = 512)(压缩了

E:\codeplace\n_learn\java\javacmd>java -jar myh.jar
17:26:59,424 INFO  [HelloWorld] 这是log4j
hello,keyboard

阐明

  • javac 不能把源文件目录直接入参
    要把 src的java文件全都搞成列表后入参给javac,
    这里用python来生成src 目录和子目录下的 java 列表,扔到一个文件sourcefiles
    sourcefiles会生成如下,过后会清理
E:\codeplace\n_learn\java\javacmd/src/com\yp\test\HelloWorld.java
E:\codeplace\n_learn\java\javacmd/src/com\yp\test\entity\Cat.java

这里的思路是先 用python生成清单文件manifest.mf,然后jar命令中加上.
manifest.mf会自动生成lib里面的jar包(最后会清理掉),如下

Class-Path: lib/log4j-1.2.17.jar

. . .

相关推荐

额外说明

将数组右移 k 位的两种算法

算法一:时间O(N),空间O(N) 算法二:时间O(k*N),空间O(1) 算法一:时间O(N),空间O(N) 利用额外的空间b[N]来直接定位到指定的位置,不需要考虑元素覆盖的问题,这是它快的原因 由于是循环右移,必然要%来循环, 核心代码:b[(i

额外说明

keepalived与nginx与MySQL

keepalived  VRRP介绍 集群(cluster)技术是一种较新的技术,通过集群技术,可以在付出较低成本的情况下获得在性能、可靠性、灵活性方面的相对较高的收益,其任务调度则是集群系统中的核心技术。 集群组成后,可以利用多个计算机和组合进行海量请

额外说明

等价无穷小的公式

等价无穷小公式是在极限运算中常用的工具,用于说明两个无穷小之间的关系。以下是一些常见的等价无穷小公式: 当 x 趋近于零时,有以下等价无穷小关系: sin(x) ≈ x tan(x) ≈ x arcsin(x) ≈ x arctan(x) ≈ x ln(

额外说明

程序猿必备的数电知识之(逻辑代数基础前半篇)

2.1 概述 1.只有两种对立逻辑状态的逻辑关系成为二值逻辑。 2.所谓逻辑,在这里是指事物间的因果关系。当两个二进制数码表示不同的逻辑状态时,它们之间可以按照指定的某种因果关系进行推理运算。我们将这种运算成为逻辑运算。 3.1849年英国数学家乔治 布

额外说明

一. c++ 中的类模板

C++ 除了支持函数模板,还支持类模板(Class Template)。 函数模板中定义的类型参数可以用在函数声明和函数定义中, 类模板中定义的类型参数可以用在类声明和类实现中。类模板的目的同样是将数据的类型参数化。 1.1 类模板的定义 声明类模板的语

额外说明

SSL连接的JAVA实现

SSL连接分为双向认证和单向认证。其中双向认证表示服务器和客户端都需要分别校验对方的身份。单向认证则只需要客户端校验服务器的身份。 SSL的双向认证的流程如下图: 从以上流程可见,要完成双向认证,服务器端和客户端都需要验证对方的证书,然后再进行加密的协商

额外说明

Gradio的web界面演示与交互机器学习模型,Blocks的事件侦听《7》

在第一篇文章我们就熟悉了Blocks的用法,使用Blocks比Interface更加灵活,这节重点关注Blocks里面的相关操作。 1、Blocks标准例子 import gradio as gr def greet(name): return

额外说明

软件设计师笔记系列(四)

-前言 随着技术的快速发展,软件已经成为我们日常生活中不可或缺的一部分。从智能手机应用到大型企业系统,软件都在为我们提供便利、增强效率和创造价值。然而,随之而来的是对软件质量的日益增长的关注。软件的质量不仅关乎其功能性和性能,还涉及其可靠性、使用性、可维

额外说明

【软考 系统架构设计师】案例分析⑧ 数据库索引与视图

>>回到总目录<< 为了不辜负已经订阅了专栏的同学们的信任,所以本专栏不会有任何的优惠活动。 另外,当订阅人数每次达到 2 n ( n > 2 ) 2^n(n>2) 2

额外说明

swift3.0 的解释在 Swift 中解包可选值 && 可选时意外发现 nil

​ 首先说一下Swift中的一些Optional,翻译过来就是可选的。它是一个枚举类型,有以下两个值。 ​   1. none:表示没有值  2. some:某一类值 原始可选项的定义: let x: Optional = 10 1 1 简单的定义: /

ads via 小工具