Can someone help me understand and fix a windows-only bug which I cannot reproduce. I have some code which tries to use java.awt.Desktop and java.net.URI api(s) to display a file, a png file in the case. One of my students claims it fails on windows, and I have no way of testing this as I don’t have access to windows. It works on MacOS.
The error message is
Exception in thread "main" java.net.URISyntaxException: Illegal character in authority at index 7: file://C:\Users\axelg\AppData\Local\Temp\thompson-13248086568388762202.png
Here is the code; the error is on the line where new URI is used.
def openGraphicalFile(fileName:String):String = {
import java.awt.Desktop
import java.net.URI
if (Desktop.isDesktopSupported) {
Desktop.getDesktop.browse(new URI("file://" + fileName))
}
else {
// I don't know all the cases where this ELSE branch is taken,
// but at least it is taken on Linux while running the CI/CD pipeline
// in gitlab.
println(s"cannot open $fileName in OS = ${System.getProperty("os.name")} because desktop not supported")
}
fileName
}
I like this solution, as I don’t have to do anything withs classes forward nor backward.
I tested your solution and it works on MacOS. Not sure how I can test it on windows, because the student who reported it has already converted to a linux VM.
Looking at that documentation section it seems file::///c:/path is supported and file:c:/path, but not file://c:/path :-(,
Will Paths.get(fileName) convert the slashes to the correct direction?
I asked my student to go back and test it, and he claims it works.
def openGraphicalFile(fileName:String):String = {
import java.awt.Desktop
if (Desktop.isDesktopSupported) {
// See: https://users.scala-lang.org/t/uri-syntaxexception-illegal-character-in-authority-at-index-7/8777
Desktop.getDesktop.browse(java.nio.file.Paths.get(fileName).toUri)
}
else {
// I don't know all the cases where this ELSE branch is taken,
// but at least it is taken on Linux while running the CI/CD pipeline
// in gitlab.
println(s"cannot open $fileName in OS = ${System.getProperty("os.name")} because desktop not supported")
}
fileName
}
Yes, but this feels like it’s not quite the right question to ask. The NIO API is supposed to abstract away file system specifics, in particular the structure of string-y path representations. If you check the API docs (Paths, Path, FileSystemProvider, etc.), you’ll find
Paths#get() will give you a Path instance for the default file system on the local system (or an exception if the argument is an illegal path representation for this file system).
Each FileSystemProvider is associated with a URL scheme. In particular, the default provider is tied to the file:// scheme.
Thus, Path#toUri for a Path instance retrieved from the default file system will give you a proper file:// URI (barring I/O or security exceptions).
If a URI instance created this way is converted to a Path, it is guaranteed to represent the same absolute path as the original Path instance (“round trip guarantee”).
IOW, once you have a proper Path instance, you shouldn’t worry about string representations at all. Just let the system do its thing.
Re-reading, just to clarify: This is probably wrong - and it doesn’t matter.
Paths#get() will parse the argument to whatever Path implementation there is for the Windows default file system provider. This may have an internal representation as a String, a String array, a Byte array or whatever (and some way to render this correctly on #toString()). Similarly, Path#toUri() will produce an instance of URI, which happens to represent the full URI (and the path, redundantly) as a String, likely with proper slashes, but that’s an internal detail, too. All that matters is that the result of URI#toString() will produce the correct String representation - everything in between is (and should be) opaque.
Can GitHub test on windows? Currently I am using my school’s gitLab installation as repo. the CI/CD is always run on linux as our administrators have installed it.