You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@rya.apache.org by "Jesse Hatfield (JIRA)" <ji...@apache.org> on 2016/04/01 20:29:25 UTC

[jira] [Commented] (RYA-68) Deserializing literals of type xsd:anyURI can fail for some relative URIs

    [ https://issues.apache.org/jira/browse/RYA-68?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15222118#comment-15222118 ] 

Jesse Hatfield commented on RYA-68:
-----------------------------------

Additionally, if the value belongs to the set of strings that pass the RyaURI validation check but aren't valid URIs in the openrdf model, initial deserialization will work but a later conversion using RyaToRdfConversions can throw an exception (either directly converting the object to a Value or converting the whole triple to a Statement). This is because A) the object representing the anyURI literal is now an instance of RyaURI; and B) convertValue uses the object's class to determine whether to convert it as a literal or a URI. Example:
{noformat}import mvm.rya.api.domain.RyaType;
import mvm.rya.api.resolver.RdfToRyaConversions;
import mvm.rya.api.resolver.RyaToRdfConversions;
import mvm.rya.api.resolver.RyaContext;

import org.openrdf.model.impl.ValueFactoryImpl;
import org.openrdf.model.vocabulary.XMLSchema;
import org.openrdf.model.Literal;
import org.openrdf.model.Value;

public class AnyUri {
    public static void main(String[] args) throws Exception {
        ValueFactoryImpl factory = new ValueFactoryImpl();
        Literal lit = factory.createLiteral("test/two", XMLSchema.ANYURI);
        System.out.println(lit.getClass() + ": " + lit);
        RyaType rt = RdfToRyaConversions.convertLiteral(lit);
        System.out.println(rt.getClass() + ": " + rt);
        Value val = RyaToRdfConversions.convertValue(rt);
        System.out.println(val.getClass() + ": " + val);
        rt = RdfToRyaConversions.convertValue(lit);

        System.out.println("(serialize->deserialize)");
        RyaContext context = RyaContext.getInstance();
        byte[] serialization = context.serialize(rt);
        rt = context.deserialize(serialization);

        System.out.println(rt.getClass() + ": " + rt);
        lit = RyaToRdfConversions.convertLiteral(rt);
        System.out.println(lit.getClass() + ": " + lit);
        val = RyaToRdfConversions.convertValue(rt);
        System.out.println(val.getClass() + ": " + val);
    }
}{noformat}
{noformat}class org.openrdf.model.impl.LiteralImpl: "test/two"^^<http://www.w3.org/2001/XMLSchema#anyURI>
class mvm.rya.api.domain.RyaType: RyaType{dataType=http://www.w3.org/2001/XMLSchema#anyURI, data='test/two'}
class org.openrdf.model.impl.LiteralImpl: "test/two"^^<http://www.w3.org/2001/XMLSchema#anyURI>
(serialize->deserialize)
class mvm.rya.api.domain.RyaURI: RyaType{dataType=http://www.w3.org/2001/XMLSchema#anyURI, data='test/two'}
class org.openrdf.model.impl.LiteralImpl: "test/two"^^<http://www.w3.org/2001/XMLSchema#anyURI>
Exception in thread "main" java.lang.IllegalArgumentException: Not a valid (absolute) URI: test/two
	at org.openrdf.model.impl.URIImpl.setURIString(URIImpl.java:79)
	at org.openrdf.model.impl.URIImpl.<init>(URIImpl.java:68)
	at mvm.rya.api.resolver.RyaToRdfConversions.convertURI(RyaToRdfConversions.java:44)
	at mvm.rya.api.resolver.RyaToRdfConversions.convertValue(RyaToRdfConversions.java:58)
	at AnyUri.main(AnyUri.java:30){noformat}

> Deserializing literals of type xsd:anyURI can fail for some relative URIs
> -------------------------------------------------------------------------
>
>                 Key: RYA-68
>                 URL: https://issues.apache.org/jira/browse/RYA-68
>             Project: Rya
>          Issue Type: Bug
>            Reporter: Jesse Hatfield
>            Priority: Minor
>
> When a literal with datatype xsd:anyURI is deserialized, a RyaURI is instantiated with that literal's string value as its uri. RyaURI attempts to validate that uri string using [org.openrdf.model.util.URIUtil.getLocalNameIndex|http://rdf4j.org/sesame/2.7/apidocs/org/openrdf/model/util/URIUtil.html#getLocalNameIndex(java.lang.String)]. This method expects the string to contain a {{#}}, {{/}}, or {{:}} character, and throws an IllegalArgumentException if it doesn't have any of those. Non-relative URIs should always have a {{:}} character, but relative URIs [don't necessarily have to|http://www.ietf.org/rfc/rfc3986.txt], and xsd:anyURI is [meant to include relative URIs|https://www.w3.org/TR/xmlschema11-2/#anyURI].
> Even if we did want to restrict anyURI values to valid absolute URIs, the current behavior is problematic because insertion works without any errors, and the problem only comes up when the literal is retrieved and resolved. It seems that initial serialization doesn't instantiate a RyaURI but uses the default string serialization, so no error is thrown until deserialization later.
> Example:
> {noformat}
> import mvm.rya.api.domain.RyaType;
> import mvm.rya.api.resolver.RdfToRyaConversions;
> import mvm.rya.api.resolver.RyaContext;
> import org.openrdf.model.Literal;
> import org.openrdf.model.impl.ValueFactoryImpl;
> import org.openrdf.model.vocabulary.XMLSchema;
> public class AnyUri {
>     public static void main(String[] args) throws Exception {
>         ValueFactoryImpl factory = new ValueFactoryImpl();
>         RyaContext context = RyaContext.getInstance();
>         Literal anyuri = factory.createLiteral("test", XMLSchema.ANYURI);
>         System.out.println("Literal: " + anyuri);
>         RyaType rt = RdfToRyaConversions.convertLiteral(anyuri);
>         System.out.println("RyaType: " + rt);
>         byte[] serialized = context.serialize(rt);
>         System.out.print("Serialization:");
>         for (byte b : serialized) {
>             System.out.format(" 0x%02x", b);
>         }
>         System.out.println(" (" + new String(serialized) + ")");
>         RyaType deserialized = context.deserialize(serialized);
>         System.out.println("Deserialized: " + deserialized);
>     }
> }
> {noformat}
> yields:
> {noformat}
> Literal: "test"^^<http://www.w3.org/2001/XMLSchema#anyURI>
> RyaType: RyaType{dataType=http://www.w3.org/2001/XMLSchema#anyURI, data='test'}
> Serialization: 0x74 0x65 0x73 0x74 0x01 0x02 (test)
> Exception in thread "main" java.lang.IllegalArgumentException: No separator character founds in URI: test
> 	at org.openrdf.model.util.URIUtil.getLocalNameIndex(URIUtil.java:63)
> 	at mvm.rya.api.domain.RyaURI.validate(RyaURI.java:60)
> 	at mvm.rya.api.domain.RyaURI.setData(RyaURI.java:54)
> 	at mvm.rya.api.resolver.impl.RyaTypeResolverImpl.deserialize(RyaTypeResolverImpl.java:117)
> 	at mvm.rya.api.resolver.RyaContext.deserialize(RyaContext.java:129)
> 	at AnyUri.main(AnyUri.java:24)
> {noformat}
> Example using the SPARQL endpoint:
> {noformat}INSERT DATA
> {   <http://example.com#x> <http://example.com#hasUri> "test"^^<http://www.w3.org/2001/XMLSchema#anyURI> }{noformat}
> ...inserts the triple, but...
> {noformat}SELECT * WHERE { <http://example.com#x> <http://example.com#hasUri> ?u }{noformat}
> ...fails:
> {noformat}
> type Exception report
> message Request processing failed; nested exception is java.lang.RuntimeException: java.lang.IllegalArgumentException: No separator character founds in URI: test
> description The server encountered an internal error that prevented it from fulfilling this request.
> exception
> org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.RuntimeException: java.lang.IllegalArgumentException: No separator character founds in URI: test
> 	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:965)
> 	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
> 	javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
> 	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
> 	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
> root cause
> java.lang.RuntimeException: java.lang.IllegalArgumentException: No separator character founds in URI: test
> 	mvm.cloud.rdf.web.sail.RdfController.queryRdf(RdfController.java:163)
> 	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> 	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	java.lang.reflect.Method.invoke(Method.java:606)
> 	org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
> 	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
> 	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
> 	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:933)
> 	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:867)
> 	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
> 	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
> 	javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
> 	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
> 	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
> root cause
> java.lang.IllegalArgumentException: No separator character founds in URI: test
> 	org.openrdf.model.util.URIUtil.getLocalNameIndex(URIUtil.java:63)
> 	mvm.rya.api.domain.RyaURI.validate(RyaURI.java:60)
> 	mvm.rya.api.domain.RyaURI.setData(RyaURI.java:54)
> 	mvm.rya.api.resolver.impl.RyaTypeResolverImpl.deserialize(RyaTypeResolverImpl.java:117)
> 	mvm.rya.api.resolver.RyaContext.deserialize(RyaContext.java:129)
> 	mvm.rya.api.resolver.triple.impl.WholeRowTripleResolver.deserialize(WholeRowTripleResolver.java:113)
> 	mvm.rya.api.resolver.RyaTripleContext.deserializeTriple(RyaTripleContext.java:88)
> 	mvm.rya.accumulo.query.RyaStatementBindingSetKeyValueIterator.next(RyaStatementBindingSetKeyValueIterator.java:122)
> 	mvm.rya.accumulo.query.RyaStatementBindingSetKeyValueIterator.next(RyaStatementBindingSetKeyValueIterator.java:51)
> 	mvm.rya.api.persist.utils.RyaDAOHelper$2.next(RyaDAOHelper.java:155)
> 	mvm.rya.api.persist.utils.RyaDAOHelper$2.next(RyaDAOHelper.java:1)
> 	info.aduna.iteration.ConvertingIteration.next(ConvertingIteration.java:88)
> 	info.aduna.iteration.ConvertingIteration.next(ConvertingIteration.java:88)
> 	mvm.rya.rdftriplestore.RdfCloudTripleStoreConnection$1.next(RdfCloudTripleStoreConnection.java:400)
> 	mvm.rya.rdftriplestore.RdfCloudTripleStoreConnection$1.next(RdfCloudTripleStoreConnection.java:1)
> 	info.aduna.iteration.IterationWrapper.next(IterationWrapper.java:82)
> 	info.aduna.iteration.IterationWrapper.next(IterationWrapper.java:82)
> 	org.openrdf.query.QueryResults.report(QueryResults.java:156)
> 	org.openrdf.repository.sail.SailTupleQuery.evaluate(SailTupleQuery.java:76)
> 	mvm.cloud.rdf.web.sail.RdfController.performQuery(RdfController.java:209)
> 	mvm.cloud.rdf.web.sail.RdfController.queryRdf(RdfController.java:149)
> 	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> 	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	java.lang.reflect.Method.invoke(Method.java:606)
> 	org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
> 	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
> 	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
> 	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:933)
> 	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:867)
> 	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
> 	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
> 	javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
> 	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
> 	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)