Erreurs lors de l'utilisation de Maven Mojo sql: exécuter
-
28-10-2019 - |
Question
Version TL; DR: Je veux pouvoir utiliser le plugin Maven Mojo SQL pour créer / supprimer n'importe quelle table donnée dans mon schéma DB (ou charger des données pour ces tables) à volonté via la ligne de commande mvn
. Comment?
Je suis un développeur Java de longue date, mais pour la plupart, j'ai vécu dans un monde basé sur des codes génériques. J'aime la puissance et l'explicitation du ant
, et le contrôle qu'il me donne sur tout. Cependant, dans mon nouveau travail, il y a une poussée pour utiliser ant
. J'ai donc décidé de l'apprendre en utilisant un projet sur lequel je travaille chez moi.
Une des choses que j'ai configurées sur un projet personnel différent est la possibilité de configurer et de détruire complètement ma base de données Postgres à partir de maven
sur la ligne de commande. Je peux découper en dés toutes les données de test de table, de séquence et d'intégration que je veux, individuellement ou de concert. Bien sûr, cela signifie que j'ai environ un gajillion de cibles ant
, mais cela fonctionne très bien. J'aime ça; cela m'a très bien servi au fil des ans.
En recherchant comment accomplir cela dans Maven ce week-end, j'ai trouvé le Plugin Mojo SQL Maven . Après avoir consulté la page d'utilisation (et j'utilise ce terme de manière vague, car il ne s'agit en réalité que d'un seul semi-exemple sans explications) et la page d'exemples , j'ai pu apporter des modifications à mon fichier ant
. J'ai corrigé des fautes de frappe évidentes dans l'exemple (postgressql) et référencé la page JDBC PostgreSQL pour m'assurer que la chaîne de connexion JDBC est correcte. Je vais coller tout le pom.xml
(modifié pour protéger les coupables) ci-dessous:
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.myapp</groupId>
<artifactId>myapp</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>myapp</name>
<url>http://maven.apache.org</url>
<repositories>
<repository>
<id>JBoss</id>
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.0.0.CR7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.3-606.jdbc4</version>
</dependency>
</dependencies>
<configuration>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://localhost:5432/myapp</url>
<settingsKey>myapp</settingsKey>
<!--all executions are ignored if -Dmaven.test.skip=true-->
<skip>${maven.test.skip}</skip>
</configuration>
<executions>
<execution>
<id>drop-db-before-test-if-any</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<!-- need another database to drop the targeted one -->
<url>jdbc:postgresql://localhost:5432/template1</url>
<autocommit>true</autocommit>
<sqlCommand>drop database myapp</sqlCommand>
<!-- ignore error when database is not avaiable -->
<onError>continue</onError>
</configuration>
</execution>
<execution>
<id>create-db</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<url>jdbc:postgresql://localhost:5432/template1</url>
<!-- no transaction -->
<autocommit>true</autocommit>
<sqlCommand>create database myapp</sqlCommand>
</configuration>
</execution>
<execution>
<id>create-schema</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<autocommit>true</autocommit>
<srcFiles>
<srcFile>src/main/sql/create_person.sql</srcFile>
</srcFiles>
</configuration>
</execution>
<execution>
<id>create-data</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<orderFile>ascending</orderFile>
<fileset>
<basedir>${basedir}</basedir>
<includes>
<include>src/test/sql/person_data.sql</include>
</includes>
</fileset>
</configuration>
</execution>
<!-- drop db after test -->
<execution>
<id>drop-db-after-test</id>
<phase>test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<url>jdbc:postgresql://localhost:5432/template1</url>
<autocommit>true</autocommit>
<sqlCommand>drop database myapp</sqlCommand>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Maintenant, comme je n'ai pas créé la base de données, elle n'apparaît pas dans un pom.xml
sur la ligne de commande PG:
[mike@mike myapp]$ psql template1
Welcome to psql 8.3.5, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
template1=# \l
List of databases
Name | Owner | Encoding
-----------+----------+----------
postgres | postgres | UTF8
template0 | postgres | UTF8
template1 | postgres | UTF8
(3 rows)
Ainsi, lorsque j'exécute \l
, je m'attends à ce que ma base de données soit créée ... Ou du moins ne pas échouer sur la tâche mvn sql:execute
puisque cela est configuré pour continuer en cas d'erreur. Mais bien sûr:
[mike@mike myapp]$ mvn sql:execute
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building myapp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- sql-maven-plugin:1.5:execute (default-cli) @ myapp ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.667s
[INFO] Finished at: Mon Dec 05 20:22:17 CST 2011
[INFO] Final Memory: 3M/81M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute (default-cli) on project myapp: FATAL: database "myapp" does not exist -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
La page d'erreur mentionnée sur la dernière ligne n'est pas utile; il me dit simplement qu'un plugin a causé l'erreur, pas Maven lui-même.
Alors, exécutons-le avec le commutateur drop-db-before-test-if-any
. Je vais juste poster la partie intéressante de l'erreur:
[ERROR] Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute (default-cli) on project myapp: FATAL: database "myapp" does not exist -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute (default-cli) on project myapp: FATAL: database "myapp" does not exist
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoExecutionException: FATAL: database "myapp" does not exist
at org.codehaus.mojo.sql.SqlExecMojo.execute(SqlExecMojo.java:618)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
... 19 more
Caused by: org.postgresql.util.PSQLException: FATAL: database "myapp" does not exist
at org.postgresql.core.v3.ConnectionFactoryImpl.readStartupMessages(ConnectionFactoryImpl.java:444)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:99)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:124)
at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:30)
at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:29)
at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24)
at org.postgresql.Driver.makeConnection(Driver.java:386)
at org.postgresql.Driver.connect(Driver.java:260)
at org.codehaus.mojo.sql.SqlExecMojo.getConnection(SqlExecMojo.java:899)
at org.codehaus.mojo.sql.SqlExecMojo.execute(SqlExecMojo.java:612)
... 21 more
Mais, mais, mais ... -X
!
Alors, aux questions:
- Qu'est-ce que je fais de mal? Est-ce mes attentes ou mon code?
- Vous remarquerez que j'ai un fichier
<onError>continue</onError>
. Je sais d'après les exemples que je peux y avoir plusieurs fichiers, tels quecreate-person.sql
. Mais danscreate-address.sql
, j'ai la possibilité de créer la tableant
séparément de la tableaddress
, tant que j'effectue les tâches de fourmi en gardant à l'esprit l'ordre d'intégrité référentielle. Est-ce que quelque chose comme ça est possible avecperson
? Si oui, comment?
Désolé pour la verbosité, et merci d'avance pour toute aide.
La solution
Échec de l'exécution de l'objectif org.codehaus.mojo: sql-maven-plugin: 1.5: exécution (default-cli)
default-cli
est le executionId
spécial lorsque le plugin est appelé à partir de la ligne de commande.Voir ceci .
Vous avez lié toute l'exécution du plugin sql aux phases du cycle de vie maven, mais vous essayez d'appeler le plugin directement.
mvn test
devrait fonctionner.
Voici une discussion SO connexe.