scm perforce: mvn release:prepare fails with IOException and a write error (Access is denied)

Details

• Type: Bug
• Status: Closed
• Priority: Major
• Resolution: Fixed
• Affects Version/s: 1.7
• Fix Version/s:
• Component/s:
• Labels:
None
• Environment:
Windows 7 both command prompt and cygwin using Perforce for SCM

Description

When running

I get the errors:

• java.io.IOException: The filename, directory name, or volume label syntax is incorrect
• [ERROR] CommandLineException Exit code: 1 - Usage: add/edit/delete [-c changelist#] [ -d -f -k -n -v ] [-t type] files...
Missing/wrong number of arguments.
• [ERROR] Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.3.1:prepare (default-cli) on project root-project: Error writing POM: D:\Server\pom.xml (Access is denied) -> [Help 1]

The full output is attached.

Sometimes I also get the error:

• [ERROR] D:\Server\pom.xml - file(s) not in client view.

Though I created the client in the same location I'm running from, and I'm not sure that error is related to the others (as the others also occur when that one doesn't).

It's been suggested (on stackoverflow: http://stackoverflow.com/questions/10999403/maven-releaseprepare-ioexception) that the error has to do with my D drive being a mapped drive, though I don't think it is as it's not listed if I run subst. However, I think it must be at least a partition on the same hard drive, unless my PC has three physical drives (work PC), but I guess that shouldn't make any difference to the program?

Attachments

1. MNG-678-perforce.patch
12 kB
Svend Hansen
2. mvn_release_output_x.txt
39 kB
Robert Scholte
3. mvn_release_output_x_client_env.txt
39 kB
Robert Scholte
4. maven-release-error.txt
11 kB
Robert Scholte

Activity

Hide
Olivier Lamy (*$^¨%£) added a comment - applied. Thanks! Show Olivier Lamy (*$^¨%£) added a comment - applied. Thanks!
Hide
Svend Hansen added a comment - - edited

I've attached a patch.
So, the fix is checking whether each file has an absolute path already, before prepending the working directory (and only doing so if they don't).
I've changed the existing unit tests, to remove some of the hard coding, and added an extra test method to test the absolute path situation for both the edit and the checkin classes.
Also, it turns out that it only breaks is the working directory exists, so I'm calling new File(".").getAbsoluteFile() to make sure it an existing directory, and to get files in there I do new File("foo.xml").getAbsoluteFile().
This is because if you have a directory c:\foo but not a directory c:\bar, then new File("c:\foo\c:\foo\abc.xml throws an IOException, while new File("c:\bar\c:\bar.abc.xml does NOT.

Show
Svend Hansen added a comment - - edited I've attached a patch. So, the fix is checking whether each file has an absolute path already, before prepending the working directory (and only doing so if they don't). I've changed the existing unit tests, to remove some of the hard coding, and added an extra test method to test the absolute path situation for both the edit and the checkin classes. Also, it turns out that it only breaks is the working directory exists, so I'm calling new File(".").getAbsoluteFile() to make sure it an existing directory, and to get files in there I do new File("foo.xml").getAbsoluteFile() . This is because if you have a directory c:\foo but not a directory c:\bar , then new File("c:\foo\c:\foo\abc.xml throws an IOException, while new File("c:\bar\c:\bar.abc.xml does NOT.
Hide
Robert Scholte added a comment -

How to I create a patch? Do I just commit my changes through SVN?
I can write a Junit test that breaks without my change, but works with... Or should I just add another test method to the PerforceEditCommandTest and PerforceCheckInCommandTest?

You don't have the rights to commit, but creating a patch is just as simple. Your IDE or tools like for instance tortoisesvn have the option 'create patch/diff' next to the commit option.
If you'd prefer executions from command line, please check http://maven.apache.org/guides/development/guide-m2-development.html#Creating_and_submitting_a_patch

Show
Robert Scholte added a comment - How to I create a patch? Do I just commit my changes through SVN? I can write a Junit test that breaks without my change, but works with... Or should I just add another test method to the PerforceEditCommandTest and PerforceCheckInCommandTest? You don't have the rights to commit, but creating a patch is just as simple. Your IDE or tools like for instance tortoisesvn have the option 'create patch/diff' next to the commit option. If you'd prefer executions from command line, please check http://maven.apache.org/guides/development/guide-m2-development.html#Creating_and_submitting_a_patch
Hide
Svend Hansen added a comment -

I've just noticed what the lines after the canonical path do. They seem to strip out the beginning of the path of the file if the file starts with the working directory. This explains why it would have been working on Linux. If the path was /home/user/project/home/user/project/pom.xml the canonical path call would probably still have worked (though the file wouldn't exist), and after stripping out the working directory it would have been back to just /home/user/project/pom.xml.

If that's a correct understanding of the problem, I'm just not sure if it wouldn't just be better to add my change and remove the removing of the working directory (unless it's supposed to strip it down to just pom.xml?

Show
Svend Hansen added a comment - I've just noticed what the lines after the canonical path do. They seem to strip out the beginning of the path of the file if the file starts with the working directory. This explains why it would have been working on Linux. If the path was /home/user/project/home/user/project/pom.xml the canonical path call would probably still have worked (though the file wouldn't exist), and after stripping out the working directory it would have been back to just /home/user/project/pom.xml . If that's a correct understanding of the problem, I'm just not sure if it wouldn't just be better to add my change and remove the removing of the working directory (unless it's supposed to strip it down to just pom.xml ?
Hide
Svend Hansen added a comment - - edited

I don't think the canonical path is causing the problem, but it's just revealing it.
I'm not completely sure I understand the code and how it should be working, but as far as I can see:

1) The files in the ScmFileSet passed into the two methods at actual runtime seem to be absolute, so using them with the ScmFileSet's basedir doesn't seem to make sense?
2) All the tests seem to set the basedir to '.' and then pass in a separate workingDirectory or workingDir, which it self seems to be relative (e.g. "baz/qux").
3) I guess this breaks less in linux as /home/me/project/home/me/project/pom.xml is still a valid file path (though it would be pointing to a wrong place, of course).

I'm not sure if the bug is that the method doesn't handle absolute paths (before my change), or that the paths of the files are absolute. I think that the latter would be a bug somewhere else in the containing/calling maven modules (maven release plugin, etc).

How to I create a patch? Do I just commit my changes through SVN?
I can write a Junit test that breaks without my change, but works with... Or should I just add another test method to the PerforceEditCommandTest and PerforceCheckInCommandTest?

Show
Svend Hansen added a comment - - edited I don't think the canonical path is causing the problem, but it's just revealing it. I'm not completely sure I understand the code and how it should be working, but as far as I can see: 1) The files in the ScmFileSet passed into the two methods at actual runtime seem to be absolute, so using them with the ScmFileSet's basedir doesn't seem to make sense? 2) All the tests seem to set the basedir to '.' and then pass in a separate workingDirectory or workingDir , which it self seems to be relative (e.g. "baz/qux"). 3) I guess this breaks less in linux as /home/me/project/home/me/project/pom.xml is still a valid file path (though it would be pointing to a wrong place, of course). I'm not sure if the bug is that the method doesn't handle absolute paths (before my change), or that the paths of the files are absolute. I think that the latter would be a bug somewhere else in the containing/calling maven modules (maven release plugin, etc). How to I create a patch? Do I just commit my changes through SVN? I can write a Junit test that breaks without my change, but works with... Or should I just add another test method to the PerforceEditCommandTest and PerforceCheckInCommandTest ?
Hide
Robert Scholte added a comment -

If I have a look at PerforceRemoveCommand and PerforceAddCommand they don't seem to require those canonical paths.
According to the comment it's for testing purpose, but it seems to cause trouble.
Could you create a Junit test with patch?

Show
Robert Scholte added a comment - If I have a look at PerforceRemoveCommand and PerforceAddCommand they don't seem to require those canonical paths. According to the comment it's for testing purpose, but it seems to cause trouble. Could you create a Junit test with patch?
Hide
Svend Hansen added a comment -

The error I'm getting now is very similar, caused by the line:

File file = new File( workingDir, fs.get( i ).getPath() );

in PerforceCheckInCommand line 139. I've now also changed this one to:

File file = null;
if(fs.get( i ).isAbsolute()) file = new File( fs.get( i ).getPath() );
else file = new File( workingDir, fs.get( i ).getPath() );

And it now seems to be working completely. I'm not sure if my setup is a bit funny, causing this error, but I can't see any reason not to allow the absolute file paths?

Also, I don't know if there are similar "bugs" anywhere else.

Show
Svend Hansen added a comment - The error I'm getting now is very similar, caused by the line: File file = new File( workingDir, fs.get( i ).getPath() ); in PerforceCheckInCommand line 139. I've now also changed this one to: File file = null; if(fs.get( i ).isAbsolute()) file = new File( fs.get( i ).getPath() ); else file = new File( workingDir, fs.get( i ).getPath() ); And it now seems to be working completely. I'm not sure if my setup is a bit funny, causing this error, but I can't see any reason not to allow the absolute file paths? Also, I don't know if there are similar "bugs" anywhere else.
Hide
Svend Hansen added a comment - - edited

(I'm the one who created this but on this bug on the maven release plugin project)

I've downloaded the code and added a line that printed out the files it's looking at on line 109 (where the exception is thrown) here:

http://maven.apache.org/scm/maven-scm-providers/maven-scm-provider-perforce/xref/org/apache/maven/scm/provider/perforce/command/edit/PerforceEditCommand.html

With the line: String canfile = file.getCanonicalPath();

and the first file looks like D:\Server\D:\Server\pom.xml which obviously breaks. Further debug before the line:

File file = new File( workingDirectory, fs.get( i ).getPath() );

shows that the file path of the fs.get file is absolute. I first tried removing the workingDirectory, as it seemed that it wasn't needed here, but that broke a test, so instead I've changed it to:

File file = null;
if(fs.get( i ).isAbsolute()) file = new File( fs.get( i ).getPath() );
else file = new File( workingDirectory, fs.get( i ).getPath() );

And now it seems to work (I'm getting a different error much later in the process, but it is now managing the update the pom's versions.

Show
Svend Hansen added a comment - - edited (I'm the one who created this but on this bug on the maven release plugin project) I've downloaded the code and added a line that printed out the files it's looking at on line 109 (where the exception is thrown) here: http://maven.apache.org/scm/maven-scm-providers/maven-scm-provider-perforce/xref/org/apache/maven/scm/provider/perforce/command/edit/PerforceEditCommand.html With the line: String canfile = file.getCanonicalPath(); and the first file looks like D:\Server\D:\Server\pom.xml which obviously breaks. Further debug before the line: File file = new File( workingDirectory, fs.get( i ).getPath() ); shows that the file path of the fs.get file is absolute. I first tried removing the workingDirectory, as it seemed that it wasn't needed here, but that broke a test, so instead I've changed it to: File file = null; if(fs.get( i ).isAbsolute()) file = new File( fs.get( i ).getPath() ); else file = new File( workingDirectory, fs.get( i ).getPath() ); And now it seems to work (I'm getting a different error much later in the process, but it is now managing the update the pom's versions.

People

• Assignee:
Olivier Lamy (*\$^¨%`£)
Reporter:
Robert Scholte