概
述
?
???
???
你可以從這里找到常見問(wèn)題的解答。
???
數(shù)據(jù)庫(kù)
Shark
怎樣與其他數(shù)據(jù)庫(kù)進(jìn)行配置?
??? 結(jié)束安裝過(guò)程后,你將有已建好的 HipersonicSQL 數(shù)據(jù)庫(kù)。這還是比較有用的, Shark 也提供了你其他數(shù)據(jù)庫(kù)的選擇: DB2, PostgreSQL, MySQL,....
???
首先你要停止任何可能正在運(yùn)行的
Shark
實(shí)例(
POJO swing
管理
/worklist
管理器,或
CORBA
服務(wù)器)。
???
編輯
configure.properties
文件并為屬性設(shè)置參數(shù):
??? db_loader_job
???
??? 目錄名包含了 Octopus 裝載工作,選項(xiàng)有: db2, hsql, informix, msql, mysql, oracle, postgresql, sybase
??? db_user
???
???
數(shù)據(jù)庫(kù)驗(yàn)證用戶名
??? db_passwd
???
???
數(shù)據(jù)庫(kù)驗(yàn)證密碼
??? db_ext_dirs
???
??? 包含 JDBC 驅(qū)動(dòng)的 jar 文件目錄,如果你需要更多,一個(gè) directory 將被指定 - 通過(guò) ${path.separator} 連接它們
???
??? ${db_loader_job}_JdbcDriver
???
???
要使用的
JDBC
驅(qū)動(dòng)的類名
???
這些項(xiàng)目都被填入了默認(rèn)值。
??? ${db_loader_job}_Connection_Url
???
??? 完整的數(shù)據(jù)庫(kù) URL
???
這些項(xiàng)目也被填入了默認(rèn)值。
??? 運(yùn)行 configure.[bat|sh]
???
???
注意
???
當(dāng)裝載新建的數(shù)據(jù)庫(kù)時(shí),
Octopus
將抱怨無(wú)法卸載索引和表,但這些警告應(yīng)忽略掉。
怎樣清理
Shark
的數(shù)據(jù)庫(kù)?
???
在測(cè)試過(guò)程中,你想清理數(shù)據(jù)庫(kù)并從頭開始。為了清理數(shù)據(jù)庫(kù),你可運(yùn)行
configure.[bat|sh]
文件。如果你不想等待多余的過(guò)濾,
war
文件存檔的話
-
你應(yīng)該運(yùn)行
bin/recreateDB.[bat|sh]
文件。
???
方法稍后只運(yùn)行
Octopus
裝載工作來(lái)卸載以及建立表和索引。
???
怎樣調(diào)整數(shù)據(jù)庫(kù)訪問(wèn)?
??? Shark
引擎是個(gè)組件包,部分利用
DODS
與數(shù)據(jù)庫(kù)交互。
???
似乎有些控制
DODS
特性的參數(shù)很難理解。
??? DatabaseManager.DB.*.Connection.MaxPoolSize
???
???
連接池能承受連接的最大數(shù)目。如果你知道程序不需要太多并發(fā)連接,它可以安全的減少數(shù)目。
??? DatabaseManager.DB.*.ObjectId.CacheSize
???
???
作為組分配和保存在內(nèi)存中的對(duì)象標(biāo)識(shí)符數(shù)目。這些標(biāo)識(shí)符被指派給新數(shù)據(jù)對(duì)象添加到數(shù)據(jù)庫(kù)。
??? DatabaseManager.defaults.cache.maxCacheSize
???
???
根據(jù)對(duì)象存儲(chǔ)的最大數(shù)目限制的緩存大小。當(dāng)緩存已滿,緩存中的對(duì)象按照
LRU
(最近使用)原則被替換為新對(duì)象。
??? DatabaseManager.defaults.cache.maxSimpleCacheSize
??? DatabaseManager.defaults.cache.maxComplexCacheSize
???
???
除了主要對(duì)象緩存,還有兩種查詢緩存可用(簡(jiǎn)單和復(fù)雜)。查詢緩存也是
LRU
緩存。
??? DatabaseManager.defaults.maxExecuteTime
???
???
每次運(yùn)行查詢都比
maxExecuteTime
打印到(
SQL
語(yǔ)句,執(zhí)行時(shí)間和
maxExecuteTime
)日志文件的時(shí)間長(zhǎng)。這種方式可在你的程序或引擎內(nèi)部發(fā)現(xiàn)很細(xì)微的可能問(wèn)題。
??? DatabaseManager.DB.sharkdb.Connection.MaxPoolSize=300
??? DatabaseManager.DB.sharkdb.ObjectId.CacheSize=200
??? DatabaseManager.defaults.cache.maxCacheSize=100
??? DatabaseManager.defaults.cache.maxSimpleCacheSize=50
??? DatabaseManager.defaults.cache.maxComplexCacheSize=25
??? DatabaseManager.defaults.maxExecuteTime=200
???
???
大量的緩存也不總是帶來(lái)高性能,這將導(dǎo)致內(nèi)存的浪費(fèi)和其他問(wèn)題。
???
注意
???
如果你在相同數(shù)據(jù)庫(kù)上運(yùn)行多個(gè)引擎實(shí)例(例如
集群),那就既不要
DODS
也不要
Shark
緩存。
客戶端接口
???
怎樣使用
Shark
庫(kù)
???? 客戶端程序通過(guò) org.enhydra.shark.api.client 包中的一組接口來(lái)訪問(wèn) Shark 庫(kù)。首先客戶端程序應(yīng)該配置庫(kù)或通過(guò)調(diào)用不帶參數(shù)的 configure() 方法(接著采用 Shark.conf 文件配置的 jar ),或通過(guò)指定文件名(做為 String 或 File 對(duì)象)或通過(guò)準(zhǔn)備并調(diào)用 Properties 對(duì)象方法。配置完畢后 org.enhydra.shark.Shark.getInstance() 返回一個(gè) SharkInterface 實(shí)例。從這點(diǎn)開始,客戶端程序開發(fā)者偏愛(或任務(wù))知道程序怎樣使用庫(kù),怎樣得到連接和執(zhí)行指派或得到 AdminInterface 以及管理用戶、組、包, ...
???
例子
1.
不是非常有用的
work-list
管理器
???
例子的第一行,引擎使用
conf/Shark.conf
文件進(jìn)行配置。當(dāng)?shù)玫竭B接和成功連接后,引擎獲取
Resource
對(duì)象,來(lái)確定為用戶進(jìn)行了多少指派(第
4
行)。
??? Shark.configure("conf/Shark.conf");
??? SharkConnection sConn = Shark.getInstance().getConneciton();
??? sConn.connect(userId, passwd, engineName, scope);
??? if (0 < sConn.getResourceObject().how_many_work_item())
??????? System.err.println("Oh, let these tasks wait until tomorrow!");
??? }
??? System.out.println("Job done!");
???
例子
2.
用戶組管理
???
該范例不能運(yùn)行。如果你把
Shark
配置為使用
LDAP user-group
組件,但是基于組件的數(shù)據(jù)庫(kù)開始時(shí)確是空的,所以要做任何實(shí)際的工作你都需要定義至少一個(gè)組和用戶。
??? Shark.configure();
??? UserGroupAdministration ugAdmin =
????? Shark.getInstance().getAdminInterface().getUserGroupAdministration()
? ?? ugAdmin.crateGroup("developers","sweat-shop");
??? ugAdmin.createUser("developers", "user", "secret", "Jane Doe", "some@email.address");
??? System.out.println("Group and user created!");
???
?
??
例子
3.
裝載包到
Shark
庫(kù)
???
包的
XPDL
文件位置與包知識(shí)庫(kù)的根路徑有關(guān)。在你執(zhí)行該操作之前,通過(guò)在客戶端對(duì)象調(diào)用
getDefinedPackagesPath()
方法你將得到所有的包相關(guān)路徑。首先根據(jù)包知識(shí)庫(kù)的根路徑,找到你需要包的
XPDL
文件位置,接著要有
PackageAdministation
實(shí)例。
??? String xpdlName = "test.xpdl";
??? Properties props = new Properties();
??? props.setProperty("enginename","testSharkInstance");
??? props.setProperty("EXTERNAL_PACKAGES_REPOSITORY","c:/Shark/repository/xpdls");
??? Shark.configure(props);
??? String pkgId = Shark.getInstance().getRepositoryManager().getPackageId(xpdlName);
??? PackageAdministration pa = Shark.getInstance().getAdminInterface().getPackageAdministration();
??? if (!pa.isPackageOpened(pkgId)) {
????? pa.openPackage(xpdlName);
??? }
??? System.out.println("Package "+ xpdlName +" is loaded");
???
???
例子
4.
構(gòu)建和開始流程
???
當(dāng)加載
XPDL
到
shark
后,再構(gòu)建它,填入初始化變量值,啟動(dòng)基于
XPDL
定義的流程。
??? String pkgId="test";
??? String pDefId1="basic";
??? String pDefId2="complex";
??? SharkConnection sConn=Shark.getInstance().getConnection();
??? sConn.connect("user","secret","","");
??? WfProcess proc1=sConn.createProcess(pkgId,pDefId1);
??? WfProcess proc2=sConn.createProcess(pkgId,pDefId2);
??? proc1.set_process_context("test_var","This is String variable defined in XPDL for the process basic");
??? proc2.set_process_context("counter",new Long(55));
??? proc1.start();
??? proc2.start();
???
???
例子
5.
設(shè)置變量
???
成功連接上
Shark
后,獲得指派列表,再作些有用的事,比如設(shè)置變量和完成該活動(dòng)。
?? /*
?? SharkConnection sConn;
?? String activityId;
?? String vName;
?? String vValue;
??? */
?? WfAssignment a = null;
?? WfAssignment[] ar = sConn.getResourceObject().get_sequence_work_item(0);
?? for (int i = 0; i < ar.length; ++i) {
????? if (activityId.equals(ar[i].activity().key())) {
???????? a = ar[i];
???????? break;
????? }
?? }
?? if (null == a)
????? throw new BaseException("Activity:"
????????????????????????????? + activityId
????????????????????????????? +" not found in "
????????????????????????????? + sConn.getResourceObject().resource_key()
????????????????????????????? +"'s worklist");
?? if (!a.get_accepted_status())
????? throw new BaseException("I don't own activity "+ activityId);
?? Map _m = new HashMap();
?? WfActivity activity = a.activity();
?? Object c = activity.process_context().get(vName);
?? if (c instanceof Long) {
????? c = new Long(vValue);
?? } else {
????? c = vValue;
?? }
?? _m.put(vName, c);
?? activity.set_result(_m);
?? activity.complete();
??
???
例子
6.
獲得基于標(biāo)準(zhǔn)的流程管理器
???
該范例展示了怎樣獲得基于標(biāo)準(zhǔn)的流程管理器。范例試圖得到包
Id
為
"test"
并且狀態(tài)是
enabled
的所有流程管理器。
?? ExecutionAdministration eAdmin=Shark.getInstance().getAdminInterface().getExecutionAdministration();
?? eAdmin.connect("user","secret","","");
?? WfProcessMgrIterator pmi=eAdmin.et_iterator_processmgr();
?? query="packageId.equals(\"test\") && enabled.booleanValue()";
?? pmi.set_query_expression(query);
?? WfProcessMgr[] procs=pmi.get_next_n_sequence(0);
??
???
例子
7.
獲得基于標(biāo)準(zhǔn)的流程
???
該范例展示了怎樣獲得由基于標(biāo)準(zhǔn)的流程管理器構(gòu)建的流程。范例試圖得到所有狀態(tài)為
"open.running"
,并且是十分種之前啟動(dòng),有
3
個(gè)以上的激活活動(dòng),有叫做
"myvariable"
且值為
"test"
的
String
類型變量的流程。
?? /*
?? WfProcessMgr mgr;
?? */
?? WfProcessIterator wpi=mgr.get_iterator_process ();
?? query="state.equals(\"open.running\") && startTime.longValue()>(java.lang.System.currentTimeMillis()-10*60*1000) && activeActivitiesNo.longValue()>3 && context_myvariable.equals(\"test\")";
?? wpi.set_query_expression(query);
?? WfProcess[] procs=wpi.get_next_n_sequence(0);
??
???
例子
8.
使用外部事務(wù)
?
???
??? Shark API
的每個(gè)方法這樣調(diào)用分離事務(wù):引擎內(nèi)部構(gòu)建,使用,任意提交,最終釋放事務(wù)。這意味著每個(gè)使用
Shark
的簡(jiǎn)單代碼將不知不覺使用很多事務(wù)。
?
???
???
有時(shí),外部事務(wù)要做些不同的事情,于是
SharkTransaction
被引入進(jìn)來(lái)了。一個(gè)程序(的開發(fā)者)會(huì)因?yàn)槎喾N因素選擇使用外部事務(wù),比如使用相同數(shù)據(jù)庫(kù)保存程序(
work-flow
無(wú)關(guān))數(shù)據(jù),這是為避免經(jīng)常構(gòu)建
/
丟棄事務(wù),
...?
???
?
??
當(dāng)然,這種方法也會(huì)有代價(jià):你必須遵從于使用規(guī)則。通過(guò)調(diào)用
Shark.getInstance().createTransaction();
事務(wù)被構(gòu)建,在你釋放一個(gè)事務(wù)之前,程序必須調(diào)用
Shark.getInstance().unlockProcesses(st);
通知
Shark
進(jìn)行內(nèi)部記帳。如果有任何錯(cuò)誤,你必須捕捉
Throwable
(異常)再調(diào)用
Shark.getInstance().emptyCaches(st);
。是的,你甚至應(yīng)該為捕獲錯(cuò)誤而準(zhǔn)備好,另外你將面對(duì)未知狀態(tài)下脫離引擎。
????
這是利用單一事務(wù)進(jìn)行變量設(shè)置的例子。
?
???
????? /*
????? SharkConnection sConn;
????? String activityId;
????? String vName;
????? String vValue;
?????? */
????? SharkTransaction st = Shark.getInstance().createTransaction();
????? try {
???????? WfAssignment a = null;
???????? WfAssignment[] ar = sConn
??????????? .getResourceObject(st)
??????????? .get_sequence_work_item(st, 0);
???????? for (int i = 0; i < ar.length; ++i) {
??????????? if (activityId.equals(ar[i].activity(st).key(st))) {
?????????????? a = ar[i];
?????????????? break;
??????????? }
???????? }
???????? if (null == a)
??????????? throw new BaseException("Activity:"
?????????????????????????????????????? + activityId
?????????????????????????????????????? +" not found in "
?????????????????????????????????????? + sConn.getResourceObject(st).resource_key(st)
?????????????????????????????????????? +"'s worklist");
???????? if (!a.get_accepted_status(st))
??????????? throw new BaseException("I don't own activity "+ activityId);
???????? Map _m = new HashMap();
???????? WfActivity activity = a.activity(st);
???? ????Object c = activity.process_context(st).get(vName);
???????? if (c instanceof Long) {
??????????? c = new Long(vValue);
???????? } else {
??????????? c = vValue;
???????? }
???????? _m.put(vName, c);
???????? activity.set_result(st, _m);
???????? activity.complete(st);
???????? st.commit();
????? } catch (Throwable t) {
???????? Shark.getInstance().emptyCaches(st);
???????? st.rollback();
???????? if (t instanceof RootException)
??????????? throw (RootException)t;
???????? else
??????????? throw new RootException(t);
????? } finally {
???????? try { Shark.getInstance().unlockProcesses(st);} catch (Exception _){}
???????? st.release();
????? }
???
???
(通過(guò)我們的
XPDL
編輯器
JaWE
會(huì)使構(gòu)建
XPDL
變得簡(jiǎn)單。)
???
怎樣為活動(dòng)定義
deadline
表達(dá)式?
???? 在 shark deadline 表達(dá)式中連同所有流程變量,你能使用特殊變量。這些變量的 Java 類型是 java.util.Date ,以下是描述: ? ???
??? PROCESS_STARTED_TIME -
流程開始的時(shí)間
?
???
??? ACTIVITY_ACTIVATED_TIME - 當(dāng)流程流到活動(dòng)以及為活動(dòng)構(gòu)建指派的時(shí)間。 ? ???
???
ACTIVITY_ACCEPTED_TIME -
第一次為活動(dòng)指派的接收時(shí)間。
???
???
注意
?
???
???
如果活動(dòng)在接收后被拒絕,或根本沒有接收,
ACTIVITY_ACCEPTED_TIME
將會(huì)設(shè)置成最大值。
???? 在構(gòu)建 deadline 表達(dá)式時(shí)有些規(guī)則:
??? Deadline 表達(dá)式就是 java.util.Date
???
如果
shark
設(shè)置為沒有重評(píng)估
deadline
,而只是最初評(píng)估
deadline
時(shí)間期限,
ACTIVITY_ACCEPTED_TIME
不會(huì)被用在表達(dá)式中,因?yàn)樗鼘⒃谝院蟀畲髸r(shí)間值。
???
那些不是流程變量(來(lái)自于
XPDL
的
DataField
或
FormalParameter
實(shí)體),和先前列出的其中之一有相同
Id
。
???
一點(diǎn)
deadline
表達(dá)式的例子:
?
???
// Deadline limit is set to 15 secunds after accepting activity
var d=new java.util.Date();
d.setTime(ACTIVITY_ACCEPTED_TIME.getTime()+15000);
d;
// Deadline limit is set to 5 minutes after activity is started (activated)
var d=new java.util.Date();
d.setTime(ACTIVITY_ACTIVATED_TIME.getTime()+300000);
d;
// Deadline limit is set to 1 hour after process is started
var d=new java.util.Date();
d.setTime(PROCESS_STARTED_TIME.getTime()+3600000);
d;
怎樣在
shark
管理程序中定義外部屬性來(lái)更新
/
查看活動(dòng)變量
???
???
為了更新
shark
管理程序中的活動(dòng)變量(由
XPDL
定義),
XPDL
活動(dòng)定義必須包含預(yù)先擴(kuò)充的屬性。
?
???
???
假如
XPDL
流程定義包含叫做
"x"
的變量(
XPDL DataField
標(biāo)記),和叫做
"input_var"
的變量(
XPDL FormalParameter
類型)。
?
???
???
如果在執(zhí)行活動(dòng)時(shí)你想讓管理用戶僅僅查看那些變量,你應(yīng)該定義如下活動(dòng)擴(kuò)展屬性:
?
???
<ExtendedAttribute Name="VariableToProcess_VIEW" Value="x"/>
<ExtendedAttribute Name="VariableToProcess_VIEW" Value="input_var"/>
???
如果你想要用戶更新同樣的變量,你應(yīng)該定義如下活動(dòng)擴(kuò)展屬性:
<ExtendedAttribute Name="VariableToProcess_UPDATE" Value="x"/>
<ExtendedAttribute Name="VariableToProcess_UPDATE" Value="input_var"/>
在
Shark
中怎樣讓
XPDL
使用自定義
Java
類做為變量
?
???
??? 要做到這些,你應(yīng)該定義變量作為 XPDL 的外部引用,并把你想要用的完整 Java 類名做為它的屬性。比如,像這樣: ? ???
...
<DataField Id="participants" IsArray="FALSE">
?? <DataType>
????? <ExternalReference location="org.enhydra.shark.wrd.Participants"/>
?? </DataType>
</DataField>
...
...
<FormalParameter Id="participantGroup" Mode="INOUT">
?? <DataType>
????? <ExternalReference location="org.enhydra.shark.wrd.Participants"/>
?? </DataType>
</FormalParameter>
...
??? 也許更好的途徑是定義 TypeDeclaration 元素做為其類型。那樣的話你就可以隨處用到了(當(dāng)建立程序的 / 子流程的 FormalParameters 時(shí)你不用定義適合的 DataType ): ? ???
...
<TypeDeclaration Id="participants_type">
?? <ExternalReference location="org.enhydra.shark.wrd.Participants"/>
</TypeDeclaration>
...
??? 定義 DataField 或 FormalParameter : ? ???
...
<DataField Id="participants" IsArray="FALSE">
?? <DataType>
????? <DeclaredType Id="participants_type"/>
?? </DataType>
</DataField>
...
<FormalParameter Id="participantGroup" Mode="INOUT">
?? <DataType>
????? <DeclaredType Id="participants_type"/>
?? </DataType>
</FormalParameter>
...
??? 通過(guò) ExternalReference 元素指定的類必須在 shark 類路徑中。
怎樣在
XPDL
中定義變量為
'null'
的初始值
?
???
???
只需簡(jiǎn)單將
DataField
的
InitialValue
元素寫成
"null"
:
??? <DataField Id="participants" IsArray="FALSE">
?? <DataType>
? ???? <DeclaredType Id="participants_type"/>
?? </DataType>
?? <InitialValue>null</InitialValue>
</DataField>
怎樣指定腳本語(yǔ)言
?
???
??? Shark
目前支持三種腳本解釋器:
JavaScript
,
BeanShell
和
Python
(最后一個(gè)未完全測(cè)試)。要告訴
shark
哪種腳本語(yǔ)言被用于書寫條件式(比如在事務(wù)條件中),你應(yīng)該指定包的
script
元素:
?
???
# if you want to use java-like syntax (interpreted by BeanShell), specify:
<Script Type="text/java"/>
# if you want to use java script syntax, specify:
<Script Type="text/javascript"/>
# if you want to use python syntax, specify:
<Script Type="text/pythonscript"/>
??? 如果你沒有指定腳本或指定的值不被 shark 支持, Shark 將會(huì)抱怨。
怎樣利用
XPDL
為特定的
ToolAgent
直接映射程序定義(不需要在運(yùn)行期為程序映射)
?
???
?
??
如果你想直接在
XPDL
中指定
ToolAgent
,
Tool
活動(dòng)將執(zhí)行該
ToolAgent
,所以你應(yīng)該為
XPDL
程序定義設(shè)置一些擴(kuò)展屬性。
?
???
??
?
主要的擴(kuò)展屬性應(yīng)該在每個(gè)程序定義中定義,趨向于映射給名叫
"ToolAgentClass"
的
ToolAgent
,并且它的值應(yīng)該是被執(zhí)行的
tool agent
類全名,例如:
?
???
??? <ExtendedAttribute Name="ToolAgentClass" Value="org.enhydra.shark.toolagent.JavaScriptToolAgent"/>
???
??? 該屬性通過(guò) shark 的 tool agent 定義工具閱讀,并且它執(zhí)行基于該屬性值的特定 ToolAgent 。
???
???
其他外部屬性被指定來(lái)實(shí)現(xiàn)
tool agent
,并通過(guò)它們讀取。比如
JavaScript
和
BeanShell tool agent
指定了名為
"Script"
的外部屬性,而且內(nèi)容是通過(guò)
tool agent
在運(yùn)行期執(zhí)行腳本獲得的。這種情況下,你就是在用
XPDL
編程了,例如:
???
??? <ExtendedAttribute Name="Script" Value="java.lang.System.out.println("I'm going to perform operation c="+a+"*"+b); c=a*b; java.lang.System.out.println("The result is c="+c);"/>
???
該腳本運(yùn)行了變量
"a"
和
"b"
的乘法運(yùn)算,并把結(jié)果保存在
"c"
中(那些變量都是
XPDL
程序定義的形參)。?
請(qǐng)注意!引用、轉(zhuǎn)貼本文應(yīng)注明原譯者:Rosen Jiang 以及出處:http://www.aygfsteel.com/rosen