[jboss-user] [JBossWS] - Re: OutOfMemory exception when loading xml schemas in WSDL
almarro1
do-not-reply at jboss.com
Wed Dec 3 07:32:55 EST 2008
Well, I think I've discovered the problem: there's a BUG in WSDL11Reader.java. When there are circular references in schemas, it creates an infginite loop.
Somehow I managed to solve it by adding a check just after a new schema include is processed. The followwing code shows what I've included in bold text:
| ...
|
| //Map of <locationURL,URL> to handle circular references in schema import
| private Map<String,URL> schemaImportMap = new HashMap<String, URL>();
| ...
|
| private URL processSchemaInclude(WSDLTypes types, URL wsdlLoc, Element schemaEl) throws IOException, WSDLException
| {
| System.out.println("processSchemaInclude: aÃÂÃÂÃÂÃÂÃÂÃÂÃÂñadiendo nuevo esquema: "+wsdlLoc.toString());
| if (wsdlLoc == null)
| throw new IllegalArgumentException("Cannot process iclude, parent location not set");
|
| File tmpFile = null;
| if (wsdlLoc == null)
| throw new IllegalArgumentException("Cannot process include, parent location not set");
|
| log.trace("processSchemaInclude: " + wsdlLoc);
|
| String schemaPrefix = schemaEl.getPrefix();
|
| String importTag = (schemaPrefix == null) ? "import" : schemaPrefix + ":import";
| Element importElement = schemaEl.getOwnerDocument().createElementNS(Constants.NS_SCHEMA_XSD, importTag);
| importElement.setAttribute("namespace", Constants.URI_SOAP11_ENC);
| schemaEl.insertBefore(importElement, DOMUtils.getFirstChildElement(schemaEl));
|
| // Handle schema includes
| Iterator it = DOMUtils.getChildElements(schemaEl, new QName(Constants.NS_SCHEMA_XSD, "include"));
| while (it.hasNext())
| {
| Element includeEl = (Element)it.next();
| String location = getOptionalAttribute(includeEl, "schemaLocation");
| if (location == null)
| throw new IllegalArgumentException("schemaLocation is null for xsd:include");
|
| URL locationURL = getLocationURL(wsdlLoc, location);
|
| if(!schemaImportMap.containsKey(location)){
| schemaImportMap.put(location, locationURL);
| Element rootElement = DOMUtils.parse(new ResourceURL(locationURL).openStream());
| URL newloc = processSchemaInclude(types, locationURL, rootElement);
| if (newloc != null)
| includeEl.setAttribute("schemaLocation", newloc.toExternalForm());
|
| }else{
| includeEl.setAttribute("schemaLocation", schemaImportMap.get(location).toExternalForm());
| }
|
| }
|
| String targetNS = getOptionalAttribute(schemaEl, "targetNamespace");
| if (targetNS != null)
| {
| log.trace("processSchemaInclude: [targetNS=" + targetNS + ",parentURL=" + wsdlLoc + "]");
|
| tmpFile = SchemaUtils.getSchemaTempFile(targetNS);
| tempFiles.add(tmpFile);
|
| FileWriter fwrite = new FileWriter(tmpFile);
| new DOMWriter(fwrite).setPrettyprint(true).print(schemaEl);
| fwrite.close();
|
| schemaLocationsMap.put(targetNS, tmpFile.toURL());
| }
|
| // schema elements that have no target namespace are skipped
| //
| // <xsd:schema>
| // <xsd:import namespace="http://org.jboss.webservice/example/types" schemaLocation="Hello.xsd"/>
| // <xsd:import namespace="http://org.jboss.webservice/example/types/arrays/org/jboss/test/webservice/admindevel" schemaLocation="subdir/HelloArr.xsd"/>
| // </xsd:schema>
| if (targetNS == null)
| {
| log.trace("Schema element without target namespace in: " + wsdlLoc);
| }
|
| handleSchemaImports(schemaEl, wsdlLoc);
|
| return tmpFile != null ? tmpFile.toURL() : null;
| }
| ...
|
With this simple modification I've solved the OutOfMemory issue, but I haven't gone so far, so I don't know if the webservice will be working in the end.
As soon as I make tests I'll post the results.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4194008#4194008
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4194008
More information about the jboss-user
mailing list