Служба контроллера DBCPConnectionPool для SQL Server, исключение jdbc

NiFi 1.1.1 протестирован как на Windows 7, так и на RHEL 7.

Фоновый поток находится здесь.

Я создал службу контроллера DBCPConnectionPool, указывающую на базу данных SQL Server, я могу извлекать данные из таблицы и записывать их на локальный диск (ExecuteSQL -> ConvertAvroToJSON -> PutFile).

Мой код:

public byte[] getMaxLSN(Connection connection, String containerDB) {
    String dbMaxLSN = "{? = CALL sys.fn_cdc_get_max_lsn()}";
    byte[] maxLSN = null;

    try (final CallableStatement cstmt = connection.prepareCall(dbMaxLSN);) {

        cstmt.registerOutParameter(1, java.sql.JDBCType.BINARY);
        cstmt.execute();

        if (cstmt.getBytes(1) == null || cstmt.getBytes(1).length <= 0) {

            System.out.println("Coudln't retrieve the max lsn for the db "
                    + containerDB);

        } else {
            maxLSN = cstmt.getBytes(1);

        }
    } catch (SQLException sqlException) {
        System.out.println("sqlException !!!");
        sqlException.printStackTrace();
    }

    return maxLSN;
}

введите здесь описание изображения

Проблема возникает, когда я использую пул как свойство в своем пользовательском процессоре. В коде процессора мне нужно вызвать функцию в базе данных, но это приводит к исключению SQLException, указывающему на драйвер JDBC. Обратите внимание, что тот же драйвер правильно работает в автономном коде Java (предоставляется в фоновом потоке, чтобы не загромождать этот пост), и я получаю возвращаемое значение из функции. Я подозреваю, что служба контроллера настроена неправильно — она может выполнять запросы на выборку, но когда код вызывает функцию, она генерирует исключение. Что мне не хватает?

Process or SQL exception in <configure logger template to pick the code location>
2017-03-17 09:25:30,717 ERROR [Timer-Driven Process Thread-6] c.s.d.processors.SQLServerCDCProcessor 
org.apache.nifi.processor.exception.ProcessException: Coudln't retrieve the max lsn for the db test
    at com.datalake.processors.SQLServerCDCProcessor$SQLServerCDCUtils.getMaxLSN(SQLServerCDCProcessor.java:692) ~[nifi-NiFiCDCPoC-processors-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
    at com.datalake.processors.SQLServerCDCProcessor.getChangedTableQueries(SQLServerCDCProcessor.java:602) ~[nifi-NiFiCDCPoC-processors-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
    at com.datalake.processors.SQLServerCDCProcessor.onTrigger(SQLServerCDCProcessor.java:249) ~[nifi-NiFiCDCPoC-processors-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
    at org.apache.nifi.processor.AbstractProcessor.onTrigger(AbstractProcessor.java:27) [nifi-api-1.1.1.jar:1.1.1]
    at org.apache.nifi.controller.StandardProcessorNode.onTrigger(StandardProcessorNode.java:1099) [nifi-framework-core-1.1.1.jar:1.1.1]
    at org.apache.nifi.controller.tasks.ContinuallyRunProcessorTask.call(ContinuallyRunProcessorTask.java:136) [nifi-framework-core-1.1.1.jar:1.1.1]
    at org.apache.nifi.controller.tasks.ContinuallyRunProcessorTask.call(ContinuallyRunProcessorTask.java:47) [nifi-framework-core-1.1.1.jar:1.1.1]
    at org.apache.nifi.controller.scheduling.TimerDrivenSchedulingAgent$1.run(TimerDrivenSchedulingAgent.java:132) [nifi-framework-core-1.1.1.jar:1.1.1]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_71]
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_71]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_71]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_71]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_71]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_71]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_71]
Caused by: java.sql.SQLFeatureNotSupportedException: registerOutParameter not implemented
    at java.sql.CallableStatement.registerOutParameter(CallableStatement.java:2613) ~[na:1.8.0_71]
    at com.datalake.processors.SQLServerCDCProcessor$SQLServerCDCUtils.getMaxLSN(SQLServerCDCProcessor.java:677) ~[nifi-NiFiCDCPoC-processors-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
    ... 14 common frames omitted

person Kaliyug Antagonist    schedule 17.03.2017    source источник


Ответы (1)


"java.sql.SQLFeatureNotSupportedException: registerOutParameter не реализован" В вашем коде используется функция, недоступная в драйвере.

В частности, на основе трассировки стека ваш драйвер вызывает registerOutParameter(int parameterIndex, SQLType sqlType), который был представлен в JDBC 4.2 (Java 8). Этот метод имеет следующую реализацию по умолчанию в интерфейсе java.sql.CallableStatement:

default void registerOutParameter(int parameterIndex, SQLType sqlType)
    throws SQLException {
    throw new SQLFeatureNotSupportedException("registerOutParameter not implemented");
}

Где throw — это строка 2613 в java.sql.CallableStatement, которая соответствует трассировке стека.

Как этот метод реализован в последней версии драйвера JDBC Microsoft SQL Server, либо вы используете более старую версию, либо объекты драйвера заключены в прокси-сервер, который не Поддерживает JDBC 4.2.

Я предлагаю вам перейти на последнюю версию драйвера, в настоящее время v6.1.0. Поскольку другой ваш вопрос предлагает вам использовать maven, то вы должны обеспечить новые координаты Maven для драйвера (они изменили его, когда открыли исходный код драйвера):

<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>mssql-jdbc</artifactId>
    <version>6.1.0.jre8</version>
</dependency>

Если проблема сохраняется, то, поскольку com.datalake.processors.SQLServerCDCProcessor — это ваш собственный код (как показано в вашем другом вопросе) , вы должны просто изменить его, чтобы он вызывал не registerOutParameter(int parameterIndex, SQLType sqlType), а более старый registerOutParameter(int parameterIndex, int sqlType).

person Mark Rotteveel    schedule 18.03.2017