用perl脚本解决ant…非法字符:\65279…的问题
用ant管理项目,编译时发现有些utf8编码的java文件无法编译,
报错是…非法字符:\65279…。
在网上查N多与ant有关的文章,但是大多数的解决方案都不是很理想。因为文件比较多,而且我的
机器上也没有装editplus。
索性自己用perl写了一个脚本
如下:
#remove the utf-8 BOM for Ant
sub remove_bom {
#open( my $in, "+<", "src/com/umpay/wap20/mobileProxy/MobileProxy.java" );
foreach my $filename (@_) {
print $filename,"\n";
open( my $in, "+<", $filename );
@lines = <$in>;
$line1 = $lines[0];
$t_chk1 = substr( $line1, 0, 1 ); #0xef -> 239
$t_chk2 = substr( $line1, 1, 1 ); #0xbb -> 187
$t_chk3 = substr( $line1, 2, 1 ); #0xbf ->191
if ( ord($t_chk1) == 239 && ord($t_chk2) == 187 && ord($t_chk3) == 191 )
{
$line1 = substr( $line1, 3 );
seek( $in, 0, 0 );
print $in $line1;
}
close $in;
}
}
&remove_bom("src/com/umpay/wap20/mobileProxy/MobileProxy.java"
,"src/com/umpay/wap20/security/GeneralKeyPairs.java"
,"src/com/umpay/wap20/security/RSAUtil.java"
,"src/com/umpay/wap/pages/WML.java");
其中remove_bom方法就是处理有问题的文件的方法。
把你的项目中出现问题的文件名称一个一个的放到remove_bom的参数列表中就可以了。ant,BOM,ant,BOM
最后运行这个perl文件。之后再运行ant就可以了。
Ant 小记
传统的ant 打包的项目需要处理文件和路径。特别是烦人的classpath。Ant内置了很多处理文件和路径的数据类型。比如fileset和path
Fileset可以枚举文件。
比如:
<fileset id=”source.fileset” dir=”src” includes=”**/*.java”/>
其中id是一个引用。其他的操作,可以通过id引用的方式调用它。比如:
<copy todir=”backup”>
<fileset refid=”source.fileset”/>
</copy>
javac
Debugging info
Javac中常用到的选项
Debug=”true” or debug=”false” debu=”true” debuglevel=”lines,vars,source”
Nowarn=”true” verbose=”true” verbose是一个有意思的选项,它会在编译的时候打印出一些编译信息。当然还有classpath。
比如:
<javac destdir="${build.classes.dir}" debug="true" verbose="true" srcdir="src">
<classpath refid="compile.classpath"/>
</javac>
Src也可以用子元素来表示
比如:
<javac destdir="${build.classes.dir}" debug="true" verbose="true">
<classpath refid="compile.classpath"/>
<src path=”src”/>
</javac>
如果源文件分散在多个目录中可以使用引用的方式
比如:
<path id="src.dir">
<pathelement path="src:conf"/>
</path>
<target name="mkdir">
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="compile" depends="mkdir">
<javac destdir="${build.classes.dir}">
<classpath refid="compile.classpath"/>
<src refid="src.dir"/>
</javac>
</target>
还有一种方法,比较土
例子:
<javac destdir="${build.classes.dir}">
<classpath refid="compile.classpath"/>
<src refid="src.dir"/>
<src path=”test”/>
</javac>
但是需要注意的是src指的是一个目录。
在path或者fileset这类标签中常常会遇到类似以”**/*.jsp”这样的匹配模式。下面就讲讲在如何匹配。这种匹配方式好像应该叫做wildcard路径匹配方式。是目前比较常见的3中路径匹配风格之一,(题外话,另两种是mod_rewrite风格和perl 正则风格的路径匹配)
“*”表示一个或多个字符
“?”表示一个字符
“**”表示零个或者多个目录
如果以”/”or”\”结尾,那么就相当于”**”
常见例子:
**/*~ linux 下的备份文件
**/CVS/ cvs元文件
**/.cvsignore cvs文件
**/.svn/ SVN元文件目录
比如在javac中的使用
<javac srcdir=”src” destdir=”build/classes”>
<include name=”org/mama/**/*.java”/>
<exclude name=”org/mama/papa/*.java”/>
</javac>
下面是一个完整的java 项目的build文件
<?xml version="1.0"?>
<project name="java_project" default="archive">
<property file="build.properties"/>
<path id="compile.classpath">
<pathelement location="lib/*.jar"/>
</path>
<path id="src.dir">
<pathelement path="src/java"/>
<pathelement path="src/conf"/>
</path>
<target name="init">
<mkdir dir="${build.classes.dir}"/>
<mkdir dir="dist"/>
</target>
<target name="compile" depends="init">
<javac destdir="${build.classes.dir}">
<classpath refid="compile.classpath"/>
<src refid="src.dir"/>
</javac>
</target>
<target name="archive" depends="compile">
<jar destfile="dist/${project.name}.jar" basedir="build/classes"/>
</target>
<target name="clear" depends="init">
<delete dir="build"/>
<delete dir="dist"/>
</target>
</project>
对应的build.properties文件也很简单
project.name=default
build.classes.dir=build/classes
<fileset id="sourec.fileset" dir="src" includes="**/*.java"/>
<!--在fileset中设置id属性。在其他datatype中可能需要refid属性,这个refid就是fileset中的id,比如-->
<copy todir="backup">
<fileset refid="source.fileset"/>
</copy>
其他常用的还有property,path,mkdir,target,javac,classpath
例如:
<property name="build.classes.dir"
location="build/classes"/>
<path id="compile.classpath">
<pathelement location="lib/junit.jar"/>
</path>
<mkdir dir="${build.classes.dir}"/>
<target name="compile">
<javac destdir="${build.classes.dir}" debug="true" srcdir="src">
<classpath refid="compile.classpath"/>
</javac>
</target>
path:包含一系列有序元素,这些元素可以使文件地址,也可以是路径。既可以使用classpath标签,也可以使用path标签
比如:
<path>
<pathelement location="lib/junit.jar"/>
</path>
<path>
<pathelement path="build/classes;lib/junit.jar"/>
</path>
<path location="lib/junit.jar"/><!--这是单个文件-->
<path path="build/classes:lib/junit.jar"/><!--这是多文件-->
当然path也可以使用我们刚刚看到的fileset标签:
<path>
<fileset dir='lib">
<include name="*.jar"/>
</fileset>
</path>
path 也有id属性,所以你当然也可以这样使用:
<path location="lib/junit.jar" id="junit.path"/>
<path refid="jubit.path"/>
在ant中,像classpath、sourcepath、bootclasspath、extdirs这些都是path。所以都可以使用refid去引用path。