وقت القراءة: 15 minutes

هل سبق لك أن عشت تلك اللحظة عندما يكون الأمر بسيطًا`./gradlew build` الذي تشغّله مئة مرة في اليوم يتوقف فجأة عن العمل بسبب خطأ لم يُرَ من قبل ? اضربه بـ أحد عشر خطأً متتاليًا، أضف جرعة جيدة من عدم توافق Docker Engine 29، رشّ Gradle 9 الذي يزيل واجهات برمجة التطبيقات التي كنا نستخدمها منذ عشر سنوات. هنا السجل الكامل.


مخطط 1 — ترحيل Gradle 9 (سلسلة الأخطاء)

الهدف: إظهار سلسلة عدم التوافق.

👉 واضح، يركّز على Gradle.
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 4) ]

@startuml
left to right direction
title ترحيل Gradle 9
rectangle "1
^^^^^
 Syntax Error? (Assumed diagram type: class)

@startuml
left to right direction
title ترحيل Gradle 9
rectangle "1
reportsDir" as A
rectangle "2
الفئة الرئيسية" as B
rectangle "3
sourceCompatibility" as C
rectangle "4
Groovy تأكيد" as D

A --> B
B --> C
C --> D

@enduml

الرسم التوضيحي 2 — مكونات JHipster غير المتوافقة

الهدف: عزل المكونات الإضافية المعطوبة

👉 رؤية واضحة للاعتمادات
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 7) ]

@startuml
left to right direction
title الإضافات التي يجب تصحيحها
skinparam shadowing false
skinparam roundcorner 18

rectangle "1
^^^^^
 Syntax Error? (Assumed diagram type: class)

@startuml
left to right direction
title الإضافات التي يجب تصحيحها
skinparam shadowing false
skinparam roundcorner 18

rectangle "1
openApiGenerate" as A #FFF3E0
rectangle "2
gitProperties
2.5.7" as B #FFF3E0
rectangle "3
إصدارات
متيازات
مصححة" as C #E3F2FD
rectangle "4
تركيب OK" as D #E8F5E9

A --> B
B --> C
C --> D

@enduml

المخطط 3 — Docker 29 / Testcontainers

الهدف: مشكلة وقت التشغيل

👉 تاريخ واضح لوقت التشغيل.
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 9) ]

@startuml
left to right direction
title Docker 29 + Testcontainers

skinparam shadowing false
skinparam roundcorner 18
skinparam defaultFontSize 14

rectangle "1
^^^^^
 Syntax Error? (Assumed diagram type: class)

@startuml
left to right direction
title Docker 29 + Testcontainers

skinparam shadowing false
skinparam roundcorner 18
skinparam defaultFontSize 14

rectangle "1
التجميع OK" as A #E8F5E9
rectangle "2
اختبارات Cucumber FAIL" as B #FFEBEE
rectangle "3
Testcontainers 1.32
مرفوض" as C #FFF3E0
rectangle "4
ترقية
الإصدارات" as D #E3F2FD
rectangle "5
البناء النهائي OK" as E #E8F5E9

A --> B
B --> C
C --> D
D --> E

@enduml

طريقة أخرى لتمثيله لنفسه
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 17) ]

@startuml


skinparam backgroundColor #FEFEFE
skinparam shadowing false
skinparam defaultFontName Inter
skinparam defaultFontSize 14
skinparam ArrowThickness 2
skinparam RoundCorner 18

title خارطة طريق الاستقرار — Gradle 9 إلى بناء نهائي
left to right direction

rectangle "�⚙️ ترحيل Gradle 9" as A #E3F2FD
rectangle "�🧩 إضافات JHipster" as B #FFF3E0
rectangle "�🐳 Docker 29
^^^^^
 Syntax Error? (Assumed diagram type: component)

@startuml

!option handwritten true

skinparam backgroundColor #FEFEFE
skinparam shadowing false
skinparam defaultFontName Inter
skinparam defaultFontSize 14
skinparam ArrowThickness 2
skinparam RoundCorner 18

title خارطة طريق الاستقرار — Gradle 9 إلى بناء نهائي
left to right direction

rectangle "�⚙️ ترحيل Gradle 9" as A #E3F2FD
rectangle "�🧩 إضافات JHipster" as B #FFF3E0
rectangle "�🐳 Docker 29
Testcontainers" as C #FCE4EC
rectangle "�✅ بناء مستقر" as D #E8F5E9

note bottom of A
reportsDir
mainClass
sourceCompatibility
Groovy assert
end note

note bottom of B
openApiGenerate
gitProperties
versions alignées
end note

note bottom of C
tests Cucumber KO
image Docker rejetée
upgrade libs
end note

A -[#42A5F5]-> B : corrections build.gradle
B -[#FB8C00]-> C : assemble OK
C -[#E53935]-> D : tests réparés

@enduml

المشهد: مشروع JHipster، بناء لم يعد يتم تحميله

المشروع`edster`هو تطبيق JHipster تم إنشاؤه في 2024. نص البناء الجذري`build.gradle`ظل مستقرًا لمدة أشهر. ثم قررنا ترقية النسخة :

مكوّن

النسخة المستهدفة

Gradle

9.4.1

جافا

21.0.11-tem (Eclipse Temurin)

JHipster

8.x (الإطار`tech.jhipster:jhipster-framework:8.11.0`)

سبرينغ بوت

3.4.5

Kotlin

2.3.0

محرك دوكر

29.4.1 (API 1.54)

التغيير في نسخة Java يتم عبر SDKMAN :

sdk use java 21.0.11-tem

الإطلاق الأول :

$ ./gradlew build --no-daemon

FAILURE: Build failed with an exception.

* Where:
Build file '/home/.../edster/build.gradle' line: 18

* What went wrong:
An exception occurred applying plugin request [id: 'jhipster.cucumber-conventions']
> Failed to apply plugin 'jhipster.cucumber-conventions'.
   > Could not create task ':cucumberTest'.
      > Could not create task ':consoleLauncherTest'.
         > Could not set unknown property 'reportsDir' for task ':consoleLauncherTest'

لا نكاد ننتقل حتى من تحميل سكريبت البناء. المشكلة تكمن في`buildSrc/src/main/groovy/jhipster.cucumber-conventions.gradle`.

خطأ 1 : المتغير الوهمي `reportsDir

السكريبت`jhipster.cucumber-conventions.gradle`يحتوي :

tasks.register('consoleLauncherTest', JavaExec) {
    dependsOn(testClasses)
    String cucumberReportsDir = file("$buildDir/reports/tests")
    outputs.dir(reportsDir)           // <-- reportsDir n'existe PAS
    classpath = sourceSets["test"].runtimeClasspath
    main = "org.junit.platform.console.ConsoleLauncher"
    // ...
}

المتغير المحدد هو`cucumberReportsDir`. المستعملة هي`reportsDir`-- التي لا تُعرّف في أي مكان.

تصحيح:`outputs.dir(cucumberReportsDir)`

الخطأ 2 : main = "…​" لم يعد موجودًا تحت Gradle 9

إعادة تشغيل فورية :

Could not set unknown property 'main' for task ':consoleLauncherTest' of type org.gradle.api.tasks.JavaExec.

Gradle 9 يحذف الخاصية`main`لمصلحة`mainClass`على المهام`JavaExec`.

تصحيح:`mainClass = "org.junit.platform.console.ConsoleLauncher"`

خطأ 3 : sourceCompatibility لم يعد خاصية للمشروع

خطأ جديد :

Could not set unknown property 'sourceCompatibility' for root project 'edster' of type org.gradle.api.Project.

النص الجذري كان:

sourceCompatibility=17
targetCompatibility=17

Gradle 9 يحذف هذه الخصائص على مستوى الجذر. يجب أن تعيش داخل كتلة`java`.

تصحيح :

java {
    sourceCompatibility = JavaVersion.VERSION_21
    targetCompatibility = JavaVersion.VERSION_21
}

خطأ 4 : تأكيد Groovy بثلاث معاملات

البرنامج القديم كان يحتوي :

assert System.properties["java.specification.version"] == "17" || "21" || "24"

في جروفي,"21" et "24"`strings truthy. التعبير يحل إلى(…​ == "17") || true || true`, ما هو دائمًا صحيح — لكن الصياغة غير صالحة للمطالبة الصارمة المطلوبة.

تصحيح:

assert System.properties["java.specification.version"] in ["17", "21", "23", "24"]

خطأ 5 : الاعتماد الضمني compileKotlin → `openApiGenerate

البناء يتقدم. تم تجميع Kotlin بنجاح. ثم :

Task ':compileKotlin' uses this output of task ':openApiGenerate'
without declaring an explicit or implicit dependency.

Gradle 9 يرفض الاعتماديات الضمنية بين المهام. لأن`compileKotlin`يقرأ المصادر المولدة من`openApiGenerate`, يجب إعلان الرابط.

تصحيحفي`build.gradle`[Nothing]

afterEvaluate {
    tasks.named("compileKotlin").configure {
        dependsOn(tasks.named("openApiGenerate"))
    }
}

Le `afterEvaluate`ضروري لأن`openApiGenerate`هي إضافة (مكوّن OpenAPI Generator) وليس مهمة يمكن الوصول إليها مباشرة خلال مرحلة الإعداد.

خطأ 6 : generateGitProperties ينكسر على `FilterOutputStream.write()

تنجح ترجمة Java. تم معالجة الموارد. ثم:

> Task :generateGitProperties FAILED

No signature of method: java.io.FilterOutputStream.write() is applicable for argument types: (Integer) values: [103]

الإضافة`gradle-git-properties`version 2.5.0 غير متوافق مع Java 21 / Gradle 9. عطل داخلي يحاول استدعاء`write(int)`باستخدام Groovy على تدفق الذي أغلقه

تصحيحفي`gradle.properties`:

gitPropertiesPluginVersion=2.5.7

أخيرًا: يدخل Testcontainers إلى المشهد

حتى الآن، كان مجرد "build script debugging" صرفًا. كل خطأ كان عدم توافق Gradle 9 أو Java 21 في سكريبتات البناء. بعد الست تصحيحات أعلاه،`./gradlew assemble`ينجح بنجاح.

لكن`./gradlew build`ينفذ أيضًا الاختبارات، وتستخدم اختبارات Cucumber Testcontainers لتشغيل PostgreSQL مؤقت.

Could not find a valid Docker environment.

EnvironmentAndSystemPropertyClientProviderStrategy: failed with exception BadRequestException
(Status 400: {"message":"client version 1.32 is too old. Minimum supported API version is 1.40"}
UnixSocketClientProviderStrategy: failed with exception BadRequestException
(Status 400: {"message":"client version 1.32 is too old. Minimum supported API version is 1.40"}

Testcontainers غير قادر على التواصل مع Docker. استراتيجيتين مختلفتين (متغيرات البيئة + مقبس يونكس) تفشلان على نفس الخطأ.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 5) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false

actor "Testcontainers
^^^^^
 Syntax Error? (Assumed diagram type: sequence)

@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false

actor "Testcontainers
1.20.6" as TC
participant "docker-java
3.4.1" as DJ
participant "Docker Engine\n29.4.1" as DE

TC -> DJ : new DockerClient()
DJ -> DE : GET /_ping\nUser-Agent: docker-java/3.4.1\nAPI-Version: 1.32
DE --> DJ : HTTP 400 Bad Request\nclient version 1.32 is too old.\nMinimum supported API version is 1.40
DJ --> TC : BadRequestException
TC --> TC : Could not find a valid\nDocker environment

note right of DE
  Docker Engine 29.x impose
  API minimum = 1.40
  (défaut ancien : 1.24)
end note

note left of DJ
  docker-java 3.4.1 envoie
  hardcoded API version 1.32
  dans l'en-tête HTTP
end note

@enduml

المرحلة 1 : مسار docker-java

أول رد فعل: عميل Docker Java المستخدم من قبل Testcontainers يرسل نسخة API`1.32`في Handshake HTTP الخاص به، لكن Docker Engine 29.4.1 يتطلب أدنى ما هو`1.40`. المشكلة على مستوى العميل، وليس على مستوى الديمون.

التحقق من إصدار docker-java الذي حله Testcontainers 1.20.6 :

$ ./gradlew dependencies --configuration testRuntimeClasspath | grep docker-java

+--- com.github.docker-java:docker-java-api:3.4.1
+--- com.github.docker-java:docker-java-transport:3.4.1

docker-java 3.4.1، يعود إلى Testcontainers 1.20.6. أحدث نسخة عامة من docker-java هي 3.5.1. نحاول إجبار ترقية الإصدار عبر`resolutionStrategy`في الكتلة`configurations` de build.gradle:

configurations {
    all {
        resolutionStrategy.eachDependency { details ->
            if (details.requested.group == "com.github.docker-java"
                && details.requested.name.startsWith("docker-java")) {
                details.useVersion("3.5.1")
            }
        }
    }
}

إعادة تشغيل البناء. نفس الخطأ :`client version 1.32 is too old`.

التحقق من ذاكرة التخزين المؤقت Gradle: تم إعادة تنزيل ملفات JAR بنجاح، لكن الخطأ لا يزال مستمرًا. docker-java 3.5.1 يرسل دائمًا`1.32`. هذه النسخة ليست كافية لمحرك Docker 29.4.1.

عملية تنقية: مسح ذاكرة التخزين المؤقت لـ Gradle بالكامل، فقط للتأكد :

rm -rf ~/.gradle/caches
rm -rf /path/to/project/.gradle

إعادة التشغيل الكاملة بعد الحذف. نفس الخطأ.

المرحلة 2 : البحث على الويب وخيط أريادن جيتهاب

docker-java 3.5.1 غير كافٍ. لم يبقَ إلا البحث عما إذا كان شخص ما قد واجه نفس المشكلة بالضبط.

بحث مستهدف على القضايا testcontainers-java و docker-java:

site:github.com/testcontainers "client version 1.32 is too old"
site:github.com/docker-java "client version 1.32" Docker Engine 29

النتائج الفورية الأولى :

مسار التنقل واضح: محرك Docker 29.x رفع الحد الأدنى لإصدار الـ API له من`1.24`(عطل قديم) إلى`1.40`. Testcontainers 1.20.x يستخدم docker-java 3.4.x الذي يتفاوض على إصدار واجهة برمجة التطبيقات عبر الإرسال`1.32`. الديamon يرفض بلطف لكنه حازم.

فيissue #11491، يرد أحد المُحافظين :

(nothing) مرحبًا، لدي مشروع يعمل بالإصدار 2.0.3 على جهاز تشغيل GH مع المحرك 29.1 وهو يعمل. هل يمكنكم جميعًا من فضلكم التحقق من عدم وجود صراع بين الإصدارات؟ من فضلك، تذكر أن جميع الوحدات كانت مسبوقة بـ`testcontainers-. لذلك، بدءًا من الإصدار 2.x، انتقلنا من`postgresql to testcontainers-postgresql __

هذه الإجابة تحتويمعلومتان حاسمتان:

  1. Testcontainers 2.0.3+ يحل المشكلة

  2. تمالمُسمّون بالبادئة `testcontainers-

المرحلة 3 : فخ القطع الأثرية المعاد تسميتها

إعادة التسمية قاسية. في Testcontainers 2.x، لا يعمل أي من الأسماء القديمة تحت هذا الاسم:

الاسم القديم(1.x)

اسم جديد (2.x)

org.testcontainers:postgresql

org.testcontainers:testcontainers-postgresql

org.testcontainers:jdbc

org.testcontainers:testcontainers-jdbc

org.testcontainers:junit-jupiter

org.testcontainers:testcontainers-junit-jupiter

org.testcontainers:testcontainers

غير متغير

المحاولة الأولى : تطبيق BOM Testcontainers 2.0.5 وأسماء artifacts الجديدة في`build.gradle`.

dependencies {
    testImplementation platform("org.testcontainers:testcontainers-bom:2.0.5")
    testImplementation "org.testcontainers:testcontainers-postgresql"
    testImplementation "org.testcontainers:testcontainers-jdbc"
    testImplementation "org.testcontainers:testcontainers-junit-jupiter"
    testImplementation "org.testcontainers:testcontainers"
}

./gradlew build

FAILURE: Could not find org.testcontainers:jdbc:2.0.5.
Could not find org.testcontainers:junit-jupiter:2.0.5.

لا يكفي BOM testcontainers-bomلماذا؟ لأن Spring Boot 3.4.5 يعرض BOM الخاص به لإدارة الاعتماديات (spring-boot-dependencies) الذياكسبعلى BOM الخاص بـ Testcontainers في الحل العابر. Spring Boot يحدّد`testcontainers` à 1.20.6، وبالتالي فإن جميع العناصر التي ليست صريحةً في BOM Spring Boot (مثل الجدد`testcontainers-*) يحلون نحو الأسماء القديمة`1.20.6-- لم تعد موجودة في هذا الإصدار.

En inspectant le dependencies --configuration testRuntimeClasspath, najd :

+--- org.testcontainers:testcontainers -> 1.20.6 (*)
|    \--- org.testcontainers:testcontainers:2.0.5 -> 1.20.6

Le →`يشير إلى الاستبدال : Testcontainers 2.0.5 هو مطلوب، لكن Spring Boot يفرض`1.20.6.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 8) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
skinparam componentStyle rectangle

left to right direction

component "build.gradle
^^^^^
 Syntax Error? (Assumed diagram type: class)

@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
skinparam componentStyle rectangle

left to right direction

component "build.gradle
(المستهلك)" as BG #E3F2FD {
    rectangle "طلب
`testcontainers-bom:2.0.5" as REQ
    rectangle "طلب
`testcontainers-postgresql" as REQ2
}

component "Maven Central" as MC #FFF3E0

component "التصريحات" as DEC #E8F5E9 {
    rectangle "testcontainers-bom:2.0.5`
يثبت 2.0.5" as BOM2
    rectangle "spring-boot-dependencies:3.4.5`
يحدد 1.20.6" as BOM1
}

component "حل Gradle" as RES #FFEBEE {
    rectangle "النسخة الفائزة
`testcontainers:1.20.6" as WIN #EF9A9A
}

BG --> DEC : "حلّل BOMs"
BOM2 --> RES : "يقترح 2.0.5"
BOM1 --> RES : "يقترح 1.20.6"
WIN -> MC : "تحميل
testcontainers:1.20.6"

note bottom of WIN
  Spring Boot BOM prime car
  le plugin spring-boot applique
  ses dépendances de gestion
  après la résolution du consommateur
end note

@enduml

المرحلة 4: إجبار الدقة

تصبح الاستراتيجية مزدوجة:

  1. إجبار docker-java على استخدام الإصدار 3.7.1 (المختبر كمتوافق مع Docker Engine 29)

  2. إجبار Testcontainers core على الإصدار 2.0.5 عبر تجاوز BOM الخاص بـ Spring Boot

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 8) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
skinparam componentStyle rectangle

left to right direction

component "build.gradle
^^^^^
 Syntax Error? (Assumed diagram type: class)

@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
skinparam componentStyle rectangle

left to right direction

component "build.gradle
(مع resolutionStrategy)" as BG #E8F5E9 {
    rectangle "BOM Testcontainers
`2.0.5" as BOM2
    rectangle "resolutionStrategy\n.eachDependency" as RS #66BB6A
}

component "تم حل النزاع" as RESOLVED #E3F2FD {
    rectangle "docker-java
`3.7.1` (مُفرض)" as DJ
    rectangle "testcontainers\n`2.0.5` (مجبر)" as TC #81C784
    rectangle "testcontainers-postgresql
`2.0.5" as TPG
    rectangle "testcontainers-jdbc
`2.0.5" as TJ
    rectangle "testcontainers-junit-jupiter
`2.0.5" as TJJ
}

component "بوم سبرينغ بوت
(ضمني، تم التجاوز)" as BOM1 #FFEBEE

component "المستودع المركزي لـ Maven" as MC #FFF3E0

BG --> RESOLVED : "BOM Testcontainers 2.0.5
تمر مباشرة"
RS -> DJ : "قوة 3.7.1"
RS -> TC : "قوة 2.0.5"
RESOLVED --> MC : "حمل ملفات JAR
المتوافقة مع Docker 29"
BOM1 -[#gray,dashed]-> RESOLVED : "تم تجاهله على testcontainers\nو docker-java"

note bottom of RS
  Le `eachDependency` intercepte
  la résolution Gradle AVANT
  que le BOM Spring Boot ne gagne.
  C'est une intervention chirurgicale.
end note

@enduml

التصحيح النهائيفي`build.gradle` :

configurations {
    all {
        resolutionStrategy.eachDependency { details ->
            if (details.requested.group == "com.github.docker-java"
                && details.requested.name.startsWith("docker-java")) {
                details.useVersion("3.7.1")
            }
            if (details.requested.group == "org.testcontainers"
                && details.requested.name == "testcontainers") {
                details.useVersion("2.0.5")
            }
        }
    }
}

dependencies {
    testImplementation platform("org.testcontainers:testcontainers-bom:2.0.5")
    testImplementation "org.testcontainers:testcontainers-jdbc"
    testImplementation "org.testcontainers:testcontainers-junit-jupiter"
    testImplementation "org.testcontainers:testcontainers-postgresql"
    testImplementation "org.testcontainers:testcontainers"
    // ... autres dépendances Spring Boot
}

Le `resolutionStrategy.eachDependency`الطريقة الوحيدة لتجاوز BOM`spring-boot-dependencies`تم إدارته بواسطة إضافة Spring Boot. اختبار المساواة على`details.requested.name == "testcontainers"`هو متعمد أن يكون مقيدًا: نحن نُجبر فقط الوحدة الأساسية. الوحدات`testcontainers-*`يتبعون BOM من Testcontainers 2.0.5 الذي أعلنا صراحةً.

النتيجة النهائية

$ ./gradlew build --no-daemon

> Task :consoleLauncherTest
[2 containers found]
[2 containers started]
[2 containers successful]

BUILD SUCCESSFUL in 1m 16s

Testcontainers 2.0.5 + docker-java 3.7.1 تنجحان أخيرًا في إنشاء حاويات PostgreSQL الخاصة بهما عبر Docker Engine 29.4.1. الخطأ الوظيفي النهائي (HTTP 500 في اختبار Cucumber) هو مشكلة تطبيقية totally مستقل عن سكريبت البناء.

جدول ملخص التصحيحات

(empty) ملف مشكلة تصحيح

1

buildSrc/src/main/groovy/jhipster.cucumber-conventions.gradle

متغير`reportsDir`غير موجودة

outputs.dir(cucumberReportsDir)

2

buildSrc/src/main/groovy/jhipster.cucumber-conventions.gradle

`main`Gradle 9 معطل

mainClass

3

build.gradle

`sourceCompatibility`مستوى أعلى ممنوع Gradle 9

كتلة`java { sourceCompatibility = JavaVersion.VERSION_21 }`

4

build.gradle

إدعاء Groovy غير صالح من حيث بناء الجملة

assert …​ in ["17", "21", "23", "24"]

5

build.gradle

الاعتماد الضمني`compileKotlin` → openApiGenerate

afterEvaluate { tasks.named("compileKotlin").dependsOn("openApiGenerate") }

6

gradle.properties

`gitPropertiesPluginVersion`غير متوافق مع Java 21

2.5.7

7

ذاكرة التخزين المؤقت Gradle

docker-java 3.5.1 تم اختباره، تم حلّه لكنه غير كافٍ

تنظيف + مرحلة docker-java 3.7.1

8

build.gradle

Testcontainers 1.20.6 غير متوافق مع محرك دوكير 29

إجبار Testcontainers 2.0.5 + البادئة`testcontainers-*`+ resolutionStrategy مقابل Spring Boot BOM

خاتمة

إذا فشل البناء JHipster/Gradle بعد ترقية الإصدار إلى Gradle 9 + Docker Engine 29، فإن الأخطاء تنقسم إلى فئتين:

أخطاء سكريبت البناء(الست الأولى) : Gradle 9 يزيل خصائصًا وصيغًا كانت تعمل لسنوات (sourceCompatibility=, main =, reportsDir). إنها هجرات ميكانيكية بمجرد أن تعرف واجهة برمجة التطبيقات الجديدة.

أخطاء وقت تشغيل Docker(الأخيران) : محرك Docker 29.4.1 يستبعد عملاء API أقل من 1.40. Testcontainers 1.20.6 (مفروض من قبل Spring Boot 3.4.5) يستخدم docker-java 3.4.1 الذي يرسل 1.32. فقط Testcontainers 2.0.5 + docker-java 3.7.1 يحلّ المشكلة، مع إعادة تسمية القطع الفنية وفرض النسخة عبر`resolutionStrategy.eachDependency`كطريقة وحيدة لتجاوز BOM الضمني لـ Spring Boot.

البرنامج النصي لبناء Gradle في جذر المشروع أصبح نظيفًا الآن.`./gradlew build`يمر على Java 21، Gradle 9.4.1، Spring Boot 3.4.5 ومحرك Docker 29.4.1.

Articles connexes