The javax.json.bind.JsonbException: Can’t deserialize JSON array into: class exception occurs when you try to convert json string data to a java object. If the json string contains an array of objects and attempts to deserialize the json string to a json object, the array of objects could not be assigned to a single java object. The deserialization exception javax.json.bind.JsonbException: Can’t deserialize JSON array into: class is therefore thrown while binding the json data.
The program attempts to deserialize the json string into a java object. The data binding api can not deserialize the string due to the json string and the java class not matching. The spring boot application will read and interpret the json file, the error is when the parsed input is translated to the java object
We’ll see in this post about this exception javax.json.bind.JsonbException: Can’t deserialize JSON array into: class and how this exception can be resolved.
Exception
Exception in thread "main" javax.json.bind.JsonbException: Can't deserialize JSON array into: class com.yawintutor.Student
at org.eclipse.yasson.internal.serializer.DeserializerBuilder.build(DeserializerBuilder.java:151)
at org.eclipse.yasson.internal.Unmarshaller.deserializeItem(Unmarshaller.java:66)
at org.eclipse.yasson.internal.Unmarshaller.deserialize(Unmarshaller.java:52)
at org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:59)
at org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:66)
at com.yawintutor.SpringBootJsonbSimpleApplication.JSONToJavaObjectArray(SpringBootJsonbSimpleApplication.java:49)
at com.yawintutor.SpringBootJsonbSimpleApplication.main(SpringBootJsonbSimpleApplication.java:19)
Root Cause
The exception “javax.json.bind.JsonbException: Can’t deserialize JSON array into: class com.yawintutor.Student” clearly states that during deserialization of the json string, it has some issue. The json string contains root as array of objects. In the spring boot application, it attempts to convert to a java object. Java can not allocate an array to an object.
Convert the json string into object array in the “fromJson” api. This addresses the exception.
How to reproduce this issue
In the spring boot application, add all dependency for json binding. create a json string containing objects in an array. Using “from Json” api in the program to convert json string to an object in java. The input json string includes an object list, and the program attempts to allocate to an object in java. This is going to throw out the exception.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.yawintutor</groupId>
<artifactId>Spring-Application</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBootJsonbSimple</name>
<description>Spring Boot Project</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Student.java
package com.yawintutor;
public class Student {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
SpringBootJsonbSimpleApplication.java
package com.yawintutor;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootJsonbSimpleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootJsonbSimpleApplication.class, args);
JavaObjectArraytoJSON();
JSONToJavaObjectArray();
}
public static void JavaObjectArraytoJSON() {
Student student1 = new Student();
student1.setId(100);
student1.setName("Yawin");
Student student2 = new Student();
student2.setId(101);
student2.setName("Spring Boot");
Student[] studentArray = new Student[2];
studentArray[0] = student1;
studentArray[1] = student2;
Jsonb jsonb = JsonbBuilder.create();
String jsonString = jsonb.toJson(studentArray);
System.out.println("Json format String : " + jsonString);
}
public static void JSONToJavaObjectArray() {
String jsonString = "[{\"id\":100,\"name\":\"Yawin\"},{\"id\":101,\"name\":\"Spring Boot\"}]";
Jsonb jsonb = JsonbBuilder.create();
Student st = jsonb.fromJson(jsonString, Student.class);
System.out.println(st.getId() + " " + st.getName());
}
Output
Exception in thread "main" javax.json.bind.JsonbException: Can't deserialize JSON array into: class com.yawintutor.Student
at org.eclipse.yasson.internal.serializer.DeserializerBuilder.build(DeserializerBuilder.java:151)
at org.eclipse.yasson.internal.Unmarshaller.deserializeItem(Unmarshaller.java:66)
at org.eclipse.yasson.internal.Unmarshaller.deserialize(Unmarshaller.java:52)
at org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:59)
at org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:66)
at com.yawintutor.SpringBootJsonbSimpleApplication.JSONToJavaObjectArray(SpringBootJsonbSimpleApplication.java:49)
at com.yawintutor.SpringBootJsonbSimpleApplication.main(SpringBootJsonbSimpleApplication.java:19)
Solution 1
The json string includes objects in an array. Hence, type cast the json string to an array of java objects. This will resolve this exception. The code below illustrates how to transform a json string to an array of objects in java.
Student[] studentArray = jsonb.fromJson(jsonString, new Student[] {}.getClass() );
The complete java code to convert from a json string to a Java object array is shown as
SpringBootJsonbSimpleApplication.java
package com.yawintutor;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootJsonbSimpleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootJsonbSimpleApplication.class, args);
JavaObjectArraytoJSON();
JSONToJavaObjectArray();
}
public static void JavaObjectArraytoJSON() {
Student student1 = new Student();
student1.setId(100);
student1.setName("Yawin");
Student student2 = new Student();
student2.setId(101);
student2.setName("Spring Boot");
Student[] studentArray = new Student[2];
studentArray[0] = student1;
studentArray[1] = student2;
Jsonb jsonb = JsonbBuilder.create();
String jsonString = jsonb.toJson(studentArray);
System.out.println("Json format String : " + jsonString);
}
public static void JSONToJavaObjectArray() {
String jsonString = "[{\"id\":100,\"name\":\"Yawin\"},{\"id\":101,\"name\":\"Spring Boot\"}]";
Jsonb jsonb = JsonbBuilder.create();
Student[] studentArray = jsonb.fromJson(jsonString, new Student[] {}.getClass() );
for(Student st : studentArray) {
System.out.println(st.getId() + " " + st.getName());
}
}
}
Output
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.5.RELEASE)
2020-03-16 07:51:20.073 INFO 52723 --- [ main] c.y.SpringBootJsonbSimpleApplication : Starting SpringBootJsonbSimpleApplication on banl1691b9157 with PID 52723 (/Users/knatarajan2/STS/workspace/SpringBootJsonbSimple/target/classes started by knatarajan2 in /Users/knatarajan2/STS/workspace/SpringBootJsonbSimple)
2020-03-16 07:51:20.075 INFO 52723 --- [ main] c.y.SpringBootJsonbSimpleApplication : No active profile set, falling back to default profiles: default
2020-03-16 07:51:20.489 INFO 52723 --- [ main] c.y.SpringBootJsonbSimpleApplication : Started SpringBootJsonbSimpleApplication in 0.649 seconds (JVM running for 3.209)
Json format String : [{"id":100,"name":"Yawin"},{"id":101,"name":"Spring Boot"}]
100 Yawin
101 Spring Boot
Solution 2
If the json string is expected to de-serialize the java object, make sure that the json string data contains the object data. The json string should not have an object data array. The json string should be the following example.
SpringBootJsonbSimpleApplication.java
package com.yawintutor;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootJsonbSimpleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootJsonbSimpleApplication.class, args);
JavaObjectArraytoJSON();
JSONToJavaObject();
}
public static void JavaObjectArraytoJSON() {
Student student1 = new Student();
student1.setId(100);
student1.setName("Yawin");
Student student2 = new Student();
student2.setId(101);
student2.setName("Spring Boot");
Student[] studentArray = new Student[2];
studentArray[0] = student1;
studentArray[1] = student2;
Jsonb jsonb = JsonbBuilder.create();
String jsonString = jsonb.toJson(studentArray);
System.out.println("Json format String : " + jsonString);
}
public static void JSONToJavaObject() {
String jsonString = "{\"course\":\"BCOM\",\"id\":100,\"name\":\"Yawin\"}";
Jsonb jsonb = JsonbBuilder.create();
Student st = jsonb.fromJson(jsonString, Student.class);
System.out.println(st.getId() + " " + st.getName()+" "+st.getCourse().name());
}
}
Output
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.5.RELEASE)
2021-02-24 19:44:21.170 INFO 6745 --- [ main] c.y.SpringBootJsonbSimpleApplication : Starting SpringBootJsonbSimpleApplication on intul1807201e8 with PID 6745 (/Users/knatarajan2/STS/workspace/SpringBootJsonbSimple/target/classes started by knatarajan2 in /Users/knatarajan2/STS/workspace/SpringBootJsonbSimple)
2021-02-24 19:44:21.173 INFO 6745 --- [ main] c.y.SpringBootJsonbSimpleApplication : No active profile set, falling back to default profiles: default
2021-02-24 19:44:21.624 INFO 6745 --- [ main] c.y.SpringBootJsonbSimpleApplication : Started SpringBootJsonbSimpleApplication in 2.925 seconds (JVM running for 3.257)
Json format String : {"course":"BCOM","id":100,"name":"Yawin"}
100 Yawin BCOM
Solution 3
More details on how to use json binding api are explained in the links below.