Поиска JNDI не с причалом для подключения JDBC пул с MySQL?


Я использую Jetty 9.2 (embedded) со стандартным API MySQL connector, и я очень смущен тем, как это должно быть настроено. В настоящее время у меня есть это в моей сети .xml файл:

<webapp ...

    <resource-ref>
        <description>JDBC Data Source</description>
        <res-ref-name>jdbc/DataSource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
</webapp>

...и это в моей пристани-env.xml:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">

   <New id="DatabaseConnector" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>
        <Arg>jdbc/DataSource</Arg>
        <Arg>
            <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
                <Set name="Url">jdbc:mysql://localhost:3306/DBName</Set>
                <Set name="User">user</Set>
                <Set name="Password">pass</Set>
            </New>
        </Arg>
    </New>

 </Configure>

...и этот код для инициализации:

Context envCtx = (Context) new InitialContext().lookup("java:comp/env");
DataSource datasource = (DataSource) envCtx.lookup("jdbc/DataSource");

Когда я пытаюсь запустить сервер, я получаю ошибку javax.naming.NameNotFoundException; remaining name 'jdbc/DataSource'. Я перепробовал множество различных вариантов строк в инициализации кода, например удаление lookup вызовите объект InitialContext, но я просто продолжаю получать вариации одной и той же ошибки с другим значением name;

Оба xml-файла находятся в моем каталоге /WAR/WEB-INF. Я просмотрел множество предыдущих вопросов и учебных пособий, блогов и т. д. но я ничего не добьюсь.

1 3

1 ответ:

Это была комбинация проблем, характерных для встроенного причала.

Во-первых, мой код запуска, который настраивал и запускал веб-сервер, выполнял поиск JNDI до того, как я фактически запустил веб-сервер, то есть до вызова server.start(), поэтому конфигурация JNDI не была инициализирована на этом этапе. Но даже это изменение не сработало, потому что envCtx.lookup("jdbc/DataSource") должен быть вызван из потока, связанного с веб-приложением. Поэтому я переместил этот код в статический блок, который получает вызывается в первый раз, когда соединение с базой данных запрашивается запросом веб-сервера.

В конце концов, у меня получилось что-то вроде этого для моего кода запуска :

public static void main(String[] args) {
    Server server = new Server();

    //Enable parsing of jndi-related parts of web.xml and jetty-env.xml
    ClassList classlist = ClassList.setServerDefault(server);
    classlist.addAfter(
            "org.eclipse.jetty.webapp.FragmentConfiguration", 
            "org.eclipse.jetty.plus.webapp.EnvConfiguration", 
            "org.eclipse.jetty.plus.webapp.PlusConfiguration");
...
...
server.start();

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

public class DatabaseUtils {

    private static DataSource datasource;

    private static synchronized Connection getDBConnection() throws SQLException {
        if (datasource == null) {
            initDataSource();
        }
        return datasource.getConnection();
    }

    public static void initDataSource() {
        try {
             datasource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/DataSource");
             LOG.info("Database connection pool initalized successfully");
        } catch (Exception e) {
            LOG.error("Error while initialising the database connection pool", e);
        }
    }