2017-09-16 70 views
0

Tomcat 8で動作するWebアプリケーションをOracleデータベースに接続しようとしています。二人ともドッカーコンテナとして実行します。Dockerコンテナ間のJDBC接続

ドッキングウィンドウ-compose.yml:

version: "3" 
services: 
    appweb: 
    build: ./app 
    image: "servlet-search-app:0.1" 
    ports: 
    - "8888:8080" 
    links: 
    - appdb 
    environment: 
    - DATA_SOURCE_NAME="jdbc:oracle:thin:@appdb:1521/XE" 

    appdb: 
    build: ./db 
    image: "servlet-search-db:0.1" 
    ports: 
    - "49160:22" 
    - "1521:1521" 
    - "8889:8080" 

Dockerfile私のオラクルのDBのイメージ(ビルド:./db):Tomcatのの

FROM wnameless/oracle-xe-11g 
ADD createUser.sql /docker-entrypoint-initdb.d/ 
ENV ORACLE_ALLOW_REMOTE=true 

Dockerfile画像:トンを接続しようとすると(ビルド./app)

FROM tomcat:8.0.20-jre8 
COPY servlet.war /usr/local/tomcat/webapps/ 
COPY ojdbc14-1.0.jar /usr/local/tomcat/lib/ 

だからアプリが期待通りに起動しますが、例外がスローされます私はDATA_SOURCE_NAME文字列を修正するとき

java.lang.IllegalStateException: java.sql.SQLException: Io exception: Invalid connection string format, a valid format is: "host:port:sid" 
    org.se.lab.ui.ControllerServlet.createConnection(ControllerServlet.java:115) 
    org.se.lab.ui.ControllerServlet.handleSearch(ControllerServlet.java:78) 
    org.se.lab.ui.ControllerServlet.doPost(ControllerServlet.java:53) 
    org.se.lab.ui.ControllerServlet.doGet(ControllerServlet.java:38) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:618) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:725) 
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 

さて問題は明らかだが、しかし:データベースoを

DATA_SOURCE_NAME="jdbc:oracle:thin:@appdb:1521:XE" 

私は次の例外を取得:

java.lang.IllegalStateException: java.sql.SQLException: Listener refused the connection with the following error: 
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor 
The Connection descriptor used by the client was: 
appdb:1521:XE" 

    org.se.lab.ui.ControllerServlet.createConnection(ControllerServlet.java:115) 
    org.se.lab.ui.ControllerServlet.handleSearch(ControllerServlet.java:78) 
    org.se.lab.ui.ControllerServlet.doPost(ControllerServlet.java:53) 
    org.se.lab.ui.ControllerServlet.doGet(ControllerServlet.java:38) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:618) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:725) 
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 

今、私がしようとしましたどちらが実際に動くべきかを調べる。したがって、私は唯一のDBコンテナ開始:

docker build -t dbtest . 
docker run -it -d --rm -p 1521:1521 --name dbtest dbtest 
docker inspect dbtest | grep IPAddress 
>> "IPAddress": "172.17.0.4" 

次へ]を、私はsqlplusで接続しよう:

sqlplus system/[email protected]:1521/XE # works 
sqlplus system/[email protected]:1521:XE #ERROR: ORA-12545: Connect failed because target host or object does not exist 

だから、問題は何ですか? docker-composeファイルのリンクのため、Tomcatコンテナは "appdb"をコンテナのIPに解決できます。

protected Connection createConnection() { 
     String datasource = System.getenv("DATA_SOURCE_NAME"); 
     try { 
      // debug 
      InetAddress address = null; 
      try { 
       address = InetAddress.getByName("appdb"); 
       System.out.println(address); // resolves in appdb/10.0.0.2 
       System.out.println(address.getHostAddress()); // resolves in 10.0.0.2 
      } catch (UnknownHostException e) { 
       e.printStackTrace(); 
      } 

      Class.forName("oracle.jdbc.driver.OracleDriver"); 
      return DriverManager.getConnection(datasource, "system", "oracle"); 
     } catch (SQLException | ClassNotFoundException e) { 
      throw new IllegalStateException(e); 
     } 
    } 

最後にここにtnsnames.oraファイルがあります:

cat $ORACLE_HOME/network/admin/tnsnames.ora 
# tnsnames.ora Network Configuration File: 

XE = 
    (DESCRIPTION = 
    (ADDRESS = (PROTOCOL = TCP)(HOST = fcffb044d69d)(PORT = 1521)) 
    (CONNECT_DATA = 
     (SERVER = DEDICATED) 
     (SERVICE_NAME = XE) 
    ) 
) 

EXTPROC_CONNECTION_DATA = 
    (DESCRIPTION = 
    (ADDRESS_LIST = 
     (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE)) 
    ) 
    (CONNECT_DATA = 
     (SID = PLSExtProc) 
     (PRESENTATION = RO) 
    ) 
) 

おかげ

は、ここで接続を確立する必要があるコードです!

+0

DBとの接続が確立されていることを確認するために、最初にドッキング・イメージ/コンテナなしで接続する必要がありますか? – JBone

答えて

1

Oracleのデフォルトのリスナーは、間違ったIPアドレスに設定されたホストを解決:

のvimの$ ORACLE_HOME/network/admin /リスナー。ora:

SID_LIST_LISTENER = 
    (SID_LIST = 
    (SID_DESC = 
     (SID_NAME = PLSExtProc) 
     (ORACLE_HOME = /u01/app/oracle/product/11.2.0/xe) 
     (PROGRAM = extproc) 
    ) 
) 

LISTENER = 
    (DESCRIPTION_LIST = 
    (DESCRIPTION = 
     (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE)) 
     (ADDRESS = (PROTOCOL = TCP)(HOST = f4c4a3638c11)(PORT = 1521)) 
    ) 
) 

DEFAULT_SERVICE_LISTENER = (XE) 

HOST値はDockerコンテナIDです。私たちは/ etc/hostsのを見れば、それはドッキングウィンドウ・コンリンクでサービスリンク用に正しく設定されています。私がしようとするとそれはまた正しくTomcatコンテナ

ping f4c4a3638c11 
PING f4c4a3638c11 (10.0.0.5): 56 data bytes 
... 

から解決さ

10.0.0.5  f4c4a3638c11 

ホストシステムからのドッキングウィンドウインターフェイスで他のインターフェイスのIPアドレスで接続するには、データベースへのWebアプリケーションからの接続は

String datasource = "jdbc:oracle:thin:@172.17.0.4:1521:XE"; 

に動作しますので、ソリューション正しいIPアドレスを聞くために、リスナーを設定することです

(ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.0.5)(PORT = 1521)) 

は今、この接続文字列は動作します:私はこの動作を報告します

jdbc:oracle:thin:@appdb:1521:XE 

がバグとして/オラクル-XE-11グラムをwnamelessする

0

申し訳ありませんが、これは決定的な回答ではありません。さんは、長いコメントとして扱いましょう:)私はあなたのエラーメッセージが興味をそそられるが再作成するために

あなたのセットアップは非常に複雑である:

環境値が appdb:1521:XEに細断したように見えます
The Connection descriptor used by the client was: 
appdb:1521:XE" 
... 

。どのようにハードコーディングしようとした場合について:

String datasource = "jdbc:oracle:thin:@appdb:1521/XE"; 

それが動作する場合は、おそらく何らかの形であなたのドッキングウィンドウDATA_SOURCE_NAME環境変数をエスケープする必要があります。

私は完全に間違っているかもしれませんが、試してみる価値はあると思います。

+0

応答をありがとう、私は同じ考えた。しかし、これは一般的なエラーメッセージのようです。 – CaptainMango

関連する問題