无法在Spring Boot 2.3.3中构建图像。

huangapple go评论145阅读模式
英文:

Not able to build an image in Spring Boot 2.3.3

问题

我有一个相当基本的`Spring Boot`应用程序,它连接到一个经过docker化的`MySql`数据库并暴露了一个端点。

数据库已经通过网络进行了docker化。

docker run -d -v mysql-volume:/var/lib/mysql -p3306:3306 --network app-db-network --name mysql -e "MYSQL_ROOT_PASSWORD=root" mysql:latest

我想将该应用程序容器化,并与上述docker化的`MySql`数据库连接在一起,尽管指定了配置文件`tst`,但无法工作。当构建镜像时,我看到选择了`tst`配置文件,但它执行了测试,这就是它在连接到数据库时失败的地方。

只要跳过测试,镜像就会成功构建,然后从镜像中启动应用程序的新容器就可以成功连接到数据库。

**工作,镜像已构建,并在浏览器中运行容器会输出“Hello Tradestar”!!!**

./mvnw spring-boot:build-image -Dspring-boot.run.profiles=tst -DskipTests

docker run -d -p8080:8080 -e "SPRING_PROFILES_ACTIVE=tst" --network app-db-network --name tradestar tradestar:1.0.1-SNAPSHOT

**不起作用,出现以下错误!!!**

./mvnw spring-boot:build-image -Dspring-boot.run.profiles=tst

**错误日志:**

Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
...

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
...

**TradestarApplicationTests.java**

@SpringBootTest
class TradestarApplicationTests {
    @Test
    void contextLoads() {
    }
}

**application-tst.properties**

spring.datasource.url=jdbc:mysql://mysql:3306/tradestar?allowPublicKeyRetrieval=true&useSSL=false
spring.datasource.username=tradestar
spring.datasource.password=tradestar
...

**MyController.java**

@RestController
public class MyController {
    @GetMapping("/")
    public String greet() {
        return "Hello World!";
    }
}

**pom.xml**

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ...>
    ...
</project>
英文:

I have a pretty basic Spring Boot application that connects to a dockerized MySql DB and exposes just one endpoint.

DB is already dockerized and using a network.

docker run -d -v mysql-volume:/var/lib/mysql -p3306:3306 --network app-db-network --name mysql -e &quot;MYSQL_ROOT_PASSWORD=root&quot; mysql:latest

I would like to containerize the application and connect it with dockerized MySql DB above which is not working despite specifying profile tst. When the image gets built I see that the tst profile gets picked up but it executes tests and that's there it fails while connecting to DB.

As soon as I skip the tests the image gets built correctly and then spinning up a new container of the application from the image works and is able to connect to DB successfully.

WORKS AND THE IMAGE GETS BUILT AND RUNNING THE CONTAINER GIVES OUTPUT "Hello Tradestar" IN THE BROWSER !!!

./mvnw spring-boot:build-image -Dspring-boot.run.profiles=tst -DskipTests 

docker run -d -p8080:8080 -e &quot;SPRING_PROFILES_ACTIVE=tst&quot; --network app-db-network --name tradestar tradestar:1.0.1-SNAPSHOT

DOES NOT WORK, GIVES FOLLOWING ERROR !!!

./mvnw spring-boot:build-image -Dspring-boot.run.profiles=tst 

Error Log:

Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) ~[na:na]
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        at com.mysql.cj.NativeSession.connect(NativeSession.java:144) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        ... 137 common frames omitted
Caused by: java.net.UnknownHostException: mysql: Name or service not known
        at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) ~[na:na]
        at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:929) ~[na:na]
        at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1515) ~[na:na]
        at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:848) ~[na:na]
        at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1505) ~[na:na]
        at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1364) ~[na:na]
        at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1298) ~[na:na]
        at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:132) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65) ~[mysql-connector-java-8.0.21.jar:8.0.21]
        ... 140 common frames omitted

[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 7.381 s &lt;&lt;&lt; FAILURE! - in com.kanaarigroup.finance.tradestar.TradestarApplicationTests
[ERROR] contextLoads  Time elapsed: 0.009 s  &lt;&lt;&lt; ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
[INFO]
[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR]   TradestarApplicationTests.contextLoads &#187; IllegalState Failed to load Applicati...
[INFO]
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  11.066 s
[INFO] Finished at: 2020-10-12T23:21:01Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project tradestar: There are test failures.

TradestarApplicationTests.java

@SpringBootTest
class TradestarApplicationTests {

	@Test
	void contextLoads() {
	}

}

application-tst.properties

spring.datasource.url=jdbc:mysql://mysql:3306/tradestar?allowPublicKeyRetrieval=true&amp;useSSL=false
spring.datasource.username=tradestar
spring.datasource.password=tradestar
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery=SELECT 1
## Hibernate Properties
# Allows Hibernate to generate SQL optimized for a particular DBMS
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
# Show or not log for each sql query
spring.jpa.show-sql=true
# drop n create table, good for testing, comment this in production
spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=none
# Naming strategy
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
#control the initialization of datasource with available DDL and DML scripts
spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:sql/schema.sql
spring.datasource.data=classpath:sql/data.sql

MyController.java

@RestController
public class MyController {

    @GetMapping(&quot;/&quot;)
    public String greet() {
        return &quot;Hello World!&quot;;
    }

}

pom.xml

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
	&lt;parent&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
		&lt;version&gt;2.3.3.RELEASE&lt;/version&gt;
		&lt;relativePath /&gt; &lt;!-- lookup parent from repository --&gt;
	&lt;/parent&gt;
	&lt;groupId&gt;com.kanaarigroup.finance&lt;/groupId&gt;
	&lt;artifactId&gt;tradestar&lt;/artifactId&gt;
	&lt;version&gt;1.0.1-SNAPSHOT&lt;/version&gt;
	&lt;name&gt;tradestar&lt;/name&gt;
	&lt;description&gt;Demo project for Spring Boot&lt;/description&gt;

	&lt;properties&gt;
		&lt;java.version&gt;11&lt;/java.version&gt;
	&lt;/properties&gt;

	&lt;dependencies&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-starter-actuator&lt;/artifactId&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-starter-webflux&lt;/artifactId&gt;
		&lt;/dependency&gt;
		&lt;!-- DB --&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;mysql&lt;/groupId&gt;
			&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
			&lt;scope&gt;runtime&lt;/scope&gt;
		&lt;/dependency&gt;
    ...
&lt;/project&gt;		

答案1

得分: 2

如果您运行docker-compose并将mysql用作连接字符串,则它将正常工作。

但是您正在为每个容器使用docker run命令行,所以将mysql更改为:

172.17.0.1是容器网络的IP地址网关。

它是:jdbc:mysql://172.17.0.1:3306/

或者:运行docker inspect mysql_container_id以获取mysql容器的IP地址。

mysql更改为:jdbc:mysql://mysql容器的ip地址:3306/

英文:

If you run docker-compose and use mysql as connection string. it will work.

But you are using docker run command line for each container so change mysql to:

172.17.0.1 is an IP address gateway of container network.

it is : jdbc:mysql://172.17.0.1:3306/

OR: docker inspect mysql_container_id to get IP address of mysql container.

Change mysql to : jdbc:mysql://ip_address_of_mysql_container:3306/

huangapple
  • 本文由 发表于 2020年10月13日 09:24:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/64327220.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定