Использование источника данных JNDI, созданного другим приложением с Tomcat - PullRequest
2 голосов
/ 21 декабря 2009

В моем приложении есть файл .properties, который содержит свойства источника данных. Я установил ссылку 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...

Теперь я хотел бы использовать этот источник данных в другом приложении. Но если я выполняю тот же поиск, что и раньше, я не нахожу myDataSource (тогда как в tomcat все еще есть предыдущее приложение, и привязка jndi выполняется при запуске с помощью слушателя).

Как я могу получить myDataSource во втором приложении, если не могу использовать ресурс Tomcat в файле server.xml или context.xml (по разным причинам я должен использовать этот файл .properties)?

Спасибо

Ответы [ 5 ]

2 голосов
/ 30 сентября 2010

«локальные» каталоги JDNI доступны только для чтения в Tomcat. Тем не менее, вы можете связать «глобальные» ресурсы JNDI в LifecycleListener, а затем «связать» их с вашим контекстом (ами) (*):

Вам необходимо реализовать org.apache.catalina.LifecycleListener http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/LifecycleListener.html

Затем зарегистрируйте его в вашем server.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 с «локальным» каталогом JNDI, используя элемент ResourceLink в вашем META-INF / context.xml:

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

Это сработало для меня до сих пор.

(*) Некоторые заметки:

Есть преимущество в использовании слушателей жизненного цикла. Поскольку порядок создания контекста не гарантирован. Преимущество состоит в том, что все ваши контексты будут видеть этот объект созданным.

Если вам нужно создавать и настраивать создание источника данных более динамично, чем при создании прослушивателя жизненного цикла, обратите внимание, что вы можете связать пользовательский класс, реализующий шаблон Factory.

Чтобы избежать проблем с несовместимостью загрузки классов, рассмотрите возможность помещения классов слушателя, источника данных и т. Д. В файл jar в каталоге lib Tomcat, чтобы они были включены в общий загрузчик классов.

Привет.

1 голос
/ 21 декабря 2009

То, что вы пытаетесь сделать, не сработает. Приложениям J2EE не разрешается изменять среду JNDI, предоставляемую сервером приложений (спецификация J2EE, раздел 5.2.2), а в документации Tomcat JNDI также говорится, что каждое веб-приложение получает каждую собственную среду JNDI только для чтения. , Я не уверен, почему привязка / повторная привязка вашего источника данных не дает сбой сразу и почему он работает в том же веб-приложении, но даже такое внутреннее использование среды JNDI для приложений - недокументированное поведение, на которое я бы не стал полагаться.

0 голосов
/ 10 декабря 2010

На самом деле, есть доступ к другим ресурсам JNDI, если сервлет реализует org.apache.catalina.ContainerServlet . Этот интерфейс имеет атрибут org.apache.catalina.Wrapper, который «заполняется» самим контейнером.

благодаря этому я создал простое приложение для мониторинга ресурсов.

НО, я хотел бы сделать это в слушателе, чтобы мой монитор ресурсов мог запускаться при запуске контейнера. Кто-нибудь знает способ?

0 голосов
/ 21 декабря 2009

JNDI-контекст является частным для каждого веб-приложения. Контекст, созданный в одном приложении, недоступен для других.

Попробуйте создать запись в GlobalNamingResources и ссылки в обоих веб-приложениях, используя <ResourceLink>, чтобы проверить, работает ли она.

Я использовал эту настройку раньше, чтобы читать из обоих приложений, но никогда не пытался писать из одного. Так что не уверен, что это сработает.

0 голосов
/ 21 декабря 2009

Несколько человек уже прокомментировали это, но я думаю, что ответ на ваш вопрос таков: у Tomcat есть файл server.xml, который вам нужно использовать. Хорошая ссылка, которую я использовал раньше, ниже:

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

Ресурсы, определенные здесь, будут видны всем развернутым приложениям (если они настроены правильно). Если вы настроили ресурс JNDI в контексте приложения или в веб-файле XML, он должен быть доступен только вашему приложению.

...