Olá colegas!
Estou tendo um problema que não consigo fazer funcionar já faz um certo tempo…
Eu fiz uma classe cliente JAXR para fazer Service Doscovery em um Service Registry (Weblogic Aqualogic Service Registry - ALSR) e retorna uma lista de Strings com os WSDLs dos web services encontrados.
Em seguida, eu fiz um cliente JAX-WS que pega cada WSDL e invoca (usando o Port ou o Dispatch).
O problema é que o cliente JAXR funciona normalmente e retorna os WSDLs. Mas logo em seguida, quando vai para a invocação do web service, ele me dá este erro:
javax.xml.ws.WebServiceException: Failed to access the WSDL at: http://xxx.yyy.zzz.com:7070/sampleGateway?WSDL. It failed with:
http://xxx.yyy.zzz.com:7070/sampleGateway?WSDL.
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:160)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:142)
at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:240)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:203)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:160)
at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:81)
at javax.xml.ws.Service.(Service.java:56)
at test.artifacts.SampleService.(SampleService.java:45)
at test.TestStaticSOAPMsgClient.testStaticInvocationClient(TestStaticSOAPMsgClient.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.io.FileNotFoundException: http://xxx.yyy.zzz.com:7070/sampleGateway?WSDL
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)
at java.net.URL.openStream(URL.java:1007)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:809)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:259)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:127)
… 22 more
Eu imaginei que poderia ser um erro no WSDL, mas não é porque eu consigo invocar o web service se eu não fizer o service discover com o JAXR antes.
Aqui está o test case que usa o JAXRCLient e tenta fazer a invocação do web service:
public void testStaticInvocationClient() throws JAXRException, MalformedURLException{
final QName SERVICE_QNAME = new QName("http://com/acme/soa", "SampleService");
URL baseUrl = SampleService.class.getResource(".");
Collection<String> wsdlAddresses = new JAXRClient().findServicesWsdlURIs("sample%");
for (String wsdlAddress : wsdlAddresses) {
System.err.println("-> " + wsdlAddress);
SampleService service = new SampleService(new URL(baseUrl, wsdlAddress), SERVICE_QNAME);
Sample servicePort = service.getSampleSoapPort();
System.err.println("Starting Static Service Invocation...");
/*call "execute" method in the sevice port to invoke remote web service
*as long as we have a Handler registered in JAX-WS runtime,
*the 'handleMessage' method in that handler will web called before the
*remote invocation occurs.
*/
String returnedString = servicePort.execute("Test Message");
//output results from server
System.err.println("Response from srv: " + returnedString);
}
System.err.println("test finished!");
}
E aqui está o código do JAXRClient (espero que sirva pra alguém tb!):
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Properties;
import javax.xml.registry.BulkResponse;
import javax.xml.registry.BusinessLifeCycleManager;
import javax.xml.registry.BusinessQueryManager;
import javax.xml.registry.Connection;
import javax.xml.registry.ConnectionFactory;
import javax.xml.registry.JAXRException;
import javax.xml.registry.RegistryService;
import javax.xml.registry.infomodel.Organization;
import javax.xml.registry.infomodel.Service;
import javax.xml.registry.infomodel.ServiceBinding;
import junit.framework.TestCase;
public class JAXRClient extends TestCase {
String httpProxyHost = "10.112.75.100";
String httpProxyPort = "7070";
String httpsProxyHost = "10.112.75.100";
String httpsProxyPort = "7072";
Connection connection;
ConnectionFactory connFactory;
BusinessQueryManager businessQueryManager;
BusinessLifeCycleManager businessLifeCycleManager;
/*
* Test Case for retrieving wsdl location of services given a keyword
* this is achieved by using JAXR API for communicating with an UDDI Service Registry
* Recovered wsdl locations are printed to console
*/
public void testServiceDiscover() throws Exception{
System.err.println("Starting Service Discovery in UDDI Registry...");
//defines search keyword
String queryString = "sample%";
//starts service lookup
Collection<String> wsdlAddresses = findServicesWsdlURIs(queryString);
//output results to console
System.err.println("Results of service discovery in registry for the keyword(s) '" + queryString + "':\n" );
for (String wsdlAddress : wsdlAddresses) {
System.err.println("-> " + wsdlAddress);
}
if(connection != null){
connection.close();
}
}
//performs service discovery given a keyword and returns WSDL locations of these services
public Collection<String> findServicesWsdlURIs(String serviceName) throws JAXRException {
//sets needed connection factory & business references
makeNewConnection();
Collection<String> wsdlAddresses = new ArrayList<String>();
//retrieves Organizations from UDDI
Collection collection = getOrganizations("%"+ serviceName +"%");
Iterator iter = collection.iterator();
while (iter.hasNext()){
Organization org = (Organization)iter.next();
//retrieves Services of each Organization
Iterator it = org.getServices().iterator();
while (it.hasNext()){
Service service = (Service) it.next();
//gets ServiceBindings for each retrieved Service
Iterator iterator = service.getServiceBindings().iterator();
while (iterator.hasNext()) {
ServiceBinding binding = (ServiceBinding) iterator.next();
//retrieves Access URI from Binding & appends wsdl suffix
//(binding does not provide wsdl suffix information)
//adds retrieved uri to return list
wsdlAddresses.add( binding.getAccessURI() + "?WSDL" );
}
}
}
//returns addresses found
return wsdlAddresses;
}
@SuppressWarnings("unchecked")
private Collection getOrganizations(String organizationName) {
Collection<String> organizations = null;
try {
Collection<String> names = new ArrayList<String>();
names.add(organizationName);
BulkResponse response = businessQueryManager.findOrganizations(null, names, null, null, null, null);
organizations = response.getCollection();
} catch (JAXRException e) {
organizations = new ArrayList<String>();
}
return organizations;
}
//creates new connection
private void makeNewConnection() throws JAXRException {
this.connFactory = ConnectionFactory.newInstance();
Properties props = new Properties();
props.setProperty("javax.xml.registry.queryManagerURL", "http://"+httpProxyHost+":"+httpProxyPort+"/registry/uddi/inquiry");
props.setProperty("javax.xml.registry.lifeCycleManagerURL", "http://"+httpProxyHost+":"+httpProxyPort+"/registry/uddi/inquiry");
props.setProperty("com.sun.xml.registry.http.proxyHost", httpProxyHost);
props.setProperty("com.sun.xml.registry.http.proxyPort", httpProxyPort);
props.setProperty("com.sun.xml.registry.https.proxyHost", httpsProxyHost);
props.setProperty("com.sun.xml.registry.https.proxyPort", httpsProxyPort);
connFactory.setProperties(props);
connection = connFactory.createConnection();
RegistryService service = connection.getRegistryService();
businessQueryManager = service.getBusinessQueryManager();
businessLifeCycleManager = service.getBusinessLifeCycleManager();
}
}
É muito estranho: eu consigo fazer as coisas funcionarem isoladas, mas se eu fizer o JAXRClient procurar os serviços no ALSR, parece que ele “trava” o runtime do JAX-WS, e eu não consigo mais fazer qualquer invocação de qualquer we service no teste.
Agradeço qualuqer ajuda!!
Obrigado desde já!!
Abraço a todos,