testcontainers / testcontainers/testcontainers-java
Could not find a valid Docker environment when using Gradle Shared Build Service (`ClassNotFoundException` when loading strategies)
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Java
- Estrellas
- 8.7k
- Forks
- 1.9k
- Merge medio
- 2 d 17 h
- PR fusionados (30 d)
- 9
Descripción
Discussed in https://github.com/testcontainers/testcontainers-java/discussions/9034
Originally posted by debapgithub July 30, 2024
Hi,
I am new to testcontainers and setting up for a gradle service where I wanted to achieve the following in sequence.
When gradle build command will run : ./gradlew clean build
- MySql Testcontainer should start
- DB migrations should apply against the testcontainer DB
- generateJooq task should execute against the testcontainer DB
- Run the integration tests against testcontainer
- At the end of the build process, testcotnainer should stop automatically.
I have tried starting MySql testcontainer as a gradle task and I was able to execute the following tasks properly except one issue due to which I have decided to switch to another approach where I can start the MySql testcontainer as a gradle Shared service so that it will automaticllay manage the testcontainer lifecycle.
Here is the code which will start the testcontainer as a gradle shared service and it worked fine as well. But next day when I tried running the gradle command, I started getting the below error.
Error
* What went wrong:
Execution failed for task ':startMySQLContainer'.
> Failed to create service 'mysqlContainerService'.
> Could not create an instance of type MySQLContainerService.
> Could not find a valid Docker environment. Please see logs and check configuration
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
Gradle Code
import org.testcontainers.containers.MySQLContainer;
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
buildscript {
repositories {
maven {
name repoName
url repoUrl
credentials() {
username = repoUsername
password = repoPassword
}
}
}
dependencies {
classpath "org.testcontainers:testcontainers:${dependencyManagement.importedProperties['testcontainers.version']}"
classpath "org.testcontainers:mysql:${dependencyManagement.importedProperties['testcontainers.version']}"
classpath "com.mysql:mysql-connector-j:${dependencyManagement.importedProperties['mysql.version']}"
}
}
// Here we register service for providing our database during the build.
gradle.sharedServices.registerIfAbsent('mysqlContainerService', MySQLContainerService) { spec ->
spec.parameters.databaseSchemaName.set(project.ext.databaseSchemaName)
}
/**
* Build service for providing database container.
*/
abstract class MySQLContainerService implements BuildService<MySQLContainerService.Params>, AutoCloseable {
interface Params extends BuildServiceParameters {
Property<String> getDatabaseSchemaName()
}
private final MySQLContainer mysqlContainer;
@javax.inject.Inject
MySQLContainerService(Params params) {
// Services are initialized lazily, on first request to them, so we start container immediately.
long startTime = System.currentTimeMillis()
println("DB Schema Name: ${params.getDatabaseSchemaName().get()}")
mysqlContainer = new MySQLContainer(MySQLContainer.IMAGE).withDatabaseName(params.getDatabaseSchemaName().get())
mysqlContainer.start()
long duration = System.currentTimeMillis() - startTime
println("MySQL Testcontainer Started successfully with URL: ${mysqlContainer.getJdbcUrl()}. Total time taken: ${duration} ms")
}
String getJdbcUrl() {
return mysqlContainer.getJdbcUrl()
}
String getUsername() {
return mysqlContainer.getUsername()
}
String getPassword() {
return mysqlContainer.getPassword()
}
String getDriverClassName() {
return mysqlContainer.getDriverClassName()
}
@Override
void close() {
// Ensure to stop container in the end
if (mysqlContainer != null) {
try {
mysqlContainer.stop()
println("MySQL container stopped successfully.")
} catch (Exception e) {
println("Failed to stop MySQL container: ${e.message}")
}
} else {
println("MySQL container is already null (was not started).")
}
}
}
tasks.register('startMySQLContainer') {
doLast {
gradle.sharedServices.getRegistrations().getByName('mysqlContainerService')
}
}
// Ensure the integrationTest uses the same container and stops it after
tasks.named('integrationTest').configure {
dependsOn 'startMySQLContainer'
doFirst {
def service = gradle.sharedServices.getRegistrations().getByName('mysqlContainerService').service.get()
systemProperty 'spring.datasource.url', service.getJdbcUrl()
systemProperty 'spring.datasource.username', service.getUsername()
systemProperty 'spring.datasource.password', service.getPassword()
systemProperty 'spring.datasource.driver-class-name', service.getDriverClassName()
}
doLast {
systemProperties.remove('spring.datasource.url')
systemProperties.remove('spring.datasource.username')
systemProperties.remove('spring.datasource.password')
systemProperties.remove('spring.datasource.driver-class-name')
}
}
Not sure whats going wrong and how it worked first time when I did this code.
Thanks in advance!!
-Deba
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza con el Gradle buildscript y MySQLContainerService mostrados en el informe, luego reproduce :startMySQLContainer con --stacktrace e inspecciona la ClassNotFoundException y los logs de detección del entorno de Docker. Se considerará completado cuando se identifique por qué el classpath del servicio compartido o la carga de la estrategia difieren entre ejecuciones y se confirme una resolución documentada o probada para la secuencia de build indicada.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- docker, java, mysql
- Área
- build-system, databases, devops, testing
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Necesita aclaración
- Aptitud para principiantes
- 25/100