niyue

Archive for the ‘programming’ Category

DbUnit的相关资料

In javaprogramming on 5月 1, 2005 at 12:00 下午

用 DbUnit 和 Anthill 控制测试环境

Effective Unit Testing with DbUnit

用DbUnit进行SqlMap单元测试

雇用dbunit来维持你的数据环境稳定

iBatis多键值查询

In javaprogramming on 4月 27, 2005 at 10:04 上午
摘自iBATIS SQL Maps 开发指南
Clinton Begin 著
刘 涛 译
Map类型输入参数
假如没必要写一个Java Bean作为参数,而要传入的参数又不只一个时,可以使用Map类(如HashMap,TreeMap等)作为参数对象。例如:
<statement id=”insertProduct” parameterClass=”java.util.Map”>
select * from PRODUCT
where PRD_CAT_ID = #catId#
and PRD_CODE = #code#
</statement>
可以注意到mapped statement的形式完全没有区别!上面的例子中,如果把Map对象作为输入参数去调用mapped statement,Map对象必须包含键值“catId”和“code”。键值引用的对象必须是合适的类型,以上面的例子来说,必须是Integer和String。Result Map(参见以下章节)也支持使用Map类型作为结果参数。要获得更多信息,请参见“Result Map”和“使用SQL Map API编程”部分。
Map类型也可以使用别名。例如,可以用“map”来代替“java.util.Map”。这些别名参见下面的“支持Parameter Map和Result Map的数据类型”表格。

复杂类型集合的属性
Result Map还可以装入代表复杂类型对象集合(List)的属性,用以表示在数据库中相互关系为多对多或一对多的数据。拥有集合属性的类作为“一”的一方,而在集合中的对象作为“多”的一方。用来装入对象集合的mapped statement和上面例子一样。唯一的不同是,让SQL Map架构装入复杂类型集合(List)的业务对象的属性必须是java.util.List或java.util.Collection类型。例如,如果Category拥有Product对象的List,mapped-statement就像下面的例子(假设Category类有一个叫productList的属性,类型是java.util.List):
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>
<result property=”id” column=”CAT_ID”/>
<result property=”description” column=”CAT_DESCRIPTION”/>
<result property=”productList” column=”CAT_ID” select=” getProductsByCatId”/>
</resultMap>
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
</resultMap>
<statement id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>
select * from CATEGORY where CAT_ID = #value#
</statement>
<statement id=”getProductsByCatId” parameterClass=”int” resultMap=”get-product-result”>
select * from PRODUCT where PRD_CAT_ID = #value#
</statement>

Workflow Patterns

In programming on 4月 4, 2005 at 4:24 上午

网上找资料的时候发现了这个网站www.workflowpatterns.com,对工作流模式进行了很详细的介绍,很帅的是对于很多工作流模式都有动画演示,十分通俗易懂.

Welcome to www.workflowpatterns.com the workflow patterns page. This site serves as a repository for workflow modeling patterns. These patterns can be used to examine the expressive power of a workflow server that you intend to work with or they can serve as a set of ideas how to implement given business requirements having some workflow server already deployed in your organization.

jBpm中的泳道

In javaprogramming on 4月 3, 2005 at 1:09 下午

在jBpm的邮件列表上的一些关于jBpm泳道的信息:
2 posible transitions for 2 different roles

Hello,
i’m reading the docs but i can’t see if, being in 1 state and having 2 possible actions (transitions to make), it’s possible to be performed by 2 different roles.
For example :
<state name=”evaluating”>
<transition name=”approve” to=”fork”/>
<transition name=”disapprove” to=”done”/>
</state>
The approve transition can be made by role 1 (swimlane) and the disapprove transition can be made only by another role(swimlane).

Can i do that?… Or how can i represent that scenario..

Thanks a lot.

You are right, it can’t. A state is acted on by one role. (think in states, not in activities!!!!)

You can ofcourse write your own gui and have additional roles there and only allow one actor to submit one transition and vise versa, but that is not what you (and I) want.

Can you explain a little What do you want to achieve? The first to act wins? IF I know a little more detail, I can maybe give you a good answer.

Ronald

jbpm does not do authentication. this should be done by the environment. (e.g. the webapplication environment or the ejb environment).

in one of the previous versions, we had the most generic organisation module possible. turned out not te be generic enough. so we eliminated any dependency from within the jbpm code. Your organisation model should only be used from within your AssignmentHandler implementations. jBPM only stores references to actors as text so they can represent people, groups or systems in your context.

regards, tom.

from one state to two different swimlane ?

Hi,
I have a use case:
– a user can submit a request
– a user can cancel a request
– a manager can approve/reject a request

So I think I need to define two swimlanes, one for requester, and one for manager. However, I donot know how to transition from ‘evaluating’ state to two states which are for different swimlanes:
<!– START-STATE –>
<start-state name=”request”
swimlane=”requester”>
<transition to=”evaluating”/>
</start-state>

<!– NODES –>
<state name=”evaluating”>
<assignment swimlane=”owner” />
<transition name=”approve” to=”done”/>
<transition name=”reject” to=”done”/>
</state>

How do I define the ‘cancel’ state for the requester ? thanks
li xin

How to assign swimlanes properly?

Thanks for your replies…

I used the following state definition:

<state name=”life”>
<assignment swimlane=”human” authentication=”verify” />
<transition to=”death” />
</state>

The test code:

try {
executionService.endOfState(token.getId());
fail(“Task is closed by unauthorized user.”);
} catch (ExecutionException e) {
e.printStackTrace();
}

Now the code passed the test.

As much as I understand from the documentation and your replies, authentication is not part of the primary responsibilities of Jbpm. But we should use getTaskList method in order to assign the tasks to the correct user.

openExecutionService(actorId) method mislead me. I thought that executionService is bound to the actorId. Thus it is responsible of authentication of the endOfState method. However the actorId parameter is passed to the executionService for logging purposes. Thus it is optional.

Thank you very much for your help…

Best regards,

Mert Nuhoglu

Tom Baeyens谈jPdl

In javaprogramming on 4月 3, 2005 at 11:36 上午

在sourceforge的jBpm项目的论坛上看到的Tom的言论:Ardian,

The reason why jBpm sticks to UML-activity-diagrams is for easy-acceptance.
Petri nets are easy, but not as easy and widespread as UML-activity-diagrams.
The downside of UML-activity-diagrams is that they are not exact and they do not contain enough information to specify a complete business process.
That is why each tool or standard that starts from an UML-activity-diagram has to extend the diagrams with information such as : which data-items are input/output on which activities, how does the process interact with other systems, to whom will the activity be assigned, …
jBpm specifies these extensions in http://jbpm.org/new/jpdl.html

So after extending the UML-activity-diagram concepts, the resulting language will be quite close to high-level-petri-nets.
That is why, in my opinion, high-level-petri-nets should be seen as the ‘mother of all process languages’
So a good BPM-system should present an easy interface to the users (=process developers) and base the internal impementation on high-level-petri-nets.
As for jBpm I think using UML-activity-diagrams is an easy way of presenting the concepts to users that lowers the learning curve. But I did not yet have time to actually compare jBpm’s interal model with high-level-petri-nets or YAWL. But I’m convinced they will not be far apart.

I talked last month to Wil van der Aalst (after I wrote the initial message of this thread) and it is also his vision that BPM-tools should be based internally on high-level-petri-nets (or YAWL) and that they should try to present it as easy as possible to the user. YAWL is an exact specified version of high-level-petri-nets that is customized for building process definitions. He thinks of YAWL as a kind of playground for research-purposes. So I got the impression that he didn’t expect that YAWL would be used in BPM-engines at this stage.

Now, I’m starting to form a new vision on standards and languages. I want to build jBpm in 2 layers : a generic layer and a set of default implementations. jBpm’s delegation principle (see http://jbpm.org/new/concepts.html#delegationprinciple) is in my opinion a very good basis for such an approach.
The generic layer should be a kind of framework for BPM-systems. The generic layer should be the basis of a BPM-engine in which implementations can be plugged (i.e. in a process definition). The generic layer should be constructed in a way that implementations can be plugged that support all workflow-patterns (see http://tmitwww.tm.tue.nl/research/patterns)
By separating these two layers, support of a specific standard or behaviour should be easy to add.

Regards, Tom.

xalan处理xslt遇到的uri异常

In javaprogramming on 3月 19, 2005 at 3:13 下午

昨天在用xalan处理xslt样式表时遇到了以下异常:com.sun.org.apache.xml.internal.utils.URI$MalformedURIException: URI 中未找到模式.因为处理的这个样式表原来在Stylus Studio里面使用过,显示是正常的,这里应该也不会有什么问题,但是在重构代码的时候将xsl文件的读取由硬编码文件路径改成为用ClassLoader的getResource方法来进行读取了.

开始的时候丝毫没有意识到是这里出了问题,还以为是xsl文件中引用的uri出了问题(因为上面那个异常导致了xalan编译xsl样式表的时候无法找到import的locale.xsl文件,于是编译器又报了locale.xsl中定义的变量找不到的错误,就是这个错误误导了我好长时间而没有发现错误的源头),修改了好半天的xsl文件都没发现有问题,而且用xalan.jar直接进行xslt转换可以通过,弄了一个晚上也没搞懂到底是怎么回事,彻底没想法掉了那个时候.

今天放松了一天,回来继续看的时候去看了一下uri解析的源码,本来想看看这个uri到底是怎么解析而后出错的,好不容易找到这段报错在源码中的位置,但是看不懂这里到底怎么解析的,和其他部分源码的关联太高了,不过看的时候看到了解析的时候有关于slash符号”/”的解析,有种顿悟的感觉,因为前面ClassLoader的getResource方法给出的绝对路径是以”/”开始的(像/G:/src/xsl/folder.xsl这种形式),开始看着就觉得很奇怪,但是直接使用这个路径确实找的到样式表所以也就没去多想,但是实际情况是xalan如果用这种路径访问样式表对于样式表中import的样式表就找不到(异常显示说没有这种模式)!

不知道这算不算是xalan的一个bug呢?或者是jdk的一个bug,ClassLoader的getResource方法给出的路径为什么前面加上一个”/”要?呼,即使不是一个bug的话,也是在这两个api同时使用时会出现的一个问题,解决方法很简单,把getResource得到的路径前面的”/”去掉就可以了,xalan一下就通过了这一样式表的编译,其他地方对这一路径的使用也没问题.

Sawmill–日志分析工具

In programmingsoftware on 3月 13, 2005 at 12:30 下午

Sawmill is a powerful, hierarchical log analysis tool that runs on every major platform. It is particularly well suited to web server logs, but can process almost any log. The reports that Sawmill generates are hierarchical, attractive, and heavily cross-linked for easy navigation. Complete documentation is built directly into the program.

Here are just a few of the major features of Sawmill:

这几天在使用Tiles+Struts搭一个portal的框架,使用的过程中发现很多debug信息都输出到Tomcat的标准输出流上去了,每次都要查看那个文本的log实在是不方便,满在google上面搜了一下想看看是否有这中工具,没想到真的让我找到了,功能很强大,Sawmill~

Java中的异常处理

In javaprogramming on 3月 12, 2005 at 5:18 上午

The Dilemma of Exception 来自 透明思考

现在的异常体系设计是:系统内部所有异常继承同一个基类BaseException,BaseException又继承RuntimeException。在一个层次(例如DAO层或者Business Service层)中有一个异常基类,对于每种具体的出错情形再派生一个新的异常类,例如UserCannotFound、HaveNoPermission等等。
这样做的好处是避免了在接口上出现异常签名,因为“抛出哪种异常”是方法的私事。如果接口签名上指明详细的异常信息,又采用Checked Exception,当方法内部实现改变时,接口就会受到影响;如果接口签名上只泛泛地标注一个高层次异常(例如Exception甚至Throwable),又起不到任何提示的效果。
但是接口上不留异常签名又带来另一个问题:client程序员要到运行时(甚至可能要过相当长的时间)才知道这个方法可能抛出哪些异常,给编写代码造成相当大的麻烦。我想的折中办法是:(1)方法稳定之后,在接口上标注异常签名,由于全部异常继承RuntimeException,即使接口异常签名改变也不会破坏client;(2)用一个拦截器把所有异常log到统一的地方,并提供足够的信息,方便调试。

ExceptionHandler 异常处理 来自 冰云@Blogging

我现在的异常处理和你做的差不多。每一层都有BaseUnckeckedException,但有时候也用CheckedException。以前在onjava看到过一篇讨论受它影响比较深。对于无法处理的异常,就用UnChecked,例如SQL错误,产生于DAL,对于系统的来说是致命的。交给BusinessLayer毫无用处,因此抛出DaException。如果是有用的可处理的例如处理用户登录的时候,UserNotExistException或PasswordNotVerfiedException就用CheckedException,交给Client去处理,显示不同的信息。 另外,在处理异常方面,我现在采用的是Struts1.1的ExceptionHandler机制。在ExceptionHandler捕获所有的Throwable,然后交给一个统一的或者按照module区分的Error.Jsp页面来显示。 另外有一个问题就是i18n在异常中如何处理。抛出的异常最终会显示到界面上。如果不做任何i18n处理恐怕不够友好。因此我让所有的自定义Exception实现一个ErrorKeyable接口。包含的Error就是i18n的key。如果我在ExceptionHandler中得到的Exception是ErrorKeyable的实例,那么就显示定制的错误信息。如果不是,就显示Unkown Error,呵呵。然后做个按钮在错误页让用户提交给admin。

早就想写一篇异常处理的文章。今天看到gigix写了一篇《The Dilemma of Exception》
基于他的观点,我也写了一点东西。基本上,思路是一致的。

trackback不能用真是郁闷。

我现在的异常处理和gigix做的差不多。每一层都有BaseUnckeckedException,但有时候也用到CheckedException。以前在onjava看到过一篇讨论受它影响比较深。对于无法处理的异常,就用UnChecked。例如SQL错误,产生于DAL,对于系统的来说是致命的。交给BusinessLayer毫无用处,因此抛出DaException。如果是有用的可处理异常就应该处理。例如用户登录的时候会产生UserNotExistException或PasswordNotVerfiedException,就用CheckedException,交给Client去处理,以显示不同的信息。 Gigix的异常签名方法看起来很好。下次可以试试看。将Exception标记在javadoc中也是应该考虑的事情。在处理异常方面,我现在采用的是Struts1.1的ExceptionHandler机制。用ExceptionHandler捕获所有的Throwable,交给一个统一的或者按照module区分的Error.Jsp页面来显示。 有一个问题就是在异常中如何处理i18n。抛出的异常最终会显示到界面上。如果不做任何i18n处理恐怕不够友好。因此我让所有的自定义Exception实现一个ErrorKeyable接口。包含的ErrorKey就是i18n的key。如果我在ExceptionHandler中得到的Exception是ErrorKeyable的实例,那么就显示定制的错误信息。如果不是,就显示Unkown Error,呵呵。当然,对于后台产生的错误以及Exception的Message,服务器的locale基本不变,并且log只有开发人员或网管才看。因此i18n毫无用处,所以内部的ExceptionMessage采用中文或者英文均可。我是采用英文,因为中的的话,不同的编译环境还可能导致乱麻。还不如英文呢简单。最后做个按钮在错误页上,一旦产生错误,就让用户按按钮将错误信息提交给admin以便记录。 后台已经有了log为什么还要这样做哪?以上的部分已经在项目中实施,基本上比较方便。不用看到Tomcat中蓝色Stupid错误提示。

JIRA破解

In javaprogramming on 3月 8, 2005 at 7:40 上午

JIRA可真是个好东西啊,自定义能力超强,虽然主要是用来做bug跟踪管理的,但是很容易的就可以改造成项目管理系统.只可惜是要收费的,为了使用它,sorry啊,只好下载了一个注册机.不过下载的注册机是JIRA3.0版的,现在的JIRA已经出到3.1版了.试了一下发现注册机不行用.几乎放弃了就,但是仔细分析了一下JIRA的包的结构,发现注册机不行用很可能是因为3.1版的包结构改变了,破解需要的那个licence包的位置变掉了.于是抱着侥幸心理把下载的注册机keygen.class反编译了一下,结果发现注册机没有被混淆过,很容易就看到了所有的代码,于是就将注册机import的包名改了一下,重新编译,呃,可以用了,真是对不起,做了错事了.

// Decompiled by DJ v3.7.7.81 Copyright 2004 Atanas Neshkov Date: 2005-2-26 22:13:16
// Home Page :
http://members.fortunecity.com/neshkov/dj.html – Check often for new version!
// Decompiler options: packimports(3)
// Source File Name: keygen.java

import com.atlassian.License.LicensePair;
import java.io.*;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;

public class keygen
{

public keygen()
{
}

public static void main(String args[])
throws IOException
{
try
{
long l = 267L;
long l1 = System.currentTimeMillis();
long l2 = System.currentTimeMillis();
String s = “”;
System.out.println(“Keygen for JIRA Enterprise Edition.”);
System.out.print(“created by mydaj[ROR].”);
do
{
System.out.print(“\nEnter your organization name: “);
for(int i = System.in.read(); i != 10 && i != 13; i = System.in.read())
s = s + (char)i;

} while(s == “”);
try
{
PKCS8EncodedKeySpec pkcs8encodedkeyspec = new PKCS8EncodedKeySpec(EncodedPrvKey);
KeyFactory keyfactory = KeyFactory.getInstance(“DSA”, “SUN”);
java.security.PrivateKey privatekey = keyfactory.generatePrivate(pkcs8encodedkeyspec);
String s1 = Long.toString(l, 10);
s1 = s1 + “^^”;
s1 = s1 + Long.toString(l1, 10);
s1 = s1 + “^^”;
s1 = s1 + Long.toString(l2, 10);
s1 = s1 + “^^”;
s1 = s1 + s;
byte abyte0[] = s1.getBytes();
Signature signature = Signature.getInstance(“SHA1withDSA”);
signature.initSign(privatekey);
signature.update(abyte0);
byte abyte1[] = signature.sign();
LicensePair licensepair = null;
try
{
licensepair = new LicensePair(abyte0, abyte1);
}
catch(Exception exception1)
{
exception1.printStackTrace();
}
System.out.println(s1);
System.out.println(“Your license key is: “);
System.out.println(licensepair.toString());
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
catch(IOException ioexception) { }
}

static byte EncodedPrvKey[] = {
48, -126, 1, 75, 2, 1, 0, 48, -126, 1,
44, 6, 7, 42, -122, 72, -50, 56, 4, 1,
48, -126, 1, 31, 2, -127, -127, 0, -3, 127,
83, -127, 29, 117, 18, 41, 82, -33, 74, -100,
46, -20, -28, -25, -10, 17, -73, 82, 60, -17,
68, 0, -61, 30, 63, -128, -74, 81, 38, 105,
69, 93, 64, 34, 81, -5, 89, 61, -115, 88,
-6, -65, -59, -11, -70, 48, -10, -53, -101, 85,
108, -41, -127, 59, -128, 29, 52, 111, -14, 102,
96, -73, 107, -103, 80, -91, -92, -97, -97, -24,
4, 123, 16, 34, -62, 79, -69, -87, -41, -2,
-73, -58, 27, -8, 59, 87, -25, -58, -88, -90,
21, 15, 4, -5, -125, -10, -45, -59, 30, -61,
2, 53, 84, 19, 90, 22, -111, 50, -10, 117,
-13, -82, 43, 97, -41, 42, -17, -14, 34, 3,
25, -99, -47, 72, 1, -57, 2, 21, 0, -105,
96, 80, -113, 21, 35, 11, -52, -78, -110, -71,
-126, -94, -21, -124, 11, -16, 88, 28, -11, 2,
-127, -127, 0, -9, -31, -96, -123, -42, -101, 61,
-34, -53, -68, -85, 92, 54, -72, 87, -71, 121,
-108, -81, -69, -6, 58, -22, -126, -7, 87, 76,
11, 61, 7, -126, 103, 81, 89, 87, -114, -70,
-44, 89, 79, -26, 113, 7, 16, -127, -128, -76,
73, 22, 113, 35, -24, 76, 40, 22, 19, -73,
-49, 9, 50, -116, -56, -90, -31, 60, 22, 122,
-117, 84, 124, -115, 40, -32, -93, -82, 30, 43,
-77, -90, 117, -111, 110, -93, 127, 11, -6, 33,
53, 98, -15, -5, 98, 122, 1, 36, 59, -52,
-92, -15, -66, -88, 81, -112, -119, -88, -125, -33,
-31, 90, -27, -97, 6, -110, -117, 102, 94, -128,
123, 85, 37, 100, 1, 76, 59, -2, -49, 73,
42, 4, 22, 2, 20, 42, 50, -88, 30, 125,
-37, 118, -50, 20, -82, -63, 0, 8, -36, 106,
-9, -110, 124, 107, 68
};

}

Spring中的异常

In javaprogramming on 3月 2, 2005 at 10:36 上午
public class BeanDefinitionStoreException
extends FatalBeanException

Exception thrown when a BeanFactory encounters an internal error, and its definitions are invalid: for example, if an XML document containing bean definitions isn’t well-formed.

程序中抛出了这个异常,检查了半天也没发现原因,后来仔细看了一下print stack信息,发现原来我同时在最外层的类和其中引用的其他类中使用了spring,出错发生在引用类中,所以是引用类的spring bean的xml文件出错了,出错的原因用XML SPY配合spring-bean.dtd一检查,原来是把java的注释符号//当成xml中的注释符号<!– –>来用了~