How can I configure my Maven pom.xml
and/or sql-maven-plugin
so that the unit test related DB executions I've specified in my dependency, lib.example.jdbc
, don't get executed when building the pom.xml
of my project com.example.project
? Currently when I run mvn clean install
on the pom.xml
for com.example.project
I find that my SQL database has tables that were created in lib.example.jdbc
. One obvious workaround is to use different properties for mysql.database
in each pom.xml
file but i feel the bigger problem is that the library's (dependency) db executions are being run in the test phase of the main project. I cant imagine this being correct since one can have hundreds of pom.xml
dependencies with their own tests and db executions that shouldn't be run when building the final project.
UPDATE: A Spring annotation was the culprit as discovered in my answer so I updated the question tags to reflect that.
Here is the relevant sample from the pom.xml
of lib.example.jdbc
:
...
<groupId>lib.example</groupId>
<artifactId>jdbc</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
...
<properties>
...
<mysql.port>3306</mysql.port>
<mysql.database>testDb</mysql.database>
<mysql.user>root</mysql.user>
<mysql.pass>password</mysql.pass>
</properties>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
</dependencies>
<configuration>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://${mysql.host}:${mysql.port}/${mysql.database}?useSSL=false</url>
<username>${mysql.user}</username>
<password>${mysql.pass}</password>
<settingsKey>sensibleKey</settingsKey>
<!--all executions are ignored if -Dmaven.test.skip=true-->
<skip>${maven.test.skip}</skip>
</configuration>
<executions>
<execution>
<id>create-db</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<url>jdbc:mysql://${mysql.host}:${mysql.port}?useSSL=false</url>
<autocommit>true</autocommit>
<sqlCommand>create database if not exists `${mysql.database}`</sqlCommand>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
And here is the relevant sample from the pom.xml
of com.example.project
:
<groupId>com.example</groupId>
<artifactId>project</artifactId>
<version>0.0.1</version>
...
<properties>
...
<mysql.port>3306</mysql.port>
<mysql.database>testDb</mysql.database>
<mysql.user>root</mysql.user>
<mysql.pass>password</mysql.pass>
</properties>
...
<dependencies>
...
<dependency>
<groupId>lib.example</groupId>
<artifactId>jdbc</artifactId>
<version>1.0.0</version>
</dependency>
...
</dependencies>
...
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
</dependencies>
<configuration>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://${mysql.host}:${mysql.port}?useSSL=false</url>
<username>${mysql.user}</username>
<password>${mysql.pass}</password>
<settingsKey>sensibleKey</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>
<url>jdbc:mysql://${mysql.host}:${mysql.port}?useSSL=false</url>
<autocommit>true</autocommit>
<sqlCommand>drop database if exists `${mysql.database}`</sqlCommand>
<sqlCommand>create database `${mysql.database}`</sqlCommand>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
After further investigation, it seems the problem is not with the sql-maven-plugin
but instead with the way a Spring annotation (@Sql) gets executed when running com.example.project
tests from a test scoped configuration in lib.example.jdbc
. Here is the class level annotation in lib.example.jdbc
that was causing problems for me. I moved the code from my schema.sql
and data.sql
into my pom.xml
<sqlCommand>
block and it was no longer executed when testing com.example.project
.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfig.class})
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = {"classpath:schema.sql","classpath:data.sql"})
public class DataDaoTest {
...
@Test
public void testRetrieval() throws Exception {
...
}
}