7

I have a basic SpringBoot 2.1.5.RELEASE app. Using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file with some RestControllers.

In 1 of the controller this is the body I send:

{
    "depositHotel": "xxx",
    "destinationHotel": "aaa",
    "depositHotelAmount": "0.2",
    "destinationHotelAmount": "4",
    "destinationAddress": [{
        "address": "asdf",
        "tag": ""
    }],
    "refundAddress": [{
        "address": "pio",
        "tag": ""
    }]
}

so I create this class to send it as a RequestBody:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"address",
"tag"
})
public class Address {



    public Address() {
        super();
    }

    public Address(String address) {
        super();
        this.address = address;
    }

    @JsonProperty("address")
    private String address;
    @JsonProperty("tag")
    private Object tag;


    @JsonProperty("address")
    public String getAddress() {
    return address;
    }

    @JsonProperty("address")
    public void setAddress(String address) {
    this.address = address;
    }

    @JsonProperty("tag")
    public Object getTag() {
    return tag;
    }

    @JsonProperty("tag")
    public void setTag(Object tag) {
    this.tag = tag;
    }
}

and

public class HotelswitchHotelOrderRequestBody {

    public static class Builder {

        private String depositHotel;
        private String destinationHotel;
        private Float depositHotelAmount;
        private Float destinationHotelAmount;
        private Address destinationAddress;
        private Address refundAddress;


        public Builder(String depositHotel, String destinationHotel) {
            this.depositHotel = depositHotel;
            this.destinationHotel = destinationHotel;
        }

        public Builder withDepositHotelAmount (Float depositHotelAmount) {
            this.depositHotelAmount = depositHotelAmount;
            return this;  
        }

        public Builder withDestinationHotelAmount (Float destinationHotelAmount) {
            this.destinationHotelAmount = destinationHotelAmount;
            return this;  
        }

        public Builder toDestinationAddress (Address destinationAddress) {
            this.destinationAddress = destinationAddress;
            return this;  
        }

        public Builder toRefundAddress (Address refundAddress) {
            this.refundAddress = refundAddress;
            return this;  
        }

        public HotelswitchHotelOrderRequestBody build(){

            HotelswitchHotelOrderRequestBody order = new HotelswitchHotelOrderRequestBody(); 
            order.depositHotel = this.depositHotel;
            order.depositHotelAmount = this.depositHotelAmount;
            order.destinationAddress = this.destinationAddress;
            order.destinationHotel = this.destinationHotel;
            order.destinationHotelAmount = this.destinationHotelAmount;
            order.refundAddress = this.refundAddress;

            return order;

        }
    }


    private String depositHotel;
    private String destinationHotel;
    private Float depositHotelAmount;
    private Float destinationHotelAmount;
    private Address destinationAddress;
    private Address refundAddress;


    private HotelswitchHotelOrderRequestBody () {
        //Constructor is now private.
    }


    public String getDepositHotel() {
        return depositHotel;
    }


    public void setDepositHotel(String depositHotel) {
        this.depositHotel = depositHotel;
    }


    public String getDestinationHotel() {
        return destinationHotel;
    }


    public void setDestinationHotel(String destinationHotel) {
        this.destinationHotel = destinationHotel;
    }


    public Float getDepositHotelAmount() {
        return depositHotelAmount;
    }


    public void setDepositHotelAmount(Float depositHotelAmount) {
        this.depositHotelAmount = depositHotelAmount;
    }


    public Float getDestinationHotelAmount() {
        return destinationHotelAmount;
    }


    public void setDestinationHotelAmount(Float destinationHotelAmount) {
        this.destinationHotelAmount = destinationHotelAmount;
    }


    public Address getDestinationAddress() {
        return destinationAddress;
    }


    public void setDestinationAddress(Address destinationAddress) {
        this.destinationAddress = destinationAddress;
    }


    public Address getRefundAddress() {
        return refundAddress;
    }

    public void setRefundAddress(Address refundAddress) {
        this.refundAddress = refundAddress;
    }
}

and

public test postOrder ( HotelswitchHotelOrderRequestBody order) {



        HttpEntity<String> entity = new HttpEntity<String>(new JSONObject(order).toString(), headers());

        ResponseEntity<OrderResponse> response = new RestTemplate()
                  .exchange(URL, 
                          HttpMethod.POST, entity,  new ParameterizedTypeReference<OrderResponse>() {});

        return response.getBody();

    }

But i have this error:

java.lang.NoSuchMethodError: org.json.JSONObject.<init>(Ljava/lang/Object;)V
    at io.bonanza.backend.service.Hotelswitch.HotelswitchHotelService.postOrder(HotelswitchHotelService.java:132)
    at io.bonanza.backend.service.Hotelswitch.HotelswitchHotelServiceTests.testPostOrder(HotelswitchHotelServiceTests.java:151)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

pom.xml:

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>       

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency> 

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
         </dependency>

         <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.googlecode.libphonenumber</groupId>
            <artifactId>libphonenumber</artifactId>
            <version>8.9.0</version>
        </dependency>


        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </dependency>

        <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

        <!-- Spring Security -->

        <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-test -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>





        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
           <!--  <version>4.5.4</version> -->
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

           <!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
       <dependency>
          <groupId>javax.ws.rs</groupId>
          <artifactId>javax.ws.rs-api</artifactId>
          <version>2.1.1</version>
       </dependency>


        <!-- Firebase dependencies -->
       <dependency>
            <groupId>com.google.firebase</groupId>
            <artifactId>firebase-admin</artifactId>
            <version>5.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>google-cloud-firestore</artifactId>
            <version>0.26.0-beta</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>23.0</version>
        </dependency>

    </dependencies>
Nunyet de Can Calçada
  • 3,615
  • 32
  • 127
  • 219
  • 1
    Add your POM please. This is normally due to not allowing Spring to manage dependencies.it manages. – Darren Forsythe Jun 01 '19 at 10:04
  • Some times there are problems with the dependencies in the pom.xml file ( Maven). There could be many reasons for that: a conflict in versions, or conflict declaring the same dependency twice with different versions. – MangduYogii Jun 04 '19 at 08:47
  • Could you post the result of mvn dependency:tree? – Shubham Kadlag Jun 05 '19 at 05:44
  • Which Java version are you using to run this? – Robin479 Jun 11 '19 at 00:28
  • For this problem, there are multi-version of [org.json](https://github.com/stleary/JSON-java) imported. The solution is exclude it from the dependency from which it was import, and specify the expected one. Furthermore, you can use [fastjson](https://sourceforge.net/projects/fastjson/) which was also imported in your project. – caisil Jun 11 '19 at 00:28

7 Answers7

10

It looks like you have more than one org.json:json dependency on your classpath.

Looking at it:

org.springframework.boot:spring-boot-starter-test depends on

com.jayway.jsonpath:json-pathwhich in turn brings

org.json:json which is may be newer/older than the version on which

io.jsonwebtoken jjwt 0.9.1 is dependend on

You could try excluding this transitive dependency from spring-boot-starter-test/io.jsonwebtoken:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
        </exclusion>
    </exclusions>
</dependency>

OR/AND

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
    <exclusions>
        <exclusion>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
        </exclusion>
    </exclusions>
</dependency>

But it's possible that there is something within json-path which depends on something from the older json library, which is no longer in the newer version, so proceed with caution and test everything thoroughly. There is also a chance that something else brings org.json:json.

To verify, please run mvn dependency:tree and search in the produced output for org.json:json.

Shubham Kadlag
  • 2,087
  • 1
  • 10
  • 31
  • Please comment if there was any problem following the answer or if didn't work. If it solved the problem accepting the answer would be appreciated. – Shubham Kadlag Jun 07 '19 at 13:13
2

I found this on another page. I tried the checked answer here and it didn't work with mine, but when I inserted this into my pom file it worked. I'm running unit tests with mockito and one of the endpoints uses JSONObject.put and was giving me the no such method error.

<dependency>
        <groupId>
            org.springframework.boot
        </groupId>
        <artifactId>
            spring-boot-starter-test
        </artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.vaadin.external.google</groupId>
                <artifactId>android-json</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
rreay724
  • 55
  • 1
  • 7
0

Your destinationAddress and refundAddress are passed as list of address or address array in the JSON while in the HotelswitchHotelOrderRequestBody your destinationAddress and refundAddress are refered to as single Address Element. Update your pojo or JSON and try again. This might be an issue.

Yogesh Patil
  • 877
  • 4
  • 13
0

You need to convert your POJO to JSONObject using ObjectMapper or include json dependency

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20180130</version>
</dependency>
user7294900
  • 47,183
  • 17
  • 74
  • 157
0

The issue should be the destinationAddress and refundAddress is mismatch between your JSON and POJO. Try to change your JSON like this:

{ "depositHotel": "xxx", "destinationHotel": "aaa", "depositHotelAmount": "0.2", "destinationHotelAmount": "4", "destinationAddress": { "address": "asdf", "tag": "" }, "refundAddress": { "address": "pio", "tag": "" } }

If you dont want to change your JSON, change your Builder POJO to use Address[] instead of Address object.

Hưng Chu
  • 733
  • 3
  • 9
0

You should not need the JSONobject

HttpEntity<HotelswitchHotelOrderRequestBody> entity = new HttpEntity<HotelswitchHotelOrderRequestBody>(order, headers());

if all you want to do is to convert your object to a string then use an object mapper.

ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(car)
Toerktumlare
  • 6,765
  • 3
  • 13
  • 33
0

Please check this link : spring-boot issue 8706

Exclusion of android-json from spring-boot-starter-test worked for me.

 <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>com.vaadin.external.google</groupId>
                <artifactId>android-json</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
venugopal
  • 342
  • 4
  • 13