文章目录

  • 项目背景
  • 1、准备Apache Ant环境
  • 3、Ant配置文件准备&打war包(两个配置文件全部在xml目录中)
  • 3.1、build.properties参数配置文件
  • 3.2、build.xml Ant运行配置文件
  • 3.3、运行Ant对HelloWorld项目打一个war包
  • 4、war包部署到tomcat
  • 5、访问测试
  • 6、写到最后


项目背景

项目在不使用mave管理的情况下,怎么快捷的在线上进行打包部署?
如果每次都需要本地编译打包然后部署到线上,这无疑是非常麻烦的,如果能把源码推送到线上,源码更新之后直接在线上完成一键打包部署就非常方便了。
下面要介绍的就是,非maven管理的项目使用Ant来编译源码,生成jar包或者war包去部署。

1、准备Apache Ant环境

Apache官网下载最新版本的Ant,下载成功之后上传至Linux服务器。

java war包反编译成源码 war包反编译成项目_apache


上传过程省略,我这里上传目录为:/dz/dz_ant/

解压文件:

cd /dz/dz_ant/
#解压
tar -zxf apache-ant-1.9.16-bin.tar.gz
#修改解压后的文件名
mv apache-ant-1.9.16 ant

java war包反编译成源码 war包反编译成项目_ant_02


测试运行:如果输出build.xml不存在说明ant已经可以使用,后面补充上配置文件即可对指定项目打包

java war包反编译成源码 war包反编译成项目_ant_03

2、准备JavaWeb项目&源码上传至服务器

目录结构:

java war包反编译成源码 war包反编译成项目_apache_04


部分代码:

package com.dz.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @WebServlet(name = "HelloWorld", value = "/sayHello")注解监听并拦截请求,代替了web.xml中关于servlet的映射配置
 * =================================>注解效果等同于如下配置
        <servlet>
            <servlet-name>HelloWorld</servlet-name>
            <servlet-class>com.example.servlet.ActionServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>HelloWorld</servlet-name>
            <url-pattern>/sayHello</url-pattern>
        </servlet-mapping>
 */
@WebServlet(name = "HelloWorld", value = "/sayHello")
public class HelloWorldServlet extends HttpServlet {


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求编码格式
        req.setCharacterEncoding("utf8");
        // 设置响应编码格式
        resp.setContentType("text/html;charset=utf-8");

        // 获取参数
        String param = req.getParameter("param");
        System.out.println("Apache Ant..." + param);

        // 响应到页面
        resp.getWriter().write("Apache Ant Say:HelloWorld!");
    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

源码上传至服务器&项目目录结构,上传位置:/dz/dz_ant

java war包反编译成源码 war包反编译成项目_ant_05


使用Ant要做的就是,对src进行编译(代码编译&资源文件编译)&一些资源文件复制(web)

3、Ant配置文件准备&打war包(两个配置文件全部在xml目录中)

接下来要做的就是,进入HelloWorld项目之后,使用Antsrc源码进行编译,并输出编译后的文件到/dz/dz_ant/webapps目录下。

3.1、build.properties参数配置文件
# 作者 dongzi
# 描述
#   1. 关于ant构建项目的一些通用配置项
#   2. 在使用时直接引入此配置文件,加载对应的配置,而不必手动依次修改构建信息
#####################################

# 项目名
project.name=HelloWorld
# HelloWorld项目所在文件夹
build.project.dir=/dz/dz_ant
# 编译后的classes文件复制到这里
build.target.dir=/dz/dz_ant/target
# 最终要使用此webapps目录进行war包的归档
build.dist.dir=/dz/dz_ant/webapps
# ant所在目录
build.ant.dir=/dz/dz_ant/ant
# 生成war包输出位置
build.war.dir=/dz/dz_ant/war
# 生成jar包输出位置
buildjar.dir=/dz/dz_ant/jar
3.2、build.xml Ant运行配置文件

具体的配置描述通过注释的方式写在文件里了。

<?xml version="1.0" encoding="UTF-8"?>

<project name="project" default="compile">
  <!-- 加载通用的配置文件 -->
	<property file="build.properties" />
	
		<!-- 在进行编译最开始需要进行一些操作 -->
        <target name="init">
				<!-- 删除上次编译产生的classes字节码文件 -->
                <delete dir="${build.target.dir}" />
				<!-- 删除webapps中上次归档记录 -->
                <delete dir="${build.dist.dir}" />
                <!-- 创建webapps目录 -->
                <mkdir dir="${build.dist.dir}" />
                <!-- 创建放置lib依赖的目录 -->
                <mkdir dir="${build.dist.dir}/WEB-INF/lib" />
                <!-- 创建放置字节码文件的目录 -->
                <mkdir dir="${build.dist.dir}/WEB-INF/classes" />
                <!-- 创建存放clasess字节码目录 -->
                <mkdir dir="${build.target.dir}/classes" />
    		</target>

		<!-- 开始编译,此步骤depends上一步init-->
        <target name="compile" depends="init">
				<!-- 编译过程中标准输出 -->
                <echo message="begin compile java src" />
				<!-- javac编译:编译后的字节码文件放到 ${build.target.dir}/classes下面-->
                <javac srcdir="${build.project.dir}/${project.name}/src" destdir="${build.target.dir}/classes"  debug="on" debuglevel="lines,vars,source" nowarn="true" failonerror="true" >
                        <compilerarg line="-encoding UTF-8"/>
						<!-- 编译过程中依赖的一些jar包classpath路径 -->
                        <classpath>
                                <fileset dir="${build.project.dir}/${project.name}/web/WEB-INF/lib" includes="*.jar" />
                        </classpath>
                        <include name="**/*.*" />
                </javac>

                <echo message="package compiled classes" />

                <!-- 把web下面所有资源复制出来放到${build.dist.dir}目录下  -->
                <copy todir="${build.dist.dir}">
                        <fileset dir="${build.project.dir}/${project.name}/web/" includes="**/*.*"/>
                </copy>

                <!-- ##########################################################################################-->
                
                <!-- 下面两种源码生成的字节码归档方式使用其中之一就可以 -->
                <!-- 方式1: target目录下产生的classes文件及其资源全部复制到WEB-INFO下面-->
               <!--  <copy todir="${build.dist.dir}/WEB-INF/">
                        <fileset dir="${build.target.dir}/" includes="**/*.*"/>
                </copy> -->

                <!--方式2:target产生的classes字节码文件全部归档到dz.jar的jar包中,在访问的时候会自动找到对应的dz.jar包去访问-->
                <jar destfile="${build.dist.dir}/WEB-INF/lib/dz.jar">
                        <fileset dir="${build.target.dir}/classes">
                                <include name="**/*.*" />
                        </fileset>
                </jar>

                <!-- ##########################################################################################-->

                <!-- 删除字节码文件,也可以不删除 -->
        	<!-- <delete dir="${build.target.dir}" /> -->
        </target>

		<!-- 打成war包,depends依赖上一项的编译结果-->
        <target name="war" depends="compile">
                <echo message="begin to create war" />
                <!--把文件归档到...-->
                <jar destfile="${build.war.dir}/${project.name}.war" >
                        <!-- 使用jar 把${build.dist.dir}这个文件夹归档为war格式文件,放到tomcat下运行-->
                        <fileset dir="${build.dist.dir}/">
                                 <!-- 归档过程中排除一些文件,避免运行过程中冲突:本地使用的jretty服务,服务器使用tomcat因此这里需要排除或者排除一些其他冲突的依赖 -->
                                <exclude name="**/jetty-server*.jar"/>
                        </fileset>
                </jar>
                <echo message="create war complete" />
        </target>
</project>
3.3、运行Ant对HelloWorld项目打一个war包

cd /dz/dz_ant # 进入ant所在目录

java war包反编译成源码 war包反编译成项目_java_06

#在当前目录,运行以下命令
./ant/bin/ant --help
#指定打包要使用的配置文件
./ant/bin/ant -f xml/build.xml war
=======================>
#为什么命令最后要使用war???
使用war是指定要执行哪一个target,因为target执行过程中有依赖的上一项,所以执行最后一个target war,会执行完成整个build.xml配置的选项。如果单独执行某一项target,如:
./ant/bin/ant -f xml/build.xml init
它只会做一些预处理,删除和创建一些文件,依次类推。

java war包反编译成源码 war包反编译成项目_java_07


至此,完成了项目编译以及war包的打包过程。

4、war包部署到tomcat

tomcat具体安装过程不在详细描述,安装tomcat可以参照:CentOS7安装Tomcat 写一些简单的脚本将/dz/dz_ant/war下面的HelloWorld.war部署到tomcat的webapp下面。
tomcat安装路径/dz/app/tomcat_helloworld

#先删除tomcat已经部署的HelloWorld项目,如果tomcat是运行的需要先停止
kill -9 ps -ef | grep tomcat_helloworld | grep -v grep | awk '{print $2}' cd /dz/app/tomcat_helloworld/webapps
rm -rf HelloWorld*
cd /dz/dz_ant/war
cp -r HelloWorld.war /dz/app/tomcat_helloworld/webapps
#重新启动tomcat
./dz/app/tomcat_helloworld/startup.sh
#查看启动日志
tail -f /dz/app/tomcat_helloworld/logs/catalina.out

java war包反编译成源码 war包反编译成项目_java war包反编译成源码_08

5、访问测试

java war包反编译成源码 war包反编译成项目_java war包反编译成源码_09


java war包反编译成源码 war包反编译成项目_java war包反编译成源码_10


是不是访问成功并且已经符合预期了呢?

6、写到最后

Ant打包过程总结:

  1. 预先处理一些要使用到的文件或文件夹(target name=init时的操作);
  2. 使用javac对源码进行编译,其中也包括将资源文件&web文件的复制到一起,方便归档;(target name=compile时的操作)
  3. 对compile已经编译好&复制到一起的文件进行归档,归档格式为war;(target name=war时的操作)

  1. 为什么全文一直使用的是./ant/bin/ant执行,而不是ant执行?
    因为这里就一个地方用到了ant,所以没有配置环境变量,有需要的话可以把环境变量配置上。

#配置ant环境变量
vi /etc/profile
#最后加入两行配置
export ANT_HOME=/dz/dz_ant/ant
export PATH=java war包反编译成源码 war包反编译成项目_java war包反编译成源码_11ANT_HOME/bin
#完成后保存,刷新配置文件
source /etc/profile
#再使用ant命令就可以使用了
ant

  1. 因为这个项目里面没有加载更多的配置文件,所以要加载的话还需要再tartget name=compile编译过程中,进行资源文件的copy(copy的位置就是classes同级路径的classpath下面)