2009-12-21 83 views
2

我的應用程序中包含一個.properties文件,其中包含dataSource屬性。 我成立了一個JNDI引用該數據源使用下面的代碼:使用其他應用程序與Tomcat創建的JNDI數據源

// first I create MyDataSource from the properties found in the .properties file 
//then : 

Context initContext = new InitialContext(); 
initContext.createSubcontext("jdbc"); 
initContext.createSubcontext("jdbc/oracle"); 
initContext.rebind(jdbc/oracle/myDataSource, MyDataSource); 

如果我使用這個應用程序查找,數據源中發現:

Context initContext = new InitialContext(); 
BasicDataSource dataSource = 
      (BasicDataSource) initContext.lookup("jdbc/oracle/myDataSource") 
//everything works fine and I can use my dataSource to getConnection, 
//requests, etc... 

現在我想用這dataSource在另一個應用程序中。但是,如果我執行的查找操作與之前相同,則不會找到myDataSource(而在Tomcat中仍然存在以前的應用程序,並且在監聽程序的幫助下啓動jndi綁定)。

如何在第二個應用程序中獲取myDataSource,因爲我無法在server.xml或context.xml文件中使用Tomcat資源(由於不同的原因,我必須使用此.properties文件)?

謝謝

+0

如果你想要它的服務器範圍,它必須在Server.xml文件中設置。 – Zoidberg 2009-12-21 14:57:46

+0

我不認爲由Tomcat中的一個webapp綁定的JNDI資源對其他webapps都是可見的。 – skaffman 2009-12-21 15:01:45

+0

因此,你有一個將在tomcat內部運行的web應用程序,並且你不能使用context.xml或web.xml? – ChadNC 2009-12-21 15:18:48

回答

1

你正在做的是不會工作。 J2EE應用程序不允許修改應用程序服務器(J2EE規範,第5.2.2節)和Tomcat JNDI documentation提供的JNDI環境,即每個Web應用程序都獲得每個自己的只讀JNDI環境。我不確定爲什麼綁定/重新綁定數據源並不是立即失敗,爲什麼它可以在同一個Web應用程序中工作,但即使是JNDI環境的這種應用程序內部使用也是未記錄的行爲,我不會依賴它。

0

有幾個人已經評論過這個,但我想你的問題的答案是:Tomcat有一個名爲server.xml的文件,你需要使用它。我以前也使用過一個很好的參考低於:這裏定義

http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html

資源將是可見的部署所有的應用程序(如果設置正確)。如果您在應用上下文或Web xml文件中設置了JNDI資源,則該資源只應用於您的應用。

0

JNDI上下文對於每個webapp都是私有的。在一個應用程序中創建的上下文無法被其他人訪問。

嘗試在GlobalNamingResources中創建一個條目,並使用<ResourceLink>這兩個webapps中的鏈接來查看它是否有效。

我之前使用此設置從兩個應用程序中讀取,但從未嘗試從一個應用程序寫入。所以不知道它是否會起作用。

2

「本地」JDNI目錄在Tomcat中是隻讀的。不過,你可以在LifecycleListener綁定 「全局」 JNDI資源,然後在 「鏈接」 到您的上下文(S)(*):

您需要實現org.apache.catalina.LifecycleListener http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/LifecycleListener.html

然後在你的服務器上註冊它。像這樣的XML(連同其他聽衆):

<Listener className="yourlistener.YourLifecycleListener"/> 

你的聽衆應該等待2個事件:

public void lifecycleEvent(final LifecycleEvent event) { 

    if (Lifecycle.START_EVENT.equals(event.getType())) { 
     // Create your datasource instance... 
     Context initContext = new InitialContext(); 
       initContext.createSubcontext("jdbc"); 
       initContext.createSubcontext("jdbc/oracle"); 
       initContext.rebind("jdbc/oracle/myDataSource", myDataSource); 
    } else if (Lifecycle.STOP_EVENT.equals(event.getType())) { 
     // unbind... 
    } 
} 

那麼你就必須傳播資源的訪問來自「全球的「鏈接」起來「JNDI目錄 」使用ResourceLink元素本地「 JNDI目錄中的META-INF/context.xml中:

<ResourceLink name="jdbc/oracle/myDataSource" global="jdbc/oracle/myDataSource" 
    type="javax.sql.DataSource" /> 

爲我工作至今。

(*)一些註釋:

使用生命週期偵聽器有一個優勢。由於上下文創建的順序不能保證。好處是所有的上下文都會看到這個對象的創建。

如果您需要在生命週期偵聽器創建時更動態地創建和配置數據源創建,請注意您可以綁定實現Factory模式的自定義類。

爲避免類加載不兼容問題,可以考慮將您的監聽器,數據源等類放在Tomcat lib目錄下的jar文件中,這樣它們就包含在通用類加載器中。

問候。

0

實際上,如果servlet實現了org.apache.catalina.ContainerServlet,則可以訪問其他JNDI資源。這個接口有一個org.apache.catalina.Wrapper屬性,它由容器本身「填充」。

通過這個,我創建了一個簡單的應用程序來監視資源。

但是,我想在監聽器中這樣做,所以我的資源監視器可以在容器啓動時啓動。任何人都知道的方式?

相關問題