How to define custom Resource Class for Requirement Folder
Hi All,
I have created a custom Resource class "Folder" in Lyo client project.
This class is used to de-serialize GET response on folder artifact.
String resourceURL="https://server:port/rm/folders/_c60fc18a132a467db44748c27d4b0e0b";
ClientResponse response = jfaClient.getResource(resourceURL,OSLCConstants.CT_RDF);
Folder fol = response.getEntity(Folder.class);
But i get null folder object.
Below is my folder resource class ::
@OslcNamespace(RmConstants.JAZZ_RM_NAV_NAMESPACE)
@OslcResourceShape(title = "Folder Resource Shape", describes = JazzConstant.TYPE_REQUIREMENTFOLDER)
public class Folder extends AbstractResource{
private URI subfolders;
private String title;
private URI parent;
private String description;
private URI serviceProvider;
public Folder() {
super();
}
public Folder(final URI about) {
super(about);
}
@OslcDescription("The base URI to use for queries. Queries are invoked via HTTP GET on a query URI formed by appending a key=value pair to the base URI, as described in Query Capabilities section")
@OslcOccurs(Occurs.ExactlyOne)
@OslcPropertyDefinition(RmConstants.JAZZ_RM_NAV_NAMESPACE+ "subfolders")
@OslcReadOnly
@OslcTitle("Sub Folders")
public URI getSubfolders() {
return subfolders;
}
@OslcDescription("Title (reference: Dublin Core) or often a single line summary of the resource represented as rich text in XHTML content.")
@OslcOccurs(Occurs.ExactlyOne)
@OslcPropertyDefinition(OslcConstants.DCTERMS_NAMESPACE + "title")
@OslcTitle("Title")
@OslcValueType(ValueType.XMLLiteral)
public String getTitle() {
return title;
}
@OslcDescription("The scope of a resource is a URI for the resource's OSLC Service Provider.")
@OslcPropertyDefinition(OslcConstants.OSLC_CORE_NAMESPACE + "serviceProvider")
@OslcRange(OslcConstants.TYPE_SERVICE_PROVIDER)
@OslcTitle("Service Provider")
public URI getServiceProvider() {
return serviceProvider;
}
@OslcDescription("Descriptive text (reference: Dublin Core) about resource represented as rich text in XHTML content.")
@OslcPropertyDefinition(OslcConstants.DCTERMS_NAMESPACE + "description")
@OslcTitle("Description")
@OslcValueType(ValueType.XMLLiteral)
public String getDescription() {
return description;
}
@OslcDescription("Parent Folder of this folder Artifact")
@OslcOccurs(Occurs.ExactlyOne)
@OslcPropertyDefinition(RmConstants.JAZZ_RM_NAV_NAMESPACE+ "parent")
@OslcReadOnly
@OslcTitle("Parent")
public URI getParent() {
return parent;
}
public void setTitle(final String title) {
this.title = title;
}
public void setSubFolders(final URI subfolders) {
this.subfolders = subfolders;
}
public void setDescription(final String description) {
this.description = description;
}
public void setParent(final URI parent) {
this.parent = parent;
}
public void setServiceProvider(final URI serviceProvider) {
this.serviceProvider = serviceProvider;
}
}
Accepted answer
I suggest you do some debugging to find out more. The Lyo project provides most of the source code for you to debug.
I have spent some time on this and the key thing I have found out is that you need to define the class as "folder", not "Folder". The reason for that is the class name will be part of the "qualified name", which will be used to extract the RDF+XML content. If we use "Folder" as the class name, the qualified name will become "http://jazz.net/ns/rm/navigation#Folder", which is incorrect.
I do not get any further after changing the class name because I get OOM instead, which is much harder to debug.
Also not that the <nav:parent> property is actually defined in the Requirement class, and is accessed as an "extended property". Maybe it has been done this way for a reason?
I have spent some time on this and the key thing I have found out is that you need to define the class as "folder", not "Folder". The reason for that is the class name will be part of the "qualified name", which will be used to extract the RDF+XML content. If we use "Folder" as the class name, the qualified name will become "http://jazz.net/ns/rm/navigation#Folder", which is incorrect.
I do not get any further after changing the class name because I get OOM instead, which is much harder to debug.
Also not that the <nav:parent> property is actually defined in the Requirement class, and is accessed as an "extended property". Maybe it has been done this way for a reason?
3 other answers
Donald,
Having been smacked by the same exception, it looks like there is a latent problem in determineErrorMediaType that leads to UndeclaredThrowableException throw loop. This is very hard to diagnose because it blows out Eclipse's stack and usually ends up crashing Eclipse and the debugging session.
This determineErrorMediaType code gets called after other code has detected something unexpected in the response entity content and is merely trying to construct an error message.
Exception in thread "main" java.lang.reflect.UndeclaredThrowableExceptionAs I step through one debugging session for this issue today, I become trained that the errors that often lead to the buildBadResponse code include:
at com.sun.proxy.$Proxy8.getAcceptableMediaTypes(Unknown Source)
at org.eclipse.lyo.oslc4j.provider.jena.AbstractOslcRdfXmlProvider.determineErrorMediaType(AbstractOslcRdfXmlProvider.java:391)
at org.eclipse.lyo.oslc4j.provider.jena.AbstractOslcRdfXmlProvider.buildBadRequestResponse(AbstractOslcRdfXmlProvider.java:368)
at org.eclipse.lyo.oslc4j.provider.jena.AbstractOslcRdfXmlProvider.readFrom(AbstractOslcRdfXmlProvider.java:357)
- Forgetting to include a no-argument constructor in the new OLSC Resource class
- Forgetting to include one half of the getter/setter pair of methods for each of the properties that may occur in the source JSON or source RDF+XML
- Mistakenly pluralizing the name of the getter method but not the setter method or vice versa
- Not including a getter that returns a 1990s-style Array instead of returning a modern Collection
- Not including a setter that accepts an Array instead of accepting a Collection
- Not including an "adder" method that accepts one instance of a collection and adds that to the Set/List of that property's type
- Encountering JSON responses where the remote serializer left out the crucial namespace "prefixes" property
Hello Amit
Can you provide some additional information around the Lyo marshalling (eg logging)? Can you confirm that the server is responding with application/rdf+xml document that looks correct? It should be something like shown below.
Can you provide some additional information around the Lyo marshalling (eg logging)? Can you confirm that the server is responding with application/rdf+xml document that looks correct? It should be something like shown below.
<rdf:RDF ... <nav:folder rdf:about="https://greenfront.edinburgh.uk.ibm.com:9444/rdm/folders/_a42a43595c3c40bfb6700f3fd0c33090"> <dcterms:title>_AMR System Requirements Specification artifacts</dcterms:title> <dcterms:description></dcterms:description>
<nav:parent rdf:resource="https://greenfront.edinburgh.uk.ibm.com:9444/rdm/folders/_dc46b44a64a84f15a9a11b29b9dc30c0"/>
<nav:subfolders rdf:resource="https://greenfront.edinburgh.uk.ibm.com:9444/rdm/folders?oslc.where=public_rm:parent=https://greenfront.edinburgh.uk.ibm.com:9444/rdm/folders/_a42a43595c3c40bfb6700f3fd0c33090"/> <oslc:serviceProvider rdf:resource="https://greenfront.edinburgh.uk.ibm.com:9444/rdm/oslc_rm/_HHPVsc5_EeWWYItNq7wdsw/services.xml" /> </nav:folder>
</rdf:RDF>
Hi Nong,
at com.sun.proxy.$Proxy8.getAcceptableMediaTypes(Unknown Source)
at org.eclipse.lyo.oslc4j.provider.jena.AbstractOslcRdfXmlProvider.determineErrorMediaType(AbstractOslcRdfXmlProvider.java:391)
at org.eclipse.lyo.oslc4j.provider.jena.AbstractOslcRdfXmlProvider.buildBadRequestResponse(AbstractOslcRdfXmlProvider.java:368)
at org.eclipse.lyo.oslc4j.provider.jena.AbstractOslcRdfXmlProvider.readFrom(AbstractOslcRdfXmlProvider.java:357)
at org.eclipse.lyo.oslc4j.provider.jena.OslcRdfXmlProvider.readFrom(OslcRdfXmlProvider.java:270)
at org.apache.wink.client.internal.handlers.ClientResponseImpl.readEntity(ClientResponseImpl.java:126)
at org.apache.wink.client.internal.handlers.ClientResponseImpl.getEntity(ClientResponseImpl.java:65)
at org.apache.wink.client.internal.handlers.ClientResponseImpl.getEntity(ClientResponseImpl.java:52)
Thanks for your guidance !!..
I have changed the Folder Class Name to "folder"
now I get following exception :
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at com.sun.proxy.$Proxy8.getAcceptableMediaTypes(Unknown Source)
at org.eclipse.lyo.oslc4j.provider.jena.AbstractOslcRdfXmlProvider.determineErrorMediaType(AbstractOslcRdfXmlProvider.java:391)
at org.eclipse.lyo.oslc4j.provider.jena.AbstractOslcRdfXmlProvider.buildBadRequestResponse(AbstractOslcRdfXmlProvider.java:368)
at org.eclipse.lyo.oslc4j.provider.jena.AbstractOslcRdfXmlProvider.readFrom(AbstractOslcRdfXmlProvider.java:357)
at org.eclipse.lyo.oslc4j.provider.jena.OslcRdfXmlProvider.readFrom(OslcRdfXmlProvider.java:270)
at org.apache.wink.client.internal.handlers.ClientResponseImpl.readEntity(ClientResponseImpl.java:126)
at org.apache.wink.client.internal.handlers.ClientResponseImpl.getEntity(ClientResponseImpl.java:65)
at org.apache.wink.client.internal.handlers.ClientResponseImpl.getEntity(ClientResponseImpl.java:52)
at repo.oslc.RMService.queryTopLevelFolderTest(RMService.java:253)
Comments
Hi Nong,
This folder class works fine if we remove subfolders getter method.
So I suspect that there is something i am missing while annotating the
getSubfolders() method....
I have a "theory" about this. It's not because your code, but rather the value of the "subfolders". It is in the form of an OSLC query, which may need to be URL escaped. But to do this, you may need to change some utility classes such as JenaModelHelper, which will not be an easy task.