jetty + jndi(with c3p0)な環境から lightsleepを使って超簡単にDBに繋ぐ - デバッグができるようになるまで
どうも、のらぬこです。
この記事では、タイトルに記載の環境が eclipseデバッグ環境でも mvn jetty:run での環境でも正しく動作するところまでを記載します。
さて、最近、個人的に立ち上げてみたいWebサービスができまして、現在こっそり実装中です。
ただ、いかんせコード書き始めてまだ3日程度なので、使うフレームワークは今後変わるかもしれないし、そもそも途中で飽きるかもしれません。
が、今のところ、言語はJava、ApplicationServer には jetty、RDBは postgreSQL、Webフレームワークにはasta4dというフレームワークを選択しています。
O/R mapperとしてDomaを使おうかとも思ったのですが、最近見かけたlightsleepというO/R mapperを検証がてら使ってみることにしました。
下準備
開発環境
まずは開発環境として以下の環境を準備します。
- Eclipse 4.5.2
- すでにneon.2 まで出ていますが、そちらでも問題ないと思います。
- run-jetty-run 1.3.5(Nightly)
- Eclipse 内の market place からもダウンロードできますが、現在公開されているバージョンはjetty 9.0.0M3 までしか対応していません。
- eclipseからデバッグ実行したとき、環境によっては(?)不具合が発生する可能性があるため、GitHub - xzer/run-jetty-run: Official successor of https://code.google.com/p/run-jetty-run/ を参考に、最新のnightly buildを使います。
- market placeからダウンロードできる1.3.4を使用た場合、デバッガから起動した際に、使用するJettyのバージョンに関わらず、IndexOutOfRangeExceptionが大量発生する謎バグに遭遇することがあります。
- なお、Eclipse market place を見ると、「Eclipse Jetty 3.9.0」 なるものもありますが、こちらのプラグインはjetty 起動時にc3p0を lib/ext としてjettyに食わせる手段がなさそうなので使えません。
とりあえずひな型WebAppの作成
これから開発を始めるという方は、まずはひな型Webプロジェクトを作成してください。
asta4dを利用する場合の手順は、GitHub - astamuse/asta4d: View first web application framework に手順が掛かれています。超簡単。
pomの設定を追加
下記のような形で書きます。とりあえず、今回追加が必要となる部分のみ抜き出しています。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <dependencies> <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.4.1212.jre7</version> </dependency> <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <dependency> <groupId>lightsleep</groupId> <artifactId>lightsleep</artifactId> <version>1.5.1</version> <scope>system</scope> <systemPath>${project.basedir}/lib/lightsleep-1.5.1.jar</systemPath> </dependency> </dependencies> </project>
なお、lightsleepは mvnrepository に登録されてなさそうなので、こちらを参考に、jarをダウンロードして pom.xml に systempath として追加しています。
jndiの設定を書く
jetty側
プロジェクトディレクトリに jetty ディレクトリを作成し、その中に jetty-local.xml という名前で jndiの設定(jetty側)を記載します。 jndi名、jdbc接続文字列等は各自適切に変更してください。
<!-- jetty/jetty-local.xml --> <Configure id="noranuk0DB" class="org.eclipse.jetty.server.Server"> <New id="noranuk0MasterDB" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg></Arg> <!-- score --> <Arg>jdbc/noranuk0DB</Arg> <!-- name --> <Arg> <!-- value --> <New class="com.mchange.v2.c3p0.ComboPooledDataSource"> <Set name="driverClass">org.postgresql.Driver</Set> <Set name="jdbcUrl">jdbc:postgresql://localhost:5432/kagure</Set> <Set name="user">admin</Set> <Set name="password">admin</Set> </New> </Arg> </New> </Configure>
webapp側
src/main/webapp/WEB-INF/web.xml の web-app要素内に以下を追記します。res-ref-name は jetty-local.xml で指定した名前と同じものを設定してください。
<resource-ref> <res-ref-name>jdbc/noranuk0DB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
lightsleepの設定
src/main/resources/lightsleep.property を新規作成し、以下のような感じで設定します。Databaseの欄は環境に合わせて適宜変更してください。
# for PostgreSQL Logger = Std$Out$Info Database = PostgreSQL ConnectionSupplier = Jndi dataSource = jdbc/noranuk0DB
各環境ごとの設定例などは、Lightsleep/Manual_ja.md at master · MasatoKokubo/Lightsleep · GitHub を参照してください。
run-jetty-runの設定
- $HOME/.m2/repository/ 以下から下記3つの jarを探してきて、プロジェクトディレクトリ内の適当な場所(jetty/lib/ext 等)にコピーします。
- c3p0-0.9.5.2.jar
- mchange-commons-java-0.2.1.jar
- postgresql-9.4.1212.jre7.jar
- JDBCドライバは、接続先DBによって適切なものに読み替えてください
- Eclipse から [Run] - [Debug configurations…] を選択します。
- 左サイドペインから [Jetty WEbApp]を選択します。
- Jettyタブを開きます。
- Jetty classpath タブを開きます
- リストを一番下までスクロールさせると[Custom Jetty Classpath]という項目があるのでそれを選択します。
- 最初にコピーした3つの jar を追加します。
ここまでの作業をしたうえで、デバッグを開始すれば、おそらく正常に実行されるはずです。
DBアクセスのテスト
URLがたたかれた時に動作するコードに、こんな感じのコード埋め込んであげると確認できるかと思います。
Transaction.execute(connection -> { Optional<Item> contactOpt = new Sql<>(Item.class) .where("id={}", 1) .select(connection); // 取得したレコード出力するなりなんなり });
mvn jetty:run 向け pom.xml の設定
そろそろ書くのに疲れてきたので、jetty-maven-pluginの設定部分のみ貼っておきます。
こっち側は、jetty + jndi(with c3p0) が正しく動作するように設定を記載するだけです。
dependencies に c3p0 と jdbc drive を追加してあげないと、jettyが起動時にjndiの設定を行う際、c3p0などが認識できずエラーになってしまうので、ちゃんと書かないとだめです。
<project> <build> <plugins> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.4.0.v20161208</version> <configuration> <webApp> <contextPath>/</contextPath> </webApp> <httpConnector> <port>8080</port> </httpConnector> <daemon>true</daemon> <jettyXml>${project.basedir}/jetty/jetty-local.xml</jettyXml> </configuration> <executions> <execution> <id>start-jetty</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> </goals> <configuration> <scanIntervalSeconds>0</scanIntervalSeconds> </configuration> </execution> <execution> <id>stop-jetty</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-io</artifactId> <version>9.4.0.v20161208</version> </dependency> <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.4.1212.jre7</version> </dependency> <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> </dependencies> </plugin> <!-- --> </plugins> </build> </project>
今回の話は以上となります。
lightsleep の使用感など、何かネタが出てくればそちらも記事にしたいと思います。
お読みいただいてありがとうございました。