Skip to content
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

spring-boot-starter-test conflicts with json library #8706

Closed
syakovyn opened this issue Mar 23, 2017 · 11 comments
Closed

spring-boot-starter-test conflicts with json library #8706

syakovyn opened this issue Mar 23, 2017 · 11 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@syakovyn
Copy link

syakovyn commented Mar 23, 2017

Hi,

org.springframework.boot:spring-boot-starter-test -> 1.5.2.RELEASE has an indirect dependency on com.vaadin.external.google:android-json:0.0.20131108.vaadin1 via org.skyscreamer:jsonassert:1.4.0.

The reference documentation mentions both org.skyscreamer:jsonassert:1.4.0 and org.json:json:20140107. As far as I understand, they should be compatible. However, com.vaadin.external.google:android-json:0.0.20131108.vaadin1 conflicts with org.json:json:20140107 as it represents the re-implementation of some older version of org.json:json.

In particular, org.json.JSONTokener#JSONTokener(java.io.Reader) exists only in org.json:json:20140107 and is absent in com.vaadin.external.google:android-json:0.0.20131108.vaadin1, causing my tests to fail with java.lang.NoSuchMethodError: org.json.JSONTokener.<init>(Ljava/io/Reader;)V exceptions.

The solution to my issue is not to use spring-boot-starter-test, but instead use spring-boot-test, spring-boot-test-autoconfigure and spring-test directly and add all other dependencies as needed.

In a case, that org.skyscreamer:jsonassert:1.4.0 is required, exclude com.vaadin.external.google:android-json:0.0.20131108.vaadin1.

If looking for the JSON assertions library consider net.javacrumbs.json-unit:json-unit-fluent that has similar to AssertJ fluent API.

Thanks,
Serhiy

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Mar 23, 2017
@philwebb
Copy link
Member

Do you have a complete stack-trace that you can attach? I'm interested to know what's the root trigger for the problem.

@philwebb philwebb added the status: waiting-for-feedback We need additional information before we can continue label Mar 23, 2017
@syakovyn
Copy link
Author

java.lang.NoSuchMethodError: org.json.JSONTokener.(Ljava/io/Reader;)V

at net.javacrumbs.jsonunit.core.internal.JsonOrgNodeFactory.readValue(JsonOrgNodeFactory.java:48)
at net.javacrumbs.jsonunit.core.internal.AbstractNodeFactory.convertToNode(AbstractNodeFactory.java:31)
at net.javacrumbs.jsonunit.core.internal.Converter.convertToNode(Converter.java:114)
at net.javacrumbs.jsonunit.core.internal.JsonUtils.convertToJson(JsonUtils.java:60)
at net.javacrumbs.jsonunit.core.internal.JsonUtils.convertToJson(JsonUtils.java:48)
at net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson(JsonFluentAssert.java:93)
at com.company.widget.WidgetRequestHandlerTest.shouldNotifyAboutTenantIdIsMissing(WidgetRequestHandlerTest.java:118)
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:497)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
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:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Mar 23, 2017
@philwebb
Copy link
Member

Thanks. It looks like net.javacrumbs.jsonunit.core.internal.JsonUtils isn't compatible with android-json. I'm guessing jsonassert happens to work with both and that's why when you exclude android-json and plug in org.json things are happy.

I'm not sure there's much that we can do about this. The org.json library has a very unhelpful "don't be evil" clause in its license (see #5929 for background). We don't really want to recommend it to our users because it can cause so many legal issues. We also have our own fluent JSON test classes so we're unlikely to want to add json-unit-fluent to the mix.

It might be worth suggesting to json-unit-fluent that they consider switching to android-json as well. The liberal Apache 2.0 license is much better for most corporate users.

As an aside, you can still use spring-boot-starter-test if you want to. You'll just need to exclude the problematic dependency.

@philwebb philwebb added status: invalid An issue that we don't feel is valid and removed status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels Mar 23, 2017
@syakovyn
Copy link
Author

Thank you for your recommendations! Will consider them.

@martin-g
Copy link

Let me add some more details to this topic.
Few months ago Ted Dunning introduced https://github.com/tdunning/open-json - a reimplementation of JSON.org done by Google Android team just because of the stupid licence.
Unfortunately it has two problems:

  • doesn't provide 100% coverage of the JSON.org API
  • still uses the same package names

And this quickly led to tdunning/open-json#11.
So now there is also https://github.com/openjson/openjson - a fork of Ted Dunning's repo but with its own package names com.github.openjson

@wilkinsona
Copy link
Member

I think it might be worth getting rid of our remaining optional dependency on org.json:json and then we could also get rid of our dependency management for it. I've opened #8710.

@rajeshja
Copy link

rajeshja commented Feb 15, 2019

Is there a specific way to get this to work? I'm using Gradle 5.2 and Java 11 with a very simple project that adds a controller and an entity package to the base starter created with Spring 2.1.2. The code in src/main/java is setup as a Java module. He is my module definition (I only have one at this time)

module rja.price.main {
    requires java.sql;
    requires spring.beans;
    requires spring.core;
    requires spring.context;
    requires spring.web;
    requires spring.webflux;
    requires spring.boot;
    requires spring.boot.autoconfigure;
    requires reactor.core;
    opens rja.price to spring.core, spring.beans, spring.context;
    exports rja.price.application.controller;
    exports rja.price.domain.entity to com.fasterxml.jackson.databind;
}

Running gradlew build breaks at compileTestJava with 100 errors of the form:

error: the unnamed module reads package org.json from both jsonassert and android.json
error: the unnamed module reads package org.hamcrest from both hamcrest.core and hamcrest.library
error: module spring.boot reads package org.json from both jsonassert and android.json
error: module spring.boot reads package org.hamcrest from both hamcrest.core and hamcrest.library

The code seems to run fine from IDEA though.

@rajeshja
Copy link

Should I log this as a new bug or should this one be reopened? The workaround mentioned in the original post still works.

@wilkinsona
Copy link
Member

From what you've said thus far, you seem to have a different, although perhaps related, problem. Please open a new issue and provide a complete sample (as a zipped attachment or a separate Git repository) that reproduces the problem.

@rajeshja
Copy link

Thanks. Doing so now.

@rajeshja
Copy link

Created new bug at #15967

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

6 participants