不做JavaME的Java程序员一般可能不会去对自己的class文件做混淆处理。做JavaME的大部分都知道Proguard、RetroGuard等用于obfuscate的工具。去年我的Ant Build Script中就已经添加了对于Proguard的支持,不过这次为了做WB2这个游戏,又有几个地方需要调整。
1) 类太多,足足有接近30个class file。
这对于ME程序而言,太多了。Proguard又不太争气,我只好找了以前做Flynn时候用过的JAX再压榨一下。JAX是IBM很早以前在alphaWork上发布的一个混淆器,后来被集成到了WSDD (Websphere Device Developer)中,作为SmartLink组件,就再也没法下到了。
我手头用的JAX版本6.3只能支持JDK1.2 -_-||| 没办法,尝试了诸多方法之后,勉强还是可以用。以下命令可以执行JAX以GUI方式启动:
# java -classpath $JAX_HOME/jax63.zip com.ibm.jax.GUI
不过Ant集成的task最好还是在命令行里运行,简洁又清爽:
# java -classpath $JAX_HOME/jax63.zip com.ibm.jax.Batch
后来有个朋友给了我一个私房版本,是用JDK5.0重新编译过的JAX,不用替换JVM就能运行,而且META-INF里面也制定了MainClass为Batch,真棒!
折腾了足足两个钟头之后,将JAX加入了ant build:
<target name="merge" if="flag.should.jaxmerge" description="Try to merge some classes using JAX">2) 主类的名字太长,导致MF文件中会折断换行。
<java jar="${lib}/${jax.jar}" fork="true">
<arg value="lib/${jax.conf}" />
</java>
<delete dir="${classes}"/>
<mkdir dir="${classes}"/>
<unzip src="${name.zip}" dest="${classes}" />
<delete file="${name.zip}" />
</target>
WB2的类放在deep package里面,也就是说,它的fully-qualified class name非常长。这就导致了MF的一个问题——Sun的JAR规范里面要求Manifest文件每行的字符最多为72个,超过的话就要自动换行。对于西欧文字而言,这没啥问题,单字节的随便换也不会出错。可是东亚字符就不灵了。这也就算了,更遗憾的是大多数手机vendor提供的JVM实现(无论是真机还是模拟器),都不支持这种被腰斩过的MF。客气点的就抛个异常说ClassNotFoundException,不友好的就直接推出应用程序。
本来想要尝试用Proguard指定mapping规则将主类做一个refactor,放到default package中,尝试了以下若干种配置:
-keepclassmembers class * {
public void startApp();
public void pauseApp();
public void destroyApp(boolean);
}
-keep public class * extends javax.microedition.midlet.MIDlet
-keepnames public class * extends javax.microedition.midlet.MIDlet
-keep public class * {
public void startApp();
public void pauseApp();
public void destroyApp(boolean);
}
-keepclassmembernames public class * extends javax.microedition.midlet.MIDlet {
public void startApp();
public void pauseApp();
public void destroyApp(boolean);
}
无奈RP不佳,最后只好先采取了另一种方法——将Ant文件做了修改,直接构造MF并用ZIP构造jar文件(不能用JAR task,否则还是会被换行)。
评论