ESB / WS integration issue on AS5
asoldano Apr 16, 2009 6:48 AMDaniel Bevenius wrote:
Hi Alession,
hope you don't mind me emailing directly. Kevin Conner gave me your email address and I'd like to ask your advice an issue I'm having.
Background
In the ESB you can specify that a service should be exposed as a WS. Upon deploying the service a web-app will get generated
and deployed. As part of this process a number of files get generated, like the webservice implementation, jaxws handler chain, wsdl file.
In JBoss AS 4.x this was done by actually creating a .war file on the local filesystem, but in AS5 it is done by using a
number of deployers.
This is what I want to achive:
1. Generate a wsdl and add that wsdl to a deployment unit so that it will be available to other deployers, mainly the WS deployer(s).
I'm trying to to add the wsdl to an in-memory VFS, and then add that as a metadata location to the deploymentunit. This is done by the following deployer:
http://anonsvn.jboss.org/repos/labs/labs/jbossesb/workspace/dbevenius/jbossas5/product/rosetta/src/org/jboss/soa/esb/listeners/deployers/mc/EsbWsdlDeployer.java
I'm currently adding this to the Deployment units metadata locations using deploymentUnit.appendMetaDataLocation(dynamicRoot.getRoot()) which I was advised on doing by Ales. I have previously adding it to the classpath but the classpath gets ignored by the tomcat deployer which can be seen in server.log.
3. Generate a ws provider which sets the 'wsdlLocation' attribute to the wsld generated above. This is done by the following deployer:
http://anonsvn.jboss.org/repos/labs/labs/jbossesb/workspace/dbevenius/jbossas5/product/rosetta/src/org/jboss/soa/esb/listeners/deployers/mc/EsbWebServiceDeployer.java
Upon deployment the following error message is displayed:
Caused by: java.io.IOException: Child not found WEB-INF/wsdl/ESBServiceSample/HelloWorldPubService.wsdl for DelegatingHandler@18297205[path=Quickstart_publish_as_webservice.esb context=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/ real=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/Quickstart_publish_as_webservice.esb], available children: [ZipEntryHandler@32154980[path=Quickstart_publish_as_webservice.esb/.classpath context=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/ real=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/Quickstart_publish_as_webservice.esb/.classpath], ZipEntryHandler@1067582[path=Quickstart_publish_as_webservice.esb/.project context=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/ real=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/Quickstart_publish_as_webservice.esb/.project], ZipEntryHandler@24788458[path=Quickstart_publish_as_webservice.esb/META-INF context=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/ real=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/Quickstart_publish_as_webservice.esb/META-INF], ZipEntryHandler@7797905[path=Quickstart_publish_as_webservice.esb/fault.xsd context=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/ real=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/Quickstart_publish_as_webservice.esb/fault.xsd], ZipEntryHandler@29339526[path=Quickstart_publish_as_webservice.esb/jbmq-queue-service.xml context=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/ real=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/Quickstart_publish_as_webservice.esb/jbmq-queue-service.xml], ZipEntryHandler@27043349[path=Quickstart_publish_as_webservice.esb/org context=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/ real=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/Quickstart_publish_as_webservice.esb/org], ZipEntryHandler@22800383[path=Quickstart_publish_as_webservice.esb/request.xsd context=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/ real=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/Quickstart_publish_as_webservice.esb/request.xsd], ZipEntryHandler@14430122[path=Quickstart_publish_as_webservice.esb/response.xsd context=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/ real=file:/opt/jboss/as/jboss-5.0.1.GA/server/default/deploy/Quickstart_publish_as_webservice.esb/response.xsd]] at org.jboss.virtual.VirtualFile.findChild(VirtualFile.java:461) at org.jboss.metadata.serviceref.VirtualFileAdaptor.findChild(VirtualFileAdaptor.java:99) at org.jboss.wsf.framework.deployment.ArchiveDeploymentImpl.getMetaDataFileURL(ArchiveDeploymentImpl.java:97) at org.jboss.ws.metadata.builder.jaxws.JAXWSProviderMetaDataBuilder.buildProviderMetaData(JAXWSProviderMetaDataBuilder.java:125) at org.jboss.ws.metadata.builder.jaxws.JAXWSServerMetaDataBuilder.setupProviderOrWebService(JAXWSServerMetaDataBuilder.java:55) at org.jboss.ws.metadata.builder.jaxws.JAXWSMetaDataBuilderJSE.buildMetaData(JAXWSMetaDataBuilderJSE.java:61) ... 24 more
As far as I can tell the WS deployers do not use the metadata location on the deployment unit. I can't see that deployment unit's metadata location is used when JAXWSProviderMetaDataBuilder tries to locate the wsdl.
When a org.jboss.wsf.framework.deployment.ArchiveDeploymentImpl is created by newDeployment(DeploymentUnit) in AbstractDeployerHook, only the deployment unit's simpleName and classloader are used.
ArchiveDeployerHook which extends AbstractDeployerHook attaches the deployment unit (to the ArchiveDeployment), so it would be available to JAXWSProviderMetaDataBuilder and could potentially be used to search for a wsdl set by an earlier deployer. This would require a code modification though.
In JAXWSProviderMetaDataBuilder, line 121
// Process WSDL String wsdlLocation = anWebServiceProvider.wsdlLocation(); if (wsdlLocation.length() > 0) { URL wsdlURL = dep.getMetaDataFileURL(wsdlLocation); serviceMetaData.setWsdlLocation(wsdlURL); // This is line 125 if you are following the above stacktrace }
The field dep is an instance of ArchiveDeplomentImpl and its getMetaDataFileUrl looks like this:
public URL getMetaDataFileURL(String resourcePath) throws IOException { URL resourceURL = null; if (resourcePath != null && resourcePath.length() > 0) { if (resourcePath.startsWith("/")) resourcePath = resourcePath.substring(1); try { // assign an absolute URL resourceURL = new URL(resourcePath); } catch (MalformedURLException ex) { // ignore } if (resourceURL == null && getRootFile() != null) { UnifiedVirtualFile vfResource = getRootFile().findChild(resourcePath); resourceURL = vfResource.toURL(); } } return resourceURL; }
If I modify JAXWSProviderMetaDataBuilder, to something like this (pardon the ugly code here):
// Process WSDL String wsdlLocation = anWebServiceProvider.wsdlLocation(); if (wsdlLocation.length() > 0) { URL wsdlURL = null; DeploymentUnit deploymentUnit = dep.getAttachment(DeploymentUnit.class); if (deploymentUnit instanceof VFSDeploymentUnit) { VFSDeploymentUnit vfsunit = (VFSDeploymentUnit) deploymentUnit; VirtualFile metaDataFile = vfsunit.getMetaDataFile(wsdlLocation); if (metaDataFile != null) { try { wsdlURL = metaDataFile.toURL(); } catch (URISyntaxException e) { e.printStackTrace(); } } } if (wsdlURL == null) { wsdlURL = dep.getMetaDataFileURL(wsdlLocation); } serviceMetaData.setWsdlLocation(wsdlURL); }
I updated the jbossws-native-3.0.5.GA/modules/core/pom.xml, but adding the two following dependencies to get the above code to build:
<dependency> <groupId>org.jboss.deployers</groupId> <artifactId>jboss-deployers-structure-spi</artifactId> <version>2.0.5.GA</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.deployers</groupId> <artifactId>jboss-deployers-vfs-spi</artifactId> <version>2.0.5.GA</version> <scope>provided</scope> </dependency>
Using this it works for me but this is sort of a hack and perhaps I'm going about this in the wrong way. Is there a better/different way of achiving this?
Thanks,
/Daniel