I'm facing a following problem. We're using Service Data Objects since our target runtime is IBM WebSphere which supposes to be native for this API. The stack that we're using is Java EE, Eclipse Oxygen as the main IDE, SDO reference implementation according to SDO 2.1.0 specification, IBM WebSphere 9 and JRE8.
According to SDO javadoc there are a define(java.io.InputStream xsdInputStream, java.lang.String schemaLocation)
method under XSDHelper
class which loads a desired XSD schema into the WAS runtime. Once the schema is being loaded its type becomes available for other operations, including DataObject
creation..
The way I define schemas looks like the following:
InputStream is = new BOStorage().getInputStreamXSD("/test.xsd");
XSDHelper.INSTANCE.define(is, null);
The define()
method invokes from the EJB constructor.
test.xsd
is located under the src folder of my eclipse project.
src
| test.xsd
| test1.xsd
|
|___ejb.package.name
Now a little bit about the test.xsd itself. It references to another XSDs of the same targetNamespace
using <include>
tag:
test.xsd snippet:
...
<xsd:schema
targetNamespace="http://ejb/package/name"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:bons0="http://ejb/package/name">
<xsd:include schemaLocation="test1.xsd"></xsd:include>
<xsd:include schemaLocation="test2.xsd"></xsd:include>
<xsd:complexType name="TestSDO">
...
<xsd:element minOccurs="0" name="RefObject"
type="bons0:RefObject">
</xsd:element>
...
test1.xsd
contains a complexType
named RefObject
, which is referenced in test.xsd
.
test1.xsd snippet:
...
<xsd:complexType name="RefObject">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="type"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
...
As official SDO Java spec for the version 2.1.0 says:
9.7 XSD Mapping Details
...
- All
<group>
references,<attributeGroup>
references,<include>
s, and<import>
s are fully expanded to the equivalent XSD as if these declarations were not present....
For my vision that means, that in my case, SDO implementation should:
Load test.xsd;
Figures out, that it references to the
test1.xsd
in its<include>
section;As the
test1.xsd
located at the samesrc
folder, as thetest.xsd
is, my expectations is that it would be implicitly loaded in WebSphere runtime environment.
But I'm experiencing an error while trying to create a DataObject of RefObject
type:
CWSDO0001E: Cannot create a data object of the type {http://ejb/package/name}RefObject because the type cannot be found
The conclusions I can make is that SDO API isn't designed to work that way or my XSD's or any aren't suitable or contain some mistakes.
Any help would be highly appreciated.
UPDATE: It works just as expected in case of using the "global" XSD, which includes all references inline. Everything I've mentioned before is running from stateless EJB bean.
A sample code leading to the error:
@Stateless(mappedName = "TestSDO")
@Remote(TestSDORemote.class)
@Local(TestSDOLocal.class)
public class TestSDO implements TestSDORemote, TestSDOLocal{
...
// default EJB constructor
public TestSDO() {
String textInfo = "";
try {
defineSDOTypes();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Could not define SDO types");
}
}
...
private void defineSDOTypes() {
HelperContext hc =
SDO.getHelperContextFactory().createHelperContext("ScopeManagerTestID",
null);
XSDHelper xsdHelper = hc.getXSDHelper();
try (InputStream is = new BOStorage().getInputStreamXSD("/test.xsd")) {
xsdHelper.define(is, null);
} catch (IOException e) {
LOGGER.logp(Level.WARNING, CLASS_NAME, METHOD_NAME, "Unable to load the
schema: " +
"test.xsd" + ": " + e.getMessage());
e.printStackTrace();
}
...
// creates the target Data Object (here comes the error)
private void createBO(){
DataObject dob = DataFactory.INSTANCE.create("http://ejb/package/name",
"RefObject");
}
...