title: Birt cannot find JDBC driver
body: <p>I'm using the Birt report, which has queries to the database. Access to the database goes through JDBC.</p>
  
  <p><strong>When generating a report, the following error occurs:</strong></p>
  
  <pre><code>сен 01, 2017 10:54:36 AM org.eclipse.birt.data.engine.odaconsumer.Driver createNewDriverHelper(Map)
  SEVERE: Cannot get ODA data source driver helper.
  org.eclipse.datatools.connectivity.oda.consumer.helper.OdaHelperException: Unable to load or instantiate the custom ODA driver class. (org.eclipse.birt.report.data.oda.jdbc.OdaJdbcDriver) ;
  org.eclipse.datatools.connectivity.oda.OdaException ;
      java.lang.ClassNotFoundException: org.eclipse.birt.report.data.oda.jdbc.OdaJdbcDriver
      at org.eclipse.datatools.connectivity.oda.consumer.helper.OdaDriver.loadDriverInstance(OdaDriver.java:251)
      at org.eclipse.datatools.connectivity.oda.consumer.helper.OdaDriver.init(OdaDriver.java:198)
      at org.eclipse.datatools.connectivity.oda.consumer.helper.OdaDriver.&lt;init&gt;(OdaDriver.java:113)
      at org.eclipse.birt.data.engine.odaconsumer.Driver.createNewDriverHelper(Driver.java:99)
      at org.eclipse.birt.data.engine.odaconsumer.DriverManager.getDriverHelper(DriverManager.java:115)
      at org.eclipse.birt.data.engine.odaconsumer.DriverManager.getNewDriverHelper(DriverManager.java:101)
      at org.eclipse.birt.data.engine.odaconsumer.ConnectionManager.openConnection(ConnectionManager.java:150)
      at org.eclipse.birt.data.engine.executor.DataSource.newConnection(DataSource.java:224)
      at org.eclipse.birt.data.engine.executor.DataSource.open(DataSource.java:212)
      at org.eclipse.birt.data.engine.impl.DataSourceRuntime.openOdiDataSource(DataSourceRuntime.java:217)
      at org.eclipse.birt.data.engine.impl.QueryExecutor.openDataSource(QueryExecutor.java:437)
      at org.eclipse.birt.data.engine.impl.QueryExecutor.prepareExecution(QueryExecutor.java:325)
      at org.eclipse.birt.data.engine.impl.PreparedQuery.doPrepare(PreparedQuery.java:463)
      at org.eclipse.birt.data.engine.impl.PreparedDataSourceQuery.produceQueryResults(PreparedDataSourceQuery.java:190)
      at org.eclipse.birt.data.engine.impl.PreparedDataSourceQuery.execute(PreparedDataSourceQuery.java:178)
      at org.eclipse.birt.data.engine.impl.PreparedOdaDSQuery.execute(PreparedOdaDSQuery.java:179)
      at org.eclipse.birt.report.data.adapter.impl.DataRequestSessionImpl.execute(DataRequestSessionImpl.java:651)
      at org.eclipse.birt.report.engine.data.dte.DteDataEngine.doExecuteQuery(DteDataEngine.java:152)
      at org.eclipse.birt.report.engine.data.dte.AbstractDataEngine.execute(AbstractDataEngine.java:286)
      at org.eclipse.birt.report.engine.executor.ExecutionContext.executeQuery(ExecutionContext.java:1947)
      at org.eclipse.birt.report.engine.executor.QueryItemExecutor.executeQuery(QueryItemExecutor.java:80)
      at org.eclipse.birt.report.engine.executor.DynamicTextItemExecutor.execute(DynamicTextItemExecutor.java:77)
      at org.eclipse.birt.report.engine.internal.executor.dup.SuppressDuplicateItemExecutor.execute(SuppressDuplicateItemExecutor.java:43)
      at org.eclipse.birt.report.engine.internal.executor.wrap.WrappedReportItemExecutor.execute(WrappedReportItemExecutor.java:46)
      at org.eclipse.birt.report.engine.internal.executor.l18n.LocalizedReportItemExecutor.execute(LocalizedReportItemExecutor.java:34)
      at org.eclipse.birt.report.engine.layout.html.HTMLBlockStackingLM.layoutNodes(HTMLBlockStackingLM.java:65)
      at org.eclipse.birt.report.engine.layout.html.HTMLPageLM.layout(HTMLPageLM.java:92)
      at org.eclipse.birt.report.engine.layout.html.HTMLReportLayoutEngine.layout(HTMLReportLayoutEngine.java:100)
      at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:181)
      at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.run(RunAndRenderTask.java:77)
      at Birt4Py.executeReport(Birt4Py.java:90)
      at EntryPoint.getStack(EntryPoint.java:18)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
      at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
      at py4j.Gateway.invoke(Gateway.java:280)
      at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
      at py4j.commands.CallCommand.execute(CallCommand.java:79)
      at py4j.GatewayConnection.run(GatewayConnection.java:214)
      at java.lang.Thread.run(Thread.java:745)
  Caused by: org.eclipse.datatools.connectivity.oda.OdaException ;
      java.lang.ClassNotFoundException: org.eclipse.birt.report.data.oda.jdbc.OdaJdbcDriver
      at org.eclipse.datatools.connectivity.oda.consumer.helper.DriverExtensionHelper.loadDriverClass(DriverExtensionHelper.java:134)
      at org.eclipse.datatools.connectivity.oda.consumer.helper.OdaDriver.loadDriverInstance(OdaDriver.java:224)
      ... 42 more
  Caused by: java.lang.ClassNotFoundException: org.eclipse.birt.report.data.oda.jdbc.OdaJdbcDriver
      at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
      at java.lang.Class.forName0(Native Method)
      at java.lang.Class.forName(Class.java:264)
      at org.eclipse.datatools.connectivity.oda.consumer.helper.DriverExtensionHelper.loadDriverClass(DriverExtensionHelper.java:130)
      ... 43 more
  </code></pre>
  
  <p><strong>In this case, the report itself is created, but there is no data from the database.</strong></p>
  
  <p>What I've done so far:</p>
  
  <p>1) Downloaded Birt Framework 4.6.0 and BIRT Runtime Release (<a href="http://download.eclipse.org/birt/downloads/" rel="nofollow noreferrer">http://download.eclipse.org/birt/downloads/</a>)<br/>
  2) Downloaded PostgreSQL JDBC 4.2 Driver, 42.1.4 (<a href="https://jdbc.postgresql.org/" rel="nofollow noreferrer">https://jdbc.postgresql.org/</a>)<br/>
  2) Added to the directory <strong>/usr/lib/jvm/java-8-oracle/jre/lib/ext</strong> libraries<br/></p>
  
  <ul>
  <li>commons-io-2.5.jar
  (<a href="http://commons.apache.org/proper/commons-io/download_io.cgi" rel="nofollow noreferrer">http://commons.apache.org/proper/commons-io/download_io.cgi</a>)    </li>
  <li>py4j0.10.4.jar   </li>
  <li>all jar's from BIRT Runtime Release and Birt Framework</li>
  <li>jar with jdbc-driver (postgresql-42.1.4.jar) <br/></li>
  </ul>
  
  <p>4) Compiled java files</p>
  
  <pre><code>javac Birt4Py.java
  javac EntryPoint.java
  </code></pre>
  
  <p>5) Launched Birt:</p>
  
  <pre><code>java EntryPoint
  </code></pre>
  
  <p>6) Launched main.py</p>
  
  <p>Code:</p>
  
  <p><strong>.rptdesign:</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1"&gt;
      &lt;property name="createdBy"&gt;Eclipse BIRT Designer Version 4.6.0.v201606072122&lt;/property&gt;
      &lt;property name="units"&gt;in&lt;/property&gt;
      &lt;property name="iconFile"&gt;/templates/blank_report.gif&lt;/property&gt;
      &lt;property name="bidiLayoutOrientation"&gt;ltr&lt;/property&gt;
      &lt;property name="imageDPI"&gt;96&lt;/property&gt;
      &lt;data-sources&gt;
          &lt;oda-data-source extensionID="org.eclipse.birt.report.data.oda.jdbc" name="Data Source" id="4"&gt;
              &lt;list-property name="privateDriverProperties"&gt;
                  &lt;ex-property&gt;
                      &lt;name&gt;metadataBidiFormatStr&lt;/name&gt;
                      &lt;value&gt;ILYNN&lt;/value&gt;
                  &lt;/ex-property&gt;
                  &lt;ex-property&gt;
                      &lt;name&gt;disabledMetadataBidiFormatStr&lt;/name&gt;
                  &lt;/ex-property&gt;
                  &lt;ex-property&gt;
                      &lt;name&gt;contentBidiFormatStr&lt;/name&gt;
                      &lt;value&gt;ILYNN&lt;/value&gt;
                  &lt;/ex-property&gt;
                  &lt;ex-property&gt;
                      &lt;name&gt;disabledContentBidiFormatStr&lt;/name&gt;
                  &lt;/ex-property&gt;
              &lt;/list-property&gt;
              &lt;property name="odaDriverClass"&gt;org.postgresql.Driver&lt;/property&gt;
              &lt;property name="odaURL"&gt;jdbc:postgresql://192.168.69.128:5432/expert&lt;/property&gt;
              &lt;property name="odaUser"&gt;visitor1&lt;/property&gt;
              &lt;encrypted-property name="odaPassword" encryptionID="base64"&gt;cXdlcnR5MTIz&lt;/encrypted-property&gt;
          &lt;/oda-data-source&gt;
      &lt;/data-sources&gt;
      &lt;data-sets&gt;
          &lt;oda-data-set extensionID="org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" name="MyDS" id="5"&gt;
              &lt;list-property name="columnHints"&gt;
                  &lt;structure&gt;
                      &lt;property name="columnName"&gt;c&lt;/property&gt;
                      &lt;text-property name="displayName"&gt;c&lt;/text-property&gt;
                      &lt;text-property name="heading"&gt;c&lt;/text-property&gt;
                  &lt;/structure&gt;
              &lt;/list-property&gt;
              &lt;structure name="cachedMetaData"&gt;
                  &lt;list-property name="resultSet"&gt;
                      &lt;structure&gt;
                          &lt;property name="position"&gt;1&lt;/property&gt;
                          &lt;property name="name"&gt;c&lt;/property&gt;
                          &lt;property name="dataType"&gt;decimal&lt;/property&gt;
                      &lt;/structure&gt;
                  &lt;/list-property&gt;
              &lt;/structure&gt;
              &lt;property name="dataSource"&gt;Data Source&lt;/property&gt;
              &lt;list-property name="resultSet"&gt;
                  &lt;structure&gt;
                      &lt;property name="position"&gt;1&lt;/property&gt;
                      &lt;property name="name"&gt;c&lt;/property&gt;
                      &lt;property name="nativeName"&gt;c&lt;/property&gt;
                      &lt;property name="dataType"&gt;decimal&lt;/property&gt;
                      &lt;property name="nativeDataType"&gt;-5&lt;/property&gt;
                  &lt;/structure&gt;
              &lt;/list-property&gt;
              &lt;xml-property name="queryText"&gt;&lt;![CDATA[select SUM(34) as c
  ]]&gt;&lt;/xml-property&gt;
              &lt;xml-property name="designerValues"&gt;&lt;![CDATA[&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;model:DesignValues xmlns:design="http://www.eclipse.org/datatools/connectivity/oda/design" xmlns:model="http://www.eclipse.org/birt/report/model/adapter/odaModel"&gt;
    &lt;Version&gt;2.0&lt;/Version&gt;
    &lt;design:ResultSets derivedMetaData="true"&gt;
      &lt;design:resultSetDefinitions&gt;
        &lt;design:resultSetColumns&gt;
          &lt;design:resultColumnDefinitions&gt;
            &lt;design:attributes&gt;
              &lt;design:identifier&gt;
                &lt;design:name&gt;c&lt;/design:name&gt;
                &lt;design:position&gt;1&lt;/design:position&gt;
              &lt;/design:identifier&gt;
              &lt;design:nativeDataTypeCode&gt;-5&lt;/design:nativeDataTypeCode&gt;
              &lt;design:precision&gt;19&lt;/design:precision&gt;
              &lt;design:scale&gt;0&lt;/design:scale&gt;
              &lt;design:nullability&gt;Unknown&lt;/design:nullability&gt;
              &lt;design:uiHints&gt;
                &lt;design:displayName&gt;c&lt;/design:displayName&gt;
              &lt;/design:uiHints&gt;
            &lt;/design:attributes&gt;
            &lt;design:usageHints&gt;
              &lt;design:label&gt;c&lt;/design:label&gt;
              &lt;design:formattingHints&gt;
                &lt;design:displaySize&gt;20&lt;/design:displaySize&gt;
              &lt;/design:formattingHints&gt;
            &lt;/design:usageHints&gt;
          &lt;/design:resultColumnDefinitions&gt;
        &lt;/design:resultSetColumns&gt;
        &lt;design:criteria/&gt;
      &lt;/design:resultSetDefinitions&gt;
    &lt;/design:ResultSets&gt;
  &lt;/model:DesignValues&gt;]]&gt;&lt;/xml-property&gt;
          &lt;/oda-data-set&gt;
      &lt;/data-sets&gt;
      &lt;page-setup&gt;
          &lt;simple-master-page name="Simple MasterPage" id="2"&gt;
              &lt;page-footer&gt;
                  &lt;text id="3"&gt;
                      &lt;property name="contentType"&gt;html&lt;/property&gt;
                      &lt;text-property name="content"&gt;&lt;![CDATA[&lt;value-of&gt;new Date()&lt;/value-of&gt;]]&gt;&lt;/text-property&gt;
                  &lt;/text&gt;
              &lt;/page-footer&gt;
          &lt;/simple-master-page&gt;
      &lt;/page-setup&gt;
      &lt;body&gt;
          &lt;text-data id="6"&gt;
              &lt;property name="dataSet"&gt;MyDS&lt;/property&gt;
              &lt;list-property name="boundDataColumns"&gt;
                  &lt;structure&gt;
                      &lt;property name="name"&gt;c&lt;/property&gt;
                      &lt;text-property name="displayName"&gt;c&lt;/text-property&gt;
                      &lt;expression name="expression" type="javascript"&gt;dataSetRow["c"]&lt;/expression&gt;
                      &lt;property name="dataType"&gt;decimal&lt;/property&gt;
                  &lt;/structure&gt;
              &lt;/list-property&gt;
              &lt;expression name="valueExpr"&gt;row['c'];&lt;/expression&gt;
              &lt;property name="contentType"&gt;html&lt;/property&gt;
          &lt;/text-data&gt;
      &lt;/body&gt;
  &lt;/report&gt;
  </code></pre>
  
  <p><strong>Birt4py.java</strong></p>
  
  <pre><code>import org.apache.commons.io.output.ByteArrayOutputStream;
  import org.eclipse.birt.core.exception.BirtException;
  import org.eclipse.birt.core.framework.Platform;
  import org.eclipse.birt.report.engine.api.EngineConfig;
  import org.eclipse.birt.report.engine.api.EngineException;
  import org.eclipse.birt.report.engine.api.HTMLRenderOption;
  import org.eclipse.birt.report.engine.api.DocxRenderOption;
  import org.eclipse.birt.report.engine.api.RenderOption;
  import org.eclipse.birt.report.engine.api.EXCELRenderOption;
  import org.eclipse.birt.report.engine.api.HTMLServerImageHandler;
  import org.eclipse.birt.report.engine.api.IReportEngine;
  import org.eclipse.birt.report.engine.api.IReportEngineFactory;
  import org.eclipse.birt.report.engine.api.IReportRunnable;
  import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
  import org.eclipse.birt.report.model.api.SessionHandle;
  import java.io.FileWriter;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.logging.Level;
  import java.util.HashMap;
  import java.io.*;
  import java.net.URL;
  
  
  public class Birt4Py {
  
        private static String report;
        private static IReportEngine engine = null;
        private static EngineConfig  config = null;
  
        public static String getReport() {
          return report;
        }
  
        public Birt4Py() throws BirtException {
            // start up Platform
            config = new EngineConfig( );
  
            Platform.startup( config );
  
            // create new Report Engine
            IReportEngineFactory factory = (IReportEngineFactory) Platform.createFactoryObject( IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY );
            engine = factory.createReportEngine( config );
        }
  
        public void executeReport(ArrayList&lt;String&gt; params) throws EngineException {
            /*
              Params are passed through the /sirenaApp/data_helpers/report_extractor -&gt; get_report_file() -&gt; my_list:
                  1st: .rptdesign full path -&gt; String
                  2nd: report file full path -&gt; String
                  3rd: report extension -&gt; String
  
            */
  
            // open the report design
            IReportRunnable design = null;
            System.out.println(params);
            design = engine.openReportDesign(params.get(0));
  
            // create RunandRender Task
            IRunAndRenderTask task = engine.createRunAndRenderTask(design);
  
            // pass necessary parameters
            task.validateParameters();
  
            // set render options including output type
            RenderOption options;
            if (params.get(2) == "doc") {
              options = new RenderOption();
            }
            else if (params.get(2) == "xls") {
              options = new EXCELRenderOption();
            }
            else {
              options = new HTMLRenderOption();
            }
  
            ByteArrayOutputStream outs = new ByteArrayOutputStream();
            options.setOutputStream(outs);
            options.setImageHandler(new HTMLServerImageHandler());
  
            options.setOutputFileName(params.get(1));
            options.setOutputFormat(params.get(2));
            task.setRenderOption(options);
  
            String output;
            task.run();
            output = outs.toString();
            task.close();
            report = output;
  
            System.out.println(report);
  
        }
  }
  </code></pre>
  
  <p><strong>EntryPoint.java</strong></p>
  
  <pre><code>import org.eclipse.birt.core.exception.BirtException;
  import org.eclipse.birt.report.engine.api.EngineException;
  
  import py4j.GatewayServer;
  import java.util.ArrayList;
  import java.util.List;
  
  public class EntryPoint {
    private Birt4Py birt;
  
    public EntryPoint() throws BirtException {
        birt  = new Birt4Py();
  
    }
  
    public Birt4Py getStack(ArrayList&lt;String&gt; params) throws EngineException {
  
        birt.executeReport(params);
        return birt;
    }
  
    public static void main(String[] args) throws BirtException {
        GatewayServer gatewayServer = new GatewayServer(new EntryPoint());
        gatewayServer.start();
        System.out.println("Birt4Py listener started!");
    }
  }
  </code></pre>
  
  <p><strong>main.py</strong></p>
  
  <pre><code># -*- coding: utf-8 -*-
  
  import os
  from py4j.java_gateway import JavaGateway, GatewayParameters
  
  BIRT_PORT = 25333
  BIRT_HOST = '127.0.0.1'
  
  
  class BirtReport(object):
  
      def __init__(self, rptdesign_name, rptdesign_path):
  
          self.rptdesign_path = rptdesign_path
          self.rptdesign_name = rptdesign_name
  
      def get_report_file(self, ext, filename):
          """
          :param ext: str - file extension, i.e. .doc, .xls
          :param filename: str - filename
          :return: str - filename with extension of the resulting report
          """
  
          # Params passed to the Birt4Py.java report executor:
          #   1st: .rptdesign full path -&gt; String
          #   2nd: report file full path -&gt; String
          #   3rd: report extension -&gt; String
  
          filepath = self.rptdesign_path + filename + '.' + ext
          my_list = [self.rptdesign_path + self.rptdesign_name, filepath, ext]
  
          try:
              gateway = JavaGateway(gateway_parameters=GatewayParameters(auto_convert=True,
                                                                         auto_field=True,
                                                                         port=BIRT_PORT,
                                                                         address=BIRT_HOST))
              gateway.entry_point.getStack(my_list)
          except Exception:
              raise
  
          return filepath
  
  
  if __name__ == '__main__':
      rptdesign_name = 'jdbc_test.rptdesign'
      rptdesign_path = os.path.dirname(os.path.abspath(__file__)) + '/'
  
      birt_report = BirtReport(rptdesign_name, rptdesign_path)
  
      generated_file = birt_report.get_report_file('docx', 'GenerateDocxFile')
      print(generated_file)
  </code></pre>
  
  <p><strong>Question: how do I get the JDBC driver to work together with Birt?</strong><br/>
  The my test project can be downloaded <a href="https://github.com/NorthCat/PythonBirt" rel="nofollow noreferrer">here</a>.</p>