Jane Wayne
Jane Wayne

Reputation: 8855

JAXB fails to load file having name containing URL encoded characters

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

Answers (1)

pirho
pirho

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

Related Questions