donderdag 17 december 2009

Proper handling of linked resources

In the Eclipse workbench you can import resources, meaning copying them into the workspace, or you can set up a folder to link to them, and they files stay where they were. For large datasets, linking has obvious advantages. There is even a Decorator to show linked resources.

When programming in Eclipse you sometimes must use plain Java based libraries. These libraries handle files using java.io.File. When you work in Eclipse you reference files in the workspace using org.eclipse.core.resources.IFile. So in this case I needed to convert between the two formats.

First attempt, WRONG!

My first attempt was to use f.getFullPath().toFile() and that worked! Because I tested all my code with small data sets in the workspace, it wasn't until later that I found out, this does not work with linked resources:
java.io.FileNotFoundException: /Remote-Data/eulumdat/data.file (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:106)
at java.io.FileReader.(FileReader.java:55)
at xxxx

Second attempt: the proper way

My went back to the offending code and used CTRL+SPACE again. Now I selected f.getLocation().toFile() and that did it!

Conclusion

In order to get your code working in all circumstances, you need to test with both resources in the workspace and outside.
I'm i good company though, as there are 64 open bugs in the Eclipse bugzilla about linked resources.
Also I suspect code that doesn't work with linked resources, will not work with the remote system explorer, like this one.

3 opmerkingen:

  1. I'm not sure if #toFile() is a better attempt. You never know if the underlying efs-implementation can handle this (i guess in 99% you'll end up with an eror when browsing through alternative filesystems). I think IFile#getContents() is the best attempt.

    BeantwoordenVerwijderen
  2. @Tom Seidel: thank you for your comments about capabilities of external filesystems. I tried with both f.getLocation().toFile() and f.getContents() connected to a remote UNIX system using SSH. Both worked, so I have to dig deeper.

    BeantwoordenVerwijderen
  3. Oh, it's something, huh?

    Because of this I have a coding policy, which I enforce strictly on my team, no exceptions: any variables, or parameters that accept an IPath must contain a suffix of Path or Location. In that way, it becomes unambiguous that you expect an on-disk location or a path inside the workspace.

    Clearly 'location' vs. 'path' doesn't clarify the difference between 'workspace' and 'on-disk resource', they could have been the "path to an on-disk resource" and "location in the workspace", but no mind: the important thing is that a good naming standard sometimes matters a great deal.

    Because of that I think you're missing something by even trying to use getFullPath() to identify the on-disk resource. Maybe not, if you know there are no linked resources. Maybe since my workspaces always have linked resources, the distinction is more obvious -- I never use the *Path methods when I really want something on the local disk.

    BeantwoordenVerwijderen