Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Как вытащить подключение к БД из контекста Tomcat?


Автор: Aoli 7.2.2007, 02:06
Понадобилось переписать программу (это я к тому, что раньше все работало ОК). Прогоняю тесты. Первый сразу же вылетает с такой ошибкой:
Код

org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
    at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:780)
    at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:540)
    at test.TestDB.doGet(TestDB.java:27)
    ...
Caused by: java.lang.NullPointerException
    at sun.jdbc.odbc.JdbcOdbcDriver.getProtocol(JdbcOdbcDriver.java:507)
    at sun.jdbc.odbc.JdbcOdbcDriver.knownURL(JdbcOdbcDriver.java:476)
    at sun.jdbc.odbc.JdbcOdbcDriver.acceptsURL(JdbcOdbcDriver.java:307)
    at java.sql.DriverManager.getDriver(DriverManager.java:253)
    at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:773)
    ... 19 more

Код тестового сервлета:
Код

public class TestDB extends HttpServlet {
    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
        DataSource ds = null;
        try {
            Context initContext = new InitialContext();
            Context envContext = null;
            envContext = (Context) initContext.lookup("java:/comp/env");
            ds = (DataSource) envContext.lookup("library");
        } catch (NamingException e) {
            e.printStackTrace();
        }

        try {
            Connection conn = ds.getConnection(); // здесь SQLException
            ...
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Проверил отладчиком: в envContext (в его HashMap) есть объект по ключу "library". ds - не пустой. Однако все поля ds - либо null, либо 0.
В чем проблема - понять не могу smile
Контекст:
Код

<Context path="/">
    <Resource name="library" auth="Container" type="javax.sql.DataSource"
              maxActive="100" maxIdle="30" maxWait="10000"
              username="sudo" password="XXX" driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/libdb?autoReconnect=true"/>
</Context>

Автор: Zamuta 7.2.2007, 03:01
Меня здесь смущает <Context path="/">...</Context>

Если это server.xml, то
 
Код

<GlobalNamingResources>
     <Resource
      name="library"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.jdbc.Driver"
      password="password"
      maxIdle="30"
      maxWait="10000"
      username="sudo"
      url="jdbc:mysql://localhost:3306/libdb?autoReconnect=true"
      maxActive="100"/>
  </GlobalNamingResources>


И в web.xml 

Код

<resource-ref>
        <res-ref-name>library</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>

Автор: Aoli 7.2.2007, 12:25
В web.xml в <resource-ref> на всякий случай добавил <res-sharing-scope>Shareable</res-sharing-scope>

В Tomcate нет server.xml, поэтому попробовал <GlobalNamingResources> написать в context.xml.

Tomcat не понял шутку. Тот же самый exception.

Автор: tux 7.2.2007, 13:08
В META-INF/context.xml:
Код

<?xml version="1.0" encoding="ISO-8859-1"?>
<Context
docBase="app"
path="/app"
reloadable="true">

<Resource
      name="library"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.jdbc.Driver"
      password="password"
      maxIdle="30"
      maxWait="10000"
      username="sudo"
      url="jdbc:mysql://localhost:3306/libdb?autoReconnect=true"
      maxActive="100"/>

</Context>

В web.xml:
Код

<resource-ref>
        <res-ref-name>library</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
</resource-ref>

А что это за Томкат, у которого нет server.xml? Никогда таких не видел.

Автор: Aoli 7.2.2007, 16:41
Цитата

А что это за Томкат, у которого нет server.xml? Никогда таких не видел. 

Сорри. Нашел в папочке conf.

Вписал в META-INF/context.xml то, что посоветовал tux.
Exception, как ни странно, тот же.
Переписал доставание контекста так:
Код

envContext = (Context) initContext.lookup("java:/comp/env/app");

и получил javax.naming.NameNotFoundException: Name app is not bound in this Context

Т.е., как я понимаю, Tomcat вообще игнорирует мой context.xml???!!!

P.S. в web.xml написано то же, что и у tux.

Автор: tux 7.2.2007, 16:53
Здесь
Код

envContext = (Context) initContext.lookup("java:/comp/env/app");

app - это что? Ссылка на источник данных вроде library называется. Или ты что-то другое ищещь?

Автор: Zamuta 7.2.2007, 16:55
Aoli, если ты хочешь получить доступ к java:/comp/env/app, то создай тогда свой ресурс в server.xml
Код

<Resource
      name="app"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.jdbc.Driver"
      password="password"
      maxIdle="30"
      maxWait="10000"
      username="sudo"
      url="jdbc:mysql://localhost:3306/libdb?autoReconnect=true"
      maxActive="100"/>



Теперь имя ресурса у тебя "app", можешь посмотреть это если зайдёшь http://localhost:[port]/admin , пароль от админки лежит в tomcat-users.xml, а обращаться в коде нужно java:/comp/env/app

Автор: Aoli 7.2.2007, 20:40
Читал доки. Много думал (С).

Создал новый проект.

В server.xml не суюсь.

В context.xml прописал:
Код

<Context path="/">
    <Resource name="jndi/test" type="javax.sql.DataSource"
              maxActive="100" maxIdle="30" maxWait="10000"
              username="root" password="XXX" driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/?autoReconnect=true"/>
</Context>


В web.xml:
Код

<resource-ref>
        <res-ref-name>jndi/test</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
</resource-ref>


В коде сервлета:
Код

public class Test extends HttpServlet {
    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
        try {
            Context initContext = new InitialContext();
            DataSource ds = (DataSource) initContext.lookup("java:/comp/env/jndi/test");
            Connection c = ds.getConnection();
            Statement s = c.createStatement();
            s.execute("USE LIB");
            ServletOutputStream sos = httpServletResponse.getOutputStream();
            sos.println("ALL OK");
            sos.flush();
            sos.close();
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}


И - чудеса на постном масле: все работает.
Отличий между способом подключения в исходном проекте и в тестовом не нашел.
Почему в исходном проекте не коннектит - не знаю.
Придется пересобирать заново smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)