星期日, 十月 30, 2005

One-Jar Open source

最近因为弄JNI,必须解决一个技术问题,就是自动加载

包含在可执行Jar中的动态库(.dll或.so).

这个问题2年前就碰到过类似的问题,不过当时是用编写脚本用 -

Xbootclasspath/a:作为加载第三方不包含在Jar文件中的class的方法。


虽然可以解决问题,很不完美。

后来用System.load来动态加载JNI的动态库,解决了这个问题后。

突然想到这个老问题,继续尝试以前想到的用ClassLoader来解决这个问题。

具体方法是:把包含在jar文件中的第三方jar包,展开到当前目录或系统临时目录

下,通过loadClass来加载这些包。

任务将近完成的时候,觉的这种方法依然要依赖用户的运行环境,如果是个限制

严格的环境,在临时展开这些class的时候,会出现运行时RuntimeException

终于在google发现了一个 one-jar的方法,是直接通过InputStream来加载

class,这是很大的进步了。仔细看看作者的实现。

http://one-jar.sourceforge.net/

星期六, 十月 29, 2005

JNI 常见问题 FAQ.

JNI 常见问题 FAQ.

  1. 如何从JNI返回一个字符串?
注意:所有JNI Method都有同样的参数, JNIEnv * env, jobject obj
JNIEnv是个系统的工具对象(ToolKit).
可以使用下列语法得到返回一个Java String
C 语法:
jstring str = (*env)->NewStringUTF(env,(char *)变量);

Java JNI 基本使用说明

Java JNI 解说.
步骤:

  1. 先建立一个标准java Class
通过native表明方法是平台相关的.
class TestNative {
     private native void print(); //注意方法声明
     public static void main ( String [ ] args ) {
           new TestNative().print();  //注意调用方法
     }
     static {
           System.loadLibrary ("helloWorld"); // 注意Load 动态库的语法.
     }
}
  • 注意:根据Java JNI 规范,
loadLibrary 根据平台不同会把 库名字修改为本地的lib名字.WindowsLib的名字同参数名字相同后缀上.dll.Unix类的平台下,往往修改为:lib参数名.so的最终名字。比如helloWorldUnix必须把文件名修改为libhelloWorld.so并设置LD_LIBRARY_PATH=包含这个.so的路径,才不会出现java.lang.UnsatisfiedLinkError的异常
  • 生成C用头文件

  • javac TestNative.java

  • javah ?jni TestNative
2.2后会产生一个头文件:TestNative.h内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestNative */

#ifndef _Included_TestNative
#define _Included_TestNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     TestNative
* Method:    print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestNative_print
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
注意红色的: Java_TestNative_print 函数名的生成是按照JNI规范产生的
模式为Java_类名_方法名.

  1. 编辑对应的C代码:
#include <stdio.h>
#include "TestNative.h" //这行必须加入

JNIEXPORT void JNICALL
Java_TestNative_print ( JNIEnv* env, jobject obj )
{
      printf ( "Hello, Native!\n" ) ;
     return ;
}

  1. 编译源程序(注意生成的动态库的命名规则
Linux :
[root]# gcc TestNative.c -o libhelloWorld.so -shared -I /usr/java/j2s
dk1.4.2/include/linux/ -I /usr/java/j2sdk1.4.2/include/
Window:..
  1. 设置路径
Linux:
export LD_LIBRARY_PATH= .so文件所在目录名
  1. java TestNative 得到结果
  Hello, Native!
    

星期四, 十月 27, 2005

JVM Memory Model

JVM Memory Model

Thread可执行的操作:
use(使用)
assign(赋值)
load
store,
lock,
unlock
useassign
Main Memory SubSystem 可执行的操作:
read,
write,
lock,
unlock

这些操作都是Atomic的操作
Main Memory:主内存
Working Memory:工作区内存
关于这些Operation的定义说明:
  • use 动作:使用一个Threaduse 动作把当前Thread里的变量内容传送到Thread的执行引擎.这个动作发生在ThreadJVM指令中使用该变量的值的时候.

  • assign 动作:赋值 一个Threadassign动作 传送Thread引擎的变量值到Threadcopy变量里.这个动作在Thread执行JVM赋值指令的时候.

  • read 动作:读 主内存用稍侯的load动作传送原版变量的值到thread的工作区内存.

  • load 动作:载入 一个Thread把一个值从主内存通过read动作放到thread的工作区的复制的变量

  • store动作: 存储  一个Thread的存储动作是用下面的Write操作传送Thread工作区的复制变量值到主内存。

  • write 动作:写入  主内存的写入动作是通过store动作放一个值从Thread工作区复制变量到在主内存里的原版变量里

  • lock 动作:缩定 Thread和主内存紧密偶合的同步 lock动作造成Thread得到了一个特定锁的声明

  • unlock 动作:解锁 Thread和猪内存的紧密同步,让Thread释放关于特定锁的声明


(image placeholder)


http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html

8.7 Rules for volatile Variables
如果一个变量被申明为volatile,哪个对操作这个变量的Thread有多了额外的约束
T 是个线程.
VWVolatile变量

  • A use operation by T on V is permitted only if the previous operation by T on V was load, and a load operation by T on V is permitted only if the next operation by T on V is use. The use operation is said to be "associated" with the read operation that corresponds to the load.

  • A store operation by T on V is permitted only if the previous operation by T on V was assign, and an assign operation by T on V is permitted only if the next operation by T on V is store. The assign operation is said to be "associated" with the write operation that corresponds to the store.

  • Let action A be a use or assign by thread T on variable V, let action F be the load or store associated with A, and let action P be the read or write of V that corresponds to F. Similarly, let action B be a use or assign by thread T on variable W, let action G be the load or store associated with B, and let action Q be the read or write of W that corresponds to G. If A precedes B, then P must precede Q. (Less formally: operations on the master copies of volatile variables on behalf of a thread are performed by the main memory in exactly the order that the thread requested.)

星期三, 十月 26, 2005

关于Class literal 的一些说明

关于Class literal 的一些说明

JLS 2.0 15.8.1 Lexical Literals 章节说明了”literal”的特定含义
A literal (§3.10) denotes a fixed, unchanging value.
A literal 表示一个固定的,不能改变的值.
因为如此我们把 literal翻译为常数
故此:我们把 Class Literal 翻译为 类常数

JLS 2.0 15.8.2 章节有如下话:
15.8.2 Class Literals(类常数)
A class literal is an expression consisting of the name of a class, interface,
or primitive type followed by a ‘.’ and the token class. The type of a class
is Class. It evaluates to the Class object for the named type (or for void)
defined by the defining class loader of the class of the current instance.
翻译如下:
类常数是有类(class),接口(class)或基本类型(primitive type)的名字接着句号”.”class
记号.

Class的类型是Class. 它相等于对应着名字标记的类型的Class对象(或者void).
这是有当前实例所定义的class Loader来定义的。

Jdk 5.0 的泛性中.class的 类常数表示方法频频使用。设计的目的,还是为了解决,在
reflection 技术中,关于使用基本类型(int,boolean….)作为参数的问题.
比如一个用int作为参数的Method通过.Class.getMethod(String methodName,Class[] param)
因为int本身不是一个Object也没有显式的定义申明,所以重载.class可以把int转换为
Class对象。
基本类型和Class之间的对应关系如下:
        boolean.class   ==   Boolean.TYPE
        char.class      ==   Character.TYPE
        byte.class      ==   Byte.TYPE
        short.class     ==   Short.TYPE
        int.class       ==   Integer.TYPE
        long.class      ==   Long.TYPE
        float.class     ==   Float.TYPE
        double.class    ==   Double.TYPE
        void.class      ==   Void.TYPE

Java Open Source的 Portlet The Portals Pluto Site

http://portals.apache.org/pluto/powered_by_pluto.html

以及企业Portal:
http://portals.apache.org/jetspeed-2

Java Reflection (Java反射)性能说明

Java Reflection in ActionReflection Cost比较昂贵的说法一直很流行。
其实,如果没有太多的getMethod方法的调用。
直接运行方法的cost和通过invoke()Cost基本是一样的。
但在某些情况下,反射书写的代码更加紧凑和幽雅。
比如在实现SQL Type -->Java Type之间的Mapping的时候.
需要更新ResultSetupdateXXX 方法组的时候。
BTW:性能测试代码:
public class TestReflection
{

public static void main(String[] args) throws Exception
{
Object object = new Object();
Class c = Object.class;

int loops = 100000;

long start = System.currentTimeMillis();
for( int i = 0; i < loops; i++ )
{
object.toString();
}
System.out.println( loops + " 正常方法调用:" + (System.currentTimeMillis() - start) + " milliseconds." );
java.lang.reflect.Method method = c.getMethod( "toString", null );

start = System.currentTimeMillis();
for( int i = 0; i < loops; i++ )
{
method.invoke( object, null );
}

System.out.println( loops + " 通过反射调用方法但没有查找方法过程:" + (System.currentTimeMillis() - start) + " milliseconds." );
start = System.currentTimeMillis();
for( int i = 0; i < loops; i++ )
{
method = c.getMethod( "toString", null );
method.invoke( object, null );
}
System.out.println( loops + " 通过反射调用方法包含查找方法过程:" + (System.currentTimeMillis() - start) + " milliseconds." );
}
}
测试结果:
C:\temp>java TestReflection
100000 正常方法调用:109 milliseconds.
100000 通过反射调用方法但没有查找方法过程:125 milliseconds.
100000 通过反射调用方法包含查找方法过程:312 milliseconds.

C:\temp>java -version
java version "1.4.2_09"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_09-b05)
Java HotSpot(TM) Client VM (build 1.4.2_09-b05, mixed mode)

C:\temp>d:\java\jdk1.5.0_05\bin\java TestReflection
100000 正常方法调用:94 milliseconds.
100000 通过反射调用方法但没有查找方法过程:110 milliseconds.
100000 通过反射调用方法包含查找方法过程:328 milliseconds.    

机器配置: 2.6G CPU.512M Memeory. WindowXp sp2

可见在调用次数非常少的情况下,花费的多余时间是可以忽略不计的。
在调用次数非常多的时候,必须注意要减少getMethod 寻找方法的
调用.

有关Java 系统级别和架构上的一些问题。

这里回答了很多经典的Java系统级别的问题:

http://www.javaolympus.com/J2SE/JavaPerformance/JavaReflectionPerformance.jsp

星期日, 十月 23, 2005

FreeMind - free mind mapping software

http://freemind.sourceforge.net/wiki/index.php/Main_Page

Freemind是一实用的开源思维导图/心智(MindMap)软件.它可用来作为:
1.管理项目(包括子任务的管理,子任务的状态,时间记录,资源链接管理).
2.笔记或知识库.
3.头脑风暴(Brain storm)
4.结构化的存储小型数据库.

星期四, 十月 20, 2005

HSQLDB vs Oracle

sqltool.rc 语法,用于SQLTools命令行输入数据.

urlid crm
url jdbc:hsqldb:/temp/testdb
username sa
password

注意:SQLTool命令行,默认commit是不自动提交的,需要设置为--autoCommit

如:
C:\Documents and Settings\William Wang>java -Dsqlfile.charset=UTF-8 -Xms512m -Xm
x512m -jar E:\hsqldb\lib\hsqldb.jar crm test.sql
,倒入了58770条记录。
查看可以使用:
C:\Documents and Settings\William Wang>java -jar e:\hsqldb\lib\hsqldb.jar --sql

速度非常快。

"select count(*) from att_M_dailyattendance" crm


HSQLDB Cached Table的索引都在.data文件里,如果建立索引(index),文件几乎要增加一倍啊。

太可怕了。不过在记录58000条左右的时候,建立索引前和索引后,查询速度几乎没什么变化 啊。
使用分页速度到是没什么变化。
SELECT LIMIT 1 10 * FROM ATT_M_DAILYATTENDANCE

HSQLDB vs MYSQL

语法非常接近。

从Mysql 倒出的Schema Create Script只要简单的调整后就可以了。


从command Line 运行HSQLDB脚本的语法:

java -jar $HSQLDB_HOME/lib/hsqldb.jar urlid file.sql

urlid通过hSQLDB Admin UI 建立的。

HSQLDB对Mysql的default ''的语法理解有点问题,似乎要把mysql脚本中非整数(int)的default语句要全部删除,才可以。
用 UltraEdit regular Expression表达:
find:NOT NULL^(*^),
replace: ^1 NOT NULL,

星期二, 十月 18, 2005

Swing Jpanel任意绝对定位

1.调用setLayout(null);把Layout设置为null
2.添加到JPanel里的组件,使用setBounds(x,y,width,height)来定位。
x,y是相对与左上角(0,0)来定位的。

Very Easy!!!!!!!!!!:)

星期五, 十月 14, 2005

Oracle 10g 企业管理工具

今天装上Oracle 10g,晕了,找不到,企业管理器(Enterprise Manager).

Google了1个多小时,才知道,原来Oracle改变了管理器的UI

全用Web Page来做了,emctl (em=Enterprise Manager)

晕啊,怎么一点兼容性都不考虑啊。

1.emctl start dbconsole
出来如图的说明

Oracle Enterprise Manager 10g Database Control Release 10.2.0.1.0
Copyright (c) 1996, 2005 Oracle Corporation. All rights reserved.
http://IMAGE:1158/em/console/aboutApplication
Starting Oracle Enterprise Manager 10g Database Control ...OracleDBConsolecrm 服
务正在启动 ...............
OracleDBConsolecrm 服务已经启动成功。

2.在Browser用地址:http://IMAGE:1158/em/console/aboutApplication
开始了管理的学习任务,

3.再大叹一声,晕啊。
Oracle 8i,9i,10G,越来越不认识了。
Online DBA Help:http://download-west.oracle.com/docs/cd/B12037_01/server.101/b10742/toc.htm

Unix下如何使用Java 颜色控制码?

Unix Console的AscII颜色控制码的格式是.^[[fg;bgm

fg=前景
bg=后景

fg和bg的手册有相关手册可以查找.标准的字符颜色控制码为^[[0;0m

^[对应的是ASCII 27,(char)0x1b

所以可以用以下代码在Unix环境下打印出来有颜色的提示:

if(System.getProperty("os.name").toLowerCase().indexOf("windows") == -1)System.out.println((char)0x1b+"[1;31m hello World! "+(char)0x1b+"[0;0m");



HSQLDB的排名很高啊。可以用来做企业数据库

http://jdj.sys-con.com/general/readerschoice.htm

Product Company Points
Birdstep RDM Embedded 7.1 Birdstep Technology
24
IBM Informix IDS v10 IBM
79
Daffodil DB Daffodil Software Ltd.
82
ObjectDB for Java/JDO ObjectDB
90
db4o db4objects
97
EAC MySQL Cluster Emic Networks
108
PointBase Embedded PointBase / DataMirror Corp.
139
Oracle Database Lite 10g Oracle Corporation
146
JDataStore 7 High Availability Edition Borland Software
165
Berkeley DB Java Edition Sleepycat Software
175
Sybase Adaptive Server Enterprise (ASE) Sybase, Inc.
258
HSQLDB HSQLDB Development Team
441
IBM DB2 Universal Database IBM
1110
Oracle Database 10g Oracle Corporation
2780

排名第三啊

星期三, 十月 12, 2005

如何在FireFox中播放MP3?

<object id="PlayerEx3" classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6" width="296" height="65"> <param name="autoStart" value="false" /> <param name="LOOP" value="false" /> <param name="URL" value="http://sunose.sitesled.com/music/vitas/TheChorus.m3u" /> <embed LOOP="false" autostart="false" showstatusbar="1" src="http://sunose.sitesled.com/music/vitas/TheChorus.m3u" type="application/x-mplayer2" width="296" height="65" controls="ImageWindow,ControlPanel,StatusBar,TACCtrl" > </embed></object>

星期五, 十月 07, 2005

Netbean 5.0 beta Release.

但是安装后,启动Netbean 5.0 beta,则IDE 处于Freeze 状态。

反复安装几次,依然如故.

最后下载了Jdk 5.0 update 5 才解决了问题。

愚昧。这种东西也能说成是beta?

Sun的产品质量越来越糟糕了。