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: " +