Tomcat の DataSource 設定で超初心者的な失敗

Javaに限ったことじゃないけど、クラス名は同じってのが結構ある。DataSource もその1つ。

  • javax.sql.DataSource
  • javax.activation.DataSource
  • sun.jdbc.odbc.ee.DataSource


EclipseJavaエディタには「折りたたみ」機能があって、コメントやimport文を折りたたんで、1行にまとめて表示できる。コメントの折りたたみは良いとして import 文の折りたたみはトラブルの元だよ…ってか、はまってもーた。反省ついでに備忘録としてメモっとこ。:-)

Tomcat の DataSource 設定

ひさしぶりに Tomcat の server.xml に DataSource のリソース設定を書こうとしたらシンプルに記述できるようになってた。

最後にいじってた Tomcat4.xのときはこんな感じだった [http://tomcat.apache.org/tomcat-4.1-doc/jndi-datasource-examples-howto.html#PostgreSQL:title=]設定が

<Resource name="jdbc/postgres" auth="Container"
          type="javax.sql.DataSource"/> 

<ResourceParams name="jdbc/postgres">
  <parameter>
    <name>factory</name>
    <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
  </parameter>
  <parameter>
    <name>driverClassName</name>
    <value>org.postgresql.Driver</value>
  </parameter>
  <parameter>
    <name>url</name>
    <value>jdbc:postgresql://127.0.0.1:5432/mydb</value>
  </parameter>
  ...
</ResourceParams> 

Tomcat6になったらこんな感じに変わってた([http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html#PostgreSQL:title=]設定)

  <Context docBase="jspAndServlet2" path="/jspAndServlet2" reloadable="true"
source="org.eclipse.jst.jee.server:jspAndServlet2">
	<Resource name="jdbc/postgres" auth="Container"
	          type="javax.sql.DataSource"
       driverClassName="org.postgresql.Driver"
	           url="jdbc:postgresql://127.0.0.1:5432/examdb"
              username="postgres"
               password="postgres"
              maxActive="20" maxIdle="10" maxWait="-1"/>
  </Context>

ふ〜んと思いつつ、さて実行って思ったら ClassCastExcetpion 発生。あれ? sun.jdbc.odbc.ee.DataSource ってどっから来たんだ? ODBC接続なんてしてないはずだけど。。。:-(

java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.BasicDataSource cannot
be cast to sun.jdbc.odbc.ee.DataSource

server.xml や web.xml をみても良さそうだし、ぱっと見た感じだと、ソースも良さげ。


悶々なやんだ挙げ句、同僚にきいたら、import 間違ってないの一言。ん?!と折りたたみを解除したら、いたよ sun.jdbc.odbc.ee.DataSource が!

超初心者的なチョンボだよ、これは。あたたたた。折りたたみ機能、可読性を良くするためのものなんだろーけど、コメントくらいで十分だよ。(^^;)>

環境


TOMCAT_HOME/conf/server.xml

  <Context docBase="jspAndServlet2" path="/jspAndServlet2" reloadable="true"
source="org.eclipse.jst.jee.server:jspAndServlet2">
	<Resource name="jdbc/postgres" auth="Container"
	          type="javax.sql.DataSource"
       driverClassName="org.postgresql.Driver"
	           url="jdbc:postgresql://127.0.0.1:5432/examdb"
              username="postgres"
               password="postgres"
              maxActive="20" maxIdle="10" maxWait="-1"/>
  </Context>


WEB-INF/web.xml

<web-app ... >
...
	<resource-ref>
		<description>postgreSQL Datasource example</description>
		<res-ref-name>jdbc/postgres</res-ref-name>
		<res-type>javax.sql.DataSource</res-type>
		<res-auth>Container</res-auth>
	</resource-ref>
</web-app>

Java Source

  protected Connection createConnection() {
    try {
      InitialContext ic = new InitialContext();
      DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/postgres");
      Connection con = ds.getConnection();
      return con;
    } catch (SQLException e) {
      System.err.println("Connect Error.\n");
    } catch (NamingException e) {
      e.printStackTrace();
    }
    return null;
  }

Error Code

java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.BasicDataSource cannot be cast to sun.jdbc.odbc.ee.DataSource
	at chap11_database.sec03.EmployeeDAO.createConnection(EmployeeDAO.java:20)
	at chap11_database.sec03.EmployeeDAO.findEmployeeById(EmployeeDAO.java:151)
	at chap11_database.sec03.DAOExerciseServlet.doPost(DAOExerciseServlet.java:38)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
	at java.lang.Thread.run(Unknown Source)