Reputation: 8855
I have a file whose path looks like this /home/jwayne/test/55-0388%25car.xml
. I try to unmarshall the XML back to an object using JAXB as follows.
File file = new File("/home/jwayne/test/55-0388%25car.xml");
JAXBContext context = JAXBContext.newInstance(Rectangle.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Rectangle rectangle = (Rectangle) unmarshaller.unmarshal(file);
However, I get a FileNotFoundException (FNFE) with the stacktrace as follows.
[java.io.FileNotFoundException: /home/jwayne/test/55-0388%car.xml (No such file or directory)] at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:246) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189) ...
Note that somehow (as suggested by the stacktrace), the unmarshaller has modified the file name from 55-0388%25car.xml
to 55-0388%car.xml
.
Stepping through the code, however, the problem is actually pretty deep: sun.net.www.protocol.file.Handler
has a method openConnection
that does the following.
File var4 = new File(ParseUtil.decode(var1.getPath()));
That sun.net.www.ParseUtil.decode
method actually transforms the file path.
Any idea on how to quickly fix this problem (besides renaming the file)? (Note I am using JDK v1.8.0_191).
Upvotes: 0
Views: 344
Reputation: 12215
The root cause of your problem is that there is a %
that is used to URL encode special characters. For %
it is %25
.
What JAXB does internally is that it decodes %25
to plain %
and thus the file cannot be found.
Quick (and dirty) solution is to do some string replacing, like:
String fileName = "/home/jwayne/test/55-0388%25car.xml":
fileName = fileName.replace("%25", "%2525");
File file = new File(fileName);
This applies whenever there is %25
in a file name. But I guess this happens to any URL encoded characters. So if there are any other special characters you need some handling for each or some clever regexp solution.
Update:
to get around this JAXB behaviour provide it with InputStream
instead of File
. So like:
FileInputStream fis = new FileInputStream(fileName);
Rectangle r2 = (Rectangle) unmarshaller.unmarshal(fis);
Then there is no means for JAXB to alter any URI / filename.
Upvotes: 1