NetBeansがよく固まる
なんだか私のNetBeansはよく固まります。
心無しか、クラスやファイルを次から次へと開いているときやたくさん開こうとしたときに固まるような気がします。
Eclipseを使ってたときの経験から考えるに、なんとなく、NetBeansを起動しているJVMのパーマネント領域が足りないような気がしなくもない。Eclipseも、たくさんプラグインを入れたりするとデフォのVM設定だとヒープがまだ残っているのによくOutOfMemoryで落ちました。
というか、たかだかクライアントソフトにメモリチューニングが必要だなんてちょっと大富豪仕様過ぎやしませんか。
まぁそれはともかくとして。
そんな訳で、NetBeansの起動オプションを弄ってみようと思うのですが、さてどれを弄ればいいのでしょう。Eclipseだと、eclipse.iniを弄ればいいのですが。
このファイルの
netbeans_default_options="-J-Dcom.sun.aas.installRoot=/Applications/NetBeans/gla ssfish-v2ur2 -J-Dcom.sun.aas.installRoot=/Applications/NetBeans/glassfish-v2ur2 -J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Xverif y:none -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=true"
このオプションすか。
netbeans_default_options="-J-Dcom.sun.aas.installRoot=/Applications/NetBeans/gla ssfish-v2ur2 -J-Dcom.sun.aas.installRoot=/Applications/NetBeans/glassfish-v2ur2 -J-client -J-Xss2m -J-Xms384m -J-Xmx384m -J-XX:PermSize=128m -J-XX:MaxPermSize=1 28m -J-Xverify:none -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=t rue"
こんな感じのオプションにすればいいっすか。
・・・
外れでした
というか、なんとなく動きのきびきび感はアップした気がするので設定ファイルやオプション自体は当たりだったような気がするのですが、相変わらずよく固まります。
- クラスをシングルクリックして選択すると「ナビゲータ」の「メンバービュー」が「お待ちください・・・」ってなってしばらくするとメンバーが表示される。
- この状態でクラスをダブルクリックするとJavaエディタにクラスを開く。
と思いますが、1と2の間に先走って「メンバービュー」が「お待ちください・・・」ってなってる最中にクラスをダブルクリックすると100%固まります。
うぅむ。
私だけでしょうか。
どうでもいいというかどうでもよくなくて話がかなり飛ぶだけなんですけど、NetBeansはEclipseと違って、
- 現在ヒープのうち実際どれくらいメモリを使っているかを表示するオプションは無い
- 「ワークスペース」という概念も無い
ってことでいいのでしょうか。まぁ慣れれば別に無くてもどうということは無いのかもしれませんけど。
guiceの基本的なインジェクション
はじめに
- 当ページは、「google guiceをベースにWebアプリケーションを作ってみよう」の1コンテンツです。
- google guiceを使った初歩的なDIについて、Spring Frameworkのそれと比較しながらまとめています。
前提
こんな感じのクラスを作成するとします。
サービスのインターフェース | Service |
サービスの実装クラス | ServiceImpl |
サービスをインジェクションされるクラスのインターフェース | Client |
サービスをインジェクションされるクラスの実装 | ClientImpl |
サービスをインジェクションされたClientを利用するクラス | Test |
サービスとクライアントのコード
こんな感じです。
- Service
public interface Service { public void execute(); }
- ServiceImpl
public class ServiceImpl implements Service { public void execute() { System.out.println("Service is executed."); } }
- Client
public interface Client { public void executeService(); }
- ClientImpl
public class ClientImpl implements Client { private Service service_; public void setService(Service service) { service_ = service; } public void executeService() { System.out.println("Client is executed."); service_.execute(); } }
Springの場合
guiceでDIする前に、比較として、デファクトなSpringでDIしてみたいと思います。
まず、Springの場合は、依存性を解決するためには以下のようなBean定義ファイルを作成する必要があります。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" (略) > <bean id="service" class="org.chiba.impl.ServiceImpl" /> <bean id="client" class="org.chiba.impl.ClientImpl"> <property name="service" ref="service" /> </bean> </beans>
上記のファイルは、とりあえずクラスパス直下に「applicationContext.xml」というファイル名で保存します。上記のBean定義ファイルを使って、Clientを通してServiceを実行するためのTestクラスのコードは以下のようになります。
public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Client client = (Client)context.getBean("client"); client.executeService(); } }
実行結果は以下のようになります。
Client is executed. Service is executed.
TestはClientImplに直接依存していませんし、ClientImplはServiceImplに直接依存していませんが、それぞれClientImplとServiceImplのメソッドが実行されていることが分かると思います。
Guiceの場合
上記のことをGuiceで行う場合にはまず、DI対象のsetterに「@Inject」アノテーションを付加する必要があります。
public class ClientImpl implements Client { private Service service_; @Inject ←←←←← ココ public void setService(Service service) { service_ = service; } public void executeService() { System.out.println("Client is executed."); service_.execute(); } }
次に、Bean定義ファイルの代わりに、「モジュール」と呼ばれるクラスを「AbstractModule」を継承して作成する必要があります。
public class TestModule extends AbstractModule { @Override protected void configure() { bind(Service.class).to(ServiceImpl.class).in(Scopes.SINGLETON); bind(Client.class).to(Client.class).in(Scopes.SINGLETON); } }
これらを利用するTestクラスのコードは以下のようになります。
public class Test { public static void main(String[] args) { Module module = new TestModule(); Injector injector = Guice.createInjector(module); Client client = injector.getInstance(Client.class); client.executeService(); } }
実行結果は以下のようになります。
Client is executed. Service is executed.
当然ですけど、Springの場合と同じですね。
比較
DIの設定をXMLで書くかコードで書くかは好みの分かれるところ*1ではあると思いますが、
- Spring
- Client client = (Client)context.getBean("client");
- Guice
- Client client = injector.getInstance(Client.class);
キャストや文字列リテラルを用いなくてもよい(IDEの補完が効く)のはGuice側のメリットだと思います。一方、Springの場合はClientやServiceはSpring自身にも依存していないのに対して、Guiceの場合は
@Inject public void setService(Service service) { service_ = service; }
ここでClientがGuice自身に依存してしまっているのが残念というかデメリットと言えばデメリットだと思います。
Guice 1.0 User's Guide和訳 その1
はじめに
- 当ページは、「google guiceをベースにWebアプリケーションを作ってみよう」の1コンテンツです。
- Guice 1.0 User's Guideの「Java on Guice」〜「Introduction」を和訳しています。
- 原文はこちらを参照して下さい。
Introduction - はじめに
エンタープライズJavaコミュニティーは、オブジェクト間の依存性を解決するために大変な労力を費やしています。Webアプリケーションでは、どのようにして中間層のサービスや、ログインユーザに対するサービスや、トランザクションマネージャーを取得すれば良いのでしょう?一般的な手法、特殊な手法を含め、多くの方法が存在すると思います。何かしらのデザインパターンを使う人も入れば、何かしらのフレームワークを使う人もいるでしょう。それらは全て、なるべくテスト容易性を確保したり、お決まりのコードの記述量を減らそうとした結果生み出されたものです。あなたはすぐに、これらの様々な手法の中でもGuiceが最善の選択肢であると思うようになるでしょう。Guiceはとてもテストが容易で、柔軟で保守性の高いアプリケーションを作成することが可能であり、お決まりのコードの記述量も少なくてすみます。
Guiceが一般的によく用いられている古典的な手法よりも優れていることを説明するために、非現実的だけど簡単な例を用いてみます。以下の例は、実際にはGuiceを使う程のことも無い簡単な例ですが、Guiceの良さをよく表しています。アプリケーションが大きく複雑になればなるほど、Guiceはその威力を発揮するでしょう。
この例では、あるクライアントはあるサービスのインターフェースに依存しています。このサービスは適当な任意のサービスなので、ここでは単に「サービス」とだけ呼ぶことにします。
public interface Service { void go(); }
サービスには通常、デフォルトの実装クラスが存在します。クライアントは通常、実装クラスには直接依存すべきではありません。将来実装クラスを変更することになった場合、全てのクライアントを修正して回るのは大変だからです。
public class ServiceImpl implements Service { public void go() { ... } }
この例ではさらに、テストで使用するためのモックのサービス実装も存在するものとします。
public class MockService implements Service { private boolean gone = false; public void go() { gone = true; } public boolean isGone() { return gone; } }
Mac de Subversion
さて。
先日Leopardにバージョンアップして以来まだSubversionを入れなおしていないのでそろそろインストールしなおそうかと思っている訳なのですが。
我がぼそっとのアクセスログを見るに「Subversion 設定」みたいな感じのキーワードでぐぐってたどり着いた人が結構いるような気配を感じるので、とりあえず私のインストール〜設定手順を晒してみたいと思います。
参考になるかどうかは分かりませんけど。
- Subversion & Apache2のインストール
- Subversionのリポジトリ作成
$ cd $ mkdir ./svn $ cd svn/ $ mkdir ./repository $ svnadmin create ~/svn/repository/
- リポジトリの公開
LoadModule dav_svn_module libexec/apache2/mod_dav_svn.so
-
- 続いて、以下のコマンドで認証用のファイルを作成します。
$ htpasswd -c ~/svn/svn-auth-file chiba_mk3 New password: Re-type new password: Adding password for user chiba_mk3
-
- 続いて以下の設定を「/etc/apache2/httpd.conf」に追加します。
<Location /svn> DAV svn SVNParentPath /(path-to-svn)/svn AuthType Basic AuthName "Subversion repository" AuthUserFile /(path-to-svn-auth-file)/svn-auth-file <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location>
-
- 以下のコマンドでapacheを起動します。
$ su - # apachectl start
-
- 以下のURLでリポジトリーを閲覧できれば成功
http://localhost/svn/repository/
- 初期ディレクトリ作成
- Subversionでは、慣例的に「trunk」「branches」「tags」というディレクトリをリポジトリ直下に作成するので、ついでにそれも作成してみます。
$ cd $ mkdir ./svn_work $ cd ./svn_work/ $ svn checkout http://localhost/svn/repository $ cd repository/ $ mkdir ./trunk $ mkdir ./branches $ mkdir ./tags $ svn add ./trunk/ $ svn add ./branches/ $ svn add ./tags/ $ svn commit -m "init import" Authentication realm: <http://localhost:80> Subversion repository Password for 'chiba_mk3': Adding branches Adding tags Adding trunk Committed revision 1.
- 「log-encoding」設定
- 以前に調べた通り、NetBeansだとデフォだと日本語のコミットコメントが通らないので、「~/.subversion/config 」の
# log-encoding = latin1
-
- の部分を、
log-encoding = UTF-8
-
- に変更。10.4のときは
log-encoding = Shift-JIS
以上で完了です。とりあえず個人でローカルで使うだけなのでSSLとか使ってません。
google guiceをベースにWebアプリケーションを作ってみよう - 目次
さて。
先日、guiceをベースとしてより上位なフレームワークを作ってみようとか偉そうなことを言ってしまった私が来た訳ですが。
実のところ、正直別に私はRailsとかSeamとかSeasarとかみたいなエレガントなものを作ってしまえるような凄腕なんて残念ながら持ち合わせてはいないので、とりあえず以下のやり方をまとめるところから初めてみたいと思います。とりあえずこの辺ができれば割といけるような気がするんですけど私だけでしょうか。
- DIについて
- 基本的なインジェクション
- 定数のインジェクション
- 文字列のインジェクション
- コレクションのインジェクション
- インジェクションするクラスを実行時に指定する方法
- プロバイダーを使用したインジェクション
- シングルトンについて
- AOPについて
- 設定ファイルとの連携
- プロパティファイルとの連携
- メッセージリソースとの連携
- シングルトン・コンテキストパターン
- ORMとの連携
- Webフレームワークとの連携
- Struts1との連携
- Struts2との連携
- JSFとの連携
- Click Frameworkとの連携
- Wicketとの連携
- ユニットテストについて
- Web層のテスト
- ビジネスロジック層のテスト
- Daoのテスト
- その他
また、既に和訳されている方もいますが、勉強も兼ねてユーザーズガイドを自分でも和訳してみたいと思います。
- Guice 1.0 User's Guide
- Introduction
- Plain Old Factories
- Dependency Injection By Hand
- Dependency Injection with Guice
- Guice vs. Dependency Injection By Hand
- More Annotations
- Architectural Overview
- Startup
- Runtime
- Bootstrapping Your Application
- Binding Dependencies
- DRY (Don't Repeat Yourself)
- Annotating Bindings
- Creating Binding Annotations
- Annotations With Attributes
- Implicit Bindings
- Injecting Providers
- Injecting Constant Values
- Converting Strings
- Custom Providers
- Example: Integrating With JNDI
- Scoping Bindings
- Creating Scope Annotations
- Eagerly Loading Bindings
- Injecting Between Scopes
- Development Stages
- Intercepting Methods
- Static Injection
- Optional Injection
- Binding to Strings
- Struts 2 Support
- A Counting Example
- JMX Integration
- Appendix: How the Injector resolves injection requests
もっと凄いものとかを期待していた人(いたらですけど)、すいません。
EclipseのWTPでApache Ivy v.s m2eclipseその2 - Ivyってどうよ
さて。では、同じようなことをIvyでやってみたいと思います。
- Eclipse上でWTPの動的Webプロジェクトを作成する
- トクダン変わったことも無く普通にウィザードで作成しますが、とりあえずプロジェクト名は「ivy_test」にします
- Ivyをここからダウンロードして解凍
- 以下のライブラリをWEB-INF/libにコピー*1
- 以下のような「ivy.xml」をプロジェクトの直下に作成
<ivy-module version="2.0"> <info organisation="org.chiba" module="ivy_test" /> <dependencies> <dependency org="org.apache.struts" name="struts-core" rev="1.3.9" /> </dependencies> </ivy-module>
- 以下のような「build.xml」をプロジェクトの直下に作成
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="ivy_test" default="resolve" basedir="."> <path id="ivy.lib.path"> <fileset dir="${basedir}/WebContent/WEB-INF/lib" includes="*.jar"/> </path> <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/> <target name="resolve" description="--> retrieve dependencies with ivy"> <ivy:retrieve /> </target> </project>
- 「resolve」タスク実行
- こんなエラーが出るも何やら正常終了
[Error] :43:30: cos-nonambig: "":license and WC[##any] (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.
・・・
予想していたのですが、
ライブラリがどこにダウンロードされたのか分かりません
まぁ、クイックスタートを読んだときから予想していたので驚きはしませんでしたが。
さて。どこにいったものかと思ってプロジェクトの表示をリフレッシュしてよぉく見てみたら、
プロジェクト直下にlib/ディレクトリができている
ではありませんか。
なるほど。
確かに、ここにstruts-core-1.3.9.jarと、それが依存するライブラリがダウンロードされています。依存性の推移的解決もできるみたいですね。このlibディレクトリからWEB-INF/libディレクトリにコピーするようなタスクを追加してあげればいけそうです。
jarプロジェクトの場合にどうやってクラスパスを通すか
がまためんどくさそうですけど、まぁそれはそれでなんとかなりそうです。ダミーの動的Webプロジェクトを作ってそのWEB-INF/libを参照するとかしてもいいですし。
話は変わって、以前の日記に書いた、
的なことは、resolverの設定とかでなんとかなりそうな気はするのですが、mavenでいうところのcompileとかのスコープ的なものは無いものでしょうか。
さっきのstrutsの例だと、servlet-apiとか「provided」にしたいようなライブラリもいくつかダウンロードされてくるのがちょっと気になるところです。後は、
- ソースのダウンロードとか
- JavaDocのダウンロードとか
ちょいちょい気になるところはありますが、
まぁそれはそれとして
結論から言うと、私が現在ant+mavenで行っているようなことは、ant+ivyで行う方が楽なような気がします。
だって、コマンドでmavenプロジェクトを作ってeclipseにインポートして設定ファイルをごにょごにょいじって動的プロジェクト化して・・・とかそもそもが面倒くさいですし。
しかし、m2eclipseも思ったよりもだいぶ良くなっているような気がします。ant+ivyだと、「動的Webプロジェクトを作って、ivy関連のjarにクラスパスを通して、ivy.xmlを書いて、build.xmlを書いて・・・」と、まぁ全部IDE上でできるものの色々手作業がある訳ですが、m2eclipseだと今やウィザード一発でプロジェクトが出来ます。ライブラリの追加もGUIベースで、ソースやJavaDocも(mavenリポジトリにあれば)ダウンロードできます。
ちょいちょい不安定ですけど。
そんな訳で、m2eclipseの勝ち・・・と、言いたいところですが、struts-layoutとかdjunitかflexとか、
的なものを扱おうと思うと、やっぱm2eclipse+antになるので、そういうケースではant+ivyの方がシンプルでいいような気がします。
*1: ほんとは、この手のビルドやテストに固有のものは、本番にデプロイしないようにWEB-INF/libには入れずに別の手法でクラスパスを通した方がいいと思いますが、ここではちょっとずぼらします。
EclipseのWTPでApache Ivy v.s m2eclipseその1 - 最近のm2eclipse
さて。
最近はどうか知りませんが、EclipseでWTPの動的プロジェクトでmavenを使うと、
- Eclipseのmavenプラグインはバージョンが低すぎて微妙
- 最近はバージョンがあがってきたのでひょっとしたらだいぶ良くなっているのかもしれないが、
- この記事を見る限りでは、少なくとも半年前の時点ではかなり微妙っぽい。
- mavenのeclipseプラグインだと、せっかくクラスパスにjarを追加してもWTPが認識しない
等々、色々微妙なところがありました。そこで、先日の日記にも書いた通り、ivyを試してみようかと思った訳なのですが。
ここのm2eclipseのリリースノートっぽいサイトを見るに、ちょうど「Mavenはビルドに適したツールか?」←この議論があった後くらいにm2eclipseのバージョンが0.0.13から0.2にジャンプアップして、その後1ヶ月もたたないうちに0.9まで大幅にジャンプアップして、現在では0.9.5なんて1.0間近までアップしているでは無いですか。
アヤシい
くらいのバージョンアップの早さですが、議論で叩かれたのでついに本気になったのかもしれません。そんな訳で、せっかくなので、大幅バージョンアップしたm2eclipseとivyを両方試してみたいと思います。
では、まずm2eclipseから。以下にアップデートサイトがあるみたいなので、そこからインストールします。
- http://m2eclipse.sonatype.org/update/
- その際、「Maven Integration for AJDT」は、依存性の解決ができなくてエラーになるのでとりあえず外します。
ガニメデになって微妙に「ソフトウェアの更新」のユーザーインターフェースが変わったのでちょっと戸惑いましたけど、とりあえずインストールできました。どうでもいいけど、「更新を反映するにはシステムの再起動が必要です。」というメッセージが表示されるのは微妙ですね。実際に再起動されたのはeclipseで、多分eclipseが再起動されるんだろうとは思いましたが、「もしかしたらOSごと再起動するのかも?」という恐怖感(?)は拭えません。eclipseそのものが悪いのか、pleiadesが悪いのかは分かりませんが。
さらに、「Maven SCM handler for Subclipse」なんてオプションがあるのも微妙に気になります。将来的にはSubversiveが標準になってデフォルトバンドルされるようになり、Subclipseは要らない子になるとかいう話はどうなったのでしょう。この辺のツール間の統一感の無さ加減がまたいかにもeclipseっぽくて素敵ですけど。一方、「Maven Integration for WTP」なんてオプションにはwktk感がそそられます。
さて。
再起動すると、予想通りメニューバーから「ファイル→新規→プロジェクト」で、mavenプロジェクトが作成できるようになっているので、とりあえず以下の手順で「Maven Project」を作成してみます。
- 最初の画面(Select project name and location)はとりあえず何も変更せずに「次へ」をクリック
- 二番目の画面(Select an Archetype)は、「Artifact Id」が「maven-archetype-webapp」のものを選択して「次へ」をクリック
- 三番目の画面(Enter an artifact ID)は、適当に入力して「終了」をクリック。
- とりあえずここでは、
- グループID:org.chiba
- アーティファクトID:m2eclipse_test
- バージョン:0.0.1
- パッケージ:org.chiba
- にしてみます。
- とりあえずここでは、
最初の画面とか何をしていいのか微妙に良く分からんオプションとかありますが、まぁまぁそんなに難しくありません。
しかも
この時点で既に何もしなくてもWTPの「動的Webプロジェクト」としても認識されています。動的Webモジュールのバージョンが2.3、JDKのバージョンが1.4と今時にしては低めのデフォルト設定なのが気になりますが、ここまではなかなか悪くありません。
あえて気になるといえば、m2eclipse関連のメニューなりなんなりは
pleiadesを入れていても全く日本語化されない
ところが凶悪(?)なところですが、そこもまぁよしとします。src/main/resourcesがあってsrc/main/javaが無いのも、まぁmaven側のミス仕様だと思うのでそれもよしとします。
では続いて、ライブラリを追加してみたいと思います。とりあえず、ここではStruts 1.3を追加してみます。
- プロジェクトを右クリックしてコンテキストメニューを表示
- 「m2 Maven→依存関係の追加」をクリック
- 「Enter groupId, (略)」のところに「struts」と入力
- 検索結果の中から「org.apache.struts struts-core」を選択し、バージョンは「1.3.9」のスコープは「compile」を選択
- 「OK」をクリック
なんかちょいちょいエラー出ましたが、とりあえずダウンロードには成功。
続いて、こんな感じで実行してみたいと思います。
<servlet> <servlet-name>action</servlet-name> <servlet-class> org.apache.struts.action.ActionServlet </servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>chainConfig</param-name> <param-value>/WEB-INF/chain-config.xml</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"> <struts-config> <!-- アクションフォーム --> <form-beans> </form-beans> <!-- アクションマッピング --> <action-mappings> <action path="/welcome" type="org.chiba.ForwardAction"> <forward name="success" path="/index.jsp" /> </action> </action-mappings> </struts-config>
- 以下のようなフォワードするだけのアクションを作成
package org.chiba; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class ForwardAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { return mapping.findForward("success"); } }
- WTP経由でTomcat6上で実行
おぉぉっぉおsぉうおぉぅっぉおっぉぉぉうぉっっぉぅお!!
なんか問題なく動いていますね。WEB-INF/libの下に無くても、ちゃんとstruts-core-1.3.9.jarを認識しています。かつてとは大違いです。しかも、NetBeansと違ってプロジェクトが完全にmavenに統合されている訳ではないので、テストケースの単独実行も楽そうです*1。
ちょいちょい不安定なところはありましたが、意外と悪く無さそうな・・・1.0には期待できそうです。
では続いてIvyは・・・その2で書きますーー;。