Развертывание функции Azure в коде Visual Studio не включает файл .jar - PullRequest
0 голосов
/ 23 апреля 2020

Azure Функция, которую я создаю, должна иметь возможность выполнять процедуру в Azure SQL Серверной базе данных.

У меня есть рабочий код Java в Eclipse (основанный на @ Ответ Даффмо в Java Соединение с БД )

Затем я перенес код в функцию Azure в Visual Studio Code для развертывания в Azure. (Обратите внимание, что я удалил код безопасности et c.) Я создал проект, используя View/Command Palette/Azure Functions - Create New Project

package com.function;

import java.sql.*;
import java.util.*;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;

/**
 * Azure Functions with HTTP Trigger.
 */
public class Function {
    /**
     * This function listens at endpoint "/api/HttpTrigger-Java". Two ways to invoke
     * it using "curl" command in bash: 1. curl -d "HTTP Body" {your
     * host}/api/HttpTrigger-Java&code={your function key} 2. curl "{your
     * host}/api/HttpTrigger-Java?name=HTTP%20Query&code={your function key}"
     * Function Key is not needed when running locally, it is used to invoke
     * function deployed to Azure. More details:
     * https://aka.ms/functions_authorization_keys
     */
    private static final String DEFAULT_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    private static final String DEFAULT_URL = "jdbc:sqlserver://myserver.database.windows.net:1433;database=mydb;loginTimeout=10;user=myuser@myserver;password=mypassword;";


    @FunctionName("HttpTrigger-Java")
    public HttpResponseMessage run(@HttpTrigger(name = "req", methods = { HttpMethod.GET,
            HttpMethod.POST }, authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {

        Connection connection = null;
        try {

            connection = createConnection(DEFAULT_DRIVER, DEFAULT_URL,context);
            connection.setAutoCommit(false);
            String sqlUpdate = "{call MYDB.MYPROC(?,?}";
            List<Object> parameters = Arrays.asList("Bar", "Foo");
            execute(connection, sqlUpdate, parameters);
            connection.commit();

        } catch (Exception e) {
            rollback(connection);
            e.printStackTrace();
        } finally {
            close(connection);
        }
        return null;
    }

    public static Connection createConnection(String driver, String url, ExecutionContext context) throws ClassNotFoundException, SQLException {
        Class.forName(driver);
        return DriverManager.getConnection(url);
    }

    public static void close(Connection connection) {
        try {
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(Statement st) {
        try {
            if (st != null) {
                st.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void rollback(Connection connection) {
        try {
            if (connection != null) {
                connection.rollback();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static double execute(Connection connection, String sql, List<Object> parameters) throws SQLException {
        CallableStatement call = connection.prepareCall(sql);
        try {
            int i = 0;
            for (Object parameter : parameters) {
                call.setObject(++i, parameter);
            }
            call.executeUpdate();

        } finally {
            close(call);
        }
        return 0;
    }
}

Однако строка

 Class.forName(driver);

вызывает следующую ошибку

java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at java.base/java.lang.Class.forName0(Native Method)

Я попытался решить эту проблему с помощью

  1. Поместив sqljdbc4.jar в каталог "lib"
  2. Вручную добавив следующее в pom. xml

    <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>sqljdbc4</artifactId> <version>4.0</version> </dependency>

  3. Попытка установить банку с терминала через

    mvn install:install-file -Dfile=’C:=myPath\myFunction\lib\sqljdbc4.jar' -DgroupId=package -DartifactId=sqljdbc4 -Dversion='4.0' -Dpackaging=jar

  4. экспериментировал с изменением порядка 'microsoft' и 'sqlserver' в строке DEFAULT_DRIVER.

  5. Попробуйте добавить SQLJDB C из нового Java Представления зависимостей (см. Ответ @hemangs) - но он не появляется в списке

  6. Я отредактировал .classPath согласно ответу @ asndr в .classpath - обратите внимание, что мне не удалось получить доступ к .classPath из кода VS, а скорее через Проводник - и затем побежал view/Command Palette/Java: Clean the java language server workspace

Есть идеи?

1 Ответ

0 голосов
/ 23 апреля 2020

На основании ответа @ nirmal в Отсутствует артефакт com.microsoft.sqlserver: sqljdbc4: jar: 4.0 Я сделал следующее:

  1. Explorer / Java Зависимости / Maven Зависимости - затем нажали '+'
  2. Набрано mssql-jdbc и нажала Enter
  3. Выбрано mssql-jdbc с com.microsoft.sqlserver
  4. Это открыло pom. xml в коде VS со следующим добавленным

    <dependency>

      <groupId>com.microsoft.sqlserver</groupId>
      <artifactId>mssql-jdbc</artifactId>
      <version>8.3.0.jre14-preview</version>
    </dependency>
    
  5. Я изменил номер версии на 6.1.0.jre8 (более высокая версия вызвала ошибки компиляции)

  6. Сохранено
  7. VS Код спросил меня, хочу ли я 'Файл сборки был изменен. Вы хотите синхронизировать Java classpath / configuration? '
  8. Я сказал «да», и затем это сработало.

Что кажется важным, так это редактировать pom. xml из кодекса VS. Кажется, что когда я редактировал его вне VS Code, VS Code не запускал синхронизацию конфигурации.

...