具体的思路就是,在打包时,配置ant的build.xml的脚本仅仅编译拷贝class,而不需要拷贝所用的jar包,或者一些其他的配置文件,比如xml或者一些log4j的文件,然后再启动时候,我们可以使用java -cp 把需要的jar包路径和配置文件的路径传进去,这样就比较灵活了,然后整个项目的jar包,会变得非常精简,
本次散仙的例子是打包一个有依赖lucene的分词器然后,并使用了log4j文件记录,注意,后面真正的运行时候,依赖的jar,log4j的包,还有一些配置文件,比如log4j等,会通过一个脚本动态的传参进去。
项目截图如下:
log4j的配置如下所示:
log4j.rootCategory=INFO,fileout,errorout,stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout.ConversionPattern=%d{MM-dd HH\:mm\:ss.SSS}[%-30F\:%-5p\:%l] %m%n log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.fileout=org.apache.log4j.DailyRollingFileAppender log4j.appender.fileout.layout.ConversionPattern=%d{MM-dd HH\:mm\:ss.SSS}[%-5p] %m%n log4j.appender.fileout.layout=org.apache.log4j.PatternLayout log4j.appender.fileout.File=index_log log4j.appender.fileout.Append=true log4j.appender.fileout.DatePattern='.'yyyy-MM-dd log4j.appender.errorout=org.apache.log4j.RollingFileAppender log4j.appender.errorout.Threshold=ERROR log4j.appender.errorout.File=error_log log4j.appender.errorout.MaxFileSize=100000KB log4j.appender.errorout.MaxBackupIndex=10 log4j.appender.errorout.Append=true log4j.appender.errorout.layout=org.apache.log4j.PatternLayout log4j.appender.errorout.layout.ConversionPattern=%d{MM-dd HH\:mm\:ss.SSS}[%-30F\:%-5p\:%l] %m%n
build.xml的配置
<project name="${component.name}" basedir="." default="jar"> <!-- 引入环境变量 --> <property environment="env"/> <!-- --> <!-- 配置lucene的home地址,编译时用到,注意写法 --> <property name="lucene.home" value="${env.LUCENE_HOME}"/> <!-- 打印调试信息 --> <echo message="java的home是${env.LUCENE_HOME}"> </echo> <!-- 指定jar包的名字 --> <property name="jar.name" value="myjob.jar"/> <!-- 编译源码时需要依赖的jar包 --> <path id="project.classpath" > <fileset dir="lib"> <include name="*.jar"/> </fileset> <fileset dir="${lucene.home}"> <include name="*.jar"/> </fileset> </path> <!-- 编译前清空上次的bin文件 --> <target name="clean"> <delete dir="bin" failonerror="false"></delete> <mkdir dir="bin"/> </target> <!-- 构建编译源码 一般为固定写法 --> <target name="build" depends="clean"> <echo message="${ant.project.name}: ${ant.file}" ></echo> <javac destdir="bin" encoding="utf-8" debug="true" includeantruntime="false" debuglevel="lines,vars,source"> <src path="src"/> <exclude name="**/.svn" /> <classpath refid="project.classpath"/> </javac> <copy todir="bin"> <fileset dir="src"> <include name="*config*"/> </fileset> </copy> </target> <!-- 打包的jar --> <target name="jar" depends="build"> <!-- 这里是精简版的配置,如果需要,可以在这里面配置拷贝依赖的jar到lib目录里 --> <!-- <copy todir="bin/lib"> <fileset dir="lib"> <include name="**/*.*"/> </fileset> </copy> --> <jar basedir="bin" destfile="${jar.name}"> <include name="**/*" /> </jar> </target> </project>
编写完成后,传到linux上,然后写个shell脚本,动态传入一些jar的路径和配置文件,例如log4j等,在linux上的目录执行ant后如下所示
[search@fsedump03sand LuceneDemo]$ ant Buildfile: /home/search/LuceneDemo/build.xml [echo] hadoop的home是/home/search/hadoop [echo] java的home是/home/search/lucenedemo/lib/lucenelib/ clean: [delete] Deleting directory /home/search/LuceneDemo/bin [mkdir] Created dir: /home/search/LuceneDemo/bin buildwithout: [echo] ${component.name}: /home/search/LuceneDemo/build.xml [javac] Compiling 7 source files to /home/search/LuceneDemo/bin [javac] Note: /home/search/LuceneDemo/src/com/study/lucene/TestAnalysis.java uses or overrides a deprecated API. [javac] Note: Recompile with -Xlint:deprecation for details. jarwithout: [jar] Building jar: /home/search/LuceneDemo/myjob.jar BUILD SUCCESSFUL Total time: 1 second [search@fsedump03sand LuceneDemo]$ ll total 44 drwxrwxr-x 3 search search 4096 Nov 13 18:01 bin -rw-rw-r-- 1 search search 3514 Nov 13 15:30 build.xml drwxrwxr-x 2 search search 4096 Nov 13 15:45 conf -rw-rw-r-- 1 search search 256 Nov 13 15:45 error_log -rw-rw-r-- 1 search search 1628 Nov 13 15:45 index_log drwxrwxr-x 2 search search 4096 Nov 13 15:36 lib -rw-rw-r-- 1 search search 10407 Nov 13 18:01 myjob.jar -rw-rw-r-- 1 search search 364 Nov 13 15:43 sme.sh drwxrwxr-x 3 search search 4096 Nov 13 15:31 src [search@fsedump03sand LuceneDemo]$
然后我们的脚本里面如何定义的,因为我们的myjob.jar里面没有任何有关依赖的jar包,和conf配置文件,所以需要在启动时,使用cp命令动态传入,脚本如下所示:
[search@fsedump03sand LuceneDemo]$ cat sme.sh #定义根路径 cs='.:' cdir=`pwd` #echo $cdir #libpath="$cdir/lucenedemo/lib/lucenelib/" #依赖的jar包 libpath="/home/search/lucenedemo/lib/lucenelib/" #echo $libpath #获取依赖jar的目录,本例只有一个依赖jar, #如果有多个,可以都拼接上即可 FILES=`ls $libpath` for txt in $FILES;do cs=$cs$libpath$txt: #注意最后有个冒号拼接jar done #echo $cs #配置文件的目录 conf="conf:" #自身的jar,注意$cs命令一定要放在首位 cs=$cs$conf"myjob.jar" #echo $cs java -Xms128m -Xmx1024m -cp $cs com.study.lucene.TestAnalysis $1 [search@fsedump03sand LuceneDemo]$
执行效果如下所示:
[search@fsedump03sand LuceneDemo]$ sh sme.sh 你 没 有 输 入 任 何 内 容 [search@fsedump03sand LuceneDemo]$
容 [search@fsedump03sand LuceneDemo]$ sh sme.sh bbc bbc [search@fsedump03sand LuceneDemo]$
而且,我们可以改动conf里面的log4j文件,再次启动时,会立刻生效,比如散仙打开了stdout控制台输出信息:
[search@fsedump03sand LuceneDemo]$ sh sme.sh 11-13 18:25:27.784[TestAnalysis.java :WARN :com.study.lucene.TestAnalysis.main(TestAnalysis.java:41)] abc你 11-13 18:25:27.789[TestAnalysis.java :INFO :com.study.lucene.TestAnalysis.main(TestAnalysis.java:42)] 当前你 你 11-13 18:25:27.790[TestAnalysis.java :WARN :com.study.lucene.TestAnalysis.main(TestAnalysis.java:41)] abc没 11-13 18:25:27.791[TestAnalysis.java :INFO :com.study.lucene.TestAnalysis.main(TestAnalysis.java:42)] 当前没 没 11-13 18:25:27.792[TestAnalysis.java :WARN :com.study.lucene.TestAnalysis.main(TestAnalysis.java:41)] abc有 11-13 18:25:27.793[TestAnalysis.java :INFO :com.study.lucene.TestAnalysis.main(TestAnalysis.java:42)] 当前有 有 11-13 18:25:27.794[TestAnalysis.java :WARN :com.study.lucene.TestAnalysis.main(TestAnalysis.java:41)] abc输 11-13 18:25:27.795[TestAnalysis.java :INFO :com.study.lucene.TestAnalysis.main(TestAnalysis.java:42)] 当前输 输 11-13 18:25:27.796[TestAnalysis.java :WARN :com.study.lucene.TestAnalysis.main(TestAnalysis.java:41)] abc入 11-13 18:25:27.797[TestAnalysis.java :INFO :com.study.lucene.TestAnalysis.main(TestAnalysis.java:42)] 当前入 入 11-13 18:25:27.798[TestAnalysis.java :WARN :com.study.lucene.TestAnalysis.main(TestAnalysis.java:41)] abc任 11-13 18:25:27.799[TestAnalysis.java :INFO :com.study.lucene.TestAnalysis.main(TestAnalysis.java:42)] 当前任 任 11-13 18:25:27.800[TestAnalysis.java :WARN :com.study.lucene.TestAnalysis.main(TestAnalysis.java:41)] abc何 11-13 18:25:27.801[TestAnalysis.java :INFO :com.study.lucene.TestAnalysis.main(TestAnalysis.java:42)] 当前何 何 11-13 18:25:27.802[TestAnalysis.java :WARN :com.study.lucene.TestAnalysis.main(TestAnalysis.java:41)] abc内 11-13 18:25:27.803[TestAnalysis.java :INFO :com.study.lucene.TestAnalysis.main(TestAnalysis.java:42)] 当前内 内 11-13 18:25:27.804[TestAnalysis.java :WARN :com.study.lucene.TestAnalysis.main(TestAnalysis.java:41)] abc容 11-13 18:25:27.805[TestAnalysis.java :INFO :com.study.lucene.TestAnalysis.main(TestAnalysis.java:42)] 当前容 容 11-13 18:25:27.806[TestAnalysis.java :ERROR:com.study.lucene.TestAnalysis.main(TestAnalysis.java:46)] erro人错误 [search@fsedump03sand LuceneDemo]$
这样以来,我们的配置就非常灵活,任何依赖的jar包和配置文件,都可以放在项目以外的位置,不提供强依赖,必要时候,可以使用-cp加载。
最后需要注意的是,在linux上配置环境变量,注意export的方式:
HADOOP_HOME=/home/search/hadoop PATH=$PATH:$HOME/bin:$HADOOP_HOME/bin export PATH export LUCENE_HOME=/home/search/lucenedemo/lib/lucenelib/ PATH=$PATH:$LUCENE_HOME export PATH