3 Replies Latest reply on Aug 31, 2012 3:42 AM by bmajsak

    Will @CleanupUsingScript and @ApplyScriptXXX support multiline scripts?

    jfrenetic

      Recently I've bumped into issue related to running scripts with APE annotations @CleanupUsingScript and @ApplyScriptXXX (which are effectively synonyms).

       

      Suppose, I have the following script:

       

      cleanup.sql

      DELETE FROM PEOPLE
      DELETE FROM GROUPS
      

       

      Running this simple test on Glassfish 3.1.2 and Apache Derby DB:

       

      @Test
      @CleanupUsingScript(phase = TestExecutionPhase.AFTER, value="cleanup.sql")
      @UsingDataSet("init_people.xml")
      @DataSource("jdbc/MyPool")
      public void test() { }
      

       

      results in the following exception:

       

      org.jboss.arquillian.persistence.data.dbunit.exception.DBUnitConnectionException: Unable to close connection.
                at org.jboss.arquillian.persistence.data.dbunit.DBUnitPersistenceTestLifecycleHandler.closeConnection(DBUnitPersistenceTestLifecycleHandler.java:92)
      ...
      Caused by: org.jboss.arquillian.core.spi.InvocationException: org.jboss.arquillian.persistence.data.dbunit.exception.DBUnitDataSetHandlingException: Unable to execute script: DELETE FROM PEOPLE
      DELETE FROM GROUPS
      ...
      Caused by: org.jboss.arquillian.persistence.data.dbunit.exception.DBUnitDataSetHandlingException: Unable to execute script: DELETE FROM PEOPLE
      DELETE FROM GROUPS
                at org.jboss.arquillian.persistence.data.dbunit.DBUnitDataHandler.executeScript(DBUnitDataHandler.java:158)
                at org.jboss.arquillian.persistence.data.dbunit.DBUnitDataHandler.cleanupUsingScript(DBUnitDataHandler.java:131)
      ...
      Caused by: java.sql.SQLSyntaxErrorException: Syntax error: Encountered "DELETE" at line 2, column 1.
                at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
      ...
      at org.jboss.arquillian.persistence.data.dbunit.DBUnitDataHandler.executeScript(DBUnitDataHandler.java:154)
      ...
      Caused by: org.jboss.arquillian.test.spi.ArquillianProxyException: org.apache.derby.client.am.SqlException : Syntax error: Encountered "DELETE" at line 2, column 1. [Proxied because : Original exception not deserilizable, ClassNotFoundException]
      

       

      It's very obvious, because looking at the source of DBUnitDataHandler#executeScript you can see this:

       

      private void executeScript(String script) {
      
      Statement statement = null;
           try {
                statement = databaseConnection.get().getConnection().createStatement();
                statement.execute(script);
           }
      ...
      

       

      So, the entire contents of a script is treated as one String. Why?

      Can't something like ScriptRunner be used here?

       

      Personally, I had to tweak it this way for my project:

       

      for (String str : script.split("\r\n")) {
           statement.execute(str);
      }
      

       

      I know, this is not ideal, but it works for me. I see no reason in using scripts with just one statement.

       

      If you looked closer at the stack trace, you might have noticed another problem.

       

      Take a look at the source code of DBUnitPersistenceTestLifecycleHandler#closeConnection

       

       

      public void closeConnection(@Observes(precedence = 1000) EventContext<AfterPersistenceTest> context)
         {
            try
            {
               context.proceed();
               databaseConnectionProducer.get().getConnection().close();
            }
            catch (Exception e)
            {
               throw new DBUnitConnectionException("Unable to close connection.", e);
            }
         }
      

       

      Why is the connection closed inside try, not the finally block? Isn't it the potential source of resources leak?