Hyper Estraierでノードを使ったWebサイトとファイルを検索対象にする

estseek.cgiでは一つのインデックスだけしか扱えないので、大量の文書やWebサイトとファイルサーバにある文章を同時に扱うことができない。そこで、P2Pを使って問題を解決したい。

ノードの構成は下の状態

+- ノードマスタ ---------------------+
|  mainノード -+- project_a ノード   |
|              +- project_b ノード   |
|              +- イントラ ノード    |
+------------------------------------+

ノードマスタは一つだけ用意。mainノードにはインデックスは持たずに、project_aノード、project_bノード、イントラノードへのリンクを張るだけ。project_aノードとproject_bノードはそれぞれのプロジェクトで作成した文章へのインデックスを持ち、イントラノードはイントラをクロールしたインデックスを持つ。project_cや新たなイントラを検索の対象に含めたい場合には、個別にノードを用意(インデックスを作成)して、mainノードからのリンクを追加する。
クライアントはmainノードだけを検索の対象にして、mainノードがそれぞれのノードに対してリクエストを投げて、帰ってきた応答をマージしてクライアントへ返す方法をとる。
これが適切な設計なのかはわからないが、試験的なものとして試してみる。

操作で使うディレクトリの状態は下の通り。

 + master マスタノードのサーバルートディレクトリ
 |  +- _node ノードディレクトリ
 |       +- main      mainノード
 |       +- project_a project_aノードのインデックス
 |       +- project_b  project_bノードのインデックス
 |       +- intra      イントラノードのインデックス
 |
 +- crawl クローラーのディレクトリ

ノードマスタとノードを作成

[参考]P2Pガイドのチュートリアル 「起動と終了」及び「管理用インターフェイス」

 $ estmaster init master
 $ estmaster start -bg master
 webブラウザで http://localhost:1978/master_ui へアクセス。認証はadmin/admin。
 Manage Nodesからmain、project_a、project_b、intraのそれぞれのノードを追加

mainノードからのリンクを設定

[参考]P2Pガイドのチュートリアル 「文書の検索」

メインノードからそれぞれのノードへのリンクを設定する。信頼度は全て1000。

 $ estcall setlink -auth admin admin http://localhost:1978/node/main \
  http://localhost:1978/node/project_a プロジェクトA 1000
 $ estcall setlink -auth admin admin http://localhost:1978/node/main \
  http://localhost:1978/node/project_b プロジェクトB 1000
 $ estcall setlink -auth admin admin http://localhost:1978/node/main \
  http://localhost:1978/node/intra 社内イントラ 1000

estcmdでproject_aとproject_bのインデックスを作成

[参考]P2Pガイドのチュートリアル 「初期導入の効率化」
ノードマスタを起動している最中はインデックスがロックされているため、estcmd gatherがロック待ちで止まりますので、ノードマスタを停止してから行います。

 $ estmaster stop master
 $ estcmd gather -cl -fx ".doc,.xls,.ppt" "H@estfxmsotohtml"  -ic UTF-8 \
     -sd -cm -pc UTF-8 master/_node/project_a /home/Projects/project_a
 $ estcmd gather -cl -fx ".doc,.xls,.ppt" "H@estfxmsotohtml" -ic UTF-8  \
     -sd -cm -pc UTF-8 master/_node/project_b /home/Projects/project_b
 $ estmaster start -bg master

クロールしてイントラノードのインデックスを作成

 $ estwaver init -xs crawl
 $ im crawl/_conf

seed: 1.0|http://intra.example.co.jp/
として他のseedを削除。seedは種文書(ここからクロールを開始する)

allowrx: ^http://http://intra\.example\.co\.jp/
クロールをイントラサーバだけに限定します。

language: 1
日本語の文書なら1にします。

nodeserv: 1|http://admin:admin@localhost:1978/node/intra
事前に作成したノードへインデックスを保存します。

 $estwaver crawl -revcont crawl

検索をしてみる

http://localhost:1978/node/main/search_ui へアクセスすると、検索フォームが表示されます。右側にはmainノードがリンクしているノードが表示されているはずです。depthが「0」のまま検索すると、リンク先を検索しないので、ヒットしないはずです。「1」以上にすると、リンクしているノードも含めて検索結果が表示されます。右側にあるノードのチェックを外すと検索の対象から除かれます。

sambaのPDCにログインしたらプロファイルが無いって言われる。

この手順で作成したドメインへログインすると

移動プロファイルのサーバー用コピーが見つからないため、ローカルプロファイルを使ってログオンしようとしています。プロファイルへの変更は、ログオフ時にサーバーにはコピーされません。ネットワークの問題が発生しているか、セキュリティの権限が不足していることが原因と考えられます。問題が解決しない場合は、管理者に問い合わせてください。

とか

ローカルのプロファイルが見つかりません。一時的なプロファイルでログインしています。ログオフ時にこのプロファイルへの変更は失われます。

って言われる。samba userのサイトを見ながらわかったことは、ldapのsambaProfilePathのディレクトリが無いのが原因。/etc/samba/smb.conflogon pathをどれだけ編集していても解決できないわけだった。smbldap-usershowlogon pathが指すディレクトリを作成することでエラーの原因は解決。

smbldap-usermod -Fでldapのlogon path/etc/samba/smb.conflogon pathが同じディレクトリを指すように変更しておく。あと、ldapのlogon path/etc/smbldap-tools/smbldap.confuserProfileをテンプレートとしているので、これも修正しておく。

hyperestraier を使って、ファイルサーバを全文検索

hyerestraier を使って、ファイルサーバのみんなで共有しているファイル群を全文検索します。インデックスを作成するときにはジャンルを使って、案件を指定できるようにします。

イントロダクションに書いてあることは省略してあります。

Excel,MS-Word,PowerPoint,PDFを検索できるようにテキストを抽出するプログラムをインストール

■MS-Wordからテキストを抽出するvwWare

  # yum install glib2-devel
  # yum install libgsf-devel
	  依存パッケージいっぱい
  $wget http://downloads.sourceforge.net/wvware/wv-1.2.4.tar.gz?modtime=1161798556&big_mirror=0
  $ tar xvfz wv-1.2.4.tar.gz
  $ ./configure
  $ make
  $ make install

■ExcelとWordからテキストを抽出するxlhtml

  $ wget http://nchc.dl.sourceforge.net/sourceforge/chicago/xlhtml-0.5.tgz
  $ tar xvfz xlhtml-0.5.tgz
  $ cd xlhtml-0.5
  $ ./configure
  $ make
  $ make install

インデックスを初期化

 $ estcmd create -attr _lpath str -attr @mdate seq -attr @size seq -attr @genre str job

インデックス化

インデックス化する際には -aa @genreを使ってフォルダ単位にジャンルを指定します。

 $ export PATH=$PATH:/usr/local/share/hyperestraier/filter/
 $ estcmd gather -cl -fx ".doc,.xls,.ppt" "H@estfxmsotohtml" -ic UTF-8 -sd -cm -pc UTF-8 -aa  @genre project_a job /home/Projects/project_a
 $ estcmd gather -cl -fx ".doc,.xls,.ppt" "H@estfxmsotohtml" -ic UTF-8 -sd -cm -pc UTF-8 -aa @genre project_b job /home/Projects/project_b

estseek.confにジャンルを指定

genrecheck: project_a{{!}}プロジェクトA
genrecheck: project_b{{!}}プロジェクトB

PostgreSQLのバッファへのヒット率を求める

最近は、記事のネタに一貫性が無いな~。

えっと、バッチの性能改善するための方法その1です。データファイルから読み込んだ内容を、PostgreSQL自身でキャッシュして再利用することでクエリーの性能を向上させます。バッファの大きさはshared_buffersっていうパラメータにブロック(1ブロック8KB)単位で大きさを指定します。その妥当性を判断する方法として、統計情報を使います。

PostgeSQLのバージョン

8.1.4です。

統計情報を取得するための設定

 vi $PGDATA/postgresql.conf
 stats_start_collector = true
 stats_command_string = true
 stats_block_level = true
 stats_row_level = true
 stats_reset_on_server_start = true

変更後はPostgreSQLを再起動

実行後に統計情報からヒット率を得る

SELECT relname,
        heap_blks_read  as "ディスクから読み込んだブロック数",
        heap_blks_hit as "キャッシュにヒットしたブロック数",
        case when heap_blks_hit = 0 then 0 else
          heap_blks_hit::real / (heap_blks_read::real + heap_blks_hit::real) end as "ヒット率",
        idx_blks_read as "ディスクから読み込んだブロック数(インデックス)",
        idx_blks_hit as "キャッシュにヒットしたブロック数(インデックス)",
        case when idx_blks_read = 0 then 0 else
          idx_blks_hit::real / (idx_blks_read::real + idx_blks_hit::real) end::real as "インデックスヒット率",
        toast_blks_read as "ディスクから読み込んだブロック数(TOAST)",
        toast_blks_hit as "キャッシュにヒットしたブロック数(TOAST)",
        case when toast_blks_read = 0 then 0 else
          toast_blks_hit::real / ( toast_blks_read::real + toast_blks_hit::real) end::real as "TOASTのヒット率",
        tidx_blks_read as "ディスクから読み込んだブロック数(TOASTのインデックス)",
        tidx_blks_hit as "キャッシュにヒットしたブロック数(TOASTのインデックス)",
        case when tidx_blks_read = 0 then 0 else
          tidx_blks_hit::real / (tidx_blks_read::real + tidx_blks_hit::real) end::real as "TOASTのインデックスヒット率"
   FROM pg_statio_user_tables
   where  heap_blks_read != 0

ヒット率は0.97以上を目指したい。TOASTってのは、1行が1ブロックに収まっていない部分のこと(略し過ぎ)。あと、統計情報はPostgreSQLを停止するリセットされる。適宜、PostgreSQLを再起動。

Hyper Estraierを入れてみる

sambaで提供しているファイルサーバに蓄積している文書を検索するためにHyper Estraierを入れてみました。
環境はCentOS5です。
今回は、お試しとして自分のホームディレクトリへインストールしました。/home/akky/hyperestraier の配下に必要なものを収めます。
インストール手順はイントロダクションに書いてあるとおりです。前提となるライブラリ事情を下に書いておきます。

  • libiconvは入れていない。ldd `which iconv` を実行すると、libiconvを使っていないけど、iconv自体は実現されている。ぐぐってみると、libcにiconvの関数が含まれているみたいだ。結果は後のお楽しみ
  • zlibはzlib-develが入っている。
  • QDBMはこの後入れる

QDBMをインストール

 # ./configure --prefix=/home/akky/hyperestraier --enable-zlib
 # make
 # make check
 # make install

zlibを使うことで、インデックスファイルの大きさ圧縮

Hyper Estraierをインストール

 # LDFLAGS="-L/home/akky/hyperestraier/lib " ./configure --prefix=/home/akky/hyperestraier
 # make
 # make check
 # make intall

configure時にLDFLAGSを指定しているのは、QDBMを /home/akky/hyperestraier へインストールしているのだが、configureではlibqdbm が無いと言われ、configureは通ってしまうのでmakeを実行するとqdbmの関数をリンクできずに失敗した。なので、半ば無理やりの対応

LDAPに登録したユーザを管理するツール LAM

先日作成した、LDAPサーバに登録してあるユーザを管理する方法を考えてみる。ベーシックにldifファイルで頑張るってもの方法だけど、メンドクサイ。LDAPの中身の直接見せてくれるツールでもいいのだけど、使い勝手が悪い。で、見つけたのが、
LDAP Account Manager (LAM)

ブラウザベースだし、日本語でも表示してくれる。でも・・・
更新するとエラーになっちゃうんだよ~。プロパティが足りていないとか言われる。

Notice: Undefined index: userPassword in /usr/local/ldap-account-manager-2.2.0/lib/modules/inetOrgPerson.inc on line 614

とか

Notice: Undefined index: delPhoto in /usr/local/ldap-account-manager-2.2.0/lib/modules/inetOrgPerson.inc on line 627

とか。LDAPに入れてある属性が足りていないのかな。でも、ここでエラーと言われるのはキツイな。

CentOS5 に sambaを使ってドメインコントローラー

足掛け2週間かけて、CentOSにOpenLDAP+Smbaを使ってドメインコントローラーを構築。なかなか、ドメインコントローラーへログインできずに手間取った。終ってみると、samba.confの記述が適切ではなかったのかな・・・
今後のためにも、手順を記載しておく。

環境はこちら。

OS
CentOS5.1。カーネルのバージョンは2.6.18-53.el5
OpenLDAP
yumでインストールした2.3.27-8
Samba
yumでインストールした3.0.25b-1.el5_1.4

手順はCentOS 5 で Samba を PDC にするを参考に、実践! Samba移行術 第2回:NT4.0→ Samba3.0への移行(1)以降の連載を見ながら。

以降は手順

LDAP インストール

# yum install openldap-servers

ldapのsamba用スキーマをコピー

# cp /usr/share/doc/samba-3.0.25b/LDAP/samba.schema /etc/openldap/schema/

LDAPサーバの設定ファイル /etc/openldap/slapd.conf を編集

# vi /etc/openldap/slapd.conf

追加
 include         /etc/openldap/schema/samba.schema
変更
 suffix          "dc=my-domain,dc=com"
 rootdn          "cn=Manager,dc=my-domain,dc=com"
↓
 suffix          "dc=example,dc=co,dc=jp"
 rootdn          "cn=Manager,dc=example,dc=co,dc=jp"
追加
 rootpw          xxx
追加
 access to * by * read

 access to attrs=userPassword,sambaLMPassword,sambaNTPassword
        by self write
        by users read
        by anonymous auth

LDAPのサービス開始

 # service ldap start
 # cp /etc/openldap/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
 # service ldap restart
 # chkconfig ldap on

認証の変更

# authconfig-tui

authconfig-tui - (c) 1999-2005 Red Hat, Inc.

            ┌───────┤ 認証の設定 ├───────────│
            │  ユーザー情報         認証                          │
            │  [ ] キャッシュ情報   [*] MD5 パスワードを使用      │
            │  [ ] Hesiod を使用    [*] シャドウパスワードを使用  │
            │  [*] LDAP を使用      [*] LDAP 認証を使用           │
            │  [ ] NIS を使用       [ ] Kerberos 5 を使用         │
            │  [ ] Winbind を使用   [ ] SMB 認証を使用            │
            │                       [ ] Winbind 認証を使用        │
            │                       [*] ローカル認証は十分です    │
            │                                                     │
            │         ┌─────┐                ┌──┐      │
            │         │ 取り消し │                │ 次 │      │
            │         └─────┘                └──┘      │
            │                                                     │
            └──────────────────────────┘

次の画面

authconfig-tui - (c) 1999-2005 Red Hat, Inc.

            ┌─────────┤ LDAP 設定 ├───────────│
            │           [ ] TLS を使用                            │
            │  サーバー: ldap://127.0.0.1/_______________________ │
            │ ベース DN: dc=example,dc=co,dc=jp________________ │
            │                                                     │
            │          ┌───┐                  ┌──┐       │
            │          │ 戻る │                  │ OK │       │
            │          └───┘                  └──┘       │
            │                                                     │
            └───────────────────────────┘

/etc/samba/smb.conf を編集

smbldap-xxはこの後インストールします。

[global]
        dos charset = CP932
        display charset = UTF-8
        workgroup = MYDOMAIN
        passdb backend = ldapsam
        guest account = Guest
        add user script = /usr/sbin/smbldap-useradd -m '%u'
        delete user script = /usr/sbin/smbldap-userdel -r '%u'
        add group script = /usr/sbin/smbldap-groupadd -p '%g'
        delete group script = /usr/sbin/smbldap-groupdel '%g'
        add user to group script = /usr/sbin/smbldap-groupmod -m '%u' '%g'
        delete user from group script = /usr/sbin/smbldap-groupmod -x '%u' '%g'
        set primary group script = /usr/sbin/smbldap-usermod -g '%g' '%u'
        add machine script = /usr/sbin/smbldap-useradd -w '%u'
        domain logons = Yes
        os level = 64
        preferred master = Yes
        domain master = Yes
        wins support = Yes
        ldap admin dn = cn=Manager,dc=my-domain,dc=com
        ldap group suffix = ou=Groups
        ldap machine suffix = ou=Computers
        ldap passwd sync = Yes
        ldap suffix = dc=my-domain,dc=com
        ldap user suffix = ou=Users
        add share command = /usr/lib/samba/bin/addshare
        change share command = /usr/lib/samba/bin/chgshare
        delete share command = /usr/lib/samba/bin/delshare
        admin users = Administrator
        force unknown acl user = Yes
        dos filetime resolution = Yes

        load printers = no
        disable spoolss = yes

;       logon home =
;       logon script = %u.bat
;       logon path = \%L\Profiles\%u
;       logon path =
        logon drive = H:

[C$]
        path = /
        valid users = administrator
        write list = administrator

[homes]
        comment = Home Directories
        read only = No
        browseable = No

[printers]
        comment = All Printers
        path = /var/spool/samba
        printable = Yes
        browseable = No

[netlogon]
        comment = Network Logon Service
        path = /var/lib/samba/netlogon
        write list = administrator
        guest ok = Yes

[Profiles]
        path = /var/lib/samba/profiles
        create mask = 0600
        directory mask = 0700
        guest ok = Yes
        profile acls = Yes
        browseable = No

netlogonとprofilesのディレクトリ作成

 # mkdir -p /var/lib/samba
 # mkdir -p /var/lib/samba/{netlogon,profiles}
 # chown root:root -R /var/lib/samba/
 # chmod 0755 /var/lib/samba/netlogon
 # chmod 1755 /var/lib/samba/profiles

LDAPの管理者(rootdn)のパスワード登録

# smbpasswd -w パスワード

smbldap-tool を設定

 # cd /usr/share/doc/samba-3.0.25b/LDAP/smbldap-tools-0.9.2
 # vi Makefile
prefix=/usr
sbindir=$(prefix)/sbin
sysconfdir=/etc
 # make install
 # chmod 755 configure.pl
 # ./configure.pl

configure.plを使うと、対話形式で/etc/smbldap-tool のsmbldap.confとsmblda_bind.confを設定できます。
これらのファイルは/usr/sbin/smbldap-xxが参照する設定ファイルです。途中エラーもでますが、無視(^ ^;)して進めちゃいます。

LDAPサーバへの初期データ投入

 # wget http://dag.wieers.com/rpm/packages/perl-Crypt-SmbHash/perl-Crypt-SmbHash-0.12-1.2.el5.rf.noarch.rpm
 # rpm -ivh perl-Crypt-SmbHash-0.12-1.2.el5.rf.noarch.rpm
 # cpan install Unicode::MapUTF8
 # /usr/sbin/smbldap-populate -a Administrator -b Guest

sambaへ登録したドメイン管理者のパスワード設定

# smbldap-passwd Administrator

sambaサービスを再起動

# service smb start
/var/log/samba/smbd.log に下のエラーが手続けるのは、 ldapに管理者で接続できていない。のが原因

[2008/01/25 11:45:31, 1] lib/smbldap.c:another_ldap_try(1153)
Connection to LDAP server failed for the x try!

対応は
・「smbpasswd -w パスワード」を再実行
・/etc/samba/smb.conf の 「ldap admin dn」を確認

sambaへグループを登録

# smbldap-groupadd -a regularStaff

sambaへユーザを登録

# smbldap-useradd -a -m -P -g regularStaff ldapuser
Domain Usersにも含めたいときは -G “Domain Users”

samba(といかLDAP)に登録したユーザとシステム認証との関係を確認

authconfig-tuiとldapへの登録が行なえていると、
# getent passwd
でユーザの、
# getent group
でグループの一覧が見れます。/etc/passwd及び、/etc/groupとLDAPへ登録した内容が合わされて表示されます。LDAPに登録した分が表示されないのであれば、authconfig-tuiを見直してください。

eclipseでPHPの開発

PHPでの開発をすることとなり、eclipseをIDEに使うこととなった。で、これまで使っているeclipse3.2.1へインストールしようとするとPDTが依存するプラグインを見つけられずに困っている。PDT/Installを見ると、1.0以降はeclipse3.3でないと動かない。
なので、諦めて、eclipse3.3をダウンロードして、日本語化。その後にPDTをインストール。

使ってみた感想は、悪くはないけどJavaでのコーディングのし易さには負けるな。リモートデバッグもやれるけど、実行前にはサーバへソースの一式転送があり起動までにもっさり感がある。Webサーバをローカルに持ち実行前に転送する必要がなければ改善されるのかな。

これまでは、エディタとftpでやって来て、これを覆す程の便利さは感じられなかった。嬉しさをあえて言えば、文法チェックが随時行われているということ。

org.eclipse.core.runtime.CoreException: XML 文書を構文解析できません

タイトルの通りです。Tomcatのプロジェクト名(ディレクトリ名に?)漢字が含まれていると,eclipseプラグインからTomcatを起動できませんでした。エラーのスタックトレースはこちら↓。

eclipse.buildId=M20060629-1905
java.version=1.5.0_09
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=ja_JP
Command-line arguments:  -os win32 -ws win32 -arch x86

エラー
Sun Jan 13 00:31:35 JST 2008
org.eclipse.core.runtime.CoreException: XML 文書を構文解析できません。at org.eclipse.debug.core.DebugPlugin.abort(DebugPlugin.java:1202)
at org.eclipse.debug.core.DebugPlugin.parseDocument(DebugPlugin.java:1178)
at org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector.doInitializeFromMemento(AbstractSourceLookupDirector.java:410)
at org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector.initializeFromMemento(AbstractSourceLookupDirector.java:546)
at org.eclipse.debug.internal.core.LaunchConfiguration.initializeSourceLocator(LaunchConfiguration.java:523)
at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:638)
at com.sysdeo.eclipse.tomcat.VMLauncherUtility.runVM(VMLauncherUtility.java:95)
at com.sysdeo.eclipse.tomcat.TomcatBootstrap.runTomcatBootsrap(TomcatBootstrap.java:202)
at com.sysdeo.eclipse.tomcat.TomcatBootstrap.start(TomcatBootstrap.java:95)
at com.sysdeo.eclipse.tomcat.actions.StartActionDelegate.run(StartActionDelegate.java:38)
at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:254)
at org.eclipse.ui.internal.WWinPluginAction.runWithEvent(WWinPluginAction.java:229)
at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:539)
at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:488)
at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:441)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:928)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3348)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2968)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1914)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1878)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:419)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:95)
at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
at org.eclipse.core.launcher.Main.run(Main.java:977)
at org.eclipse.core.launcher.Main.main(Main.java:952)
org.eclipse.core.runtime.CoreException[120]: org.xml.sax.SAXParseException: Invalid byte 1 of 1-byte UTF-8 sequence.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:236)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:215)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:386)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:316)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1810)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:368)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:834)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:148)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:250)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:292)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:98)
at org.eclipse.debug.core.DebugPlugin.parseDocument(DebugPlugin.java:1172)
at org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector.doInitializeFromMemento(AbstractSourceLookupDirector.java:410)
at org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector.initializeFromMemento(AbstractSourceLookupDirector.java:546)
at org.eclipse.debug.internal.core.LaunchConfiguration.initializeSourceLocator(LaunchConfiguration.java:523)
at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:638)
at com.sysdeo.eclipse.tomcat.VMLauncherUtility.runVM(VMLauncherUtility.java:95)
at com.sysdeo.eclipse.tomcat.TomcatBootstrap.runTomcatBootsrap(TomcatBootstrap.java:202)
at com.sysdeo.eclipse.tomcat.TomcatBootstrap.start(TomcatBootstrap.java:95)
at com.sysdeo.eclipse.tomcat.actions.StartActionDelegate.run(StartActionDelegate.java:38)
at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:254)
at org.eclipse.ui.internal.WWinPluginAction.runWithEvent(WWinPluginAction.java:229)
at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:539)
at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:488)
at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:441)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:928)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3348)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2968)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1914)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1878)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:419)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:95)
at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
at org.eclipse.core.launcher.Main.run(Main.java:977)
at org.eclipse.core.launcher.Main.main(Main.java:952)

このログ、ワークスペースの下にある.metadata/.log を見ると漢字が文字化けしています。「ウィンドウ」→「ビュー」→「エラー・ログ」から見ると文字化けしてないです。

いきなり、eclipseプラグインからTomcatが立ち上がらなくなったと感じてしまったが、プロジェクト名に漢字を含むものを作り、Tomcatのコンテキストに追加したのが原因でした。

警告「Cannot modify header information」にはまる

Webの記事を参考にコピペでページを作成すると下の警告が出てしまう。

( ! ) Warning: Cannot modify header information - headers already sent by (output started at /usr/local/corpjoin/app/controllers/users_controller.php:66) in /usr/local/corpjoin/cake/libs/controller/components/request_handler.php on line 135
Call Stack
# Time Function Location
1 0.0017 {main}( ) ../index.php:0
2 0.0377 dispatcher->dispatch( ) ../index.php:82
3 0.1971 dispatcher->_invoke( ) ../dispatcher.php:245
4 0.1971 dispatcher->start( ) ../dispatcher.php:256
5 0.1972 requesthandlercomponent->startup( ) ../dispatcher.php:298
6 0.1972 requesthandlercomponent->setajax( ) ../request_handler.php:120
7 0.1972 header ( ) ../request_handler.php:135

警告のメッセージで探してみると、/usr/local/corpjoin/app/controllers/users_controller.phpの66行目(要はエラーが出ている場所)から後ろにスペースもしくは改行があるのではないか。ということ。

はい。その通りでした。安易なコピペが思わぬ警告につながってしまった。