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/

2007年8月23日木曜日

ubuntu 7.04にtomcat5.5にインストールでハマル

Tomcat5.5のインストール自体は、
Synaptic

sudo apt-get install tomcat5.5
で良い。(ubuntu 6.10の時と変わらず)

環境変数JAVA_HOMEを設定は当然行う。

TOMCATのbinディレクトリで以下をとりあえず実行
sudo -u tomcat55 ./startup.sh

Using CATALINA_BASE: /usr/share/tomcat5.5
Using CATALINA_HOME: /usr/share/tomcat5.5
Using CATALINA_TMPDIR: /usr/share/tomcat5.5/temp
Using JRE_HOME: /usr/lib/jvm/java-1.5.0-sun-1.5.0.11

と表示され後はエラーも出ないが、起動もしない現象

原因:
 /usr/share/tomcat5.5/logs$ file catalina.out
 catalina.out: fifo (named pipe)
 となっておりTOMCATの起動シェルの中で詰まっていた。

対策:
  sudo rm ./catalina.out

結果:
 正常起動

ubuntu 7.04にJDK5.0をインストールする

sudo apt-get install sun-java5-jdk

パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
Reading state information... 完了
The following packages were automatically installed and are no longer required:
libcommons-pool-java liblucene-java eclipse-rcp libcommons-el-java junit
libregexp-java libcommons-modeler-java liblog4j1.2-java libswt3.2-gtk-java
libservlet2.4-java libtomcat5.5-java libbcel-java ant
libcommons-launcher-java libcommons-dbcp-java liblucene-java-doc
libjsch-java libswt3.2-gtk-jni ant-optional libmx4j-java
"apt-get autoremove"を使ってこれらを削除してください。
以下の特別パッケージがインストールされます:
libltdl3 odbcinst1debian1 sun-java5-bin sun-java5-demo sun-java5-jre
unixodbc
提案パッケージ:
sun-java5-doc sun-java5-source sun-java5-plugin ia32-sun-java5-plugin
sun-java5-fonts ttf-sazanami-gothic ttf-sazanami-mincho libmyodbc
odbc-postgresql libct1
推奨パッケージ:
gsfonts-x11
以下のパッケージが新たにインストールされます:
libltdl3 odbcinst1debian1 sun-java5-bin sun-java5-demo sun-java5-jdk
sun-java5-jre unixodbc
アップグレード: 0 個、新規インストール: 7 個、削除: 0 個、保留: 2 個。
45.2MB のアーカイブを取得する必要があります。
展開後に追加で 117MB のディスク容量が消費されます。
続行しますか [Y/n]? Y
警告: 以下のパッケージは認証されていません!
libltdl3 odbcinst1debian1 unixodbc sun-java5-bin sun-java5-jre
sun-java5-demo sun-java5-jdk
検証なしにこれらのパッケージをインストールしますか [y/N]? y

2007年8月12日日曜日

redMine カレンダーでエラー

■環境
Windows One-Click Ruby Installer を利用
http://rubyforge.org/projects/rubyinstaller/
(Rails 1.2.3)

mysql-5.0.45-win32
mongrel 1.0.1 (mswin32)
redmine-0.5.1

■エラー
(操作)
カレンダーやガントチャートを表示しようとするとエラー

(ブラウザの表示)
 Status: 500 Internal Server Error Content-Type: text/html

Internal error

An error occurred on the page you were trying to access.
If you continue to experience problems please contact your redMine administrator for assistance.

(コマンドプロンプト)

#{RAILS_ROOT}/vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb:36:in `to_default_s'
#{RAILS_ROOT}/vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb:43:in `to_default_s'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/core_ext/array/conversions.rb:43:in `to_s'
#{RAILS_ROOT}/vendor/plugins/gloc-1.1.0/lib/gloc-rails-text.rb:129:in `select_html'
#{RAILS_ROOT}/vendor/plugins/gloc-1.1.0/lib/gloc-rails-text.rb:94:in `select_month'
#{RAILS_ROOT}/app/views/projects/calendar.rhtml:14:in `_run_rhtml_47app47views47projects47calendar46rhtml'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb:108:in `call'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb:108:in `capture_erb_with_buffer'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb:67:in `capture'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb:51:in `form_tag'
#{RAILS_ROOT}/app/views/projects/calendar.rhtml:4:in `_run_rhtml_47app47views47projects47calendar46rhtml'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/caching.rb:331:in `call'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/caching.rb:331:in `cache_erb_fragment'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/helpers/cache_helper.rb:6:in `cache'
#{RAILS_ROOT}/app/views/projects/calendar.rhtml:1:in `_run_rhtml_47app47views47projects47calendar46rhtml'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/base.rb:326:in `send'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/base.rb:326:in `compile_and_render_template'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/base.rb:301:in `render_template'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/base.rb:260:in `render_file'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:806:in `render_file'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:711:in `render_with_no_layout'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/layout.rb:247:in `render_without_benchmark'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
c:/ruby/lib/ruby/1.8/benchmark.rb:293:in `measure'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:1096:in `perform_action_without_filters'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:632:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:634:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:619:in `perform_action_without_benchmark'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
c:/ruby/lib/ruby/1.8/benchmark.rb:293:in `measure'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/rescue.rb:83:in `perform_action'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:430:in `send'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:430:in `process_without_filters'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:624:in `process_without_session_management_support'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/session_management.rb:114:in `process'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:330:in `process'
#{RAILS_ROOT}/vendor/rails/railties/lib/dispatcher.rb:41:in `dispatch'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/rails.rb:78:in `process'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/rails.rb:76:in `synchronize'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/rails.rb:76:in `process'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:618:in `process_client'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:617:in `each'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:617:in `process_client'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:736:in `run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:736:in `initialize'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:736:in `new'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:736:in `run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:720:in `initialize'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:720:in `new'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:720:in `run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/configurator.rb:271:in `run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/configurator.rb:270:in `each'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/configurator.rb:270:in `run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/bin/mongrel_rails:127:in `run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/command.rb:211:in `run'
c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/bin/mongrel_rails:243
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
#{RAILS_ROOT}/vendor/rails/railties/lib/commands/servers/mongrel.rb:60
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
#{RAILS_ROOT}/vendor/rails/railties/lib/commands/server.rb:39
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
script/server:3
by/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
script/server:3

■調査
gloc-rails-text.rb:129:in `select_html'の所は、
select_html << options.to_s
と言うコードで、HTMLのSELECTタグを作っている所、
ここをコメントアウトするとエラーは止まる。
画面が表示されるが、SELECTのプルダウンが空となる。
となると、to_sが怪しい。

よく見ると、active_supportが2重に有効になっている。
#{RAILS_ROOT}/vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb:36:in `to_default_s'
#{RAILS_ROOT}/vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb:43:in `to_default_s'
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/core_ext/array/conversions.rb:43:in `to_s'

たしかに私の環境は、Windows One-Click Ruby Installerなので、
Railsのセットは既に入っている。

redMineのconfig/boot.rbに、
こんな行があるので、私の環境の場合2重に起動した訳です。
if File.directory?("#{RAILS_ROOT}/vendor/rails")
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"

■対策
 ソースは弄らずに、redMineのインストールディレクトリ配下に入っている
 /vendor/railsのrailsディレクトリをralis_noneedに変えました。

■結果
 カレンダーが正しく表示される様になりました。
 もちろんSELECTタグのプルダウンには月が
 ちゃんと入っています。

2007年8月7日火曜日

pentahoメモ field名、型

1)
field名の語末のスペースはトリムされません。
SQLでフィールドが無い旨のエラーが出た場合には、
ログを良く見て、語末にスペースが無いか確認しましょう。

2)
InputとOutputのテーブルの項目名が同じでも
型が違う場合にはフォーマットエラー等が発生し易いので、
「Select value」のMeta Dataタブにて型を合わせると
良いです。

3)
Spoonで作成したJobをバッチから動かす。
updateMspToOracle.kjbは自分で作ったJob
ディレクトリも適当な場所で、以下の様な感じで実行出来る。
./kitchen.sh -file='/home/rsos01/KettleWrk/updateMspToOracle/updateMspToOracle.kjb' -logfile=./mspToOra.log -level=Basic
SpoonではJobのタイマー起動があったが、kitchenでは無さげ。
cronなどで自分でやれば済む問題だが、、、

2007年8月2日木曜日

ubuntu 6.10にJDK5.0をインストールする

すでにファイルをダウンロードして来ている場合
ファイルにパーミッションで実行権限をつけ
コマンドラインからダウンロードしてきたファイルを実行

pentahoメモ Date型にいれる書式

Oracleからの取得した形式がYYYY/MM/DD HH24:MI:SSの場合
KettleのDate型に入れても取り込まれない。

取得した結果に.000を文字列結合してあげれば取り込まれる。