2008年1月15日火曜日

Ubuntu7.10 で Intalio Server を 稼働させる

開発環境なので、.bashrcにJAVA_HOMEへのパスを追記する。

export JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun-1.5.0.13

Intalioからダウンロードしたintalio-bpms-server-5.1.0.013.zipファイルを
自分のホームディレクトリに解凍する。

解凍したフォルダのサブディレクトリに行く
~/intalio-bpms-server-5.1.0.013/bin

./startup.sh
Using GERONIMO_BASE: /home/rsos01/intalio-bpms-server-5.1.0.013
Using GERONIMO_HOME: /home/rsos01/intalio-bpms-server-5.1.0.013
Using GERONIMO_TMPDIR: var/temp
Using JRE_HOME: /usr/lib/jvm/java-1.5.0-sun-1.5.0.13/jre
Using GERONIMO_OUT: /home/rsos01/intalio-bpms-server-5.1.0.013/var/log/geronimo.out

Geronimo started in background. PID: 8406

と表示されて動いている感を醸し出します。

ブラウザから
http://localhost:8080/bpms-console/
と入力しログイン画面が出れば、とりあえず完了

デフォルトのユーザーとパスワードは以下
admin/changeit

ログイン後にHelloWordプロセス等を適当に動かしてみましょう。
問題がなければ動くはず

うまくいったら、調子こいて別のサンプルを試す
http://localhost:8080/ui-fw/login.htm

このサンプルのユーザーとパスは以下
examples\msmith/password

さっぱりした画面が出る。
タブがTasksになっている為
ここにはやるべきタスクが表示される場所

Processesをクリック

Examples-Absence Requestをクリック

休暇申請の為の画面が表示される。

Auto-Fillボタンを押下すると、サンプルデータが
自動的に埋められる。

スクロールしないと出てこない
start processボタンをクリックすると
プロセスが開始される。

一旦ログアウトし、上司でログインし直す。
ユーザーとパスは以下
examples\ewilliams/password

今回は上司であるので、Tasksタブに1件データが
出来ている。

Examples-Absence Approvalのリンクをクリックして
内容を見る。

これもまた、スクロールしないと見れない
ラジオボタンとCompleteボタンを押下する。

Tasks一覧からタスクが消える。

ここでログアウトする。

申請者examples\msmithでログインし直す。
Notificatiosタブに上司が処理した事が通知されている。

Dismissボタンを押下する事で表示を消す事ができる。

ここでログアウトして管理者として入って、
プロセスを確認しましょう。

URLはコンソール画面を入力
http://localhost:8080/bpms-console/processes.htm

INSTANCESタブをクリックし、さらにDataタブを
クリックすると、各変数が確認出来る。

2008年1月11日金曜日

Install Intalio5.1 to ubuntu7.10

Ubuntu7.10にIntalio5.1をインストール完了
Zipを解凍したあとで、「Eclipse」を選択し
右クリックープロパティーアクセス権
「プログラム」として実行できるにチェック

簡単に稼働します。

2007年8月29日水曜日

Web化したPentaho ETL で JNDIをつかう

開発環境と品証、本番環境のデータベース接続情報が違うのは当たり前ですね。
Pentaho ETLで素直に作るとTransformファイルの中にデータベース接続文字列が
埋め込まれてしまう。

これは、上記の様な場合には都合が悪い。
Jobで複数のTransformファイルを使うので環境毎に書き換えるのは大変な作業となる。

その為の対策としてPentahoにはJNDI接続が用意されている
別にAPサーバー等が無くても使う事が出来る。

インストールしたディレクトリのサブディレクトリに
simple-jndi
と言うディレクトリがある。デフォルトでは中身が空

ここにjdbc.propertiesと言う名前でファイルを作成

以下の様な内容を入れる。
例はオラクルの例、
サーバーはservernameと言うマシン
オラクルユーザーはorauserと言うid
パスワードもそれに対応した物

sample/type=javax.sql.DataSource
sample/driver=oracle.jdbc.driver.OracleDriver
sample/url=jdbc:oracle:thin:@servername:1521:ora09
sample/user=orauser
sample/password=orapass

pentahoのConnection Informationとして
Method of accessをJNDI
Datebase nameを上記の例ならsample
とする。

これで接続はOKとなる。

今日の作業は、昨日作成したPentaho on Web Apサーバー上で
JNDIが正しく使えるか確認する事。

早速の悩みは何処にsimple-jndi/jdbc.propertiesファイルを
配置すれば良いかと言うことである。

上記ファイルをWEB-INF/classesの配下に配置する
今回はJNDI名を上と変えてora09にした

結果はダメ
Error occured while trying to connect to the database
Invalid JNDI connectionora09: 名前 ora09 はこのコンテキストにバインドされていません

TOMCAT側に設定するのか?
 最悪ソースを読めば仕組みがわかるが、とりあえずやってみる。
 この辺の安心感がオープンソースの良い所
やってみたが結果は同じエラーが出ている。

まじめに追いかけるしか無いようである。

まずTOMCATの設定の確認の為のソース
public class JndiTest {
public JndiTest() {
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("ora09");
Connection conn = ds.getConnection();
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
catch (NamingException ex) {
ex.printStackTrace();
}
}
}

TOMCATのJNDIの設定が正しければエラーは発生しない。
ここで注意なのはTOMCATのADMINISTRATION TOOL(WEB)の
画面で設定したものが、NetBeansで作成したプロジェクトでは
使えない。
NetBeansにてプロジェクトのConfiguration Filesの
Context.xmlを修正すること。以下の様な感じ

(大小記号省略)
Context path="/threading"
Resource
name="ora09"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
password="pass"
maxIdle="2"
maxWait="5000"
validationQuery="select sysdate from dual"
username="user"
url="jdbc:oracle:thin:@192.168.XXX.XXX:1521:ora09"
maxActive="4"
/Context

最初テストコードが間違ってコネクションをクローズしなかったので
何回か行うとエラーが発生した。この事からJNDIで接続出来ている事が確認できる。

続いて、テストコードではなく昨日作成したPentahoを呼び出すクラスを
使ってみる。

エラーメッセージが変わらない。

Pentahoのフォーラムを見ると英語で同じ様な事を言っている人がいる。
org.pentaho.core.util.DatasourceHelperが問題みたいである。
しかし、これはpentaho.jarの中なのでソースを持っていない。
Pentaho ETLであるkettleはSourceForge.netから取得済なので
こちらのソースで対応する。

対応内容は以下の通り
DatasourceHelper.getDataSourceFromJndiの変わりに
自前のコードに修正して確認する。

private void initWithJNDI(String jndiName) throws KettleDatabaseException {
connection = null;
try {

//DataSource dataSource = DatasourceHelper.getDataSourceFromJndi(jndiName);
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource dataSource = (DataSource)envContext.lookup(jndiName);

これで実行するとうまく行く。
Pentaho.jar内のDatasourceHelper.getDataSourceFromJndiが調子悪い事が
判明した。

先ほどみたら少しバージョンが上がった物がリリースされていた。
こちらのjarならうまく行くかもしれない。

明日の作業とする。

2007年8月28日火曜日

Pentaho Spoon ETLのJobをWeb Appサーバーで動かす

Pentaho のETLツールのひとつであるSpoonはそれ自体でETLのデザインと実行、
タイマー起動まで行えるので良いと考えている。
しかし訳があり、
 UNIX機(Solaris)
 GUI無し
 Cron起動等のバッチはダメ
 Webアプリなら良い
と言う制約からWebアプリでPentahoで作成したJobを動かす様にした。

やった事
  1. PentahoのソースKettle-src-2.5.0.zipをSourceForgeから取得する。
  2. be.ibridge.kettle.panのソースをみて、SpoonのJobを起動方法を理解し、コピペ等してWebアプリから呼ばれるクラスを作成する
  3. WebアプリのLibにPentaho KettleのJarファイルをごっそり入れる。とってくる元は、Kettle/libext,Kettle/libswt,Kettle/libである。
参考ファイル
 作成したクラスファイルの中身
  注意:Jobファイルはリポジトリからではなく、ファイル渡し前提、もちろん改良の余地あり

package daemon;

import be.ibridge.kettle.core.Const;
import be.ibridge.kettle.core.LocalVariables;
import be.ibridge.kettle.core.LogWriter;
import be.ibridge.kettle.core.Result;
import be.ibridge.kettle.core.exception.KettleException;
import be.ibridge.kettle.core.exception.KettleJobException;
import be.ibridge.kettle.core.util.EnvUtil;
import be.ibridge.kettle.job.Job;
import be.ibridge.kettle.job.JobEntryLoader;
import be.ibridge.kettle.job.JobMeta;
import be.ibridge.kettle.pan.CommandLineOption;
import be.ibridge.kettle.repository.RepositoriesMeta;
import be.ibridge.kettle.repository.Repository;
//import be.ibridge.kettle.repository.RepositoryDirectory;
import be.ibridge.kettle.repository.RepositoryMeta;
import be.ibridge.kettle.repository.UserInfo;
import be.ibridge.kettle.trans.StepLoader;
import be.ibridge.kettle.version.BuildVersion;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

public class KettleLuncher {

public static final String STRING_KITCHEN = "Kitchen";

public KettleLuncher() throws KettleException {
EnvUtil.environmentInit();
Thread parentThread = Thread.currentThread();
LocalVariables.getInstance().createKettleVariables(parentThread.getName(), null, false);

ArrayList args = new ArrayList();
args.add("-file=/home/rsos01/kettleJob/testKettleJob.kjb");
args.add("-logfile=/home/rsos01/logs/testKettleJob.log");
args.add("-norep=Y");

RepositoryMeta repinfo = null;
UserInfo userinfo = null;
Job job = null;

StringBuffer optionRepname;
StringBuffer optionUsername;
StringBuffer optionPassword;
StringBuffer optionJobname;
StringBuffer optionDirname;
StringBuffer optionFilename;
StringBuffer optionLoglevel;
StringBuffer optionLogfile;
StringBuffer optionLogfileOld;
StringBuffer optionListdir;
StringBuffer optionListjobs;
StringBuffer optionListrep;
StringBuffer optionNorep;
StringBuffer optionVersion;

CommandLineOption[] options = new CommandLineOption[]{
new CommandLineOption("rep", "Repository name", optionRepname = new StringBuffer())
, new CommandLineOption("user", "Repository username", optionUsername = new StringBuffer())
, new CommandLineOption("pass", "Repository password", optionPassword = new StringBuffer())
, new CommandLineOption("job", "The name of the transformation to launch", optionJobname = new StringBuffer())
, new CommandLineOption("dir", "The directory (don\'t forget the leading /)", optionDirname = new StringBuffer())
, new CommandLineOption("file", "The filename (Job XML) to launch", optionFilename = new StringBuffer())
, new CommandLineOption("level", "The logging level (Basic, Detailed, Debug, Rowlevel, Error, Nothing)", optionLoglevel = new StringBuffer())
, new CommandLineOption("logfile", "The logging file to write to", optionLogfile = new StringBuffer())
, new CommandLineOption("log", "The logging file to write to (deprecated)", optionLogfileOld = new StringBuffer(), false, true)
, new CommandLineOption("listdir", "List the directories in the repository", optionListdir = new StringBuffer(), true, false)
, new CommandLineOption("listjobs", "List the jobs in the specified directory", optionListjobs = new StringBuffer(), true, false)
, new CommandLineOption("listrep", "List the available repositories", optionListrep = new StringBuffer(), true, false)
, new CommandLineOption("norep", "Do not log into the repository", optionNorep = new StringBuffer(), true, false)
, new CommandLineOption("version", "show the version, revision and build date", optionVersion = new StringBuffer(), true, false)};

if (args.size() == 0) {
CommandLineOption.printUsage(options);
throw new KettleException("No Argments");
}
CommandLineOption.parseArguments(args, options);

LogWriter log;
if (Const.isEmpty(optionLogfile) && !Const.isEmpty(optionLogfileOld)) {
// if the old style of logging name is filled in, and the new one is not
// overwrite the new by the old
optionLogfile = optionLogfileOld;
}

if (Const.isEmpty(optionLogfile)) {
log = LogWriter.getInstance(LogWriter.LOG_LEVEL_BASIC);
} else {
log = be.ibridge.kettle.core.LogWriter.getInstance(optionLogfile.toString(), true, be.ibridge.kettle.core.LogWriter.LOG_LEVEL_BASIC);
}

if (!Const.isEmpty(optionLoglevel)) {
log.setLogLevel(optionLoglevel.toString());
log.logMinimal(STRING_KITCHEN, "Logging is at level : "+log.getLogLevelDesc());
}

if (!Const.isEmpty(optionVersion)) {
BuildVersion buildVersion = BuildVersion.getInstance();
log.logBasic("Pan", "Kettle version "+Const.VERSION+", build "+buildVersion.getVersion()+", build date : "+buildVersion.getBuildDate());
}

// Start the action...
//
if (!Const.isEmpty(optionRepname) && !Const.isEmpty(optionUsername)) {
log.logDetailed(STRING_KITCHEN, "Repository and username supplied");
}
log.logMinimal(STRING_KITCHEN, "Repository and username supplied");

/* Load the plugins etc.*/
StepLoader steploader = StepLoader.getInstance();
if (!steploader.read()) {
log.logError(STRING_KITCHEN, "Error loading steps... halting Kitchen!");
throw new KettleException("Error loading steps...");
}

/* Load the plugins etc.*/
JobEntryLoader jeloader = JobEntryLoader.getInstance();
if (!jeloader.read())
{
log.logError(STRING_KITCHEN, "Error loading job entries & plugins... halting Kitchen!");
}

Date start, stop;
Calendar cal;
SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
cal=Calendar.getInstance();
start=cal.getTime();

log.logDebug(STRING_KITCHEN, "Allocate new job.");
JobMeta jobMeta = new JobMeta(log);

// In case we use a repository...
Repository repository = null;

try {
// Read kettle job specified on command-line?
if (!Const.isEmpty(optionRepname) || !Const.isEmpty(optionFilename)) {
// log.logDebug(STRING_KITCHEN, "Parsing command line options.");
// しばらくコメント
// }
// }
// Try to load if from file anyway.
if (!Const.isEmpty(optionFilename) && job == null) {
jobMeta = new JobMeta(log, optionFilename.toString(), null);
job = new Job(log, steploader, null, jobMeta);
}
} else if ("Y".equalsIgnoreCase(optionListrep.toString())) {
RepositoriesMeta ri = new RepositoriesMeta(log);
if (ri.readData()) {
System.out.println("List of repositories:");
for (int i = 0; i < ri.nrRepositories(); i++) {
RepositoryMeta rinfo = ri.getRepository(i);
System.out.println("#" + (i + 1) + " : " + rinfo.getName() + " [" + rinfo.getDescription() + "] ");
}
} else {
System.out.println("ERROR: Unable to read/parse the repositories XML file.");
}
}
} catch (KettleException e) {
job = null;
jobMeta = null;
System.out.println("Processing stopped because of an error: " + e.getMessage());
}

if (job == null) {
if (!"Y".equalsIgnoreCase(optionListjobs.toString()) &&
!"Y".equalsIgnoreCase(optionListdir.toString()) &&
!"Y".equalsIgnoreCase(optionListrep.toString())) {
System.out.println("ERROR: Kitchen can't continue because the job couldn't be loaded.");
}
throw new KettleException("Error job couldn't be loaded...");
}

Result result = null;

int returnCode = 0;

try {
// Add Kettle variables for the job thread...
//LocalVariables.getInstance().createKettleVariables(job.getName(), parentThread.getName(), true);
// Set the arguments on the job metadata as well...
if (args.size() == 0) {
job.getJobMeta().setArguments(null);
} else {
job.getJobMeta().setArguments((String[]) args.toArray(new String[args.size()]));
}

result = job.execute(); // Execute the selected job.
job.endProcessing("end", result); // The bookkeeping...
} catch (KettleJobException je) {
if (result == null) {
result = new Result();
}
result.setNrErrors(1L);

try {
job.endProcessing("error", result);
} catch (KettleJobException je2) {
log.logError(job.getName(), "A serious error occured : " + je2.getMessage());
returnCode = 2;
}
} finally {
if (repository != null) {
repository.disconnect();
}
}

log.logMinimal(STRING_KITCHEN, "Finished!");

if (result != null && result.getNrErrors() != 0) {
log.logError(STRING_KITCHEN, "Finished with errors");
returnCode = 1;
}

cal=Calendar.getInstance();
stop=cal.getTime();
String begin=df.format(start).toString();
String end =df.format(stop).toString();

log.logMinimal(STRING_KITCHEN, "Start="+begin+", Stop="+end);
long millis=stop.getTime()-start.getTime();
log.logMinimal(STRING_KITCHEN, "Processing ended after "+(millis/1000)+" seconds.");

}

public KettleLuncher(String kettelJob) {
}
}

Webアプリに加えたJarファイル(

kettle.jar
CacheDB.jar
commands.jar
common.jar
edtftpj-1.5.4.jar
jackcess-1.1.5.jar
jakarta-oro-2.0.8.jar
javadbf.jar
jface.jar
js.jar
jsch-0.1.24.jar
jug-lgpl-2.0.0.jar
jxl.jar
mail.jar
runtime.jar
commons-codec-1.3.jar
commons-fileupload-1.0.jar
commons-httpclient-3.0.1.jar
commons-lang-2.2.jar
commons-net-1.4.1.jar
asjava.zip
jtds-1.2.jar
nzjdbc.jar
ojdbc14.jar
orai18n.jar
rdbthin.jar
sapdbc.jar
unijdbc.jar
xdbjdbc.jar
jcommon-1.0.8.jar
libformula-0.1.3.jar
pentaho-1.2.0.jar
activation.jar
simple-jndi-0.11.1.jar
log4j-1.2.8.jar
commons-logging-1.1.jar
commons-vfs-1.0.jar

TOMCAT5.5でLog4jにはまる

自分のWebアプリのログ出力のLibとしてLog4jを加えたら
catalina.outファイルが行数が巨大に成ってしまった。軽く10万行
Log4jを外したら元にもどった。
Log4j.propertiesはちゃんと作成し自分のアプリにいれた。
自分のアプリのログは正しく出力されている。
WebSphere6ではこの現象は無かった。

tomcatのドキュメントに書いてありました。
commons Logging を内部コード全体で使っている。
tomcat全体用にlog4j.propertiesを作成して
/usr/share/tomcat5.5/common/classes
ディレクトリに配置

# Global logging configuration
log4j.rootLogger=ERROR, run
log4j.appender.run=org.apache.log4j.RollingFileAppender
log4j.appender.run.File=/usr/share/tomcat5.5/logs/tomcat.log
log4j.appender.run.maxBackupIndex=20
log4j.appender.run.maxFileSize=10MB
log4j.appender.run.layout=org.apache.log4j.PatternLayout
log4j.appender.run.layout.ConversionPattern=%d %5p %-21t %-70c - %m%n

/usr/share/tomcat5.5/common/libにlog4jのjarを配置
commons-logging.jarも同じくこの場所には配置

プロジェクトを選択し、右クリックで
clean and Build
unDeploy and deploy

tomcat再起動

ログファイルの行数が10万行から、150行まで小さくなった。

実は、これにからみ昨夜色々やっていた。
そのひとつがjavaセキュリティも外し

/etc/init.d/tomcat5.5シェルを以下の様に修正し
# Use the Java security manager? (yes/no)
#TOMCAT5_SECURITY=yes
TOMCAT5_SECURITY=no
Java securityをわざと効かなくして調査をした。

Windowsと比べてLinuxはパーミッションにより
ディレクトリ毎に権限が細かくなっているのに、
さらにJava securityが入るので面倒なので
こうした。

でも、このおかげでウィルス等に強いと言う特性も
ありますね。Windowsはユルスギですから。

2007年8月27日月曜日

ubuntu 7.04にnetbeans6を入れてtomcatと連系

NetBeans6のServicesのServersを開いて右クリックadd Server...
Tomcat5.5を選択
先日構築したtomcat5.5の環境なので、
以下の様に設定
Catalina Homeは/usr/share/tomcat5.5
Catalina Baseは/usr/share/tomcat5.5

User NameとPasswordは
tomcat-users.xmlに書いた物と合わせる。
ファイルの場所は自分の環境なら/usr/share/tomcat5.5/conf配下にある。
xmlの中身の例
role rolename="manager"
role rolename="admin"
user username="tomcat" password="tomcat" roles="manager,admin"
これで、NetBeansとTomcatが関連ついた。

NetBeansで作成したプロジェクトは
/conf/Catalina/localhostの下に
プロジェクト名.xmlが作成され、
その中身にTomcatが見るドキュメントベースの
パスが記述される。
それは、NetBeansのBuildディレクトリを指しており、
これでNeatBeansとTomcatがこれで連系する。



2007年8月24日金曜日

ubuntu 7.04にEclipse3.3 All-in-oneをインストール

ファイルはここからとってくる
http://download.eclipse.org/webtools/downloads/drops/R2.0/R-2.0-200706260303/