0

Tomcat で実行されている Spring を使用してデータ ソースを作成しようとすると、データベース ドライバ クラスで ClassNotFoundException が発生します。ただし、ドライバー クラスを同じデータ アクセス コンポーネントから ( と の両方を介しClass.forNamegetClass().getClassLoader().loadClass()) 直接読み込むことができます。ドライバ jar は 1 か所にのみインストールされます ( $CATALINA_HOME/lib)。

Spring 構成ファイルのデータ ソース定義:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

Spring 構成ファイルの DAO 定義:

<bean id="countryDao" class="com.mycompany.pmo.dao.CountryDao">
    <constructor-arg ref="dataSource"/>
</bean>

DAO 自体:

public class CountryDao {
    private NamedParameterJdbcTemplate jdbcTemplate;

    public CountryDao(DataSource dataSource) {
        jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    public List<Country> getCountries() {
        //I can manually load the driver class here
        String sql = "select * from ref.country";

        Map<String, Object> namedParameters = new HashMap<String, Object>();
        //next line is line 34, where the stack trace starts
        return jdbcTemplate.query(sql, namedParameters,new CountryMapper());
    }
}

スタック トレース:

Feb 20, 2013 2:18:35 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/PMO] threw exception [Request processing failed; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '"com.microsoft.sqlserver.jdbc.SQLServerDriver"'] with root cause
java.lang.ClassNotFoundException: "com.microsoft.sqlserver.jdbc.SQLServerDriver"
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    at org.apache.commons.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1420)
    at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:573)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:662)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:702)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:166)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:172)
    at com.mycompany.pmo.dao.CountryDao.getCountries(CountryDao.java:34)
4

2 に答える 2

4

はにあっjarてはなりません$CATALINA_HOME/libWEB-INF/libそれはあなたのウェブアプリの中にあるはずです。を$CATALINA_HOME/libロードして実行するために使用されるとTomcat思いますが、アプリのクラスパスの依存関係は からロードされWEB-INF/libます。

IDE で開発し、そこでプログラムを実行している場合は、プロジェクトのビルド パスに jar を追加する必要がある場合もあります。

于 2013-02-20T19:44:49.547 に答える
2

@Sotirios Delimanolisが言及したように(+1)、jarをWEB-INF/libアプリケーションの下に置いてみてください。

手動コードを使用してクラスが見つかり、Spring 経由では見つからないという事実は、問題がクラスローダーにあることを示しています。呼び出すClass.forName()ときは、間違いなくシステム クラス ローダーを使用しているため、クラスは catalina lib ディレクトリからロードされます。DAO から呼び出すときになぜ機能するのか説明できませんgetClass().getClassLoader().loadClass()。この場合、同じアプリケーション クラス ローダーを使用する必要があります。しかし、おそらく、Spring 自体がクラス ローダーとどのように連携するかについて、私は十分に理解していません。

于 2013-02-20T19:50:15.433 に答える