Since I can’t reproduce the bug myself, I need some people to help me test
it. What isn’t supposed to happen is that you get an error when attempting
to save a module (particularly on Windows). Additionally, other things
involving file I/O which worked before should continue working.
If you’d like to help get this bug fixed, please try this build, and
report back to me whether it works for you:
Finally re-produced the error with your build Joel
I opened the module for editing, then started another instance of Vassal, selected “Play Module” and opened it again; Then went back to the Edit session and tried to save. Good to know we can re-produce it!
– OS Windows Vista
– Java version 1.6.0_03
– VASSAL version 3.0.16-svn2780
Invalid version format :3.0.16-svn2780, 3.0.16-svn2780
– Sweden Fights On versijava.io.IOException: Unable to overwrite C:\Users\Public\Gaming Stuff\VASSAL-3.0 - testing\Sweden Fights On v1.0.mod\Sweden Fights On vtest.mod.zip
Data stored in C:\Users\Public\Gaming Stuff\VASSAL-3.0 - testing\Sweden Fights On v1.0.mod\temp1.zip
at VASSAL.tools.ArchiveWriter.write(ArchiveWriter.java:302)
at VASSAL.build.GameModule.save(GameModule.java:753)
at VASSAL.build.GameModule.save(GameModule.java:739)
at VASSAL.configure.ModuleEditWindow.save(ModuleEditWindow.java:189)
at VASSAL.configure.ModuleEditWindow$2.actionPerformed(ModuleEditWindow.java:83)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
When I “Save As” a different filename and get the error, the original module file has been removed somehow. Presumably this is because Vassal has deleted it in preparation for copying the temp file to the same name?
No, that’s not a bug on its own. What is a bug is if trying to do that
gets us into a state where it becomes impossible to save to other files
instead.
I was under the impression that we had the former situation, and that
was causing this bug, at least in some cases.
For what it’s worth I don’t consider this bug to be a high priority as it only applies to module designers (a minority) and personally I’ve managed to churn out 15 modules with very little impact. It’s rare enough to probably push down a notch or two. I would much rather get rid of that Vassal startup wizard!
Just to clarify, this is the problem at hand:
you open a module for editing.
Make modifications.
Click “Save”.
A dialog pops up with “Couldn’t save module {0}”.
At this point, a simple Save As with a different file name will usually fix the problem. Otherwise another dialog pops up with “Couldn’t save module {0}”.
Retries with “Save” and “Save As” repeatedly generate the same error.
With Vassal still open, when you open Windows Explorer and look in the folder where the module file should be, you see that it has gone!
At this point, there will usually be a temp1.zip file of around the same size as your old module. This file will still have your saved changes and allow you to recover the module fully.
If there’s no temp.zip files or they’re all too small to be your old module then you’re boned. The only option is to quit Vassal and restore from backup.
What should happen is that whenever you save module.mod, VASSAL writes
to tempN.zip, and if that succeeds, moves tempN.zip to module.mod.
What we actually do after writing tempN.zip is delete module.mod and
then rename tempN.zip to module.mod, because File.renameTo() isn’t
guaranteed to succeed on all platforms if the destination file already
exists.
I guess this problem could be caused by an open stream on the temp
file, since then the deletion of the module would succeed but it wouldn’t
be possible (on Windows) to rename the temp file.
I think this means that we should manage these temp files with the temp
file manager I wrote, which will ensure that the temp files have globally
unique names—and so nothing else could have a stream open on them.
Thanks—this comment was really helpful for me, since it made me think
about how the save process could fail.