Eclipse4.4JavaEE + Tomcat7 でJavaEE6開発環境を構築
Eclipse JavaEE 4.4 (Eclipse IDE for Java EE Developers Luna) とTomcat7を使って、JavaEE6の開発環境を1から構築します。
JavaEE6入門ではなく、JavaEE6入門のためのEclipse環境を作るのが目的です。
今回はスクリーンショット多めにしてみました。
(同日 22:00頃)記述ミスと記述不足を20箇所ほど修正しました。概要の文章を少し手直ししました。
目次
- 概要
- 前提条件
- 初期設定
- ソフトウェアのインストール
- Eclipseの起動
- プロジェクトの作成
- プロジェクトの設定変更(Mavenの設定変更)
- デバッグ用サーバーでHello World !
- EL式の動作確認
- JSTLの動作確認
- テスト用データベースの準備 (H2database)
- JSTLのデータベース接続 (1) 直接接続
- JSTLのデータベース接続 (2) データソース
- Servletの動作確認
- ビルド・デプロイ設定
- (おわりに)
概要
私が実際に使っているJavaEEはかなりバージョンが古く、その知識はほとんどJavaEE 5.0よりも前で止まっています。
そのせいで最近ちょっと困ったことがあったので、今後のためにも、基礎知識として比較的新しいJavaEEを学んでおく必要があるかな、そしてどうせなら、一部のJavaEE機能を使うだけではなく、純粋なJavaEEでどこまで開発できるのかを知っておいた方が良いかな、と思ったのが今回の記事を書いたきっかけでした。
そうするには、少なくとも、実際に試すことのできる環境を構築しておかなければと思い、色々と試行錯誤の結果、EclipseでJavaEE開発するにはやはりfor JavaEE Developerを使うのが簡単、という結論に落ち着きました。最初はMavenだけでやってみようとも考えていましたが、ちょっと無理でした。
それと、この記事は、どうしてもEclipseを使いたい人向けです。
試していませんが、NetBeansやIntelliJのほうが簡単に構築・開発できるかも知れません。
以下の内容を含んでいます。
前提条件
JavaとEclipseの基本操作は知っている前提です。
初心者向けではありません。手順書に近いものです。
実際に動作を確認したのは下記の環境ですが、Windowsに特化した内容ではありません。
記事の中では、パスの区切り表記は、主にスラッシュ(/)を使います。Windows固有のものはバックスラッシュも使います。
初期設定
ディレクトリー*1の構成を決めておきます。
Windows7での例を記載しておきます。これ以降の説明では、ディレクトリーを示すのにこれらの名前を使用します。
HOME
(%USERPROFILE%
, Unix系では$HOME
)jee6
(%USERPROFILE%\jee6
=C:\Users\argius\jee6
)$TOMCAT_HOME
(.\jee6\apache-tomcat-7.0.56
)database
(.\jee6\database
)$ECLIPSE_HOME
(.\jee6\eclipse-jee-luna-SR1
*2 )workspace
(.\jee6\workspace
)
JDKだけは、インストールウィザードに従ってインストールすることになります。
サンプルでは、H2databaseは相対パスの方が都合が良いので、HOMEディレクトリーの下に作っていますが、必ずしもこの通りでなくても構いません。
Eclipseを使うだけならば環境変数の設定は不要ですが、コマンドプロンプト(ターミナル)からTomcatやMavenを実行する場合は、環境変数$JAVA_HOME
の設定が必要です。
Windowsの場合は、文字エンコーディング設定が初期設定でMS932
になっています。ここは、UTF-8
にしておくのが無難です。今回のサンプルもUTF-8
で書くようにしています。
ソフトウェアのインストール
- JDKのインストール
Java SE - Downloads | Oracle Technology Network | Oracleから、Java7以上のJDKをダウンロードしてインストールします。既にインストール済みであれば無視してください。
- Eclipseのインストール
Eclipse IDE for Java EE Developers | Packagesの"Download Links"の下にあるリンクから、OSに対応したパッケージをダウンロードし、$ECLIPSE_HOME
に展開します。
- Tomcatのインストール
Apache Tomcat - Apache Tomcat 7 Downloadsから、Binary Distributionsの下のCoreのいずれか(ZIPで良いでしょう)をダウンロードし、$TOMCAT_HOME
に展開します。
Eclipseの起動
$ECLIPSE_HOME
ディレクトリーにあるeclipse(.exe)を実行します。
初回起動時に、ワークスペースの場所を尋ねられます。デフォルトでは$HOME/workspace
になります。今回は$HOME/jee6/workspace
にします。
また、Use this as the default and don ont ask again
チェックボックスをオンにすれば、次回の起動時にはここで選択したワークスペースが自動的に選択されます。後で変えることもできます。
Installed JREにJDK7が設定されていることを確認しましょう(メニューの[workspace]
→ [Preference]
の設定ダイアログを開き、[Java]
→ [Installed JREs]
を選択)。
JREに設定されている場合は、JDKの設定を追加して、JDKをデフォルト(チェックボックスをオン)にしておきます。
プロジェクトの作成
メニューの[File]
→ [New]
→ [Maven Project]
を選択して、ウィザードを起動します。
最初のページはそのままにして[Next]
ボタンを押します。
2ページ目では、ひな形となるArchetypeを選択します。ここでは、maven-archetype-webapp
を選択し、[Next]
ボタンを押します。
2ページ目: ひな形のArchetypeを選択
3ページ目では、プロジェクトのArchetypeを入力します。私はnet.argius.webapp1
としています。
3ページ目: プロジェクトのArchetypeを入力して完了
おそらく数秒で、Mavenのプロジェクト初期化が完了します。
プロジェクトの設定変更(Mavenの設定変更)
このあと、部分ごとにMavenの設定(pom.xml
)を修正していきます。完成版はGistにアップしておきます。
この時点では、4箇所を変更する必要があります。
また、この時点でディレクトリーの無いソースフォルダーが2つ(src/main/java
,src/test/java
)ありますので、必要に応じて作成します。ここでは無くてもOKです。
最初に、ビルド設定を行います。maven-compiler-plugin
を設定します。
pom.xml
を開くと、POMエディターで開きます。下側にあるタブのpom.xml
を選択すると、直接入力できるようになります。
build
の部分を以下のように書き換えます。入力後、保存するのを忘れないようにしましょう。
maven-compiler-plugin
の設定
<build> <finalName>webapp1</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
今回は、Java1.7がターゲットなのでこうなります。エンコーディングは、プロジェクトの設定に合わせます。
この時点では、JSPエラー(JSP Problems)が表示されています。これは、servlet-api
のライブラリーが設定されていないからです。*3
POMエディターのDependency
を選択すると、依存関係を設定するページが開きます。
既にjunit
が設定済みです。
エディターを使って入力できます。こちらも入力後に保存するのを忘れないようにしましょう。
dependency: javax.servlet-api
の設定
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
これを設定すると、今度はMavenエラー(Maven Problems)が表示されます。「Updateを実行しろ」というメッセージが出ていますので、アップデートを実行します。[Quick Fix]
から(エラーメッセージを右クリック→[Quick Fix]
)でも実行できます。
次に、web.xml
(src/main/webapp/WEB-INF/web.xml
)の変更です。
maven-archetype-webapp
でプロジェクトを作成すると、web.xml
がバージョン2.3で作成されます。
今回は、Servlet 3.0を使用しますので、web.xml
がバージョン3.0に変更します。
下記ページに見本がありますので、参考にしてください。他のバージョンのものも記載されています。
- Java Servlet - Wikipedia
最後に、Dynamic Web Moduleのバージョンを設定します。
プロジェクトのプロパティーを開いて、[Project Facets]
を選択します。Dynamic Web Moduleは初期状態では2.3になっています。
さて、ここが重要なのですが、このままバージョンを3.0にするとなぜかOKが押せません。ここは一旦、チェックを外してOKします。再度開くと、3.0になっていて、チェックすると今度はOKができるようになっていますので、OKします。
一度チェックを外してから再度ダイアログを開くと、3.0になっているので、チェックし直す
良く見ないと分かりませんが、プロジェクトの下にある"Deployment Descriptor"のアイコンが3.0
になります。
Deployment Descriptorのアイコンが3.0になっている
ここでもう一度、Mavenアップデート(プロジェクトを右クリック → [Maven]
→ [Update Project]
)を実行しておきます。
これで、Servlet 3.0を利用する環境が整いました。
デバッグ用サーバーでHello World !
それでは、最初からあるindex.jsp
を表示してみます。
プロジェクトを右クリックして、[Debug As]
→ [Debug On Server]
を実行すると、ダイアログが表示されます。
この時点ではサーバーが未設定ですので、"Apache Tomcat 7.0 Server"を選択し、次のページ([Next]
)へ。
次に、Tomcatのインストールディレクトリー(installation directory)を聞かれますので、$TOMCAT_HOME
を設定(変数は使えませんので、実際のパスを設定)し、次のページ([Next]
)へ。
なお、このページは次回も同じサーバーを使う場合はスキップされます。
最後に次に、起動するサーバーにクラスパスを通すプロジェクトを設定します。右側のCongifuredにweabpp1
があればOKです。[Finish]
を押して完了します。
Eclipse上でWebブラウザーが起動し、"Hello World!"が表示されるはずです。
サーバーが上手く起動しない場合は、Mavenのアップデートを実行してから再度サーバーを起動してみてください。
EL式の動作確認
簡単なEL式を書いてみます。ページスコープに値を設定し、それをEL式で出力させます。
<html> <body> <% pageContext.setAttribute("msg", "Hello World!"); %> <h2>${ pageScope.msg.toUpperCase() }</h2> </body> </html>
更新ボタンを押して、表示が変わることを確認しましょう。
ちなみに、web.xml2.3を使うと、デフォルトではEL式が無効(isELdisabled=true
)になるので注意です。
詳しくは、下記ページを参照。
JSTLの動作確認
EL式は、JSTLと組み合わせるともっと使いやすくなります。JSTLとEL式があれば、ディレクティブやコメント以外では従来のJSPタグ(<% %>
)を使わなくてもJSPを書くことができます。
JSPの先頭行に、taglib
ディレクティブを宣言します。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
追加すると、JSPエラーが出ます。これは、JSTLライブラリーが未設定のためです。
servlet-api
と同様に、POMエディターのDependency
で追加しましょう。
dependency: jstl
の設定
<dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> <scope>runtime</scope> </dependency>
JSTLは実行時にも必要なので、scopeはruntime
に設定します。
body内の適当な行に、
<p><c:set var="msg2" value="Goodbye!" /> msg2=${ msg2 } </p>
を書きます。
サーバーを再起動して、更新ボタンを押して、表示が変わることを確認しましょう。
なお、c:set
は書く場所によってはJSP警告が出ることがあります。ブロックタグの中に書けば出なくなったりしますが、発生条件が良く分かりません。
テスト用データベースの準備 (H2database)
今回は、テスト用データベースにH2databaseバージョン1.4を使用します。データベースファイルは、$HOME/jee6/database/webapp1.mv.db
になるようにします。この場合、JDBC-URLはjdbc:h2:file:~/jee6/database/webapp1
になります。さらに、AutoServerモードを有効(jdbc:h2:file:~/jee6/database/webapp1;AUTO_SERVER=TRUE
)にしておけば、複数のクライアントから同時接続することも可能になります。
H2databaseを使用するには、まずJDBCドライバーを取得します。
POMの依存関係にH2databaseを追加します。
dependency: h2database
の設定
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.182</version> <scope>runtime</scope> </dependency>
$HOME/.m2/repository/com/h2database/h2/1.4.182/h2-1.4.182.jar
がダウンロードされているのを確認します。
次に、データベースに接続します。
H2databaseは、スタンドアローンでJARを実行することで、Webベースのデータベースクライアントが起動します。
なお、Eclipse JEEでは、Data Source Explorerビューを使って、データベースに接続できます。これを使ってH2databaseに接続するには、Generic JDBC
で設定します。
H2databaseはブラウザーベースのクライアントが利用できる
接続したら、DDLとINSERTを実行します。何でも良いです。
create table table1 ( id varchar(16) primary key, name varchar(64) ); INSERT INTO table1 VALUES('001', 'argius'); INSERT INTO table1 VALUES('002', 'zzz');
JSTLのデータベース接続 (1) 直接接続
JSTLのSQLアクションを使って、データベースにアクセスしてみましょう。
SQLアクションを使用するためのtaglib
ディレクティブを追加します。
それから、sql:setDataSource
でデータソースを設定します。
index.jsp
SQLアクションの例
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%> <html> <body> <sql:setDataSource var="ds" driver="org.h2.Driver" url="jdbc:h2:file:~/jee6/database/webapp1;AUTO_SERVER=TRUE" user="sa" password="sa" /> <sql:query var="rs" dataSource="${ds}">select * from table1</sql:query> <table> <c:forEach var="r" items="${rs.rows}"> <tr><td>${ r.name }</td></tr> </c:forEach> </table> </body> </html>
ここでもJSPに警告が出ますが、正常に実行されると消えます。消えなくても無視してください。
JSTLのデータベース接続 (2) データソース
毎回、JSPでデータソースを設定するのは無駄が多いので、名前参照できるように設定しましょう。
JDBCドライバーは、Webコンテナー(Tomcat7)側に持たせておきます。$HOME/.m2/repository/com/h2database/h2/1.4.182/h2-1.4.182.jar
を、$TOMCAT_HOME/lib
にコピーします。
前項でH2databaseの依存関係を追加している場合は、削除して、アプリケーションに直接JDBCドライバーを持たせないようにします。
Eclipse上ではServers
の下にある、デバッグ時に接続しているTomcat7の設定に、データソースを追加します。
Project ExplorerのServers/ v7 .../
の下に、context.xml
がありますので、そこにデータソース設定を追加します。
このアプリケーションを実際にデプロイする場合は、デプロイ先環境と同じ名前のResource
のname
を合わせておくと良いでしょう。
context.xml
にResource
を追加
<Resource name="jdbc/mydb" auth="Container" type="javax.sql.DataSource" username="sa" password="sa" driverClassName="org.h2.Driver" url="jdbc:h2:file:~/jee6/database/webapp1;AUTO_SERVER=TRUE" validationQuery="select 1" maxActive="10" maxIdle="2" />
JSP側では、データソースを名前参照するように修正します。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%> <html> <body> <sql:setDataSource var="ds" dataSource="jdbc/mydb" /> <sql:query var="rs" dataSource="${ds}">select * from table1</sql:query> <table> <c:forEach var="r" items="${rs.rows}"> <tr><td>${ r.name }</td></tr> </c:forEach> </table> </body> </html>
Tomcatの設定を変更したので、サーバーを再起動させてから動作確認してください。
Servletの動作確認
サーブレットを動かしてページを表示できるようにして見ましょう。
ウィザードで[New]
→ [Servlet]
で追加すると、web.xml
が壊れてしまうので、ウィザードで作られた雛形を元に、ウィザードを使わずにサーブレットを作ってみました。これを、普通の「新規クラスの追加」([New]
→ [Class]
)で追加します。
src/main/java
が作られていない場合は、ここで追加します。
webapp1.SearchServlet
クラス (src/main/java/webapp1/SearchServlet.java
)
package webapp1; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; /** * Servlet implementation class SearchServlet */ @WebServlet("/search") public final class SearchServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public SearchServlet() { super(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<String> a = getNames(); request.setAttribute("rows", a); RequestDispatcher dispatcher = request.getRequestDispatcher("/search.jsp"); dispatcher.forward(request, response); } private List<String> getNames() throws ServletException { List<String> a = new ArrayList<String>(); try { InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mydb"); try (Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select name from table1")) { while (rs.next()) { a.add(rs.getString(1)); } } } catch (SQLException |NamingException e) { throw new ServletException(e); } return a; } }
Servlet 3.0のアノテーションをちょっとだけ使っています。
@WebServlet
アノテーションを使うと、従来はweb.xml
に記述していたサーブレットマッピングが不要になります。
データベースへのアクセスは、今回はEJBやJPAは扱いませんので、NamingAPIとJDBCを使っています。
出力先ページは、search.jsp
とします。
search.jsp
(src/main/webapp/search.jsp
)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Search Result</title> </head> <body> <h3>Search Result</h3> <table> <c:forEach var="r" items="${ rows }"> <tr><td>${ r }</td></tr> </c:forEach> </table> </body> </html>
サーバーを再起動してからlocalhost:8080/webapp1/search
にアクセスし、ページが表示できればOKです。
ビルド・デプロイ設定
まずは、WARファイルをビルドする設定を追加します。
pom.xml
のbuild
-plugins
の下に、maven-war-plugin
を追加します。
build-plugin: maven-war-plugin
の設定
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.5</version> </plugin>
Run AsでMaven BuildでGoalsに war:war
を入力し、実行すれば、target/webapp1.war
が作られます。
autodeployに対応しているWebコンテナーならば、これをそのままautodeployディレクトリーに置けばデプロイされます。
最後に、テスト環境とは別のTomcat7サーバーに、WARをデプロイしてみましょう。
まず、デプロイの準備を行います。
- MavenのTomcat7プラグインの設定
- Tomcatに設定追加(ユーザー設定、manager-scriptモードを有効に)
- Mavenの
settings.xml
に設定追加(デプロイ先Tomcatへのログイン設定)
その後、Eclipseからでなく、直接Tomcat7を起動します。($JAVA_HOME
の設定をお忘れなく)
設定内容は、下記を参考にしました。
一部だけ書いておきます。
build-plugin: tomcat7-maven-plugin
の設定
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <server>mydeployserver</server> <port>8080</port> <path>/webapp1</path> <update>true</update> </configuration> </plugin>
settings.xml
には、mydeployserver
の設定を追加します。
Goals = tomcat7:deploy
を実行すれば、デプロイされます。
update=true
を設定しないと、上書き配備できませんので注意してください。
メッセージに
OK - コンテキストパス /webapp1 でアプリケーションを配備しました
が出力されていれば、デプロイは成功です。
ここまで設定してきたpom.xml
は、もちろん直接Mavenで使うことができます。説明は割愛しますが、Maven3をスタンドアローンでインストールしてコマンドラインからの実行を試してみてください。
デプロイは、実際の開発では、Jenkinsなどで動作させることになるでしょう。
この場合、Jenkinsを動作させる環境のsettings.xml
にも設定を追加する必要があるので忘れないように。
おわりに
ここまで作るのには、一部のハマりポイントを除けば、情報もそれなりにありますし、この内容が無くてもそれほど苦労しないと思います。
なので、最初は一部分だけの説明にとどめようと思いましたが簡単には行かず、結局は全部入りになってしまいました。
ご参考になれば幸いです。