Apache的BCEL庫,文檔很少,例子也很簡單。動態(tài)構建類的工作,要求的只是并不是熟練使用BCEL類庫本身,而是要對java的class結構了解。我對java的pcode也不熟悉,但是我曾經(jīng)做過大量的.NET的反編譯工作,兩者類似,所以我用BCEL也不覺得困難。
我提供一個例子,這里例子是使用BCEL創(chuàng)建類的實例,而不是使用反射。
如下:
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);

// 創(chuàng)建構造函數(shù)

{
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、密鑰必須隨機產(chǎn)生
2、密鑰不能重復使用
3、密鑰和密文的長度是一樣的。
one-time pad是最安全的加密算法,雙方一旦安全交換了密鑰,之后交換信息的過程就是絕對安全的啦。這種算法一直在一些要求高度機密的場合使用,據(jù)說美國和前蘇聯(lián)之間的熱線電話、前蘇聯(lián)的間諜都是使用One-time pad的方式加密的。不管超級計算機工作多久,也不管多少人,用什么方法和技術,具有多大的計算能力,都不可能破解。
一次一密的一種實現(xiàn)方式,如下:

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不再安全,現(xiàn)在都流行使用AES加密算法替代DES,Rijndael是AES的實現(xiàn)。
我從網(wǎng)上找到了很多Rijndael的java實現(xiàn)代碼,我用了其中的一個,并且寫了一個工具類,使得更方便使用它。
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的算法要求每次加密的數(shù)據(jù)必須是一個block,blockSize可以是16、24或者32。因此,當需要加密一個byte數(shù)組paintBytes時,如果byte數(shù)組plainBytes的長度不為blockSize的倍數(shù),則需要補位。此時,就需要一個數(shù)值來保留明文byte數(shù)組的長度。最初我是用四個byte來保存plainBytes的長度,然后直接放在密文byte數(shù)組cipherBytes的最前面。但是我考慮到把直接把明文的長度暴露出來,不是很好,于是,就做了一個處理。
當blockSize為16或者24時,而且plainBytes的長度不為blockSize的倍數(shù),最后一個block的blockSize使用一個長度為blckSize+8的byte數(shù)組lastBlockBytes來保存,這樣,最后一個block的長度就比普通的block長8個byte,這個8個byte的前4位用來保存plainBytes的長度。
當blockSize為32時,則最后一個block拆為兩個block,一個block的長度為16,一個block的長度為24,這樣一來,又有多余的8位來保存plainBytes的長度了。
把int變?yōu)樗膫€byte和把四個byte讀回一個int的實現(xiàn)如下:

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的實現(xiàn),可能會有收獲。我查看后java.nio.Bytes類后,發(fā)現(xiàn)了java.nio.Bits的實現(xiàn)比我做的更好一些。java.nio.Bits是一個內(nèi)部類,不是public,我們不能調(diào)用它,但是可以參考他的源碼實現(xiàn)。
在這個過程中,我和以往的感覺一樣,一個基礎類庫,開放源碼對于使用者會有很大幫助。
最近有人對.NET的前途提出質疑,有人說到關鍵點上來了:.NET是一個相當封閉的平臺。微軟對于公開基礎類庫的源碼,在走倒退的道路。以前微軟的基礎類庫MFC是可以查看源碼的,你甚至可以調(diào)試源碼,但是微軟提供.NET的基礎類庫而是不開放源代碼的,雖然你可以通過Reflectro或者Mono了解一些基礎類庫的源碼,但這個不能夠確定你通過這些途徑得到的源碼和你正在使用的是一致的。
從.NET轉向Java快兩年了,越來越對Java的前途充滿希望,也很多人一樣,對微軟的.NET越來越失望。

文章來源:
http://www.cnblogs.com/jobs/archive/2005/03/20/122208.html
jdk 1.5中中,引入了concurrent包,非常棒,在閱讀源碼時發(fā)現(xiàn)其文檔的一個小蟲,如下:
java.util.concurrent.Semaphore源碼中,26行,有如下示例代碼:
private static final MAX_AVAILABLE = 100;
應該為:
private static final int MAX_AVAILABLE = 100;
這只是文檔中Sample代碼的錯誤,嘻嘻……
我吃飽沒事干了??
最近試用了幾個數(shù)據(jù)庫
1、MySQL的最新版本mysql-5.0.2-alpha非常不穩(wěn)定。如果你查詢了系統(tǒng)表,例如執(zhí)行show columns之類的語句,會導致整個數(shù)據(jù)庫崩潰。值得一提的是,MySQL的管理工具和安裝配置都有了較大的進步。
2、HSQL,這是一個純Java的數(shù)據(jù)庫,性能很不錯,可以嵌入到程序內(nèi)部,可以作為一個進程內(nèi)的數(shù)據(jù)庫,感覺很棒。HSQL是開源的,文檔作的不夠好,一些系統(tǒng)表的使用,需要直接查看其JDBC Driver實現(xiàn)的源碼才得知。
http://sourceforge.net/projects/hsqldb/
3、SQLite,我用了一下,感覺也不錯,不過我認為,對于Java開發(fā)人員,使用Sqlite就不如直接使用HSQL。Sqlite是使用C開發(fā)的數(shù)據(jù)庫,在Java中也可以通過JNI來實現(xiàn)進程內(nèi)使用(sqlite網(wǎng)站提供了windows平臺的dll下載),但是這樣,你的程序安裝配置就麻煩了。

文章來源:
http://www.cnblogs.com/jobs/archive/2005/02/24/108362.html
架構師?一定是開發(fā)人員的職業(yè)發(fā)展方向嗎?
兩年前,也很希望自己能夠成為一個軟件架構設計師。后來,慢慢就失去了興趣,甚至很不喜歡架構師這個詞。
架構師通常是,最大程度利用現(xiàn)有成熟的技術完成產(chǎn)品目標。但在我看來,這意味著妥協(xié),抑制創(chuàng)新,而我恰恰是,一個憑激情和沖動來完成一些挑戰(zhàn)性任務,以對現(xiàn)有產(chǎn)品在性能、功能進行大幅度改進的一個人。
架構師通常協(xié)調(diào)不同的人的設計,達成一種妥協(xié),一種平衡又或取舍。盡管架構師通常對產(chǎn)品的發(fā)展,對項目的成功能夠起很大的作用,但是,我想在未來的幾年內(nèi),我還有能力創(chuàng)造的時候,不會刻意要自己成為一個架構師。
我所認識的要做架構師或職位是架構師的人,大多數(shù)沒有什么技術創(chuàng)新,也沒有什么突出成就,所以覺得這個詞很虛。認為他們沒有什么突出成就,是從一個技術狂熱愛好者的角度來看的。注意,我無意貶低他們的工作成果,我承認,從產(chǎn)品方面來看,他們起的作用很大。
我更佩服一些有激情的程序員,也就是老一輩的黑客。例如Dennis Richie和Ken Thompson,他們創(chuàng)造了Unix,C語言,Linus Trovalds創(chuàng)造了Linux。我們會稱這些頂級的程序員為大師,稱很多優(yōu)秀的程序員為黑客(不是那種發(fā)動網(wǎng)絡攻擊的黑客)。他們憑激情創(chuàng)造一切,不為常規(guī)所約束,是真正的程序員。
我要說明的是,架構師不是程序員,它是更像項目經(jīng)理的一種角色,充擔很多協(xié)調(diào)性的工作。
我是一個程序員,渴望能夠成為一個優(yōu)秀的程序員,有所創(chuàng)造,我不希望成為一個架構師!這就是我在新年里的職業(yè)發(fā)展定位。。。

文章來源:
http://www.cnblogs.com/jobs/archive/2005/01/06/87100.html
微軟的技術專家Don Box最近在一篇BLOG中提出了對2005年IT技術前景的預測,包括:
Windows平臺上的其他非微軟瀏覽器將超越FireFox
Sun公司將擁抱Eclipse
SOA的鼓吹將走到盡頭,軟件業(yè)會找出另一個“大詞”來加以鼓吹
Intel和/或AMD會發(fā)布6GHZ主頻的CPU
BEA不會被收購
盡管有很多新技術發(fā)布,微軟PDC2005還是會令人失望
Miguel de Icaza會離開Novell加盟Google
蘋果會發(fā)布Mac OS X媒體中心版本
XML Query、語意web和WS-*不會有任何重大突破
Robert Scoble會登上一份全美重要雜志的封面
我對其中部分十分認同:
1、SOA的鼓吹將走到盡頭,軟件業(yè)會找出另一個“大詞”來加以鼓吹
盡管有我十分尊敬的前輩在鼓吹SOA,但似乎他們都沒有足夠的理由,讓我覺得SOA是一件值得注意的事情。我甚至覺得SOA沒有任何實質的內(nèi)容。
2、盡管有很多新技術發(fā)布,微軟PDC2005還是會令人失望
我估計微軟將要發(fā)布的一些技術,都不是新技術,都是一些在.NET一種模擬實現(xiàn)。
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有什么改進,我現(xiàn)在機器上安裝的是RC1版本,用得好好的,正是版本不出來之前,就不更換了。
PostgreSQL的文檔做得不夠好。我還不知道8.0比7.0有哪些增強的功能列表 

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