Merge pull request #706 from KyleAure/703-url-stacktrace
fix: handle maformed resources [URL, URI]
diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/UriDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/UriDeserializer.java
index 26ea0fb..59b9425 100644
--- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/UriDeserializer.java
+++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/UriDeserializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -14,8 +14,13 @@
import java.lang.reflect.Type;
import java.net.URI;
+import java.net.URISyntaxException;
+
+import jakarta.json.bind.JsonbException;
import org.eclipse.yasson.internal.DeserializationContextImpl;
+import org.eclipse.yasson.internal.properties.MessageKeys;
+import org.eclipse.yasson.internal.properties.Messages;
/**
* Deserializer of the {@link URI} type.
@@ -28,6 +33,10 @@
@Override
Object deserializeStringValue(String value, DeserializationContextImpl context, Type rType) {
- return URI.create(value);
+ try {
+ return new URI(value);
+ } catch (URISyntaxException e) {
+ throw new JsonbException(Messages.getMessage(MessageKeys.URI_PARSE_ERROR, value), e);
+ }
}
}
diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/UrlDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/UrlDeserializer.java
index 54cd2f3..018448f 100644
--- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/UrlDeserializer.java
+++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/UrlDeserializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -16,7 +16,11 @@
import java.net.MalformedURLException;
import java.net.URL;
+import jakarta.json.bind.JsonbException;
+
import org.eclipse.yasson.internal.DeserializationContextImpl;
+import org.eclipse.yasson.internal.properties.MessageKeys;
+import org.eclipse.yasson.internal.properties.Messages;
/**
* Deserializer of the {@link URL} type.
@@ -29,12 +33,10 @@
@Override
Object deserializeStringValue(String value, DeserializationContextImpl context, Type rType) {
- URL url = null;
try {
- url = new URL(value);
+ return new URL(value);
} catch (MalformedURLException e) {
- e.printStackTrace();
+ throw new JsonbException(Messages.getMessage(MessageKeys.URL_PARSE_ERROR, value), e);
}
- return url;
}
}
diff --git a/src/main/java/org/eclipse/yasson/internal/properties/MessageKeys.java b/src/main/java/org/eclipse/yasson/internal/properties/MessageKeys.java
index d08377c..fde557a 100644
--- a/src/main/java/org/eclipse/yasson/internal/properties/MessageKeys.java
+++ b/src/main/java/org/eclipse/yasson/internal/properties/MessageKeys.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2026 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -265,6 +265,14 @@
*/
ZONE_PARSE_ERROR("zoneParseError"),
/**
+ * There has been an error parsing a URI value.
+ */
+ URI_PARSE_ERROR("uriParseError"),
+ /**
+ * There has been an error parsing a URL value.
+ */
+ URL_PARSE_ERROR("urlParseError"),
+ /**
* {@link JsonbTransient} was not the only annotation on class property.
*/
JSONB_TRANSIENT_WITH_OTHER_ANNOTATIONS("jsonbTransientWithOtherAnnotations"),
diff --git a/src/main/resources/yasson-messages.properties b/src/main/resources/yasson-messages.properties
index 4d22449..a059313 100644
--- a/src/main/resources/yasson-messages.properties
+++ b/src/main/resources/yasson-messages.properties
@@ -76,6 +76,8 @@
unknownJsonProperty=Json property {0} can not be mapped to a class {1}.
jsonbCreatorMissingProperty=JsonbCreator parameter {0} is missing in json document.
zoneParseError=Cannot parse zone from json value: {0}
+uriParseError=Cannot parse URI from json value: {0}
+urlParseError=Cannot parse URL from json value: {0}
jsonbTransientWithOtherAnnotations=JsonbTransient annotation cannot be used with other jsonb annotations on the same property.
nonParametrizedType=Type: {0} is not a parametrized type.
propertyNameClash=Property {0} clashes with property {1} by read or write name in class {2}.
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java
index 4963b12..afd68ba 100644
--- a/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2026 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -15,6 +15,8 @@
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.net.URI;
+import java.net.URL;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
@@ -30,6 +32,7 @@
import org.eclipse.yasson.TestTypeToken;
import org.eclipse.yasson.defaultmapping.generics.model.GenericTestClass;
+import org.eclipse.yasson.defaultmapping.generics.model.ScalarValueWrapper;
import org.eclipse.yasson.defaultmapping.specific.model.ClassWithUnsupportedFields;
import org.eclipse.yasson.defaultmapping.specific.model.CustomUnsupportedInterface;
import org.eclipse.yasson.defaultmapping.specific.model.SupportedTypes;
@@ -69,7 +72,7 @@
String expected = "{\"customInterface\":{\"value\":\"value1\"}}";
assertEquals(expected, defaultJsonb.toJson(unsupported));
try {
- defaultJsonb.fromJson(expected, ClassWithUnsupportedFields.class);
+ defaultJsonb.fromJson(expected, ClassWithUnsupportedFields.class);
fail("Should report an error");
} catch (JsonbException e) {
assertTrue(e.getMessage().contains("Cannot infer a type"));
@@ -133,11 +136,11 @@
@Test
public void testMissingFieldIgnored() {
- assertThrows(JsonbException.class, () -> {
- Jsonb defaultConfig = JsonbBuilder.create(new JsonbConfig().setProperty(FAIL_ON_UNKNOWN_PROPERTIES, true));
- String json = "{\"nestedPojo\":{\"integerValue\":10,\"missingField\":5},\"optionalLong\":11}";
- SupportedTypes result = defaultConfig.fromJson(json, SupportedTypes.class);
- });
+ assertThrows(JsonbException.class, () -> {
+ Jsonb defaultConfig = JsonbBuilder.create(new JsonbConfig().setProperty(FAIL_ON_UNKNOWN_PROPERTIES, true));
+ String json = "{\"nestedPojo\":{\"integerValue\":10,\"missingField\":5},\"optionalLong\":11}";
+ SupportedTypes result = defaultConfig.fromJson(json, SupportedTypes.class);
+ });
}
@Test
@@ -223,11 +226,33 @@
Type type = new TestTypeToken<GenericTestClass<OptionalLong, OptionalLong>>(){}.getType();
assertFail("{\"field1\":\"\"}", type,"field1", Long.class); //We are reusing Long deserializer
}
+
+ @Test
+ public void testMalformedURL() {
+ Type type = new TestTypeToken<ScalarValueWrapper<URL>>(){}.getType();
+ try {
+ defaultJsonb.fromJson("{\"value\":\"www.oracle.com\"}", type);
+ fail("Expected to catch JsonbException but did not");
+ } catch (JsonbException e) {
+ assertTrue(e.getMessage().contains("Cannot parse URL") && e.getMessage().contains("www.oracle.com"));
+ }
+ }
+
+ @Test
+ public void testMalformedURI() {
+ Type type = new TestTypeToken<ScalarValueWrapper<URI>>(){}.getType();
+ try {
+ defaultJsonb.fromJson("{\"value\":\"www .oracle .com\"}", type);
+ fail("Expected to catch JsonbException but did not");
+ } catch (JsonbException e) {
+ assertTrue(e.getMessage().contains("Cannot parse URI") && e.getMessage().contains("www .oracle .com"));
+ }
+ }
private void assertFail(String json, Type type, String failureProperty, Class<?> failurePropertyClass) {
try {
- defaultJsonb.fromJson(json, type);
- fail();
+ defaultJsonb.fromJson(json, type);
+ fail("Expected to catch JsonbException but did not");
} catch (JsonbException e) {
if(!e.getMessage().contains(failureProperty) || !e.getMessage().contains(failurePropertyClass.getName())) {
fail("Expected error message to contain '" + failureProperty + "' and '" + failurePropertyClass.getName() + "', but was: " +