(1) 普通の Hello World だとこんな風に紹介されることが多い気がします。
class test01 { public static void main(String args[]) { System.out.println("Hello World!"); } }
$ javac test01.java $ java test01 Hello World!
(2) パッケージ名をつけて実行してみると classモジュールは test ディレクトリ配下にないと叱られます。
package test; class test01 { public static void main(String args[]) { System.out.println("Hello World!"); } }
$ javac test01.java $ java test01 Exception in thread "main" java.lang.NoClassDefFoundError: test01 (wrong name: test/test01) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:788) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:447) at java.net.URLClassLoader.access$100(URLClassLoader.java:71) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482) $ mkdir test $ mv test01.class test $ java test/test01 Hello World!(3) javac -d オプションを指定するとパッケージディレクトリを作ってその下にクラスファイルを配置してくれます。
$ tree . . └── test01.java 0 directories, 1 file $ javac -d . test01.java $ tree . . ├── test │ └── test01.class └── test01.java 1 directory, 2 files $ java test/test01 Hello World!(4) 配布パッケージにはソースコードは含まれないので、ソースフォルダとクラスフォルダは分けたいところです。やっぱり class ファイルの階層と src のファイル階層は同じにしたいところです。
$ tree . . ├── classes └── src └── test └── test01.java 3 directories, 1 file $ javac -d classes src/test/test01.java $ tree . . ├── classes │ └── test │ └── test01.class └── src └── test └── test01.java 4 directories, 2 files $ cd classes $ java test/test01 Hello World!
(5) WEB配布パッケージは基本構成が決まっているので、基本構成の中に class ファイルを配置するようにしてみます。
$ tree . . ├── deploypkg.war │ ├── META-INF │ └── WEB-INF │ ├── classes │ └── lib └── src └── test └── test01.java 7 directories, 1 file $ javac -d deploypkg.war/WEB-INF/classes src/test/test01.java $ tree . . ├── deploypkg.war │ ├── META-INF │ └── WEB-INF │ ├── classes │ │ └── test │ │ └── test01.class │ └── lib └── src └── test └── test01.java 8 directories, 2 files $ cd deploypkg.war/WEB-INF/classes $ java test/test01 Hello World!
(6) この形式でサーブレットプログラムをコンパイル、配布してみます。
$ tree . . ├── deploypkg.war │ ├── META-INF │ └── WEB-INF │ ├── classes │ └── lib └── src └── test └── test01.java 7 directories, 1 file
test01のソースコード
package test; import java.io.*; import java.sql.*; import javax.sql.*; import javax.naming.*; import javax.servlet.*; import javax.servlet.annotation.*; import javax.servlet.http.*; @WebServlet(name="test01", urlPatterns={"/test01"}) public class test01 extends HttpServlet { @Override public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,IOException { InitialContext initctx = null; Connection con = null; try { initctx = new InitialContext(); DataSource ds = (DataSource)initctx.lookup("java:jboss/datasources/MySqlDS"); con = ds.getConnection(); res.setContentType("text/html; charset=UTF-8"); PrintWriter out = res.getWriter(); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("select * from foods;"); out.println("<html>"); out.println("<head>"); out.println("<title> SERVLET-MYSQL-TEST </title>"); out.println("</head>"); out.println("<body>"); out.println("<h3>果物一覧</h3>"); out.println("<table>"); out.println("<tr>"); out.println("<th>CODE</th>"); out.println("<th>名前</th>"); out.println("<th>値段</th>"); out.println("</tr>"); while(rs.next()) { out.println("<tr>"); out.println("<td>" + rs.getString("code") + "</td>" ); out.println("<td>" + rs.getString("name") + "</td>" ); out.println("<td>" + rs.getString("price") + "</td>" ); out.println("</tr>"); } out.println("</body>"); out.println("</html>"); con.close(); initctx.close(); } catch(NamingException e) { e.printStackTrace(); } catch(SQLException e) { e.printStackTrace(); } } }
コンパイル・配備
$ javac -d deploypkg.war/WEB-INF/classes -classpath ~/jboss7/modules/javax/servlet/api/main/jboss-servlet-api_3.0_spec-1.0.0.Final.jar src/test/test01.java $ tree . . ├── deploypkg.war │ ├── META-INF │ └── WEB-INF │ ├── classes │ │ └── test │ │ └── test01.class │ └── lib └── src └── test └── test01.java 8 directories, 2 files $ cp -rp deploypkg.war ~/jboss7/standalone/deployments $ touch ~/jboss7/standalone/deployments/deploypkg.war.dodeploy
実行
(7) deplypkg.war を jar で圧縮して配備してみます。touch ファイルを作らずともホットデプロイされました。
$ mv deploypkg.war deploypkg $ cd deploypkg $ jar cvf ../deploypkg.war . マニフェストが追加されました WEB-INF/を追加中です(入=0)(出=0)(0%格納されました) WEB-INF/lib/を追加中です(入=0)(出=0)(0%格納されました) WEB-INF/classes/を追加中です(入=0)(出=0)(0%格納されました) WEB-INF/classes/test/を追加中です(入=0)(出=0)(0%格納されました) WEB-INF/classes/test/test01.classを追加中です(入=2501)(出=1398)(44%収縮されました) エントリMETA-INF/を無視します $ cd .. . ├── deploypkg │ ├── META-INF │ └── WEB-INF │ ├── classes │ │ └── test │ │ └── test01.class │ └── lib ├── deploypkg.war └── src └── test └── test01.java 8 directories, 3 files $ cp -rp deploypkg.war ~/jboss7/standalone/deployments