Skip to content

INT-4543: JacksonJsonObjectMapper: fix toJsonNode #2592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 10, 2018

Conversation

artembilan
Copy link
Member

JIRA: https://jira.spring.io/browse/INT-4543

When inbound payload is type of String, byte[], File, URL,
InputStream or Reader, we have to use an ObjectMapper.readTree()
function.
For all other types the valueToTree() should be used as a fallback

Cherry-pick to 5.0.x

@@ -137,7 +157,8 @@ protected JavaType extractJavaType(Map<String, Object> javaTypes) throws Excepti
JavaType contentClassType = this.createJavaType(javaTypes, JsonHeaders.CONTENT_TYPE_ID);
if (classType.getKeyType() == null) {
return this.objectMapper.getTypeFactory()
.constructCollectionType((Class<? extends Collection<?>>) classType.getRawClass(), contentClassType);
.constructCollectionType((Class<? extends Collection<?>>) classType
.getRawClass(), contentClassType);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More IDEA weirdness - did you upgrade again?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I get this option since I moved to new Mac Book.
So, it is independent of the upgrade.
I'll switch off an option to wrap if longer then 120.

Copy link
Contributor

@garyrussell garyrussell Oct 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's something else...

			return this.objectMapper.getTypeFactory()
					.constructCollectionType((Class<? extends Collection<?>>) classType.getRawClass(), 
							contentClassType);

is wrapped at 102 so I don't know why it split at 87; maybe wrapping at 90?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, original line for me in IDEA looks like this:

image

So, it is longer than 120, therefore during reformatting IDEA decides to wrap it on the last . assuming it is a method call. That's what I see in other cases you pointed, too.

I don't think it's a big deal to have a discussion now. And unfortunately I don't see how to turn it off now 😢

public JsonNode toJsonNode(Object json) throws Exception {
if (json instanceof String) {
return this.objectMapper.readTree((String) json);
}
Copy link
Contributor

@garyrussell garyrussell Oct 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not as simple as this; if it's a simple String (rather than a String containing JSON), we need to encode foo as "foo".

org.springframework.integration.transformer.MessageTransformationException: failed to transform message; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'foo': was expecting 'null', 'true', 'false' or NaN
 at [Source: (String)"foo"; line: 1, column: 7], failedMessage=GenericMessage [payload=foo, headers={id=de53795e-2ab8-e5a0-032a-b20b38700a8e, timestamp=1539113912065}]
	at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:44)
	at org.springframework.integration.json.ObjectToJsonTransformerTests.testJsonStringAndJsonNode(ObjectToJsonTransformerTests.java:241)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
	at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:39)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.Iterator.forEachRemaining(Iterator.java:116)
	at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
	at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:79)
	at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:70)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
	at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'foo': was expecting 'null', 'true', 'false' or NaN
 at [Source: (String)"foo"; line: 1, column: 7]
	at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1804)
	at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:679)
	at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2835)
	at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2813)
	at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._matchToken2(ReaderBasedJsonParser.java:2620)
	at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._matchToken(ReaderBasedJsonParser.java:2598)
	at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._matchFalse(ReaderBasedJsonParser.java:2572)
	at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:719)
	at com.fasterxml.jackson.databind.ObjectMapper._readTreeAndClose(ObjectMapper.java:4042)
	at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:2551)
	at org.springframework.integration.support.json.Jackson2JsonObjectMapper.toJsonNode(Jackson2JsonObjectMapper.java:96)
	at org.springframework.integration.support.json.Jackson2JsonObjectMapper.toJsonNode(Jackson2JsonObjectMapper.java:1)
	at org.springframework.integration.json.ObjectToJsonTransformer.buildJsonPayload(ObjectToJsonTransformer.java:147)
	at org.springframework.integration.json.ObjectToJsonTransformer.doTransform(ObjectToJsonTransformer.java:115)
	at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:33)
	... 44 more

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow this was dropped from my review.

@artembilan
Copy link
Member Author

DO NOT MERGE YET.

We shouldn't fallback to the valueToTree() if that is not simple String or byte[].

@artembilan artembilan changed the title INT-4543: JacksonJsonObjectMapper: fix toJsonNode [DO NOT MERGE YET] INT-4543: JacksonJsonObjectMapper: fix toJsonNode Oct 10, 2018
JIRA: https://jira.spring.io/browse/INT-4543

When inbound payload is type of `String`, `byte[]`, `File`, `URL`,
`InputStream` or `Reader`, we have to use an `ObjectMapper.readTree()`
function.
For all other types the `valueToTree()` should be used as a fallback

**Cherry-pick to 5.0.x**
@artembilan artembilan changed the title [DO NOT MERGE YET] INT-4543: JacksonJsonObjectMapper: fix toJsonNode INT-4543: JacksonJsonObjectMapper: fix toJsonNode Oct 10, 2018
@artembilan
Copy link
Member Author

Ready for review.

Thanks

@garyrussell garyrussell merged commit ddcfa25 into spring-projects:master Oct 10, 2018
garyrussell pushed a commit that referenced this pull request Oct 10, 2018
* INT-4543: JacksonJsonObjectMapper: fix toJsonNode

JIRA: https://jira.spring.io/browse/INT-4543

When inbound payload is type of `String`, `byte[]`, `File`, `URL`,
`InputStream` or `Reader`, we have to use an `ObjectMapper.readTree()`
function.
For all other types the `valueToTree()` should be used as a fallback

**Cherry-pick to 5.0.x**

* * Fallback to the `valueToTree()` if not valid JSON

* * Fallback to `valueToTree()` only for `String` and `byte[]`
@garyrussell
Copy link
Contributor

Cherry-picked as 5874ae8 after resolving test conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants