部落客廣告聯播

2009年12月11日 星期五

WebApp從tomcat遷移到jboss的data source問題

最近將WebApp從tomcat包成war檔移到jboss上,但卻履出現deploy failed失敗訊息,
後來發現是data source問題,若web.xml裡面有<resource-ref>參考到資料來源的話,
就要多一個jboss-web.xml設定jndi連結,詳細請參考:
JBoss deployment failure - missing resource-ref element in web.xml
How to configure the Jira DataSource on JBoss

2009年11月18日 星期三

JPA 使用annotation設定self join結構的Entity bean

請參考:
http://detailfocused.blogspot.com/2009/05/jpa-self-join-table.html

JPA/hibernate 使用MySQL讓資料為UTF-8 encoding

使用JPA/hibernate時若要讓預設資料庫的encoding為utf-8,並預設engine為innodb,則設定my.cnf在[mysqld]區段加上:
default-character-set=utf8
default-collation=utf8_general_ci
default-storage-engine=innodb
另外,Datasource JDBC url要加上
?characterEncoding=UTF-8&useUnicode=true&connectionCollation=utf8_general_ci&characterSetResults=utf8

2009年10月15日 星期四

Liferay Portal繁體中文翻譯外掛

Liferay Portal是一套功能相當齊全的open source portal server,
但國內似乎不是很多人用,
然而其內附的介面中文翻譯說真的是辭不達意容易令人造成誤解(或不解),
我猜應該是外國人用翻譯軟體做的。
今小弟重新整理了zh_TW的中文翻譯,並做成了外掛,放在這裡,
歡迎有需要的人下載使用。

安裝方法 -
將此 WAR 檔案放到 ${liferay_home_dir}/deploy 後,
Liferay portal會自動進行安裝,
待安裝完後,請刪除Tomcat的Work內的所有檔案,重啟Tomcat。

關於如何使用Plug-in SDK 來修改語言 properties可參考:
http://wikis.sun.com/display/websynergy/
Customizing+Language.properties+using+hooks+plugin

2009年10月6日 星期二

OpenSSO安裝問題

將OpenSSO WAR檔上到了tomcat,開啟Web介面執行第一次設定時,
使用簡易設定(使用內建OpenDS)會發生NullPointException,
tomcat console會出現「@BASE_DIR@\install.log找不到檔案路徑」訊息,
經百般找尋解決方法,發現到windows 控制台設定地區選項先改為英語-美國,
確認後重啟tomcat,開啟Opensso Web介面,再次執行配置就OK了,
接著再次將地區選項設回來
,即可正常使用。

問題在於內建的OpenDS在叫用java的KeyTool工具產生金鑰時,
若我們當前使用者設定的地區非為英文語系者,則Keytool產生的提示訊息非為英文語系,
則此時便會無法正常產生金鑰,便會導致此失敗~~


詳請見:
http://markmail.org/message/5ne5lcjzoezxarlz#query:Error%20while%20attempting%20to%20generate%20a%20self-signed%20certificate%20ads-certificate%20in%20the%20trust%20store%20file%20config%2Fads-truststore%3A%20KeyStoreException%28Multi-prompt%20didn%27t%20match+page:1+mid:sjwepz5abub4nbmp+state:results

2009年9月18日 星期五

啟用tomcat內建之HTTPS

1. 到 %JAVA_HOME%\bin目錄, 執行:
keytool -genkey -alias tomcat -keyalg RSA
輸入keystore密碼: **********
您的名字與姓氏是什麼?
[Unknown]: Lili.Wang
您的組織單位名稱是什麼?
[Unknown]: myCompany
您的組織名稱是什麼?
[Unknown]: myCompany
您所在的城市或區域名稱是什麼?
[Unknown]: Taipei
您所在的州或省份名稱是什麼?
[Unknown]: Taiwan
該單位的兩字母國家代碼是什麼
[Unknown]: TW
CN=Lili.Wang, OU=myCompany, O=myCompany, L=Taipei, ST=Taiwan, C=TW正確嗎?
[否]: y

輸入的主密碼
(如果和 keystore 密碼相同,按回車): {{直接按enter}}

2. 編輯 tomcat 的conf\server.xml找到下面區段,取消註解,並加上紅字部分,紅字雙引號內的值與第一步的密碼要相同
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true" keystorePass="**********"
clientAuth="false" sslProtocol="TLS" />

3. 重啟Tomcat

4. 開啟瀏覽器 https://localhost:8443 ,測試是否成功

(P.S. 要注意的是如果用admin1身份執行tomcat,則就要以admin1登入執行
keytool -genkey指令)

2009年9月17日 星期四

Tomcat 開啟 Access Log

Access Log會紀錄哪個時間哪個IP連入tomcat哪個網址,
tomcat是使用VALV的機制達成(類似filter),預設並無開啟,
若要開啟則須 修改conf\server.xml,找到內有一段
directory="logs" prefix="localhost_access_log." suffix=".log"
pattern="common" resolveHosts="false"/>
把前後包夾的註解符號拿掉後,存檔,重啟tomcat,便會在log目錄裡面看到
localhost_access_log.開頭的紀錄檔了。

2009年8月19日 星期三

tomcat server.xml設定全域的DataSource / mailSession資源

所謂全域就是指同一tomcat中的所有context

1. 在server.xml的<globalnamingresources>中加入新的<resource>元素。
2. 在context.xml的<context>中加入 <resourcelink name="mail/MailSession" global="mail/MailSession" type="javax.sql.DataSource"></resourcelink>

2009年8月4日 星期二

JAVA Cache System

Java Cache System 是Apache Jakarta下的一個子專案,
下為一篇介紹Java Cache System的文章:

Knowing Cache and Java Cache System(英文)

Apache的Mail Server、FTP Server都是純JAVA的

Apache JAMES Mail Server

而要將JAMES使用Windows Services的方式執行:
\bin>wrapper -i ..\conf\wrapper.conf
移除windows service:
\bin>wrapper -r ..\conf\wrapper.conf

Apache FTP Server

要將FTP Server以服務方式執行:
\bin\
service install
移除windows service:
\bin\service remove

2009年7月20日 星期一

Eclipse + tomcat 遠端Debug

[Tomcat端]
修改catalina.bat
set JAVA_OPTS=%JAVA_OPTS% -Xmx256m 這行後面加上
-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888

[Eclipse端]
自己google一下吧

2009年6月21日 星期日

Apache Directory Server

Apache DS是一個通過LDAP v3相容性認證open source目錄伺服器。
Apache DS是100%的JAVA應用程式,可內嵌於Java應用程式或是以獨立伺服器方式運作。

官方網站: http://directory.apache.org/
除了Directory Server外, 還有Apache Directory Studio是Eclipse-based工具,可用來操作Directory Server的內容。

相關參考文章:

ApacheDS and Tomcat For J2EE Authentication

Articals

2009年5月21日 星期四

用Java壓縮/解壓縮Zip檔案

相當實用的文章:
[JAVA] zip壓縮 與 解壓縮

jBPM 3.2.6安裝後問題

jBPM 3.2.6安裝後登入web-console後發現,
所有資料表內的資料都被清空了,
要解決這個問題要修改 hibernate.cfg.xml 內的
<property name="hibernate.hbm2ddl.auto">create</property>
改為
<property name="hibernate.hbm2ddl.auto">update</property>

2009年5月19日 星期二

jBPM 3.2.6安裝於Tomcat 6 由eclipse啟動

1. 依
http://www.javaworld.com.tw/jute/post/view?bid=43&id=255869
安裝,並記得將build path 的output目錄設到/WEB-INF/classes並將hibernate.cfg.xml放到其中。

2. 接著參考
http://linliangyi2007.javaeye.com/blog/176339
step5的sql指令將user資料插入mysql
或使用下列sql指令:

INSERT INTO JBPM_ID_GROUP VALUES(2,'G','admin','security-role',NULL);
INSERT INTO JBPM_ID_GROUP VALUES(3,'G','user','security-role',NULL);
INSERT INTO JBPM_ID_GROUP VALUES(5,'G','manager','security-role',NULL);

INSERT INTO JBPM_ID_USER VALUES(1,'U','user','user@sample.domain','user');
INSERT INTO JBPM_ID_USER VALUES(2,'U','manager','manager@sample.domain','manager');
INSERT INTO JBPM_ID_USER VALUES(3,'U','admin','admin@sample.domain','admin');

INSERT INTO JBPM_ID_MEMBERSHIP VALUES(5,'M',NULL,NULL,1,3);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(6,'M',NULL,NULL,2,3);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(7,'M',NULL,NULL,3,3);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(8,'M',NULL,NULL,3,2);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(9,'M',NULL,NULL,2,2);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(10,'M',NULL,NULL,2,5);


3. 另外若在jbpm_id_group裡面若有另外新增security-role,便須修改web.xml,如下範例:

....略....
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
<security-role>
<role-name>participant</role-name>
</security-role>
....略....
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure Area</web-resource-name>
<url-pattern>/app/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
<role-name>admin</role-name>
<role-name>participant</role-name>
</auth-constraint>
</security-constraint>
....略....

上列的role-name對應到jbpm_id_group的name_

4.
ok ~

2009年3月4日 星期三

[XX隱藏關卡XX] BIRT中使用外部.js檔案

當在使用BIRT開發多個報表時,常會有多張報表需要使用相同函數的時候,偏偏在BIRT中無法使用外部.js當作函數庫使用。
但在BIRT 2.3的Release Note指出, 該版確實是提供了該功能,但好笑的是並沒有說如何做。

原來GUI Designer並沒有提供介面,必須以XML Source內修改ptdesign,加入:

<list-property name="includeScripts">
<property>system.js</property>
</list-property>

2009年2月18日 星期三

JAVA 寫UTF-8文字檔關於BOM議題...

如果各位使用JAVA IO的OutputStreamWriter指定編碼為UTF-8寫檔時,單純寫ASCII英文字和數字、符號不包含中文字寫出的檔案,使用windows的記事本另存新檔看其編碼為「ANSI」但若檔案內包含中文字(或任何非ASCII文字)會發現記事本另存新檔看其編碼為「UTF-8」。
明明不是我們指定UTF-8了嗎?一切都是BOM的問題,這又是另一段故事了,欲知詳情請上Google....

這裡單純說明如何在上列兩任一情況下如何一致讓記事本另存新檔看其編碼為「UTF-8」,下列兩隻CLASS供各位參考:

import java.io.IOException;
import java.io.PushbackInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import sun.nio.cs.StreamDecoder;

public class UnicodeInputStreamReader extends InputStreamReader {

private static final int BOM_SIZE = 4;
private final StreamDecoder decoder;
private PushbackInputStream pushBack;
private String encode;
private String defaultEnc;

public UnicodeInputStreamReader(InputStream input, String defaultEnc) throws UnsupportedEncodingException {

super(input);

try {
this.defaultEnc = defaultEnc;
this.pushBack = new PushbackInputStream(input, BOM_SIZE);
init();
} catch (Exception e) {
e.printStackTrace();
}

this.decoder = StreamDecoder.forInputStreamReader(this.pushBack, this, this.encode);
}

private void init() throws IOException {

byte[] bom = new byte[BOM_SIZE];
int n, unread;

// 初始讀取一次
n = this.pushBack.read(bom, 0, bom.length);

// 比對表頭
if ( (bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF) ) {
this.encode = "UTF-32BE";
unread = n - 4;
} else if ( (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00) ) {
this.encode = "UTF-32LE";
unread = n - 4;
} else if ( (bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF) ) {
this.encode = "UTF-8";
unread = n - 3;
} else if ( (bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF) ) {
this.encode = "UTF-16BE";
unread = n - 2;
} else if ( (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) ) {
this.encode = "UTF-16LE";
unread = n - 2;
} else {
// 如果沒有找到任何表頭, 則退回長度等於原先總長
this.encode = this.defaultEnc;
unread = n;
}

// System.out.println("has BOM=" + ((unread == n) ? false : true) + ", encode=" + encode + ", read=" + n + ", unread=" + unread);
// 計算應該退回多少byte
if ( unread > 0 ) {
this.pushBack.unread(bom, (n - unread), unread);
}

}

public String getEncoding() {
return this.encode;
}

public int read() throws IOException {
return this.decoder.read();
}

public int read(char cbuf[], int offset, int length) throws IOException {
return this.decoder.read(cbuf, offset, length);
}

public boolean ready() throws IOException {
return this.decoder.ready();
}

public void close() throws IOException {
this.decoder.close();
}
}




import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class UTF8OutputStreamWriter extends OutputStreamWriter{
public UTF8OutputStreamWriter(OutputStream pos) throws IOException{
super(pos,"UTF-8");

// write UTF8 BOM mark if file is empty
final byte[] bom = new byte[] { (byte)0xEF, (byte)0xBB, (byte)0xBF };
pos.write(bom);

}

public UTF8OutputStreamWriter(OutputStream pos,String pencoding) throws IOException{
this(pos);
}
}

2009年1月20日 星期二

關於Servlet和JSP的同步化

眾所周知,Servlet/Jsp 在WebContainer裡都是被Instance後會以Multi-Thread被執行,這樣做當然是讓效能提升了不少,不過在此同時應該要注意Thread-Safe問題,對許多初入門者,常會掉入這個陷阱而不自知~~ ( Class attribute is not thread safe in Multi-Thread environment ...)

然而今天我遇到的是相反的問題:
如果說 我們想要某個 servlet或JSP同一時間只會(只能)有一個人執行那該怎做呢?

Servlet --
方法 1. doGet() 裡轉呼叫 doPost() 而doPost()宣告為 synchronized方法。
方法 2. implements javax.servlet.SingleThreadModel介面。(Servlet規格建議方式)
方法 3. 如果只是針對某些class attribute要有同步化,那只要將該class attribute宣告為synchronized即可。

JSP --
使用page Directive -- <%@page isThreadSafe="false" %>

不管是實做SingleThreadModel或是設JSP pageDirective的isThreadSafe為false, 都可以看做是將servlet的service( )方法做synchronized ( 當然底層webContainer是否是這樣做 這倒不得而知 , 可能個別webContainer會有不同的實作方式 )

另外重要的是,上列不論哪種方法一定會照成效能上的些許損耗(由其在該Servlet/JSP作業時間長,且同時間執行該servlet/JSP人數又多時) , 故除非必要 ,盡量避免使用 ~~


(
呵呵 ,都差點忘記有SingleThreadModel這個介面,在SCWCD1.3教材本來是有,SCWCD1.4似乎就沒看到,也難怪 ~~
)