【问题标题】:Birt 4.6.0-20160607 throws ClassNotFoundException for OracleDriverBirt 4.6.0-20160607 为 OracleDriver 引发 ClassNotFoundException
【发布时间】:2017-01-10 13:15:00
【问题描述】:

我有一个使用 Birt 4.6 的 naven 应用程序。在我的依赖项下方。

    <dependency>
         <groupId>org.eclipse.birt.ojdbc</groupId>
         <artifactId>odajdbc</artifactId>
         <version>4.6.0-201606072122</version>
     </dependency>

    <dependency>
      <groupId>org.eclipse.birt.runtime</groupId>
      <artifactId>org.eclipse.birt.runtime</artifactId>
      <version>4.6.0-20160607</version>
      <exclusions>
        <exclusion>
            <groupId>org.eclipse.birt.runtime</groupId>
            <artifactId>org.apache.xerces</artifactId>
        </exclusion>
        <exclusion>
          <artifactId>org.apache.poi</artifactId>
          <groupId>org.eclipse.birt.runtime</groupId>
        </exclusion>
      </exclusions>
    </dependency>

我能够连接数据库并生成报告。这些是好消息。

不幸的是,我注意到在我的日志文件中抛出了一个异常。异常可以在下面看到

2017-01-10 14:57:15,446 严重 [org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager](默认任务 6)DriverClassLoader 无法加载类:oracle.jdbc.driver.OracleDriver : java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver 在 org.eclipse.birt.core.framework.URLClassLoader.findClass1(URLClassLoader.java:188) 在 org.eclipse.birt.core.framework.URLClassLoader$1.run(URLClassLoader.java:156) 在 org.eclipse.birt.core.framework.URLClassLoader$1.run(URLClassLoader.java:1) 在 java.security.AccessController.doPrivileged(本机方法) 在 org.eclipse.birt.core.framework.URLClassLoader.findClass(URLClassLoader.java:151) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:424) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:357) 在 java.lang.Class.forName0(本机方法) 在 java.lang.Class.forName(Class.java:348) 在 org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.loadExtraDriver(JDBCDriverManager.java:1064) 在 org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.findDriver(JDBCDriverManager.java:859) 在 org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.loadAndRegisterDriver(JDBCDriverManager.java:986) 在 org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.loadAndRegisterDriver(JDBCDriverManager.java:958) 在 org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.doConnect(JDBCDriverManager.java:285) 在 org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.getConnection(JDBCDriverManager.java:236) 在 org.eclipse.birt.report.data.oda.jdbc.Connection.connectByUrl(Connection.java:254) 在 org.eclipse.birt.report.data.oda.jdbc.Connection.open(Connection.java:163) 在 org.eclipse.datatools.connectivity.oda.consumer.helper.OdaConnection.open(OdaConnection.java:250) 在 org.eclipse.birt.data.engine.odaconsumer.ConnectionManager.openConnection(ConnectionManager.java:165) 在 org.eclipse.birt.data.engine.executor.DataSource.newConnection(DataSource.java:224) 在 org.eclipse.birt.data.engine.executor.DataSource.open(DataSource.java:212) 在 org.eclipse.birt.data.engine.impl.DataSourceRuntime.openOdiDataSource(DataSourceRuntime.java:217) 在 org.eclipse.birt.data.engine.impl.QueryExecutor.openDataSource(QueryExecutor.java:437) 在 org.eclipse.birt.data.engine.impl.QueryExecutor.prepareExecution(QueryExecutor.java:325) 在 org.eclipse.birt.data.engine.impl.PreparedQuery.doPrepare(PreparedQuery.java:463) 在 org.eclipse.birt.data.engine.impl.PreparedDataSourceQuery.produceQueryResults(PreparedDataSourceQuery.java:190) 在 org.eclipse.birt.data.engine.impl.PreparedDataSourceQuery.execute(PreparedDataSourceQuery.java:178) 在 org.eclipse.birt.data.engine.impl.PreparedOdaDSQuery.execute(PreparedOdaDSQuery.java:179) 在 org.eclipse.birt.report.data.adapter.impl.DataRequestSessionImpl.execute(DataRequestSessionImpl.java:651) 在 org.eclipse.birt.report.engine.data.dte.DteDataEngine.doExecuteQuery(DteDataEngine.java:152) 在 org.eclipse.birt.report.engine.data.dte.AbstractDataEngine.execute(AbstractDataEngine.java:286) 在 org.eclipse.birt.report.engine.executor.ExecutionContext.executeQuery(ExecutionContext.java:1947) 在 org.eclipse.birt.report.engine.executor.QueryItemExecutor.executeQuery(QueryItemExecutor.java:80) 在 org.eclipse.birt.report.engine.executor.TableItemExecutor.execute(TableItemExecutor.java:62) 在 org.eclipse.birt.report.engine.internal.executor.dup.SuppressDuplicateItemExecutor.execute(SuppressDuplicateItemExecutor.java:43) 在 org.eclipse.birt.report.engine.internal.executor.wrap.WrappedReportItemExecutor.execute(WrappedReportItemExecutor.java:46) 在 org.eclipse.birt.report.engine.internal.executor.l18n.LocalizedReportItemExecutor.execute(LocalizedReportItemExecutor.java:34) 在 org.eclipse.birt.report.engine.layout.html.HTMLBlockStackingLM.layoutNodes(HTMLBlockStackingLM.java:65) 在 org.eclipse.birt.report.engine.layout.html.HTMLPageLM.layout(HTMLPageLM.java:92) 在 org.eclipse.birt.report.engine.layout.html.HTMLReportLayoutEngine.layout(HTMLReportLayoutEngine.java:100) 在 org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:181) 在 org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.run(RunAndRenderTask.java:77)

由于某种原因,JDBCDriverManager 很难找到正确的驱动程序,抛出异常,最后找到连接到数据库的驱动程序并生成报告。

我在 JDBCDriverManager 上进行了调试,希望下面的信息能有所帮助。

  1. 应用程序通过 doConnect() 函数 JDBCDriverManager。里面有 Connection getJndiDSConnection(driverClass, jndiNameUrl, connectionProperties); 返回 null 。 doConnect 中的 getJndiDSConnection 也是如此。也返回 null
  2. 然后loadAndRegisterDriver(driverClass, driverClassPath);使用以下参数调用 oracle.jdbc.driver.OracleDrivernull
  3. 在 loadAndRegisterDriver 内部,使用以下参数调用 findDriver( className, driverClassPath, refreshClassLoader ) oracle.jdbc.driver.OracleDriver , null, false强>
  4. 下一步 driverClass = loadExtraDriver( className, true, refresh, driverClassPath );使用 oracle.jdbc.driver.OracleDriver 、 true 、 false 、 null 调用,这会引发上述 ClassNotFoundException
  5. 最后一步,我们仍然在 findDriver 方法里面 driver = this.getDriverInstance( driverClass, refresh );方法被调用并最终返回 oracle.jdbc.driver.OracleDriver 。

在第 5 步之后一切正常。正如我所提到的,异常只出现一次,并且仍然创建了与数据库的连接并生成了报告。之后,无论我创建多少次报告,都不会再次抛出异常。

我想在这里添加一些有关 findDriver 方法的更多信息。此方法尝试通过多种方式获取驱动程序。首先是

// Driver not in plugin class path; find it in drivers directory
driverClass = loadExtraDriver( className, true, refresh, driverClassPath );

返回 null 然后尝试从上下文中获取驱动程序

driverClass = Class.forName( className, true, Thread.currentThread( ).getContextClassLoader()); 

这次终于实现了找回驱动。

我错过了什么?很明显,它无法从插件加载它,因为我没有任何插件目录。有没有办法克服这个异常?

【问题讨论】:

  • 你应该加载oracle.jdbc.OracleDriver,但它可能只是工作,因为它已经使用通过ServiceLoader加载的JDBC 4(和更高版本)驱动程序加载
  • 经过如此多的更改后,我在某处丢失了我在做什么的踪迹。我真的以为我尝试了很多次都没有成功。那成功了。非常感谢马克

标签: maven jakarta-ee jdbc birt ojdbc


【解决方案1】:

正如 Mark 所说,没有必要将 org.eclipse.birt.ojdbc 作为依赖项添加。我停止使用 org.eclipse.birt.report.data.oda.jdbc_4.6.0.v201606072122.jar 并使用我的本地 ojdbc 驱动程序。

    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>11.2.0.4.0</version>
    </dependency>

上面修复了我们第一次尝试加载驱动程序时遇到的异常。

【讨论】:

    【解决方案2】:

    在Birt Viewer文件夹(Web / App Server端)的WEB-INF路径下添加ojdbc7.jar为我解决了这个问题:

    [1] ../lib  
    [2] ../platform/plugins/org.eclipse.birt.report.data.oda.jdbc_<VERSION>/drivers
    

    日志

    在上面添加 [2] 之前(只有 [1])

    20-Mar-2017 14:12:26.752 SEVERE [http-nio-8080-exec-4] org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.loadExtraDriver DriverClassLoader failed to load class: oracle.jdbc.driver.OracleDriver  java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    

    在上面添加 [2] 之后(只有 [1])

    20-Mar-2017 14:49:42.196 INFO [http-nio-8080-exec-4] org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager$DriverClassLoader.refreshFileURL JDBCDriverManager: found JAR file ojdbc7.jar. URL=file:../WEB-INF/platform/plugins/org.eclipse.birt.report.data.oda.jdbc_4.6.0.v201606072122/drivers/ojdbc7.jar
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-23
      • 1970-01-01
      相关资源
      最近更新 更多