Version 2.9.5
There is no out of box method to read from Path and write to Path, it will be usefull to make these methods.
java.nio.Path should be supported: serialization via StringLikeSerializer, and deserialization via FromStringDeserializer.
Do you have a unit test to show this failing?
No, i'm not about serialization/deserialization, i'm about readValue and writeValue methods, there is readValue(File) and writeValue(File, Object), but no readValue(Path), writeValue(Path, Object).
Sorry for wrong info in first comment.
@XakepSDK Ah! Yes that makes more sense.
Since this is API addition, will need to go in 3.0. But makes sense, the only (?) concern is large number of potential overloads. But I can see whether it should be added to just ObjectReader / ObjectWriter, or for ObjectMapper too.
I know nothing about the innards of Jackson, but you cannot deserialize Path because it is an interface and you'd need the FileSystem instance for. You cannot even transport between Windows and Un*x.
@michael-o I think this would not be about deserializing Path instances, but allowing their use as source to read from.
@cowtowncoder Are you certain? The discussion is about serializers and not JSON readers.
@michael-o cowtowcoder is correct
You should improve your description to make this clear.
Is this a big change?
As Path and File are arbitrary interchangeable one method might simply be a delegate to the other method:
public void writeValue(File resultFile, Object value) throws IOException, JsonGenerationException, JsonMappingException {
this._configAndWriteValue(this._generatorFactory.createGenerator(resultFile, JsonEncoding.UTF8), value);
}
public void writeValue(Path resultPath, Object value) throws IOException, JsonGenerationException, JsonMappingException {
writeValue(resultPath.toFile(), value);
}
@sdoeringNew No, it is not a difficult thing to do at all -- the only possible concern is that the API size for ObjectMapper is already rather big. But even there these could be just added for ObjectReader / ObjectWriter.
Originally this was requested when Jackson 2.9 had been released and expectation was that we'd go to 3.0 after 2.9, but situation has changed -- we are developing 2.13 now (3.0 is still work-in-progress, concurrently) -- so this addition could go in 2.13.
I just haven't had time to consider this. But it would be a relatively simple thing for PR, I think, unless I miss something.
Great. I'd be happy to add the PR. 馃憤
Ideally the new methods would not use Path#toFile() because that method throws UnsupportedOperationException if the path is not on the default file system. Examples of non-default file systems include zip file systems and in-memory file systems.
I maintain an application that uses Jackson to interact with both of those types of file systems. If you added methods that accept Path objects but invoke toFile() on them, I wouldn't be able to use any of those methods.
I'd think it would be better if the Path-accepting methods delegate to {Input,Output}Stream-accepting ones. For example:
public void writeValue(Path resultPath, Object value) throws IOException, JsonGenerationException, JsonMappingException {
try (OutputStream out = Files.newOutputStream(resultPath)) {
writeValue(out, value);
}
}
Yeah, well, if I can't use toFile() then there is a different problem.
If I want to do it right and neat like this:
public <T> T readValue(Path src, Class<T> valueType)
throws IOException, StreamReadException, DatabindException
{
_assertNotNull("src", src);
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
The TokenStreamFactory has to be updated in the jackson-core project. But that project is still at Java 1.6. Path came at 1.7.
Of course I could delegate it:
public <T> T readValue(Path src, Class<T> valueType)
throws IOException, StreamReadException, DatabindException
{
_assertNotNull("src", src);
return readValue(Files.newInputStream(src), valueType);
}
But that seems rather ugly if there is a whole factory dedicated to this kind of operation.
(Btw. the ObjectReader does this ugly thing, but not the ObjectWriter.)
Ideas?
But that seems rather ugly if there is a whole factory dedicated to this kind of operation.
I'm not following this part. What factory do you mean?
The second readValue you shared looks fine to me, except I thought you would need to close the InputStream.
My reading of _jsonFactory.createParser((File) src) is that it converts the file into an InputStream, and that it ends up reading that InputStream in the same way that your method does. The only difference I can see is that the File-accepting _jsonFactory.createParser could produce better exception messages than the InputStream-accepting one (it attaches the input object to the context for that purpose, and File has a helpful toString() whereas InputStream generally does not).
Yes, jackson-core is still JDK 6 only; even if jackson-databind is now moving to JDK 8 for Jackson 2.13 (and had JDK7 for a while now). Jackson 3.0 has JDK 8 as baseline for all components, so specific version for TokenStreamFactory could be added there if that is useful (I have no strong opinion).
So I guess it is possible to have different implementation for 2.13 vs 3.0 -- I would start with 2.13.
I've started with 3.0 and added pull requests for jackson-core and jackson-databind.
I'm unsure about adding it to 2.13, though. It would be a half-heartedly support for Path after the JDK has the nio-package ("new" IO) for ten years now. This issue had the 3.0-label three years and it still can be 3.0. :smirk:
But if you say so I'll add it "workaround-ish" to 2.13.
Merged to master for 3.0.0, thank you @sdoeringNew!
Most helpful comment
Ideally the new methods would not use
Path#toFile()because that method throwsUnsupportedOperationExceptionif the path is not on the default file system. Examples of non-default file systems include zip file systems and in-memory file systems.I maintain an application that uses Jackson to interact with both of those types of file systems. If you added methods that accept
Pathobjects but invoketoFile()on them, I wouldn't be able to use any of those methods.I'd think it would be better if the
Path-accepting methods delegate to{Input,Output}Stream-accepting ones. For example: