Birt 4.6.0-20160607 создает исключение ClassNotFoundException для OracleDriver
У меня есть приложение Naven, в котором я использую Birt 4.6. Ниже моих зависимостей.
<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 SEVERE [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.URlassLoLader (ULL) Java:156) в org.eclipse.birt.core.framework.URLClassLoader$1.run(URLClassLoader.java:1) в java.security.AccessController.doPrivileged(собственный метод) в org.eclipse.birt.core.framework.URlass.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 ".loadAndRegisterDriver(JDBCDriverManager.java:958) в org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.doConnect(JDBCDriverManager.java:285) в org.eclipse.birt.an.jd.ddddd.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.data.engine.impl.QueryExecutor.prepareExecution(QueryExecutor.java:325) в org.eclipse.birt.data.engine.impl.PreparedQuery.doPrepare(PreparedQuery.java:463) в org.eclipse.birt.data.impl.PreparedDataSourceQuery.produceQueryResults(PreparedDataSourceQuery.java:190) по адресу org.eclipse.birt.data.engine.impl.PreparedDataSourceQuery.execute(PreparedDataSourceQuery.javaden.l..p.Exp.Imp.Op. выполнить (PreparedOdaDSQuery.java:179) в org.eclipse.birt.report.data.adapter.impl.DataRequestSessionImpl.execute(DataRequestSessionImpl.java:651) в org.eclipse.birt.report.engine.data.data.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.en.executor.TableItemExecutor.execute(TableItemExecutor.java:62) в org.eclipse.birt.report.engine.internal.executor.dup.SuppressDuplicateItemExecutor.execute(SuppressDuplicateItemExecutor.java:43) в org.eclipse.b..executor..engine.layout.html.HTMLBlockStackingLM.layoutNodes(HTMLBlockStackingLM.java:65) в org.eclipse.birt.report.engine.layout.html.HTMLPageLM.layout(HTMLPageLM.java:92) в org.irtlipse.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 и надеюсь, что приведенная ниже информация немного поможет.
- Приложение проходит через функцию doConnect() JDBCDriverManager. Внутри есть соединение getJndiDSConnection( driverClass, jndiNameUrl, connectionProperties); возвращает ноль. То же самое происходит для getJndiDSConnection в doConnect. также возвращает ноль
- Затем loadAndRegisterDriver( driverClass, driverClassPath); вызывается со следующими аргументами oracle.jdbc.driver.OracleDriver и null
- Внутри loadAndRegisterDriver findDriver( className, driverClassPath, refreshClassLoader) вызывается со следующими аргументами oracle.jdbc.driver.OracleDriver, null, false
- На следующем шаге driverClass = loadExtraDriver( className, true, refresh, driverClassPath); Вызывается с помощью oracle.jdbc.driver.OracleDriver, true, false, null, который вызывает исключение ClassNotFoundException, упомянутое выше.
- Последний шаг, мы все еще находимся внутри метода 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 );
Который возвращает ноль, а затем дает попытку получить драйвер из контекста
driverClass = Class.forName( className, true, Thread.currentThread( ).getContextClassLoader());
На этот раз, наконец, удается восстановить драйвер.
Что мне не хватает? Ясно, что он не может загрузить его из плагинов, так как у меня нет каталога плагинов. Есть ли способ преодолеть это исключение?
2 ответа
Как уже упоминал Марк, нет необходимости добавлять в качестве зависимости 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>
Выше исправлено исключение, которое мы получаем при первой попытке загрузить драйвер.
Добавление ojdbc7.jar
под WEB-INF
Путь к папке Birt Viewer (сторона Web/App Server) решил проблему для меня:
[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