当前位置: 首页 > 知识库问答 >
问题:

Docker找不到合适的驱动程序sqlserver

苏健柏
2023-03-14

所以我有一个在我localhost的端口8080上运行的Spring Boot应用程序。它连接到Azure sqlserver数据库并从该数据库中提取或插入项目。本地一切正常。现在我正在尝试对应用程序进行文档化。我的Dockerfile如下所示:

FROM maven:3.5-jdk-8 AS build
COPY src /usr/src/app/src
COPY pom.xml /usr/src/app
COPY mssql-jdbc-9.2.1.jre15.jar .
RUN mvn -f /usr/src/app/pom.xml clean package

FROM gcr.io/distroless/java
COPY --from=build /usr/src/app/target/ProfileService-0.0.1-SNAPSHOT.jar /usr/app/ProfileService-0.0.1-SNAPSHOT.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/app/ProfileService-0.0.1-SNAPSHOT.jar"]

Dockerfile位于根文件夹中,与pom的文件夹相同。xml和mssql-jdbc-9.2.1。jre15.jar文件。此jar是从Microsoft官方来源下载的。我的pom包含多个依赖项,其中一个是mssql jdbc依赖项。

<dependency>

    <groupId>com.microsoft.sqlserver</groupId>

    <artifactId>mssql-jdbc</artifactId>

    <version>9.2.1.jre15</version>

</dependency>

要连接到数据库,我使用以下代码:

private final String connectionUrl = "jdbc:sqlserver://x.database.windows.net:1433;DatabaseName=profile;user=x@xr;password=x;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;";

以以下方法为例获取数据:

public GetProfileReturnModel getProfile(String profile_name) {
    GetProfileReturnModel returnModel = new GetProfileReturnModel();
    try (Connection connection = DriverManager.getConnection(connectionUrl)) {
        try {
            CallableStatement cstmnt = connection.prepareCall("{CALL getProfile(?)}");
            cstmnt.setString(1, profile_name);

            cstmnt.execute();
            ResultSet rs = cstmnt.getResultSet();
            if (rs.next()) {
                returnModel.setUser_id(rs.getInt("user_id"));
                returnModel.setBio(rs.getString("bio"));
                returnModel.setLocation(rs.getString("location"));
                returnModel.setProfile_name(rs.getString("profile_name"));
                returnModel.setPicture(rs.getString("picture"));
                returnModel.setWebsite(rs.getString("website"));
            }
            returnModel.setSuccess(true);
        } catch (SQLException e) {
            returnModel.setSuccess(false);
            returnModel.setErrorMessage(e.toString());
    }
    } catch (SQLException e) {
        returnModel.setErrorMessage(e.getMessage());
        returnModel.setSuccess(false);
    }
    return returnModel;
}

这在当地效果很好。但是,当我在Docker中运行构建映像并调用相同的请求时,我得到以下错误:

未找到适合jdbc的驱动程序:sqlserver://x.database.windows.net:1433;DatabaseName=配置文件;用户=x@xr;密码=x;加密=真;trustServerCertificate=false;主机名证书=*。数据库windows。网loginTimeout=30;

还有一个奇怪的行为,当我运行打包的。jar文件使用cmd运行得很好,但是如果我双击jar启动它,就会出现与上面提到的相同的错误

我完整的pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.kwetter.profileservice</groupId>
    <artifactId>ProfileService</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>ProfileService</name>
    <description>Demo project for Spring Boot</description>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <distributionManagement>
        <repository>
            <id>ProfileServiceBuild</id>
            <url>https://pkgs.dev.azure.com/382763/Kwetter/_packaging/ProfileServiceBuild/maven/v1</url>
        </repository>
    </distributionManagement>
    <repositories>
        <repository>
            <id>ProfileServiceBuild</id>
            <url>https://pkgs.dev.azure.com/382763/Kwetter/_packaging/ProfileServiceBuild/maven/v1</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.4.3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.amqp/spring-rabbit -->
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
            <version>2.3.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.amqp/spring-amqp -->
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-amqp</artifactId>
            <version>2.3.6</version>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>9.2.1.jre15</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.spec.javax.ws.rs</groupId>
            <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.11.3</version>
        </dependency>
    </dependencies>
</project>

共有3个答案

潘修为
2023-03-14

您似乎在构建映像中包含jdbc驱动程序,而不是在运行时映像中

您应该通过以下方式将其复制到运行时图像:(请检查相应的目标文件夹,但我假设是)

FROM gcr.io/distroless/java
COPY --from=build /usr/src/app/target/ProfileService-0.0.1-SNAPSHOT.jar /usr/app/ProfileService-0.0.1-SNAPSHOT.jar
COPY mssql-jdbc-9.2.1.jre15.jar /usr/app/
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/app/ProfileService-0.0.1-SNAPSHOT.jar"]
孟花蜂
2023-03-14

这可能是因为Azure SQL要求通过AD身份验证登录。您的连接字符串如下所示:

jdbc:sqlserver://x.database.windows.net:1433;DatabaseName=profile;user=x@xr;password=x;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword;
郎鸿雪
2023-03-14

默认情况下,在配置jar打包时,spring boot maven插件应该在mvn包运行时重新打包并将所有项目依赖项包含在一个大jar中,因此可能还应该包括SQL Server JDBC驱动程序相关的类。

与docker相关的问题可能与您在运行应用程序时为提供的SQL服务器驱动程序使用不兼容的Java版本这一事实有关。

您正在为Java15使用SQL服务器JDBC驱动程序:

<dependency>
  <groupId>com.microsoft.sqlserver</groupId>
  <artifactId>mssql-jdbc</artifactId>
  <version>9.2.1.jre15</version>
  <scope>compile</scope>
</dependency>

可能您正在本地环境中使用Java15,并且运行良好。

但您正在使用gcr运行应用程序。io/distroless/java,该映像只支持java 1.8和java 11。

请考虑使用不同版本的SQL Server驱动程序,例如:

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

并在必要时调整Dockerfile:

FROM maven:3.5-jdk-8 AS build
COPY src /usr/src/app/src
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml clean package

FROM gcr.io/distroless/java:8
COPY --from=build /usr/src/app/target/ProfileService-0.0.1-SNAPSHOT.jar /usr/app/ProfileService-0.0.1-SNAPSHOT.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/app/ProfileService-0.0.1-SNAPSHOT.jar"]

我删除了COPYmssql-jdbc-9.2.1.xxx.jar行。:如果您在pom中包含依赖项,则没有必要。

如果您使用的JVM版本与操作系统中默认配置的版本不同,那么双击问题也可能与此相关。

 类似资料:
  • 问题内容: 我希望有一个人可以帮助我。我正在研究一个与SQLite数据库连接的简单应用程序。以下是我的连接代码: 这只是一个在数据库中加载用户名和密码的窗口。我的问题是,当我单击按钮时,出现以下异常: (我找到了一个有关如何使用Java连接到SQLite数据库的示例,我发现该示例运行良好) 这个程序我正在窗口构建器(日食)中做。我使用的示例中使用的驱动程序相同。我不知道我是否必须使用其他驱动程序。

  • 问题内容: 这个问题已经在这里有了答案 : 臭名昭著的java.sql.SQLException:未找到合适的驱动程序 (13个答案) 4年前关闭。 我有一个Java类,该类通过在Tomcat上运行的JSP中使用的JDBC通过JDBC访问MySQL数据库,并且遇到“未找到驱动程序异常”的问题。 我有一个方法: 这会在“ 这是我从catalina.out的打印输出”上引发错误: 唯一重要的错误是一个

  • 我正在开发一个android应用程序,它从SQL Server导入lat/long以在地图中显示为标记。我已经输入了jtds-1.21。jar到lib的路径,但我得到了错误 这是我的代码图。Java语言

  • 我总是在数据库中发现“没有合适的驱动程序”,我无法确定connect类出了什么问题?有人帮忙吗?我已经把5个罐子都装进去了。我想连接到Microsoft Access数据库。

  • 连接到sqlite数据库时遇到问题。在我的Windows PC上,一切正常,但如果我想在Linux(Raspberry PI)上运行我的程序,我会得到错误,如标题所示。 这是我在Windows上的连接: 在为Linux导出程序之前,我更改了连接字符串: 如果没有数据库,我使用以下代码创建它: 这是我的构建路径 这是我的项目 谁能帮帮我吗?THX

  • 问题内容: 我正在尝试编写一个程序以在eclipse中连接到MySQL数据库,但出现错误 “ java.sql.SQLException:找不到合适的驱动程序” 。 Java代码是: } 控制台选项卡中的输出为: 我已经使用了MySQL Connector / J。将其解压缩到MySQL安装目录中,并将jar文件添加到CLASSPATH中。 另请参阅此图像。有一个 !在项目根目录上标记。image