flyway - why can't switch to a newly created schema? - spring

I'm having a go with flyway and it looks promising. So, on the root project's pom.xml file, I have this:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway.version}</version>
<configuration>
<driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver>
<url>jdbc:sqlserver://localhost</url>
<user>sa</user>
<password>dbPassword/</password>
<schemas>
<schema>schemaA</schema>
<schema>schemaB</schema>
</schemas>
</configuration>
<dependencies>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>${mssql.version}</version>
</dependency>
</dependencies>
</plugin>
On projectA's and projectB's pom.xml, I have this:
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>${flyway.version}</version>
</dependency>
Also, on each project's application.properties there is the following:
#flyway
flyway.baseline-description= #
flyway.baseline-version=1 # version to start migration
flyway.baseline-on-migrate= #
flyway.check-location=false # Check that migration scripts location exists.
flyway.clean-on-validation-error= #
flyway.enabled=true # Enable flyway.
#flyway.encoding= #
#flyway.ignore-failed-future-migration= #
#flyway.init-sqls= # SQL statements to execute to initialize a connection immediately after obtaining it.
flyway.locations=classpath:db/migration
#flyway.out-of-order= #
#flyway.placeholder-prefix= #
#flyway.placeholder-replacement= #
#flyway.placeholder-suffix= #
#flyway.placeholders.*= #
flyway.schemas=schemaX
#flyway.sql-migration-prefix=V #
#flyway.sql-migration-separator= #
#flyway.sql-migration-suffix=.sql #
flyway.table= #
flyway.url=jdbc:sqlserver://localhost
flyway.user=sa
flyway.password=dbPassword
flyway.validate-on-migrate= #
So, in order to try make it work, here's what I do:
create schemaA and schemaB on the database using user sa and password dbPassword.
place at location [projectA]/src/main/resources/db/migration/m a file V1_0_Initialize.sql which is creates the structure of the tables and populates with standardized data.
try to run with the following command: mvn clean flyway:migrate -DskipTests
On step 3, I get the error message:
[INFO] Current version of schema [dbo.schemaA]: null
[INFO] Migrating schema [dbo.schemaA] to version 1.0 - Initialize
And after a few lines:
[ERROR] Message : The specified schema name "dbo.schemaA" either does not exist or you do not have permission to use it.
If I try to import the script using the DBMS, everything works perfectly.
What am I not seering?
Kind regards,

Related

mvn liquibase:generateChangeLog not working with an URL problem

I don't understand something with Liquibase and Spring Boot.
When I run my spring boot project with : mvn spring-boot:run
My changelog-v1.0.xml create a table and add two users inside my table user. So my liquibase is linked to my mySQL Database with success. But ... I don't know why, I can't used mvn liquibase command without failure.
Exemple, I want to save my database using :
mvn liquibase:generateChangeLog
But I have that log failure :
Failed to execute goal org.liquibase:liquibase-maven-plugin:4.9.0:generateChangeLog (default-cli) on project demo: The database URL has not been specified either as a parameter or in a properties file.
I think, when i'm using the command line, he don't use my configuration inside pox.xml but I don't know how to do that.
# pom.xml
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>4.9.0</version>
<configuration>
<propertyFileWillOverride>true</propertyFileWillOverride>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
<ChangeLogFile>src/main/resources/db/changelog/changelog-master.xml</ChangeLogFile>
<driver>${spring.datasource.driverClassName}</driver>
<url>${spring.datasource.url}</url>
<username>${spring.datasource.username}</username>
<password>${spring.datasource.password}</password>
</configuration>
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
</plugin>
My pom.xml is correctly setup because new changelog file inside liquibase directory create or update my data from my mysql database.
mvn liquibase:generateChangeLog does not depend on spring, so it is not going to read the spring file. You can either create a liquibase.properties file and reference it.
I changed the pom to reference a properties file
https://docs.liquibase.com/tools-integrations/maven/maven-pom-file.html
and then changed the changeLogFile configuration to use outputChangeLogFile like this:
<outputChangeLogFile>src/main/resources/db/changelog/changelog-master.xml</outputChangeLogFile>

What is the difference between Flyway Core and Flyway Maven Plugin?

I am using Flyway in my Spring-Boot project (in Eclipse with maven) with
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
and I ran into some interesting issues.
The whole thing worked fine until I failed a migration (because of a typo in the schema syntax). I tried to run fly:repair and I got this error
Failed to execute goal org.flywaydb:flyway-maven-plugin:6.4.1:repair (default-cli) on project springboot: org.flywaydb.core.api.FlywayException: Unable to connect to the database. Configure the url, user and password!
Now, the curious thing I do not understand is that if I add all the information into pom.xml
<properties>
<flyway.user>databaseUser</flyway.user>
<flyway.password>databasePassword</flyway.password>
<flyway.url>urlAddress</flyway.url>
</properties>
it builds. But if I add the information to my application.properties file
spring.flyway.user=databaseUser
spring.flyway.password=databasePassword
spring.flyway.url=urlAddress
the same error message occurs.
According to Baedlung Database Migrations with Flyway (they are using Flyway Maven Plugin), it does not matter where you configure Flyway.
So I wonder if I should switch to flyway-maven-plugin? I would really like to have all configuration in the .properties file.
First thing: Flyway-core for database migration by Java programming code.
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>7.0.0</version>
</dependency>
import org.flywaydb.core.Flyway;
...
Flyway flyway = Flyway.configure().dataSource(url, user, password).load();
flyway.migrate();
// Start the rest of the application (incl. Hibernate)
...
Second thing: Flyway-plugin for Maven goal, run by command-line.
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>4.0.3</version>
</plugin>
and
mvn clean flyway:migrate -Dflyway.configFile=myFlywayConfig.properties
You can choose first thing or second thing, depend on your preference (Database migration by Java code or by command)

Spring Cloud Contract not deploying to Artifactory in Maven multi module projects

I have a multi module project in which each module deploys fine to Artifactory until I add spring-cloud-contract-maven-plugin to one of the modules (the service, as it is a producer API).
The project has this structure:
parent
- common (shared DTOs)
- client
- service
We want to remove the client and the common in the future and have Feign clients in the consumers for reducing the coupling, and have a basic project without inner modules, but for now we have to keep this structure.
I first noticed that the stubs were not pushed to Artifactory, so my initial workaround was to add this to the Jenkins pipeline
sh './mvnw clean deploy -U --projects=xxx-service'
It deploys the service and the stubs, but I noticed that none of the modules gets deployed when this command is executed:
sh './mvnw clean deploy -U'
This is the end of the output:
[INFO] Installing /xxx/xxx-service/target/xxx-service-1.7.0-SNAPSHOT.jar to /xxx/.m2/repository/xxx/xxx-service/1.7.0-SNAPSHOT/xxx-service-1.7.0-SNAPSHOT.jar
[INFO] Installing /xxx/xxx-service/pom.xml to /xxx/.m2/repository/xxx/xxx-service/1.7.0-SNAPSHOT/xxx-service-1.7.0-SNAPSHOT.pom
[INFO] Installing /xxx/xxx-service/target/xxx-service-1.7.0-SNAPSHOT-stubs.jar to /xxx/.m2/repository/xxx/xxx-service/1.7.0-SNAPSHOT/xxx-service-1.7.0-SNAPSHOT-stubs.jar
[INFO]
[INFO] --- maven-deploy-plugin:2.8.2:deploy (default-deploy) # xxx-service ---
[INFO] Deploying xxx:xxx-service:1.7.0-SNAPSHOT at end
I have tried to move all the Maven configuration to the parent POM file and keep the contracts and the base test classes in the service module. I have looked to this page that explains how to configure the plugin and I have seen that I can use contractsDirectory to specify the directory of the contract files, gmavenplus-plugin to specify the directory of the generated tests and packageWithBaseClasses to specify the package of the base classes. However I don't see any way to specify the directory of the base classes. I cannot move the base test classes to the parent because they use some classes of the service module for generating the mocks.
Is there any way of doing it or I have to create a separate project for the contracts?
Thanks in advance
Cause of the problem:
I had this in a parent project extended by my API:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
<configuration>
<deployAtEnd>true</deployAtEnd>
</configuration>
</plugin>
Why is this a problem:
maven-deploy-plugin seems to conflict with multi module projects with plugins that use extensions like spring-cloud-contract-maven-plugin. There is a known issue documented here, look to the answer of Jerome that is also here.
Solution 1:
Remove the deployAtEnd option from the previous block so it would be:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
</plugin>
Solution 2:
Configure the plugin in all the modules although they don't need it. For doing so:
Add an empty "contracts" folder under src/test/resources on all the modules
Add this to the pom file of the service module:
<build>
<plugins>
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
<configuration
<baseClassForTests>com.xxx.BaseContractTest</baseClassForTests>
</configuration>
</plugin>
</plugins>
</build>
Add this to the pom file of the other modules:
<build>
<plugins>
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>

How to use log4j with maven and java9 in Eclipse Oxygen?

I try to migrate a Java8 project to Java9. The auto generated module-info.java contains an entry
requires log4j;
and an error is shown:
log4j cannot be resolved to a module
=> How do I correctly include log4j as a module dependency with Java9?
(I have the same issue for following dependencies:
requires hibernate.core;
requires hibernate.jpa.2.1.api;
requires jcommander;
requires junit;
requires reflections;
)
What I did so far:
Installed Java 9.0.1
Upgraded Eclipse to Oxygen.1a Release (4.7.1a)
Changed Compliance level of my Java project to 9
Generated module-info.java with Right click on project=>Configure=>Generate module-info.java
Updated the plugins in my pom.xml file (also see https://cwiki.apache.org/confluence/display/MAVEN/Java+9+-+Jigsaw) and set java version to 9:
<!-- plugin for compile phase (and test-compile phase) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<!-- specify current java version here: -->
<source>9</source>
<target>9</target>
</configuration>
</plugin>
Updated log4j version in pom.xml file since log4j 1.2 does not seem to work with Java9 (see https://blogs.apache.org/logging/entry/moving_on_to_log4j_2)
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
Errors in module-info.java
Even if the compliance level of the project has been set to Java9, there might be shown misleading errors for module-info.java in Eclipse.
I expected that an update of the maven project would only be required if I change the pom.xml file. Now I learned that changing the module-info.java also requires a manual update of the maven project.
=> update the maven project (Alt+F5)
After that update my errors vanished.
I also learned that it is better to first update the versions in the pom.xml file and then generate the module-info.java. Otherwise the module-info.java will include non-existing modules like "requires log4j" instead of "requires log4j.api"
Another misleading error in module-info.java might occur due to pom packaging, see below.
Unresolved imports
For the case that an import can not be resolved the question might be "Which corresponding (new) module do I need for that (old) import?". What might help here:
Search at following page for the required page:
http://cr.openjdk.java.net/~mr/jigsaw/ea/module-summary.html
(lists all exported packages of the JDK-modules)
Use JDeps on the (old) *.jar file to get a list of required jar files, e.g.
jdeps --class-path "lib" -recursive MY-OLD.jar >output.txt
Use jar to find the module for a jar file
jar --describe-module --file REQUIRED-JAR-FILE.jar
Also see:
What are the predefined modules in JDK9 or Which module do I need to fix dependency problems?
https://blog.codefx.org/tools/jdeps-tutorial-analyze-java-project-dependencies/#Getting-To-Know-JDeps
Re-Export dependencies
In order to automatically make log4j visible for a grandparent project
grandparent => parent => log4j
you might want to use
requires transitive log4j.api
in parent instead of
requires log4j.api
in grandparent. Also see:
What's the difference between requires and requires transitive statements in Java 9 module declaration
POM packaging
My main issue seems to be that my Java8 pom.xml file used pom packaging:
<packaging>pom</packaging>
If I remove that line, no errors are shown in module-info.java
Also see this extra question: How to use maven with Java9.0.1 and pom packaging in Eclipse Oxygen 1a Release (4.7.1a)?
New log4j version
A. In addition to the change "requires log4j" => "requires log4j.api" I had to adapt the calling code for the new log4j version that is compatible to Java9:
private static Logger sysLog = Logger.getLogger(Main.class);
to
private static Logger sysLog = LogManager.getLogger(Main.class);
B. log4j 2 does not have PropertyConfigurator. Also see this related question:
PropertyConfigurator in log4j2
C. log4j 2 does not support log4j.properties files. Previously I used
src/main/resources/META-INF/log4j.properties
for configuration. Now I use
src/main/resources/log4j2.xml
Also see
Log4j 2 doesn't support log4j.properties file anymore?
Converting log4j.properties to log4j.xml
Working example as a reference
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Log4JWithJava9</groupId>
<artifactId>Log4JWithJava9</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<release>9</release>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
</project>
module-info.java:
module Log4JWithJava9 {
requires javafx.base;
requires log4j.api;
}
Main.java:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Main {
private static Logger sysLog = LogManager.getLogger(Main.class);
public static void main(String[] args) {
}
}
Eclipse plugins
In order to add log4j to an eclipse plugin, I copied the file log4j-api-2.10.0.jar in a folder "lib" and added the jar file to Java Build Path=>Libraries=>ModulePath
Instead of requires log4j.api I had to use requires org.apache.logging.log4j
I was able to make this work somehow.
I downloaded the latest Eclipse Photon Release (4.8.0), I don't know if this fix will work with older versions.
I changed the module-info.java to have the following lines:
requires log4j.api;
requires log4j.core;
I had to switch to an earlier version of log4j, 2.8.2.
I changed all my imports that say import org.apache.logging.log4j.*; to not use the wildcard. So they changed to: import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
That's it, it works with both Maven and Eclipse.

maven release:perform with Perforce does not create target/checkout directory

I can not make the maven-release plugin work with Perforce. The release:prepare seems to work correctly: a Perforce label is created and it contains the correct files. Yet when I run release:perform it fails because the target/checkout directory is empty.
I've done some experiments. If I only sync to my pom.xml and then run
mvn scm:checkout
then my other files are checked out into the P4 root directory just as if I had done a
p4 sync ...
Yet Maven outputs
[INFO] Checkout working directory: /home/chris/perforce/pips/target/checkout
[INFO] sync -f //depot/pips/...
Maven thinks it's checking out the target/checkout but it is not. I dug into the P4Maven code a little bit and noticed this in P4Executor.java
public String getRepoPath(P4ScmProviderRepository repo, File basedir) {
// Handles a case where executing release:prepare on a module with an
// invalid SCM location. The release.properties contains the invalid URL
// for checkout during release:perform and the basedir is not the module
// root. So, the trailing target/checkout directory must be removed.
if (basedir.toString().replace('\\', '/').endsWith("/target/checkout")) {
String dir = basedir.toString();
basedir = new File(dir.substring(0, dir.length()
- "/target/checkout".length()));
if (getLogger().isDebugEnabled()) {
logger.debug("Fixing checkout URL: " + basedir);
}
}
This code is pretty clear. P4Maven won't check things out to target/checkout. If you tell it to checkout to target/checkout it will simply remove the "target/checkout" and checkout to the root directory. This is consistent with what I see being done. I also see the "Fixing checkout URL" message when I run release:perform
How then do people work around this?
Below is my pom.xml. I am using
Perforce Server version: P4D/LINUX26X86_64/2014.2/935585 (2014/09/16). p4d is running locally. Authentication is disabled and I don't need a password.
Nexus 2.10.0-02 running locally.
Ubuntu Linux.
Maven 3.2.3
java 1.7.0_55
Thanks.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.ap
ache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.icap</groupId>
<artifactId>pips</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>pips</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<scm>
<connection>scm:p4:192.168.1.8:1666://depot/pips</connection>
<developerConnection>scm:p4:192.168.1.8:1666://depot/pips</developerConnection>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.4</version>
<dependencies>
<dependency>
<groupId>com.perforce</groupId>
<artifactId>p4maven</artifactId>
<version>[2011,2012)</version>
</dependency>
</dependencies>
<configuration>
<connectionType>connection</connectionType>
<username>chelck</username>
<includes>**</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
<dependencies>
<!-- P4Maven -->
<dependency>
<groupId>com.perforce</groupId>
<artifactId>p4maven</artifactId>
<version>[2011,2012)</version>
</dependency>
</dependencies>
<configuration>
<connectionType>connection</connectionType>
<username>chelck</username>
<includes>**</includes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<fork>true</fork>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>deployment</id>
<name>Internal Releases</name>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>deployment</id>
<name>Internal Releases</name>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
I have struggled for several days on perforce / maven / release integration and finally got it working. Here are my findings, they might help you and others with similar issues.
Do not use the perforce plugin as described on perforce.com (http://www.perforce.com/perforce/r11.1/manuals/p4maven/index.html). Although it is the first link to come out of a search on google, my understanding is that this plugin is outdated.
In your configuration, if you refer to scm:p4:... you are using the com.perforce plugin. Instead, use org.apache.maven.scm/maven-scm-provider-perforce which uses scm:perforce:... syntax. Your <scm> should look like this:
<properties>
<p4path>//perforce-path/toyour/project</p4path>
</properties>
<scm>
<connection>scm:perforce:yourp4server:1666:${p4path}</connection>
<developerConnection>scm:perforce:yourp4server:1666:${p4path}</developerConnection>
<url>perforce:yourp4server:1666:${p4path}</url>
</scm>
The newer plugin does not require username/password, it will use your active P4 credentials.
I am using maven 3.2.5 and did not have to specify any plugin dependency. The built-in scm recognized the :perforce: scm and downloaded maven-scm-provider-perforce 1.9.2 which is the latest as of this writing. You can make sure you are using an up to date plugin by deleting the maven-scm-provider-perforce folder in .m2\repository\org\apache\maven\scm and then doing a mvn scm:status - it will download the missing plugin and you can see which one it picked.
Here is my maven-release-plugin definition:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
</plugin>
I do not have a maven-scm-plugin definition in my pom (I used the default settiings from the superpom).
Test on a non-module project.
You should be able to do the following without error:
- mvn scm:status to check that your scm setup is working correctly
- mvn release:prepare
- mvn release:perform
If you get errors, rollback (mvn release:rollback), make sure everything is back to normal, and rerun with mvn -X to get more details.
In my case, a non-modular project worked without much trouble.
Test on the parent of a reactor project.
There are a few things that were not obvious to me at first and that I found out:
When the is defined in the parent pom, the child module name gets appended to the path for the child module. If your child is not physically under the parent (in my case, it was beside), you need to redefine a configuration in the child pom. In my case, I was using a property (p4path above), simply changing its value was not enough. This was counter-intuitive since the parent pom is normally just a "include", and I expected the parent definitions to be "copy-pasted" in the child module, but in this particular case, it is modified to include the module name at the end of the scm path when it is copy-pasted. [More on modules that do not sit under the parent directory below]
A temporary client spec is created by the perforce scm plugin. This was also counter intuitive, I expected the scm plugin to use my current client-spec. Instead, it will create a new one on the fly, and populate it with the path you provided only and name it username-hostname-MavenSCM-localpath. I was initially surprised by that and tried to change it so it would use by client-spec by customizing the maven.scm.perforce.clientspec.name property, this behaviour was actually correct. With this temporary client-spec, the plugin can limit the lookup for changes, the submit and tagging to this directory. It also makes it easy to track what was done by this plugin in the perforce history.
Creation of the temporary client spec will fail if the modules are not under the parent directory. As I described above, my modules were sitting beside the parent. My <module> tag in the parent pom referred to them using <module>../mymodule</module> which worked fine in eclipse for everything else. The scm perforce plugin includes modules in the client spec by appending the path to the module to the path of the parent. Since Maven resolves the ../ to an absolute path, the client spec ends up containing something like this: //perforce-path/toyour/project/C:\Path\To\Your\Project/mymodule/ and the client spec fails. I could not find a work around for this issue other than moving my modules under their parent. Since the client spec was invalid, I had no file being checked-out under target/checkout. You will get the content of your generated client spec on the console by using mvn -X when invoking release:perform.
Moral of the story: You want to make sure that all your modules sit under their parent directory. When you do this, everything becomes simple and magical: you can leave the declaration in your parent pom and the module path gets magically appended for the module scm paths. You can refer to your modules using <module>mymodule</module> which gets correctly appended in the client-spec. Tagging of the parent in perforce ends up also tagging the modules since they are contained within.

Resources