2016年10月21日 星期五

jboss eap 6.2 + postgresql 9.4 (jndi)

這說起來有點血淚,然後一直卡在 JBoss 的設定上...

完整的內容是要做 EJB,不過光搞 JNDI+persistence 設定檔 就被搞死了~
大致上的內容參考
http://theopentutorials.com/examples/java-ee/ejb3/how-to-create-ejb3-jpa-project-in-eclipse-jboss-as-6-1/

這篇先寫建立 JNDI / DataSource 的方式

有再用到 JBoss 的 cli 指令
https://docs.jboss.org/author/display/AS71/CLI+Recipes

最後整理出來的步驟就是~
(因為Naming 太多,用顏色分一下=.=,當初就各種 name 對不到)

1. 先找到 postgresql jdbc jar 檔
(你以為 jar 檔抓來就有,還是有陷阱阿阿阿阿阿)
一直有趕上時代的 postgresql...新的 jar 檔都是用 jdk 8 包的...
所以要記得挑 JBoss 有吃的 jdk 版本,我目前環境是用7,要挑 jre7 的版本

<dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.4.1207.jre7</version>
        </dependency>

PS: 這個 jar 檔,不用放在 WEB-INF/lib 下,因為 JBoss 不是從這裡拿 driver,只是因為我先裝進去,還是要有這個jar

2. 在 JBoss 上建立 postgresql 的 module/driver
JBoss 的 jdbc driver,規定只能從他的 driver module 設定內取得,不能自己定義在 application 內...
理論上,是更改  jboss-eap-6.2\standalone\configuration\standalone.xml 的內容,不過因為 cli 可以在 server run 時運作,而且感覺比較安全!所以就用 cli 在加內容,基本上 cli cmd 執行成功,這個檔的內容都會有對應的變化~~
(網路上很多的 datasource 範例都是 貼這邊的內容出來,但是跟app層能用的又有微妙不同,所以...唉~算了Orz...就當是個經驗)

這邊用 cli 方式建立 (win版),記得JBoss server 要先起來~
jboss-eap-6.2\jboss-cli.bat
### 進入 cli cmd mode
connect
### 連 jboss server (server沒起,連不到就不能用了)

### 加入 module,注意 name 要取好記好~
### windows 的路徑 folder 是「\」不用反過來(反過來會找不到orz)
module add --name=org.postgres --resources=D:\project\jars\postgresql-9.4.1207.jre7.jar --dependencies=javax.api,javax.transaction.api
### 成功後 在 jboss-eap-6.2\modules\org\postgres\main 這邊就會自動生出來 module.xml, postgresql-9.4.1207.jre7.jar
手動加一個空的純文字檔,與檔名同,再加字尾.index是  XXXX.jar.index
(ex:postgresql-9.4.1207.jre7.jar.index
加一下比較保險, 不然掃不到又會一直吐訊息....

jboss-eap-6.2\modules\org\postgres\main\module.xml
(xmlns 有人說 urn:jboss:module:1.0 有bug..還好這版已修正。 name 就是指 module name,cli 生出來直接就是對的,要是自己手動貼的就要注意來源...)
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.1" name="org.postgres">
    <resources>
        <resource-root path="postgresql-9.4.1207.jre7.jar"/>
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
    </dependencies>
</module>
### 加入 driver
### 傳統的 jdbc driver, driver name=postgres
/subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-name="org.postgres",driver-class-name=org.postgresql.Driver)

### 比較先進的 xa-datasource-class ,driver name=postgresql
/subsystem=datasources/jdbc-driver=postgresql:add(driver-name="postgresql",driver-module-name="org.postgres",driver-xa-datasource-class-name=org.postgresql.xa.PGXADataSource)

### 寫成功後,去看 standalone.xml 的 drivers 裡面也應該會生出來
###PS:  xa-datasource-class tag 是用 driver-xa-datasource-class-name 代入

3. 建立 DataSource
建立 DataSource  有兩種,一是做在 JBoss 裡面,就可以直接調用
### cli cmd
data-source add --jndi-name=java:jboss/datasources/PostgresDS1 --name=PostgresDS1Pool --connection-url=jdbc:postgresql://127.0.0.1:5432/XYZ --driver-name=postgres --user-name=xxxx --password=xxxx
### 這個會被寫進 standalone.xml 裡。要注意的是 url 後面不能帶 ?參數,會被截斷有錯

不過我是自己定在 webapp 裡面,就只給自己的 app用,就是看環境的規畫與管理方式吧
放在 webapp/META-INF 下,檔名為 xxx-ds.xml (一定要 -ds.xml結尾,不然JBoss會裝作不認識)。

在 這版的 Jboss 裡, datasource 好像都得放在  java:jboss/datasources/ ,亂擺可能會被亂吐,因為後來覺得煩了,乾脆都照標準放。
在 xxx-ds.xml 內,不可以用 <drivers> 的 tag,那個只能放在 standalone.xml。所以 xxx-ds.xml 就是只給用有匯進去的 driver, datasource 裡的設定 tag 是都也還都可以用
postgres-ds.xml
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <datasource jndi-name="java:jboss/datasources/PostgresDS" pool-name="PostgresDS_Pool"  enabled="true" use-java-context="true">
    <connection-url>jdbc:postgresql://localhost:5432/XYZ</connection-url>
    <driver>postgresql</driver>
    <security>
      <user-name>xxxxx</user-name>
      <password>xxxxxx</password>
    </security>
</datasources>

4. 驗證
反正就包一包,然後 deploy 可以起來的話,可以再用  cli 的指令看一下
/subsystem=naming:jndi-view()

有成功的話,就會看到自訂的 jndi 生出來了
"datasources" => {
    "class-name" => "javax.naming.Context",
    "children" => {
        "ExampleDS" => {
            "class-name" => "org.jboss.jca.adapters.jdbc.WrapperDataSource",
            "value" => "org.jboss.jca.adapters.jdbc.WrapperDataSource@ee07b70"
        },
        "PostgresDS" => {
            "class-name" => "org.jboss.jca.adapters.jdbc.WrapperDataSource",
            "value" => "org.jboss.jca.adapters.jdbc.WrapperDataSource@5a91e85c"
        }
    }
}
這指令蠻好用的,因為會列出所有的 Naming...=.=後面看 EJB 有沒有生出來也可以用這個對名字~~


5. 其它 
### exit cli mode
exit

### remove driver name
/subsystem=datasources/jdbc-driver=postgres:remove

#### remove module
module remove --name=org.postgres
理論上,這指令是要這麼打,但是...有bug不會動...所以就是自己去實體資料夾,把頭砍了就是...


整體上來說就是,設個 JNDI 的過程就會有很多 對應的 name 跟內容,概是降子
jndi-name (datasource) >> driver (driver name) >> module (module name, jdbc jar)

------------------------------------------------------------------------------
xa-datasource-class 和 driver-class 的差別
可以 google 「xa-datasource-class vs driver-class」
http://stackoverflow.com/questions/27456584/why-should-we-define-xa-datasource-class-within-a-driver-configuration-in-jbos

沒有留言: