fasterxml / jackson-core Goto Github PK
View Code? Open in Web Editor NEWCore part of Jackson that defines Streaming API as well as basic shared abstractions
License: Apache License 2.0
Core part of Jackson that defines Streaming API as well as basic shared abstractions
License: Apache License 2.0
Current JsonParser.getText() requires reading of the whole JSON String value as String.
While convenient, this may not be optimal when processing large payloads.
As an alternative method, there should be something like:
boolean readText(Writer w);
which would read JSON String value, and pass it using given Writer; but possibly in separate chunks, without aggregating it. This allows caller to do incremental processing and avoid potentially big temporary memory usage.
In addition, for non-blocking parser implementations, this method could do partial decoding, meaning that it would only parse part of textual value; return value indicating whether full contents (true) or partial content (false) was processed.
Referencing this thread:
http://jackson-users.ning.com/forum/topics/avoid-exposing-implementation-details-in-jsonmappingexeption
Here's the situation:
A user gives my application JSON w/ an improperly formatted Date string. This generates an IllegalArgumentException in DateTime, which is then wrapped in a JsonMappingException with a message like the following:
Invalid format: "badDateString" (through reference chain: com.example.MyPojo["date"]).
I'd like to provide the user an informative error message that gives some idea of the cause, however I don't want to expose the internal details of my POJO. There doesn't seem to be a good way to do this currently.
It would be ideal if Jackson provided additional subclasses of JsonMappingException (as has been done with UnrecognizedPropertyException) that could provide additional contextual details that would allow the exception to be better handled and reported. (E.g. it can be difficult to determine if the exception is the result of unexpected JSON or JSON->POJO coding errors).
Thanks!
Usually we don't care whether non-persisted objects are Serializable. But in case of JsonFactory
there are reasons to do this, for certain platforms. Specifically, on mobile platforms like Android, "freezing state" may require flushing out lots of things. And re-creating those things, conversely, may be more costly than would simple de-serialization be.
To see if this could work, it would be good to see how easy it'd be to make JsonFactory
(which is the entry point to core streaming api) java.io.Serializable
. And if that works, continue up the stack to databinding.
Search for "@JsonUnwrapped" and remove the leading ''
It seems like UTF8StreamJsonParser.nextFieldName()
does not work properly when a field name straddles the 4000 byte boundary of _inputBuffer.
Test-case below:
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.io.SerializedString;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestJackson {
// ROUND.length() * 223 == 4014; UTF8StreamJsonParser._inputBuffer will end with "f" in "fieldName".
private static final int TESTROUNDS = 223;
private static final String TESTJSON = "{ \"fieldName\": 1 }";
private static final JsonFactory FACTORY = new JsonFactory(new ObjectMapper());
private static JsonParser parser(String json) throws Exception {
return FACTORY.createParser(new ByteArrayInputStream(json.getBytes(Charset.forName("utf-8"))));
}
private static String rounds(String json, int rounds) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < rounds; i++) {
sb.append(json);
}
return sb.toString();
}
@Test
public void testNextFieldName() throws Exception {
SerializableString fieldName = new SerializedString("fieldName");
JsonParser parser = parser(rounds(TESTJSON, TESTROUNDS));
for (int i = 0; i < TESTROUNDS - 1; i++) {
assertEquals(JsonToken.START_OBJECT, parser.nextToken());
// These will succeed
assertTrue(parser.nextFieldName(fieldName));
parser.nextLongValue(-1);
assertEquals(JsonToken.END_OBJECT, parser.nextToken());
}
assertEquals(JsonToken.START_OBJECT, parser.nextToken());
// This will fail
assertTrue(parser.nextFieldName(fieldName));
}
}
When the same module is registered twice, a NullPointerException will be thrown during json parsing.
For example,
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(DefaultScalaModule);
mapper.registerModule(DefaultScalaModule);
I'm struggling with a problem that is probably common for people that extensively use @JSONVIEW. Since only one view can be active at any one time, and jsonview classes are singly-inherited, the facility is very tightly constrained. There are a lot of cases where I need to define multiple views: "Show me the properties relevant to green administrators and the fields relevant to blue administrators", where these are not perfect subsets.
From an API perspective, one solution would be to allow json views to be defined by interfaces and thus enable multiple inheritance. Alternatively, just allow multiple views to be specified - although this raises the question of AND vs OR.
P.S. Thank you thank you THANK YOU for moving development to github!
Please centralize annotation validation so serializers/deserializes can invoke the method once at startup. This will ensure we throw exceptions instead of ignoring errors silently. See issue #41 for background information.
If you attempt to parse a UTF-32 byte array (not input stream), Jackson will throw an NPE. The bug is in here:
For UTF-8 and UTF-16, a null check is done on the passed in input stream (which will be null when parsing a byte array), but for UTF-32, no null check is done, and no null check is done in UTF32Reader either.
(migrated from http://jira.codehaus.org/browse/JACKSON-39 -- note, high vote count)
(suggested by Dimitri M on user list)
There are use cases where it'd be good to be able to feed input to parser, instead of trying to provide an input stream for parser to read from. This would cover use cases where input comes in chunks; for example, part of logical document in one chunk, then after a delay (perhaps in a separate request) another one and so forth. In these cases it may be difficult to implement InputStream (Reader etc) abstraction; instead, it would be better if application could feed (push) data to parser.
But if so, parser must be able to indicate cases where no data is YET available (but may become available).
This is similar to how Aalto Xml processor (http://www.cowtowncoder.com/hatchery/aalto/index.html) operatesd in its async mode. However, since Json is much simple format than xml, implementation might be simpler.
Based on my experiences with Aalto, implementation is a non-trivial thing however. One problem is that even UTF-8 decoding needs to be somewhat aware of chunk boundaries, so in the end a separate parser may be required: this because current parser uses blocking to handle these split cases. A smaller problem is that of indicating "not-yet-available" case โ this can probably be handled by introducing a new member in JsonToken enumeration.
Current 'writeBinary()' method requires binary data to be passed as a byte array. This may not work well with larger payloads; so we should an alternative method where one can define source for binary data.
In addition to InputStream, it should be possible to indicate exact number of bytes to include; this because some formats (not JSON however!) require such information to be written before data, or used for initializing write. It should be possible to pass marker value -1 to indicate "not known": not all generators are required to support it, however.
One naming change that should have gone in 2.0, but was sadly forgotten is that of making JsonFactory's factory methods more generic. There is no need to emphasize "json" in methods to begin with; and with 2.0, there are many non-JSON backends, so this is becoming bit of an eyesore.
So, with 2.1, we should add methods:
JsonFactory.createParser(...) to replace 'creteJsonParser(...) methods
JsonFactory.createGenerator(...) to replace 'createJsonGenerator(...) methods
and implement them, initially to delegate to old variants in 2.1; and ensure that non-JSON data formats also override methods if and as necessary (usually they override secondary methods which may not be changing).
And with 2.2, old methods should be deprecated, to get application-level code to eventually be upgraded.
We will not be able to remove the old methods until 3.0 (if ever), but while this is bit of nuisance, I think readability of sample code will improve. Too bad we didn't do this for 2.0 to eliminate the issue, but better late than never.
In addition to [Issue-21](try to prevent hash collision attacks), it seems prudent to also add fallback verification to throw exception in case abnormal number of hash collisions is detected. In case where no collision attacks exist, this should have no measurable impact; but just in case new attacks are formulated, they would get caught.
I didn't know where to file bugs related to the website. If you go to:
http://xircles.codehaus.org/projects/jackson/lists
and click on "archive" for any of the mailing lists you will get a broken link. Furthermore, it's not clear where is the best place to ask for help with Jackson. Do you prefer Stackoverflow? The mailing lists? The forum on your blog? etc... This should be clarified.
Since some data formats (YAML, for example) have their own notions of Object Identity handling, it would make sense to push bit more semantical information through lower level abstractions. One way to do this would be to add new methods to use when serializing Object ids and references.
Got question or request for Feature to be added.
I have json object that does not follow json standard.
Example
[,,"41513053","30120.00",]
I have no control over the json only that I receive it.
I understand why the developers did it. ( to preserve bandwith ).
[null,null,"41513053","30120.00",null]
So I get ' com.fasterxml.jackson.core.JsonParseException: Unexpected
character (',' (code 44)): expected a valid value (number, String,
array, object, 'true', 'false' or 'null')'
It would be a nice feature to except this as null value.
JsonParser.Feature.ALLOW_NULL_EMPTY_VALUES.
This program:
public static void main(final String... args)
throws IOException
{
try {
new ObjectMapper().reader().readTree("treu");
} catch (JsonProcessingException e) {
System.out.println(e.getOriginalMessage());
}
}
prints out:
Unrecognized token 'treu': was expecting
And nothing else. Generally speaking, it happens each time a JSON boolean or null is input which is at least the correct length but mispelled or followed by unexpected letters (for instance, truez
also outputs the same).
It does not happen though if the value does not have the expected length (ie, tru
, nul
, in which case the message is Unexpected end-of-input in a value
).
Current 'writeString()' method requires text value to be passed in its entirety. This may not work well with larger payloads; so we should an alternative method where one can define source for text, used for incremental/streaming read+write.
In addition to Reader, it should be possible to indicate exact number of bytes to include; this because some formats (not JSON however!) require such information to be written before data, or used for initializing write. It should be possible to pass marker value -1 to indicate "not known": not all generators are required to support it, however.
If length is indicated, it is an error for Reader to provide less data (more is ok; generator just will not read anything beyond indicated amount).
I see in the Maven repo jackson-core-asl-1.9.6.jar and jackson-core-asl-1.9.6-sources.jar, but not jackson-core-asl-1.9.6-javadoc.jar. The majority of packages in the Maven Central repository include javadoc jars. A javadoc jar can be useful for tools like Eclipse that make use of these jars. Also, when using the Play 2 framework eclipsify task, I get numerous warnings that jackson-core-asl-1.9.6-javadoc.jar cannot be found, which is pretty annoying.
I'm currently using a library which depends on jackson-core.jar, jackson-databind.jar and jackson-annotations.jar in an Android project. When looking at the project's APK contents, I realized there are files at
project.apk/com/fasterxml/jackson/core/json/VERSION.txt
project.apk/com/fasterxml/jackson/databind/cfg/VERSION.txt
It seems Android's apkbuilder tool does not filter out text files from the source tree before packaging the APK (although it filters out several other files, see checkFileForPackaging()). I'm not sure the VERSION.txt files are there on purpose after all, as jackson-annotations.jar comes without it. So I'd like to kindly ask you to consider removing the VERSION.txt from the distribution JARs, or to place it e.g. in the META-INF directory which gets filtered by the ApkBuilder tool.
(I'm filing this issue for jackson-core only, although it affects jackson-databind, too.)
There have been some attacks (DoS) that make use of collisions in String.hashCode() values (or at least their low-bits collisions).
The one place where this matters most is in handling of symbol table: although Jackson actually does not directly use String.hashCode(), internal calculation is along the same lines.
This should be changed by, for example:
Care needs to be taken as this is one of more performance critical paths.
This request is to support updating of existing entities when inheritance is being used. It seems like everytime it just throws a UnsupportedException. We are using Jackson 1.9.11
Here is a test case:
import java.io.IOException;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonSubTypes.Type;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.annotate.JsonTypeInfo.As;
import org.codehaus.jackson.annotate.JsonTypeInfo.Id;
import org.codehaus.jackson.annotate.JsonTypeName;
import org.codehaus.jackson.map.ObjectMapper;
public class TestUpdating {
@JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, isGetterVisibility=Visibility.NONE)
@JsonTypeInfo(include=As.PROPERTY, use=Id.NAME, property="type")
@JsonSubTypes(value={
@Type(value=Child.class)})
abstract static class Parent {
@JsonProperty("x")
int x;
@JsonProperty("y")
int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, isGetterVisibility=Visibility.NONE)
@JsonTypeName("child")
public static class Child extends Parent {
@JsonProperty("w")
int w;
@JsonProperty("h")
int h;
public int getW() {
return w;
}
public void setW(int w) {
this.w = w;
}
public int getH() {
return h;
}
public void setH(int h) {
this.h = h;
}
}
public static void main(String[] args) {
Child c = new Child();
c.setW(10);
c.setH(11);
ObjectMapper mapper = new ObjectMapper();
try {
mapper.readerForUpdating(c).readValue("{\"x\":3,\"y\":4}");
System.out.println(c.getX());
System.out.println(c.getY());
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Usually we don't care whether non-persisted objects are Serializable. But in case of JsonFactory
there are reasons to do this, for certain platforms. Specifically, on mobile platforms like Android, "freezing state" may require flushing out lots of things. And re-creating those things, conversely, may be more costly than would simple de-serialization be.
To see if this could work, it would be good to see how easy it'd be to make JsonFactory
(which is the entry point to core streaming api) java.io.Serializable
. And if that works, continue up the stack to databinding.
Jackson allows skip null values when serializing maps. This doesn't work, when map value is generated by the method annotated with @JsonValue. For example:
@JsonProperty
private Map<String, SomeClass> fields;
and:
class SomeClass {
@JsonValue
public String getValue() { ... }
}
result:
{"id1":"a","id2":null}
(note: moved from https://jira.codehaus.org/browse/JACKSON-885)
JsonLocation is marked as serializable, and it is included as a member of JsonProcessingException, that is also serializable.
The problem is that JsonLocation has an Object attribute called _sourceRef, and this object is not always serializable.
This object can be a reference to a input stream and this input stream may not be serializable as it happen to me when trying to serialize a JsonProcessingException exception:
java.io.NotSerializableException: libcore.net.http.FixedLengthInputStream
I would advice to mark _sourceRef as volatile (not serializable). This will make it possible to serialize the exception without problems.
jackson-core 2.1.0
Bellow is the unit test, the fourth test fails with timeout indicating an infinite loop. The test is trying to parse a simple JSON object string converted to byte array. It works for:
{"field":"value"}
but fails for:
{"field"<space_here!>:"value"}
The loop starts in UTF8StreamJsonParser._skipColon() which keeps calling _skipCR().
import junit.framework.Assert;
import java.io.IOException;
import java.nio.charset.Charset;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.io.SerializedString;
public class JsonParserNextFieldNameTest
{
private static final JsonFactory JSON_FACTORY = new JsonFactory();
private static final String JSON = "{\"field\":\"value\"}";
private static final String JSON_WITH_SPACE_BEFORE_COLON = "{\"field\" :\"value\"}";
@Test
public void parseJsonAsString() throws IOException
{
parse(JSON, false);
}
@Test
public void parseJsonAsBytes() throws IOException
{
parse(JSON, true);
}
@Test
public void parseJsonWithSpaceAsString() throws IOException
{
parse(JSON_WITH_SPACE_BEFORE_COLON, false);
}
@Test(timeout = 5000L)
public void parseJsonWithSpaceAsBytes() throws IOException
{
parse(JSON_WITH_SPACE_BEFORE_COLON, true);
}
private void parse(String json, boolean asBytes) throws IOException
{
JsonParser jp = asBytes ? JSON_FACTORY.createParser(json.getBytes(Charset.forName("UTF-8"))) : JSON_FACTORY.createParser(json);
Assert.assertEquals(JsonToken.START_OBJECT, jp.nextToken());
Assert.assertTrue(jp.nextFieldName(new SerializedString("field")));
}
}
There's a unit test to repro the issue below. Basically, when you're on a FIELD_NAME token, if you call getTokenLocation() and then nextToken() and then getTokenLocation() again, you'll get the same location for both calls to getTokenLocation(), even though you've advanced to a new token.
The issue seems to be the _nextToken logic in ReaderBasedJsonParser and UTF8StreamJsonParser. When calling nextToken() on a FIELD_NAME, it calls _nextAfterName(), which updates _currToken but doesn't update _tokenInputRow and _tokenInputCol for the new token's location.
I started to try to fix it, but the _nextToken logic is spread across so much code that it looked like it'd be a pretty major surgery. Not something I'm willing to do at this point. :-)
public void testTokenLocationAfterFieldName() throws Exception
{
_testTokenLocationAfterFieldName(false);
_testTokenLocationAfterFieldName(true);
}
private void _testTokenLocationAfterFieldName(Boolean useStream) throws Exception
{
final String DOC = "{\"name\":123}";
JsonFactory jf = new JsonFactory();
JsonParser jp = useStream ?
jf.createJsonParser(new ByteArrayInputStream(DOC.getBytes("UTF-8")))
: jf.createJsonParser(new StringReader(DOC));
assertEquals(JsonToken.START_OBJECT, jp.nextToken());
assertEquals(JsonToken.FIELD_NAME, jp.nextToken());
assertEquals(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
assertEquals(1, jp.getTokenLocation().getLineNr());
assertEquals(9, jp.getTokenLocation().getColumnNr());
jp.close();
}
Related jackson-core version is 2.0.4.
In com.fasterxml.jackson.core.util.TextBuffer line 498 expand( len ) is called which results in setting the _currentSegment to MAX_SEGMENT_LEN, even when the segment size is supposed to grow.
Thanks in advance for your support with this!
Related test is given below:
package europass.ewa.services.conversion.xml;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.util.Random;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class BytesToXmlTest{
@Test
public void write256KBData() throws JsonGenerationException, JsonMappingException, IOException {
testWriteData(256);
}
@Test( expected=JsonMappingException.class )
public void write384KBData() throws JsonGenerationException, JsonMappingException, IOException {
testWriteData(384);
}
public void testWriteData(int kb) throws JsonGenerationException, JsonMappingException, IOException {
Random r = new Random(1);
Data data = new Data();
data.bytes = new byte[1024*kb];
r.nextBytes(data.bytes);
String xml = new XmlMapper().writeValueAsString(data);
assertThat(xml, is(notNullValue()));
}
public static class Data {
@JsonProperty
byte[] bytes;
}
}
The JsonProcessingException class doesn't give you access to the original message string.
It looks like the way to get the message is via 'getMessage()' which also includes location information.
One use case where having the raw message is useful is in a GUI. You want to use the location object to figure out where the error is, and then use the message string to display the error message. It's ugly to have the location repeated in the message string.
My use case has to do with prepending the "logical path" to an error message (things like "field 'servers', array index 4". At every step in my object processing, I catch JsonParseException, prepend the current "logical path" to the error message and rethrow. Unfortunately, I have no access to the original message so I do a super hack where I search for the last occurrence of " at " and strip out everything after that :-\
I'd like to transform:
{
"singleKey":
[
"value1",
"value2"
]
}
into:
[
"value1",
"value2"
]
I tried using @JsonUnwrapped on the List in question but Jackson ignores it silently. I assume this is what is meant by the Javadoc: "can not unwrap JSON arrays using this mechanism". I have three questions:
(moved from http://jira.codehaus.org/browse/JACKSON-447)
(request by David Yu, via mailing list)
Feature request:
byte[] raw = JsonParser.getRawString();
Kinda like the raw getBinaryValue() except that the value was never b64 encoded (e.g a utf8 string)
(Tatu's comments)
I think a good name would be "getTextAsBytes()", to follow existing naming convention. I think it is ok to only expose UTF-8 encoded Strings, given that JSON itself only supports Unicode encodings.
One open question is whether there should be complementary method(s) that would take a byte array (or buffer) to append/write string into. But maybe it's best to start simple and improve things over time.
...
Sounds like David was hoping to get contents before replacing escaped codes (probably to pass through JSON output with minimal changes). This is unfortunately very difficult to do in general case, so I will not consider this for inclusion with 1.7.0. Perhaps a solution can be found in future; leaving this issue open still.
The stacktrace has been attached at the bottom. Known issue ?
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.fasterxml.jackson.core.util.TextBuffer._charArray(TextBuffer.java:705)
at com.fasterxml.jackson.core.util.TextBuffer.expand(TextBuffer.java:664)
at com.fasterxml.jackson.core.util.TextBuffer.append(TextBuffer.java:468)
at com.fasterxml.jackson.core.io.SegmentedStringWriter.write(SegmentedStringWriter.java:67)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator._flushBuffer(WriterBasedJsonGene
rator.java:1799)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator._writeString(WriterBasedJsonGene
rator.java:975)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeString(WriterBasedJsonGener
ator.java:436)
at com.fasterxml.jackson.databind.ser.std.StringSerializer.serialize(StringSerializer.java:3
6)
at com.fasterxml.jackson.databind.ser.std.StringSerializer.serialize(StringSerializer.java:1
)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter
.java:464)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerB
ase.java:504)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedLi
stSerializer.java:94)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedLi
stSerializer.java:1)
at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerB
ase.java:150)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter
.java:464)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerB
ase.java:504)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedLi
stSerializer.java:94)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedLi
stSerializer.java:1)
at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerB
ase.java:150)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter
.java:464)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerB
ase.java:504)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedLi
stSerializer.java:94)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedLi
stSerializer.java:1)
at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerB
ase.java:150)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter
.java:464)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerB
ase.java:504)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedLi
stSerializer.java:94)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedLi
stSerializer.java:1)
This will allow users to specify multiple type parameters, as well it will allow them to easily mix simple (URL
) and compound type (List<URL>
) parameters with ease. Finally, by having JavaType
extend java.lang.reflect.Type
we will be able to tunnel JavaType
through Jersey's Client.get(Type)
method.
See issue #41 for more information.
Currently (2.1) TreeNode
interface has little actual functionality, and can not be used for traversal. It would make sense to add bit more functionality to allow some level of generic traversal over different implementations. For example:
JsonParser.getValueAsLong() calls getValueAsInt(0), instead of getValueAsLong(0). As a result, if you call getValueAsLong() without a default value you return an integer instead.
This method has special handling for file URLs - once it detects them, it does this:
return new FileInputStream(url.getPath());
This fails with FileNotFoundException if the path contains spaces, encoded as usual in URLs with %20. And it probably also fails on any other sort of percent-encoded character.
(In case you're wondering, calls to ...getContextClassLoader().getResource() are a frequent source of such URLs, at least in my case.)
Suggested fix:
return new FileInputStream(URLDecoder.decode(url.getPath(), "UTF-8"));
Regrettably it looks like YAML does not support C or C++ comments but only scripting comments (hash sign until end of the line). While this should not cause problems with JSON per se, there are some cases where this is problematic: specifically, when YAML is viewed as a superset of JSON; in which case one has no common comments (granted, comments are not in standard JSON, so it is superset of standard JSON).
Anyway: ability to enable handling of "hash comments" would be useful and simple to implement; quite similar to how C++ comments are handled. As such, it would make sense to add in 2.2.
I have been trying to implement my own pretty printing for json output but due to the API, I cannot find a way to detect that I am going to output an empty array or an empty map and act accordingly.
The issue is that the api PrettyPrinter.writeStartObject(JsonGenerator jg)
does not provide the number of entries (it is provided only on writeEndObject
).
I would like to output:
{
"a": {
"b1": 3,
"b2": 4,
},
"c": {}
}
but cannot find a way with the api to output an empty map ({}
) this way when there are no elements since I don't know until the end.
According to the 1.9.0 release notes and issue 594 on the JIRA tracker, there is support for deserializing inner classes. However, trying to deserialize properties containing lists of non-static inner classes gives an error still.
We will need a way to indicate property ids that are based on ints as opposed to Strings, for formats like Thrift and Protobuf (and probably others). For this a new method is probably needed.
Also, it would make sense to additionally return some kind of marker for existing String-based method(s) (getCurrentName()); while value may be something like empty String, it'd be good to be able to use identity comparison.
Since this is an API change, needs to go in 2.1
I am getting a response like this from a pHp(cakePhp) server :
[
{
"id": "42389",
"start": "0000-00-00",
"end": "0000-00-00",
"event_id": null,
"trip_id": "5791",
"location_id": "231552",
"user_id": "105",
"users_attending": "0",
"user_local": "0",
"Trip": {
"name": "Asdas"
},
"Event": [],
"Location": {
"name": "South Melbourne"
}
},
{
"id": "42392",
"start": "0000-00-00",
"end": "0000-00-00",
"event_id": "1218",
"trip_id": "4772",
"location_id": "271505",
"user_id": "105",
"users_attending": "3",
"user_local": "50",
"Trip": {
"name": "trip by 1059200"
},
"Event": {
"title": "SampleEvent 454",
"id": "1218"
},
"Location": {
"name": "Houston"
}
},
.......
]
The thing is that the parser expects Event object but if its null then it is receiving empty array and throws com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of out of START_ARRAY token
On iOS restkit handles it automatically. but with Jackson I have to create Custom deserializer for Event Object which affects performance.
Is there any better way to do this.
I have put this on StackOverflow too (http://stackoverflow.com/questions/12684808/jackson-parser-ignore-deserializing-for-type-mismatch/) and (http://stackoverflow.com/questions/13175420/jackson-deserializing-with-custom-deserializer-causes-a-lot-of-gc-calls-and-take)
04:55:30 PM) henning_asf: https://gist.github.com/3173456
(04:56:19 PM) tatu_seaforce: one thing is that you can avoid JsonGenerator itself, pass Writer, write linefeed separately
(04:56:25 PM) tatu_seaforce: but I don't know if that makes much difference
(04:56:32 PM) tatu_seaforce: (under the hood, will create new one anyway in that case)
(04:57:08 PM) tatu_seaforce: you could implement mostly bogus PrettyPrinter also, to suppress that space
(04:57:28 PM) tatu_seaforce: or, if you are using 2.0.x, you could file an RFE to suppress that space for JsonGenerator via new JsonGenerator.Feature
(04:57:43 PM) tatu_seaforce: think it should be easy to add. I am trying to finalize 2.1 soon
(04:58:30 PM) henning_asf: so the problem is in _verifyValueWrite in the Utf8Generator
(04:59:20 PM) henning_asf: it turns out that the state when starting the second object is "STATUS_OK_AFTER_SPACE" and then it adds a space to the buffer.
(04:59:43 PM) tatu_seaforce: right, idea is that if someone outputs, say, numbers at root context
(04:59:52 PM) tatu_seaforce: it typically needs separator.
(04:59:56 PM) henning_asf: and that one is called from writeStartObject() in the JsonGeneratorBase.
(05:00:02 PM) tatu_seaforce: but, usually people woudl probably want a linefeed instead
(05:00:20 PM) henning_asf: yes. If I could set the separator, my world would be perfect (because then I would set the newline as the separator)
(05:00:33 PM) tatu_seaforce: ok. Or empty String to disable it.
(05:00:37 PM) henning_asf: but because I can not do that, I write the newline myself and now I have an annoying space. :-)
(05:00:40 PM) henning_asf: yes, or empty string.
(05:00:44 PM) tatu_seaforce: sounds like a good feature... care to file an issue at github?04:55:30 PM) henning_asf: https://gist.github.com/3173456
(04:56:19 PM) tatu_seaforce: one thing is that you can avoid JsonGenerator itself, pass Writer, write linefeed separately
(04:56:25 PM) tatu_seaforce: but I don't know if that makes much difference
(04:56:32 PM) tatu_seaforce: (under the hood, will create new one anyway in that case)
(04:57:08 PM) tatu_seaforce: you could implement mostly bogus PrettyPrinter also, to suppress that space
(04:57:28 PM) tatu_seaforce: or, if you are using 2.0.x, you could file an RFE to suppress that space for JsonGenerator via new JsonGenerator.Feature
(04:57:43 PM) tatu_seaforce: think it should be easy to add. I am trying to finalize 2.1 soon
(04:58:30 PM) henning_asf: so the problem is in _verifyValueWrite in the Utf8Generator
(04:59:20 PM) henning_asf: it turns out that the state when starting the second object is "STATUS_OK_AFTER_SPACE" and then it adds a space to the buffer.
(04:59:43 PM) tatu_seaforce: right, idea is that if someone outputs, say, numbers at root context
(04:59:52 PM) tatu_seaforce: it typically needs separator.
(04:59:56 PM) henning_asf: and that one is called from writeStartObject() in the JsonGeneratorBase.
(05:00:02 PM) tatu_seaforce: but, usually people woudl probably want a linefeed instead
(05:00:20 PM) henning_asf: yes. If I could set the separator, my world would be perfect (because then I would set the newline as the separator)
(05:00:33 PM) tatu_seaforce: ok. Or empty String to disable it.
(05:00:37 PM) henning_asf: but because I can not do that, I write the newline myself and now I have an annoying space. :-)
(05:00:40 PM) henning_asf: yes, or empty string.
(05:00:44 PM) tatu_seaforce: sounds like a good feature... care to file an issue at github?
I have been back and forth over the Jackson 2.x source, binary and documentation and I can find no mention of the license used. Jackson 1.x was dual-licensed as LGPL and ASL, but had separate downloads for each. Does Jackson 2.x have a similar license, and where can I find the license information?
(see [https://github.com//issues/21] for related problem)
Given that it is easy to fabricate collisions for String.hashCode() (since JDK's impl allows substring-replacement style attacks very easily), ObjectNode is prone to attacks.
Since JsonParser
use has been fixed (Issue-21), it is necessary to simialrly address the issue of use of HashMap
with default String hashCode().
The big problem here is the performance: not so much that of cost of calculating hashCode() alone, but lack of caching of that value (JDK aggressively caches hashCode on first access).
We should probably do similar two-part solution here as earlier: make it possible to detect abnormal (super high collision list) cases and error out; but also improve hash code used as much as possible.
It would be great to have the option to add the ability to write a UTF string from an InputStream
, not just byte array.
jackson is used in the riak-java-client and my java tool which does a conversion of mysql data into riak db had a lot of complete lockdowns during conversion. The tools starts about 200 threads which do the conversion in parallel. Doing several thread dumps quickly revealed the threads were waiting a lot to get into the synchronized "intern"-Method in your InternCache.
I removed the InternCache and run the script again, this time the performance improved a lot and the strange lockdowns were gone. Possibly at a cost of higher cpu-load, I didn't measure that.
I doubt this InternCache is of any use because of the need of synchronisation. Maybe doing it as ThreadLocal would help. The way it is currently done is critical for environments with a lot of threads.
Current JsonParser.getBinaryValue() requires reading of the whole value (base64 decoded text for JSON; may be native for other formats) and return it as a byte[]. While convenient, this is not scalable for larger binary payloads.
As an alternative method, there should be something like:
boolean readBinaryValue(OutputStream out);
which would read binary content (decoding if necessary), and pass it using given OutputStream; but possibly in separate chunks, without aggregating it. This allows caller to do incremental processing and avoid potentially big temporary memory usage.
In addition, for non-blocking parser implementations, this method could do partial decoding, meaning that it would only parse part of binary payload; return value indicating whether full contents (true) or partial content (false) was processed.
Specific stream length causes infinite loop on UTF8Generator.
Test Code:
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
IOContext ioc = new IOContext(new BufferRecycler(), bytes, true);
JsonGenerator gen = new UTF8JsonGenerator(ioc, 0, null, bytes);
ByteArrayInputStream data = new ByteArrayInputStream(new byte[2000]);
gen.writeBinary(data, 1999);
Patch:
--- a/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java
@@ -1681,7 +1681,11 @@
maxRead = Math.min(maxRead, readBuffer.length);
do {
- int count = in.read(readBuffer, inputEnd, maxRead - inputEnd);
+ int length = maxRead - inputEnd;
+ if (length == 0) {
+ return inputEnd;
+ }
+ int count = in.read(readBuffer, inputEnd, length);
if (count < 0) {
return inputEnd;
}
InputStream returns 0 on not reached stream end.
I'm getting a stack overflow when trying to serialize this:
public class HashTree<K, V> extends HashMap<K, HashTree<K, V>>
Is this a limitation of Jackson or am I doing something wrong?
http://stackoverflow.com/questions/12466292/serializing-a-recursive-class-with-jackson-json
Thanks!
Although JSON specification does not make duplicate Object values strictly illegal (behavior is undefined I think), their existence is problematic, as behavior is not specified.
On the other hand, checking for duplicates adds non-trivial amount of cost which for valid content is pure overhead.
So it would probably make sense to add a feature to let users request that duplicate detection is enabled, and reported as an exception. For bonus points it should be possible to dynamically enable this via ObjectMapper
(from databind) as well, since this will allow per-request handling (as opposed to JsonParser
feature which may be more difficult to set).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.