[
https://issues.apache.org/jira/browse/AXIS2-4353?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12713975#action_12713975
]
Ben Reif edited comment on AXIS2-4353 at 5/28/09 6:26 AM:
----------------------------------------------------------
To get around this issue, for now, I have changed the Axis2 code to look like
this:
ServiceClient:
------------------
//Fix for AXIS2-4353, Added URIResolver argument so that we can resolve
//schema files that are inside Jars
public ServiceClient(ConfigurationContext configContext, Definition
wsdl4jDefinition,
QName wsdlServiceName, String portName, URIResolver
customResolver) throws AxisFault {
configureServiceClient(configContext,
AxisService.createClientSideAxisService(
wsdl4jDefinition, wsdlServiceName, portName, options,
customResolver));
}
//Fix for AXIS2-4353, Added URIResolver argument so that we can resolve
//schema files that are inside Jars
public ServiceClient(ConfigurationContext configContext, URL wsdlURL,
QName wsdlServiceName, String portName, URIResolver
customResolver) throws AxisFault {
configureServiceClient(configContext,
AxisService.createClientSideAxisService(wsdlURL,
wsdlServiceName,
portName,
options,
customResolver));
Parameter transportName = axisService.getParameter("TRANSPORT_NAME");
if(transportName != null ) {
TransportOutDescription transportOut =
configContext.getAxisConfiguration().getTransportOut(
transportName.getValue().toString());
if (transportOut == null) {
throw new AxisFault("Cannot load transport from binding, either
defin in Axis2.config " +
"or set it explicitely in ServiceClinet.Options");
} else {
options.setTransportOut(transportOut);
}
}
}
AxisService:
-----------------
//Fix for AXIS2-4353, Added URIResolver argument so that we can resolve
//schema files that are inside Jars
public static AxisService createClientSideAxisService(URL wsdlURL,
QName wsdlServiceName, String portName, Options options, URIResolver
customResolver)
throws AxisFault {
try {
InputStream in = wsdlURL.openConnection().getInputStream();
Document doc = XMLUtils.newDocument(in);
WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();
reader.setFeature("javax.wsdl.importDocuments", true);
Definition wsdlDefinition =
reader.readWSDL(getBaseURI(wsdlURL.toString()), doc);
if (wsdlDefinition != null) {
wsdlDefinition.setDocumentBaseURI(getDocumentURI(wsdlURL.toString()));
}
return createClientSideAxisService(wsdlDefinition, wsdlServiceName,
portName, options, customResolver);
} catch (IOException e) {
log.error(e.getMessage(), e);
throw AxisFault.makeFault(e);
} catch (ParserConfigurationException e) {
log.error(e.getMessage(), e);
throw AxisFault.makeFault(e);
} catch (SAXException e) {
log.error(e.getMessage(), e);
throw AxisFault.makeFault(e);
} catch (WSDLException e) {
log.error(e.getMessage(), e);
throw AxisFault.makeFault(e);
}
}
//Fix for AXIS2-4353, Added URIResolver argument so that we can resolve
//schema files that are inside Jars
public static AxisService createClientSideAxisService(
Definition wsdlDefinition, QName wsdlServiceName, String portName,
Options options, URIResolver customResolver) throws AxisFault {
WSDL11ToAxisServiceBuilder serviceBuilder = new WSDL11ToAxisServiceBuilder(
wsdlDefinition, wsdlServiceName, portName);
//Fix for AXIS2-4353
if(customResolver != null){
serviceBuilder.setCustomResolver(customResolver);
}
//End Fix for AXIS2-4353
serviceBuilder.setServerSide(false);
AxisService axisService = serviceBuilder.populateService();
AxisEndpoint axisEndpoint = (AxisEndpoint) axisService.getEndpoints()
.get(axisService.getEndpointName());
options.setTo(new EndpointReference(axisEndpoint.getEndpointURL()));
if (axisEndpoint != null) {
options.setSoapVersionURI((String) axisEndpoint.getBinding()
.getProperty(WSDL2Constants.ATTR_WSOAP_VERSION));
}
return axisService;
}
This allows me to pass in my own implementation of URIResolver via the
ServiceClient, like this:
ServiceClient serviceClient = new ServiceClient(axisConfigContext, wsdlDef,
wsdlServiceQName, port.getName(), new URIResolver());
I'm wondering though if the Axis2 team thinks this is the best long term
solution, or if the correct solution would be to just fix the
DefaultURIResolver in the ws-commons project? I can include the logic for my
custom URIResolver, which just extends the DefaultURIResolver. But I think the
same logic could easily be added to the DefaultURIResolver to make it a bit
more robust. Ideally that would be the best solution for us. I'm curious to
hear any opinions.
URIResolver
------------------
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.ws.commons.schema.resolver.DefaultURIResolver;
import org.xml.sax.InputSource;
public class URIResolver extends DefaultURIResolver {
private String schemePrefix;
private static final String JAR_SCHEME = "jar:";
private static final String ZIP_SCHEME = "zip:";
private static final String FILE_SCHEME = "file:";
public InputSource resolveEntity(String targetNamespace, String
schemaLocation, String baseUri) {
if (baseUri == null || isAbsolute(schemaLocation) ||
baseUri.startsWith(FILE_SCHEME)) {
return super.resolveEntity(targetNamespace, schemaLocation,
baseUri);
} else if(baseUri.startsWith(JAR_SCHEME+FILE_SCHEME) ||
baseUri.startsWith(ZIP_SCHEME+FILE_SCHEME)){
if(baseUri.startsWith(JAR_SCHEME)){
schemePrefix = JAR_SCHEME;
} else{
schemePrefix = ZIP_SCHEME;
}
try {
baseUri = baseUri.replaceFirst(schemePrefix, "");
String ref = schemePrefix + new URI(baseUri).resolve(new
URI(schemaLocation)).toString();
InputSource inputSource = new InputSource(new
URI(ref).toURL().openStream());
inputSource.setSystemId(ref);
inputSource.setPublicId(targetNamespace);
return inputSource;
} catch (URISyntaxException e) {
throw new RuntimeException(e);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return new InputSource(schemaLocation);
}
}
was (Author: breif):
To get around this issue, for now, I have changed the Axis2 code to look
like this:
ServiceClient:
------------------
//Fix for AXIS2-4353, Added URIResolver argument so that we can resolve
//schema files that are inside Jars
public ServiceClient(ConfigurationContext configContext, Definition
wsdl4jDefinition,
QName wsdlServiceName, String portName, URIResolver
customResolver) throws AxisFault {
configureServiceClient(configContext,
AxisService.createClientSideAxisService(
wsdl4jDefinition, wsdlServiceName, portName, options,
customResolver));
}
//Fix for AXIS2-4353, Added URIResolver argument so that we can resolve
//schema files that are inside Jars
public ServiceClient(ConfigurationContext configContext, URL wsdlURL,
QName wsdlServiceName, String portName, URIResolver
customResolver) throws AxisFault {
configureServiceClient(configContext,
AxisService.createClientSideAxisService(wsdlURL,
wsdlServiceName,
portName,
options,
customResolver));
Parameter transportName = axisService.getParameter("TRANSPORT_NAME");
if(transportName != null ) {
TransportOutDescription transportOut =
configContext.getAxisConfiguration().getTransportOut(
transportName.getValue().toString());
if (transportOut == null) {
throw new AxisFault("Cannot load transport from binding, either
defin in Axis2.config " +
"or set it explicitely in ServiceClinet.Options");
} else {
options.setTransportOut(transportOut);
}
}
}
AxisService:
-----------------
//Fix for AXIS2-4353, Added URIResolver argument so that
we can resolve
//schema files that are inside Jars
public static AxisService createClientSideAxisService(URL wsdlURL,
QName wsdlServiceName, String portName, Options
options, URIResolver customResolver)
throws AxisFault {
try {
InputStream in =
wsdlURL.openConnection().getInputStream();
Document doc = XMLUtils.newDocument(in);
WSDLReader reader =
WSDLFactory.newInstance().newWSDLReader();
reader.setFeature("javax.wsdl.importDocuments", true);
Definition wsdlDefinition =
reader.readWSDL(getBaseURI(wsdlURL
.toString()), doc);
if (wsdlDefinition != null) {
wsdlDefinition.setDocumentBaseURI(getDocumentURI(wsdlURL
.toString()));
}
return createClientSideAxisService(wsdlDefinition,
wsdlServiceName,
portName, options, customResolver);
} catch (IOException e) {
log.error(e.getMessage(), e);
throw AxisFault.makeFault(e);
} catch (ParserConfigurationException e) {
log.error(e.getMessage(), e);
throw AxisFault.makeFault(e);
} catch (SAXException e) {
log.error(e.getMessage(), e);
throw AxisFault.makeFault(e);
} catch (WSDLException e) {
log.error(e.getMessage(), e);
throw AxisFault.makeFault(e);
}
}
//Fix for AXIS2-4353, Added URIResolver argument so that
we can resolve
//schema files that are inside Jars
public static AxisService createClientSideAxisService(
Definition wsdlDefinition, QName wsdlServiceName,
String portName,
Options options, URIResolver customResolver) throws
AxisFault {
WSDL11ToAxisServiceBuilder serviceBuilder = new
WSDL11ToAxisServiceBuilder(
wsdlDefinition, wsdlServiceName, portName);
//WFX - Fix for AXIS2-4353
if(customResolver != null){
serviceBuilder.setCustomResolver(customResolver);
}
//End WFX - Fix for AXIS2-4353
serviceBuilder.setServerSide(false);
AxisService axisService = serviceBuilder.populateService();
AxisEndpoint axisEndpoint = (AxisEndpoint)
axisService.getEndpoints()
.get(axisService.getEndpointName());
options.setTo(new
EndpointReference(axisEndpoint.getEndpointURL()));
if (axisEndpoint != null) {
options.setSoapVersionURI((String)
axisEndpoint.getBinding()
.getProperty(WSDL2Constants.ATTR_WSOAP_VERSION));
}
return axisService;
}
This allows me to pass in my own implementation of URIResolver via the
ServiceClient, like this:
ServiceClient serviceClient = new ServiceClient(axisConfigContext, wsdlDef,
wsdlServiceQName, port.getName(), new URIResolver());
I'm wondering though if the Axis2 team thinks this is the best long term
solution, or if the correct solution would be to just fix the
DefaultURIResolver in the ws-commons project? I can include the logic for my
custom URIResolver, which just extends the DefaultURIResolver. But I think the
same logic could easily be added to the DefaultURIResolver to make it a bit
more robust. Ideally that would be the best solution for us. I'm curious to
hear any opinions.
URIResolver
------------------
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.ws.commons.schema.resolver.DefaultURIResolver;
import org.xml.sax.InputSource;
public class URIResolver extends DefaultURIResolver {
private String schemePrefix;
private static final String JAR_SCHEME = "jar:";
private static final String ZIP_SCHEME = "zip:";
private static final String FILE_SCHEME = "file:";
public InputSource resolveEntity(String targetNamespace, String
schemaLocation, String baseUri) {
if (baseUri == null || isAbsolute(schemaLocation) ||
baseUri.startsWith(FILE_SCHEME)) {
return super.resolveEntity(targetNamespace, schemaLocation,
baseUri);
} else if(baseUri.startsWith(JAR_SCHEME+FILE_SCHEME) ||
baseUri.startsWith(ZIP_SCHEME+FILE_SCHEME)){
if(baseUri.startsWith(JAR_SCHEME)){
schemePrefix = JAR_SCHEME;
} else{
schemePrefix = ZIP_SCHEME;
}
try {
baseUri = baseUri.replaceFirst(schemePrefix, "");
String ref = schemePrefix + new URI(baseUri).resolve(new
URI(schemaLocation)).toString();
InputSource inputSource = new InputSource(new
URI(ref).toURL().openStream());
inputSource.setSystemId(ref);
inputSource.setPublicId(targetNamespace);
return inputSource;
} catch (URISyntaxException e) {
throw new RuntimeException(e);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return new InputSource(schemaLocation);
}
}
> ServiceClient can not resolve WSDL with imported schemas
> --------------------------------------------------------
>
> Key: AXIS2-4353
> URL: https://issues.apache.org/jira/browse/AXIS2-4353
> Project: Axis 2.0 (Axis2)
> Issue Type: Bug
> Components: client-api
> Affects Versions: 1.4.1, 1.4
> Environment: all
> Reporter: Ben Reif
> Priority: Blocker
> Attachments: ResolveXSDTestCase.zip
>
>
> I am using the ServiceClient to invoke a Web Service, but the WSDL file and
> imported schema files are located within a jar file that is in the Classpth.
> I can get the Definition object, and I set the DocumentBaseURI to the proper
> URL pointing inside the jar file, but when I pass it to the ServiceClient I
> get an error saying that it can't resolve the imported schema files. This
> happens when it calls AxisService.createClientSideAxisService().
> It looks like a fix was put in the WSDLToAxisServiceBuilder class (the
> addition of the setCustomResolver() method) so that you can set a custom
> URIResolver to resolve imported schema files. This gets inherited by the
> WSDL11ToAxisServiceBuilder, however the problem is that this setter is not
> exposed to the ServiceClient, so I can never use it. The ServiceClient
> constructors and the AxisService.createClientSideAxisService() methods should
> take in an additional argument so that calling code can pass in the right
> URIResolver instance which would get set on the WSDL11ToAxisServiceBuilder
> instance.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.