2011-12-06 45 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