-
Notifications
You must be signed in to change notification settings - Fork 53.3k
Bael 7805 how to fix json io exception failed making field property accessible in gson #19293
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
base: master
Are you sure you want to change the base?
Changes from all commits
037df57
8680734
ef3482d
94a64da
3753c06
ad79e4b
e3eaa0d
a461a1d
be445b0
88a9b48
af29485
2c42e30
9137581
31bc8dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <?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"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <parent> | ||
| <groupId>com.baeldung</groupId> | ||
| <artifactId>gson-4</artifactId> | ||
| <version>1.0.0-SNAPSHOT</version> | ||
| </parent> | ||
|
|
||
| <artifactId>gson-module-opens</artifactId> | ||
| <packaging>jar</packaging> | ||
| </project> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package gson.exception; | ||
|
|
||
| public class ConferencePojo { | ||
|
|
||
| private String name; | ||
| private int numberOfParticipants; | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public int getNumberOfParticipants() { | ||
| return numberOfParticipants; | ||
| } | ||
|
|
||
| public void setName(String name) { | ||
| this.name = name; | ||
| } | ||
|
|
||
| public void setNumberOfParticipants(int numberOfParticipants) { | ||
| this.numberOfParticipants = numberOfParticipants; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package gson.exception; | ||
|
|
||
| import java.time.LocalDate; | ||
|
|
||
| public class ConferencePojoWithDate { | ||
|
|
||
| private String name; | ||
| private int numberOfParticipants; | ||
| private LocalDate conferenceStart; | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public int getNumberOfParticipants() { | ||
| return numberOfParticipants; | ||
| } | ||
|
|
||
| public void setName(String name) { | ||
| this.name = name; | ||
| } | ||
|
|
||
| public void setNumberOfParticipants(int numberOfParticipants) { | ||
| this.numberOfParticipants = numberOfParticipants; | ||
| } | ||
|
|
||
| public LocalDate getConferenceStart() { | ||
| return conferenceStart; | ||
| } | ||
|
|
||
| public void setConferenceStart(LocalDate conferenceStart) { | ||
| this.conferenceStart = conferenceStart; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package gson.exception; | ||
|
|
||
| import java.time.LocalDate; | ||
|
|
||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| import com.google.gson.Gson; | ||
|
|
||
| public class GsonModuleMain { | ||
|
|
||
| static Logger log = LoggerFactory.getLogger(GsonModuleMain.class); | ||
|
|
||
| public static void main(String[] args) { | ||
|
|
||
| String moduleName = GsonModuleMain.class.getModule() | ||
| .getName(); | ||
|
|
||
| if (moduleName == null) { | ||
| log.info("Mode: [ Class Path ] (Class in the Unnamed Module)"); | ||
| } else { | ||
| log.info("Mode: [ Module Path ] - Module name: " + moduleName); | ||
| } | ||
| LocalDate excpectedDate = LocalDate.of(2026, 8, 17); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is unused - let's remove it (and the import) |
||
| Gson gson = new Gson(); | ||
| String json = "{\"name\":\"Java Conference\"}"; | ||
|
|
||
| try { | ||
| ConferencePojo pojo = gson.fromJson(json, ConferencePojo.class); | ||
| log.info("Deserialization successful! Object " + pojo); | ||
| } catch (Exception e) { | ||
| log.info("Expected exception caught!"); | ||
| e.printStackTrace(); | ||
| } | ||
|
Comment on lines
+31
to
+34
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. e.printStackTrace() still counts as using System.out - if you want to log the exception put it as a parameter in the logging call - and the logging level should probably be error Alternatively just let the main method throw exception so we don't have to handle this at all |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| module gson.exception { | ||
|
|
||
| requires com.google.gson; | ||
| requires org.slf4j; | ||
|
|
||
| opens gson.exception to com.google.gson; | ||
|
|
||
| exports gson.exception; | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing newline at end of file |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package gson.exception; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; | ||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
|
|
||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import com.google.gson.Gson; | ||
|
|
||
| class ModularOpensGsonUnitTest { | ||
|
|
||
| @Test | ||
| void givenModularAndOpens_whenDeserializingPojo_thenSuccess() { | ||
| String json = "{\"name\":\"Java Conference\",\"numberOfParticipants\":150}"; | ||
| Gson gson = new Gson(); | ||
|
|
||
| ConferencePojo result = assertDoesNotThrow(() -> { | ||
| return gson.fromJson(json, ConferencePojo.class); | ||
| }); | ||
|
|
||
| assertNotNull(result); | ||
| assertEquals("Java Conference", result.getName()); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package gson.exception; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
|
||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| class ModularStructureConfirmationUnitTest { | ||
|
|
||
| @Test | ||
| void whenModular_thenModuleIsNamed() { | ||
| Module module = this.getClass() | ||
| .getModule(); | ||
|
|
||
| assertTrue(module.isNamed(), "Test run on Classpath, JPMS strong encapsulation won't work!"); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||
| package gson.exception; | ||||||
|
|
||||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
| import static org.junit.jupiter.api.Assertions.assertThrows; | ||||||
|
|
||||||
| import java.time.LocalDate; | ||||||
|
|
||||||
| import org.junit.jupiter.api.Test; | ||||||
|
|
||||||
| import com.google.gson.Gson; | ||||||
| import com.google.gson.JsonSyntaxException; | ||||||
|
|
||||||
| class PojoWithLocalDateUnitTest { | ||||||
|
|
||||||
| @Test | ||||||
| void whenObjectDateFormat_thenSuccessfulDeserialization() { | ||||||
| String correctJson = "{" | ||||||
| + "\"name\":\"Java Conference\"," | ||||||
| + "\"numberOfParticipants\":500," | ||||||
| + "\"conferenceStart\":{\"year\":2026,\"month\":8,\"day\":17}" | ||||||
| + "}"; | ||||||
|
Comment on lines
+17
to
+21
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (optional) since you're using a multiline format you can use of the """ syntax so we can avoid the need to escape the double quotes - if you do this then let's make similar changes for all the other JSON strings throughout the codebase |
||||||
|
|
||||||
| Gson gson = new Gson(); | ||||||
| ConferencePojoWithDate result = gson.fromJson(correctJson, ConferencePojoWithDate.class); | ||||||
|
|
||||||
| LocalDate excpectedDate = LocalDate.of(2026, 8, 17); | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Typo |
||||||
| assertEquals(excpectedDate, result.getConferenceStart(), "Date should be the same as in JSON"); | ||||||
| } | ||||||
|
|
||||||
| @Test | ||||||
| void whenISOTextFormat_thenJsonSyntaxException() { | ||||||
|
|
||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have a few of these leading whitespace issues on several methods please remove those blank lines at the start and end of methods |
||||||
| String wrongDateInJson = "{" | ||||||
| + "\"name\":\"Java Conference\"," | ||||||
| + "\"numberOfParticipants\":500," | ||||||
| + "\"conferenceStart\":\"2026-08-17\"" | ||||||
| + "}"; | ||||||
|
|
||||||
| Gson gson = new Gson(); | ||||||
| assertThrows(JsonSyntaxException.class, () -> { | ||||||
| gson.fromJson(wrongDateInJson, ConferencePojoWithDate.class); | ||||||
| }, "JsonSyntaxException was expected due to an incompatible date format"); | ||||||
|
|
||||||
| } | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| <?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"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <parent> | ||
| <groupId>com.baeldung</groupId> | ||
| <artifactId>gson-4</artifactId> | ||
| <version>1.0.0-SNAPSHOT</version> | ||
| </parent> | ||
|
|
||
| <artifactId>gson-module</artifactId> | ||
| <packaging>jar</packaging> | ||
| </project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package gson.exception; | ||
|
|
||
| public class ConferencePojo { | ||
|
|
||
| private String name; | ||
| private int numberOfParticipants; | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public int getNumberOfParticipants() { | ||
| return numberOfParticipants; | ||
| } | ||
|
|
||
| public void setName(String name) { | ||
| this.name = name; | ||
| } | ||
|
|
||
| public void setNumberOfParticipants(int numberOfParticipants) { | ||
| this.numberOfParticipants = numberOfParticipants; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package gson.exception; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| import com.google.gson.TypeAdapter; | ||
| import com.google.gson.stream.JsonReader; | ||
| import com.google.gson.stream.JsonWriter; | ||
|
|
||
| public class ConferencePojoAdapter extends TypeAdapter<ConferencePojo> { | ||
|
|
||
| @Override | ||
| public void write(JsonWriter out, ConferencePojo value) throws IOException { | ||
| throw new UnsupportedOperationException("This adapter is for deserialization only!"); | ||
| } | ||
|
|
||
| @Override | ||
| public ConferencePojo read(JsonReader in) throws IOException { | ||
| String name = null; | ||
| int numberOfParticipants = 0; | ||
|
|
||
| in.beginObject(); | ||
| while (in.hasNext()) { | ||
| String key = in.nextName(); | ||
| if ("name".equals(key)) { | ||
| name = in.nextString(); | ||
| } else if ("numberOfParticipants".equals(key)) { | ||
| numberOfParticipants = in.nextInt(); | ||
| } else { | ||
| in.skipValue(); | ||
| } | ||
| } | ||
| in.endObject(); | ||
|
|
||
| ConferencePojo result = new ConferencePojo(); | ||
| result.setName(name); | ||
| result.setNumberOfParticipants(numberOfParticipants); | ||
|
|
||
| return result; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package gson.exception; | ||
|
|
||
| public class ConferencePojoPublic { | ||
|
|
||
| public String name; | ||
| public int numberOfParticipants; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package gson.exception; | ||
|
|
||
| public record ConferenceRecord(String name, int numberOfParticipants) { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package gson.exception; | ||
|
|
||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| import com.google.gson.Gson; | ||
|
|
||
| public class GsonModuleMain { | ||
|
|
||
| static Logger log = LoggerFactory.getLogger(GsonModuleMain.class); | ||
|
|
||
| public static void main(String[] args) { | ||
|
|
||
| String moduleName = GsonModuleMain.class.getModule() | ||
| .getName(); | ||
|
|
||
| if (moduleName == null) { | ||
| log.info("Mode: [ Class Path ] (Class in the Unnamed Module)"); | ||
| } else { | ||
| log.info("Mode: [ Module Path ] - Module name: " + moduleName); | ||
| } | ||
|
|
||
| Gson gson = new Gson(); | ||
| String json = "{\"name\":\"Java Conference\"}"; | ||
|
|
||
| try { | ||
| ConferencePojo pojo = gson.fromJson(json, ConferencePojo.class); | ||
| log.info("Deserialization successful! Object " + pojo); | ||
| } catch (Exception e) { | ||
| log.info("Expected exception caught!"); | ||
| e.printStackTrace(); | ||
| } | ||
|
MBuczkowski2025 marked this conversation as resolved.
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| module gson.exception { | ||
|
|
||
| requires com.google.gson; | ||
| requires org.slf4j; | ||
|
|
||
| exports gson.exception; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The placeholder namespaces are fixed, but the xsi:schemaLocation attribute is still missing compared with the sibling modules