2011-12-06 54 views
7

TL; DR版本:我希望能够使用Maven Mojo SQL插件在数据库模式中创建/删除任何给定的表(或为这些表加载数据) mvn命令行。怎么样?使用Maven Mojo sql的错误:执行


我是一个长期的Java开发人员,但在大多数情况下,我一直生活在ant基于世界。我喜欢ant的力量和明确性,以及它为我提供的一切控制。但是,在我的新工作中,有一个推动使用maven。所以我决定使用我在家工作的一个项目来学习它。

我在不同的个人项目上设置的一项功能是能够在命令行上完全设置并从ant中拆除我的Postgres数据库。我可以单独或一致地对我喜欢的任何表格,序列和集成测试数据进行切片和切片。当然,这意味着我有一个gajillion ant目标,但它工作得很好。我喜欢这个;多年来它一直很好。

在研究如何在周末的Maven中完成这项工作时,我发现了Mojo SQL Maven Plugin。在查看了usage page(并且我使用这个术语松散地,因为它实际上只是一个没有解释的半实例)和example page之后,我能够对我的pom.xml文件进行一些更改。我在示例(postgressql)中修复了一些明显的拼写错误,并引用了PostgreSQL JDBC page以确保我的JDBC连接字符串正确。我会贴上所有的pom.xml(修改,以保护有罪)表示:

<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> 

现在,因为我还没有创建数据库时,它不会对PG命令行一个\l露面:

[[email protected] 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) 

因此,当我运行mvn sql:execute,我希望我的数据库,以获得创建......或者至少不要因为这将继续下去在错误的drop-db-before-test-if-any任务失败。但当然:

[[email protected] 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 

最后一行提到的错误页面没有帮助;它只是告诉我,一个插件导致了错误,而不是Maven本身。

所以让我们用-X开关运行它。我只是张贴错误的有趣的部分:

[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 

但是,但是,但是... <onError>continue</onError>

所以,问题:

  1. 我在做什么错?是我的期望,还是我的代码?
  2. 你会注意到我有一个create-person.sql文件。我从例子中知道,我可以在那里有多个文件,例如create-address.sql。但是在ant中,只要我执行蚂蚁任务时要记住参照完整性的顺序,我就能够独立于person表创建address表。是这样的可能与maven?如果是这样,怎么样?

对不起,详细的事先感谢您的帮助。

+0

我意识到这是一个古老的线程,但你可能会发现我开始写这个插件很有用:https://github.com/adrianboimvaser/postgresql-maven-plugin。它仍处于早期阶段,缺乏文档,但大多数都是有效的。我已经向Maven Central发布了0.1版本。干杯! – adrianboimvaser

回答

4

Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute (default-cli)

default-cli是当从命令行调用插件时的特殊executionId。见this

您已经将所有sql插件执行绑定到maven生命周期阶段,但是您试图直接调用插件。

mvn test应该工作。

Here是一个相关的SO讨论。

+0

那么这是非常不幸的,Maven不允许我像之前在Ant中那样行事,但是要感谢这些信息。 – Mike