|
We recently upgraded our nightly build server from 2003 32-bit to 2008 64-bit.
Since the upgrade, invocations of the maven-native-plugin are failing when executing the manifest goal
http://mojo.codehaus.org/maven-native/native-maven-plugin/manifest-mojo.html
http://mojo.codehaus.org/maven-native/native-maven-plugin/lifecycle.html
with an error like
mt.exe : general error c101008d: Failed to write the updated manifest to the resource of file "C:\dev\someproduct\somecomponent\somecomponent\Win32\target\somecomponent-Win32.exe". The process cannot access the file because it is being used by another process.
This appears to be a defect caused by a lock being held by java.exe for a very long time; in my tests it took 48 minutes before java.exe released the lock on the .dll created by the first cmd.exe running link.exe. I don't know what happened after 48 minutes, perhaps something like a call to System.gc(). I was able to time the lock and termine java.exe was holding it because I have a special mt.exe which keeps calling the real mt.exe repeatedly as long as error 31 is returned (31 is the error for file locked). I got the code for this special mt.exe from a workaround posted at
http://connect.microsoft.com/VisualStudio/feedback/details/363060/mt-exe-fails-due-to-files-momentarily-locked-by-link-exe
Perhaps the defect is in one of the lines of code in org.codehaus.mojo.natives.msvc.MSVCManifest#run not closing a file handle...
public void run( ManifestConfiguration config )
throws NativeBuildException
{
Commandline cl = new Commandline();
cl.setExecutable( "mt.exe" );
cl.setWorkingDirectory( config.getWorkingDirectory().getPath() );
cl.createArg().setValue( "-manifest" );
int manifestType = 0;
if ( "EXE".equalsIgnoreCase( FileUtils.getExtension( config.getInputFile().getPath() ) ) )
{
manifestType = 1;
}
else if ( "DLL".equalsIgnoreCase( FileUtils.getExtension( config.getInputFile().getPath() ) ) )
{
manifestType = 2;
}
if ( manifestType == 0 )
{
throw new NativeBuildException( "Unknown manifest input file type: " + config.getInputFile() );
}
cl.createArg().setFile( config.getManifestFile() );
cl.createArg().setValue( "-outputresource:" + config.getInputFile() + ";" + manifestType );
EnvUtil.setupCommandlineEnv( cl, config.getEnvFactory() );
CommandLineUtil.execute( cl, this.getLogger() );
}
For some reason, I can only reproduce this problem when the build is run through a Jenkins maven job. If I try the same maven build from the command line it seems to always work. For the Jenkins case, it doesn't matter whether I run Jenkins from the command like 'java -jar jenkins.war' running as administrator or run jenkins as a service logging on as administrator.
This problem did not occur on Windows Server 2003. A similar problem has been worked around in various Ant tasks
by checking/waiting for the file status before acting.
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Delete.java?r1=703151&r2=703150&pathrev=703151
http://svn.apache.org/viewvc?view=revision&revision=703151
https://issues.apache.org/bugzilla/show_bug.cgi?id=45960
This is a "clean server" with no antivirus, no indexing, etc. which might cause the file to be locked.
|