Apache的BCEL库,文档很少,例子也很简单。动态构建类的工作,要求的只是并不是熟练使用BCEL类库本身,而是要对java的class结构了解。我对java的pcode也不熟悉,但是我曾经做过大量的.NET的反编译工作,两者类似,所以我用BCEL也不觉得困难。
我提供一个例子,这里例子是使用BCEL创建类的实例,而不是使用反射。
如下:
IFactory.java

public interface IFactory
{
public Object newInstance();
} FileClassLoader.java
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;


public class FileClassLoader extends ClassLoader
{

public FileClassLoader()
{
super();
}


public FileClassLoader(ClassLoader parent)
{
super(parent);
}


public Class getClass(String className, String filePath)
{
FileInputStream fileInputStream = null;
byte[] data = null;

try
{
fileInputStream = new FileInputStream(new File(filePath));

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int ch = 0;

while ((ch = fileInputStream.read()) != -1)
{
byteArrayOutputStream.write(ch);
}
data = byteArrayOutputStream.toByteArray();
return defineClass(className, data, 0, data.length);

} catch (IOException e)
{
e.printStackTrace();
throw new Error(e.getMessage(), e);
}
}
} buildFactory方法:
public static IFactory buildFactory(String procductClassName)

throws Exception
{
InstructionList il = new InstructionList();
String className = "HelloWorld";
ClassGen class_gen = new ClassGen(className, "java.lang.Object",
"", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null);
ConstantPoolGen cons_pool = class_gen.getConstantPool();
class_gen.addInterface(IFactory.class.getName());

InstructionFactory il_factory = new InstructionFactory(class_gen);

// 创建构造函数

{
String methodName = "";

Type returnType = Type.VOID;

Type[] arg_Types = new Type[]
{};

String[] arg_names = new String[]
{};
MethodGen method_gen = new MethodGen(Constants.ACC_PUBLIC,
returnType, arg_Types, arg_names, methodName, className,
il, cons_pool);

// super();
il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
il.append(il_factory.createInvoke("java.lang.Object", "",
Type.VOID, new Type[0], Constants.INVOKESPECIAL));
il.append(InstructionFactory.createReturn(Type.VOID));

method_gen.setMaxStack();
class_gen.addMethod(method_gen.getMethod());
il.dispose(); // Reuse instruction handles of list
}


{
String methodName = "newInstance";
Type returnType = Type.OBJECT;

Type[] arg_Types = new Type[]
{};

String[] arg_names = new String[]
{};
MethodGen method_gen = new MethodGen(Constants.ACC_PUBLIC,
returnType, arg_Types, arg_names, methodName, className,
il, cons_pool);
il.append(il_factory.createNew(procductClassName));
il.append(InstructionConstants.DUP);
il.append(il_factory.createInvoke(procductClassName, "",
Type.VOID, new Type[0], Constants.INVOKESPECIAL));
il.append(InstructionFactory.createReturn(Type.OBJECT));
method_gen.setMaxStack();

class_gen.addMethod(method_gen.getMethod());
il.dispose(); // Reuse instruction handles of list
}

// 保存到文件中
JavaClass clazz = class_gen.getJavaClass();
String path = "e:\\temp\\" + className + ".class";
class_gen.getJavaClass().dump(path);

// 使用ClassLoader装载class
FileClassLoader classLoader = new FileClassLoader();
Class factoryClass = classLoader.getClass(className, path);
Object newInst = factoryClass.newInstance();

return (IFactory) newInst;
} 测试用例:
String className = "java.lang.Object";
IFactory factory = buildFactory(className);
Object inst = factory.newInstance();

在密码学里,有一种理想的加密方案,叫做一次一密乱码本(one-time pad)。
one-time pad的算法有以下要求:
1、密钥必须随机产生
2、密钥不能重复使用
3、密钥和密文的长度是一样的。
one-time pad是最安全的加密算法,双方一旦安全交换了密钥,之后交换信息的过程就是绝对安全的啦。这种算法一直在一些要求高度机密的场合使用,据说美国和前苏联之间的热线电话、前苏联的间谍都是使用One-time pad的方式加密的。不管超级计算机工作多久,也不管多少人,用什么方法和技术,具有多大的计算能力,都不可能破解。
一次一密的一种实现方式,如下:

public class OneTimePadUtil
{

public static byte[] xor(byte[] bytes, byte[] keyBytes)
{

if (keyBytes.length != bytes.length)
{
throw new IllegalArgumentException();
}

byte[] resultBytes = new byte[bytes.length];


for (int i = 0; i < resultBytes.length; ++i)
{
resultBytes[i] = (byte) (keyBytes[i] ^ bytes[i]);
}

return resultBytes;
}
} 使用例子:
String plainText = "温少";
String keyText = "密码";

byte[] plainBytes = plainText.getBytes();
byte[] keyBytes = keyText.getBytes();

assert plainBytes.length == keyBytes.length;

//加密
byte[] cipherBytes = OneTimePadUtil.xor(plainBytes, keyBytes);

//解密
byte[] cipherPlainBytes = OneTimePadUtil.xor(cipherBytes, keyBytes);
这是最简单的加密算法,但也是最安全的机密算法。前天和朋友讨论到了这个问题,所以写了这篇文章。
我在阅读JDK 1.5中java.util.concurrent的源码时,对atomic下的一大堆atomic对象感到迷惑,google一把,得到一些有用的信息,与大家分享:
http://www-900.ibm.com/developerWorks/cn/java/j-jtp11234/index.shtml

文章来源:
http://www.cnblogs.com/jobs/archive/2005/03/08/114711.html
真的很棒,推荐大家去看一看!!
http://www.cnblogs.com/Files/jobs/1.rar

文章来源:
http://www.cnblogs.com/jobs/archive/2005/03/18/121437.html
由于DES不再安全,现在都流行使用AES加密算法替代DES,Rijndael是AES的实现。
我从网上找到了很多Rijndael的java实现代码,我用了其中的一个,并且写了一个工具类,使得更方便使用它。
http://www.cnblogs.com/Files/jobs/Rijndael.rar
Rijndael_Util.java是我写的,使用方法如下:
import mit.Rijndael.Rijndael_Util;

String strKey = "欲练神功挥刀子宫";
String plainText = "葵花宝典";

String cipherText = Rijndael_Util.encode(strKey, plainText);
System.out.println(cipherText);
System.out.println(Rijndael_Util.decode(strKey, plainText);
由于Rijindael的算法要求每次加密的数据必须是一个block,blockSize可以是16、24或者32。因此,当需要加密一个byte数组paintBytes时,如果byte数组plainBytes的长度不为blockSize的倍数,则需要补位。此时,就需要一个数值来保留明文byte数组的长度。最初我是用四个byte来保存plainBytes的长度,然后直接放在密文byte数组cipherBytes的最前面。但是我考虑到把直接把明文的长度暴露出来,不是很好,于是,就做了一个处理。
当blockSize为16或者24时,而且plainBytes的长度不为blockSize的倍数,最后一个block的blockSize使用一个长度为blckSize+8的byte数组lastBlockBytes来保存,这样,最后一个block的长度就比普通的block长8个byte,这个8个byte的前4位用来保存plainBytes的长度。
当blockSize为32时,则最后一个block拆为两个block,一个block的长度为16,一个block的长度为24,这样一来,又有多余的8位来保存plainBytes的长度了。
把int变为四个byte和把四个byte读回一个int的实现如下:

public final static void putInt(int val, byte[] bytes, int offSet)
{
bytes[offSet] = (byte) (val >> 24);
bytes[offSet + 1] = (byte) (val >> 16);
bytes[offSet + 2] = (byte) (val >> 8);
bytes[offSet + 3] = (byte) val;
}

public final static int getInt(byte[] bytes, int offSet)
{
return ((bytes[offSet + 0] & 0xff) << 24)
| ((bytes[offSet + 1]) << 16)
| ((bytes[offSet + 2] & 0xff) << 8)
| ((bytes[offSet + 3] & 0xff) << 0);
}
.NET的朋友注意,java中的byte是带符号,而c#中的byte是无符号的。
以前,由于很少写低级的代码,所以对位运算不够熟悉,最初是,把一个int拆成4个byte的算法自己写,但是觉得不够好,后来和flier_lu交流后,flier_lu建议我看java.nio中的ByteBuffer的实现,可能会有收获。我查看后java.nio.Bytes类后,发现了java.nio.Bits的实现比我做的更好一些。java.nio.Bits是一个内部类,不是public,我们不能调用它,但是可以参考他的源码实现。
在这个过程中,我和以往的感觉一样,一个基础类库,开放源码对于使用者会有很大帮助。
最近有人对.NET的前途提出质疑,有人说到关键点上来了:.NET是一个相当封闭的平台。微软对于公开基础类库的源码,在走倒退的道路。以前微软的基础类库MFC是可以查看源码的,你甚至可以调试源码,但是微软提供.NET的基础类库而是不开放源代码的,虽然你可以通过Reflectro或者Mono了解一些基础类库的源码,但这个不能够确定你通过这些途径得到的源码和你正在使用的是一致的。
从.NET转向Java快两年了,越来越对Java的前途充满希望,也很多人一样,对微软的.NET越来越失望。

文章来源:
http://www.cnblogs.com/jobs/archive/2005/03/20/122208.html
jdk 1.5中中,引入了concurrent包,非常棒,在阅读源码时发现其文档的一个小虫,如下:
java.util.concurrent.Semaphore源码中,26行,有如下示例代码:
private static final MAX_AVAILABLE = 100;
应该为:
private static final int MAX_AVAILABLE = 100;
这只是文档中Sample代码的错误,嘻嘻……
我吃饱没事干了??
最近试用了几个数据库
1、MySQL的最新版本mysql-5.0.2-alpha非常不稳定。如果你查询了系统表,例如执行show columns之类的语句,会导致整个数据库崩溃。值得一提的是,MySQL的管理工具和安装配置都有了较大的进步。
2、HSQL,这是一个纯Java的数据库,性能很不错,可以嵌入到程序内部,可以作为一个进程内的数据库,感觉很棒。HSQL是开源的,文档作的不够好,一些系统表的使用,需要直接查看其JDBC Driver实现的源码才得知。
http://sourceforge.net/projects/hsqldb/
3、SQLite,我用了一下,感觉也不错,不过我认为,对于Java开发人员,使用Sqlite就不如直接使用HSQL。Sqlite是使用C开发的数据库,在Java中也可以通过JNI来实现进程内使用(sqlite网站提供了windows平台的dll下载),但是这样,你的程序安装配置就麻烦了。

文章来源:
http://www.cnblogs.com/jobs/archive/2005/02/24/108362.html
架构师?一定是开发人员的职业发展方向吗?
两年前,也很希望自己能够成为一个软件架构设计师。后来,慢慢就失去了兴趣,甚至很不喜欢架构师这个词。
架构师通常是,最大程度利用现有成熟的技术完成产品目标。但在我看来,这意味着妥协,抑制创新,而我恰恰是,一个凭激情和冲动来完成一些挑战性任务,以对现有产品在性能、功能进行大幅度改进的一个人。
架构师通常协调不同的人的设计,达成一种妥协,一种平衡又或取舍。尽管架构师通常对产品的发展,对项目的成功能够起很大的作用,但是,我想在未来的几年内,我还有能力创造的时候,不会刻意要自己成为一个架构师。
我所认识的要做架构师或职位是架构师的人,大多数没有什么技术创新,也没有什么突出成就,所以觉得这个词很虚。认为他们没有什么突出成就,是从一个技术狂热爱好者的角度来看的。注意,我无意贬低他们的工作成果,我承认,从产品方面来看,他们起的作用很大。
我更佩服一些有激情的程序员,也就是老一辈的黑客。例如Dennis Richie和Ken Thompson,他们创造了Unix,C语言,Linus Trovalds创造了Linux。我们会称这些顶级的程序员为大师,称很多优秀的程序员为黑客(不是那种发动网络攻击的黑客)。他们凭激情创造一切,不为常规所约束,是真正的程序员。
我要说明的是,架构师不是程序员,它是更像项目经理的一种角色,充担很多协调性的工作。
我是一个程序员,渴望能够成为一个优秀的程序员,有所创造,我不希望成为一个架构师!这就是我在新年里的职业发展定位。。。

文章来源:
http://www.cnblogs.com/jobs/archive/2005/01/06/87100.html
微软的技术专家Don Box最近在一篇BLOG中提出了对2005年IT技术前景的预测,包括:
Windows平台上的其他非微软浏览器将超越FireFox
Sun公司将拥抱Eclipse
SOA的鼓吹将走到尽头,软件业会找出另一个“大词”来加以鼓吹
Intel和/或AMD会发布6GHZ主频的CPU
BEA不会被收购
尽管有很多新技术发布,微软PDC2005还是会令人失望
Miguel de Icaza会离开Novell加盟Google
苹果会发布Mac OS X媒体中心版本
XML Query、语意web和WS-*不会有任何重大突破
Robert Scoble会登上一份全美重要杂志的封面
我对其中部分十分认同:
1、SOA的鼓吹将走到尽头,软件业会找出另一个“大词”来加以鼓吹
尽管有我十分尊敬的前辈在鼓吹SOA,但似乎他们都没有足够的理由,让我觉得SOA是一件值得注意的事情。我甚至觉得SOA没有任何实质的内容。
2、尽管有很多新技术发布,微软PDC2005还是会令人失望
我估计微软将要发布的一些技术,都不是新技术,都是一些在.NET一种模拟实现。
3、Sun公司将拥抱Eclipse
Eclipse做的实在太好了,比Visual Studio .NET要好得多。SUN自己的IDE连Visual Sutdio .NET也超不过,不如接受Eclipse。。。

文章来源:
http://www.cnblogs.com/jobs/archive/2005/01/01/85167.html
23日出的。不知道RC2有什么改进,我现在机器上安装的是RC1版本,用得好好的,正是版本不出来之前,就不更换了。
PostgreSQL的文档做得不够好。我还不知道8.0比7.0有哪些增强的功能列表 

文章来源:
http://www.cnblogs.com/jobs/archive/2004/12/25/81711.html