T
tomjbr.10216233
When I have tried to generate java and C# servers/clients from the same
WSDL as described further below, these are the results I have been able
to achieve:
OK: C# proxy invokes C# service
OK: C# proxy invokes Java service
OK: Java proxy invokes Java service
NOT OK: Java proxy invokes C# service
When I try to invoke a C# web service with a java axis client I get the
error message:
"Server did not recognize the value of HTTP Header SOAPAction: ."
I have been struggling with implementing web services with java and
..NET that are supporting the same WSDL and to be able to reuse client
code that are using these services.
To be more specific, I would like to implement the very same (from a
WSDL point of view) web service with both Java Axis and C# (as an
ASP.NET web services).
For both of these two servers, I would then like to create one client
with Java Axis and one client with C# that can reuse these two services
through polymorphistic invocations of a common interface.
My key question is:
Where can I find code examples that describe the best way to create
java axis clients/servers and .NET web services clients/servers which
can communicate with each other in a transparent way ???
I mean, since the location transparency is often described as a key
issue in a SOA implemented with web services then this should be a very
common problem ?
Anyone who is using UDDI to look up implementations of a certain WSDL
that is pointed to from a tModel in an UDDI server should have run into
this kind of problem, when you want to dynamically bind to different
implementations of the same WSDL interface...
(though, maybe not too many people are actually using UDDI in reality,
and maybe UDDI still essentially just occurrs on nice power point
slides showing what you can do with web services...)
This is the kind of approach I have tried:
1. Define a normal java interface
2. Generate a WSDL file from that java interface by using the java axis
tool "org.apache.axis.wsdl.Java2WSDL"
3. Generate java client and service code from the WSDL file by using
the java axis tool "org.apache.axis.wsdl.WSDL2Java" (including the
interface "MyServiceInterface" and the class "MyServiceLocator" in the
code below and also including a skeleton server class
"MyServiceSoapBindingImpl" where I then put the implementation)
4. Generate an abstract C# class from the WSDL file by using the MS
tool "wsdl.exe"
5. Create a web service "service.asmx" (with Visual Studio.NET 20003)
and manually change it so it inherits from the class generated in the
previous step 4, instead of the default inheritance from
"System.Web.Services.WebService".
In this subclass (Service1.asmx.cs) I then implement the abstract
methods and tag them with "[WebMethod]"
6. Manually define a C# interface ( "IMyWebServiceInterface" in the
code further below with the C# web service methods)
7. Generate a C# client proxy class for the java axis web service
(which I of course deployed after step 3 above) by adding a web
reference in VS.NET 2003 and then pointing to the WSDL file.
8. Manually edit the proxy class generated in step 7 above (the class
that inherits from "SoapHttpClientProtocol") so that it also implements
the interface I created in step 6 above.
9. Repeat step 7 och 8 above to create a C# proxy class that can use
the C# web service through that same C# interface created in step 6.
The only thing that I can not make work is the java axis client to
invoke the C# web service.
When I do it, I get the following SOAP faultstring message:
"Server did not recognize the value of HTTP Header SOAPAction: ."
I believe that the reason for the trouble is that the ASP.NET web
service does not generate exactly the same WSDL as the original WSDL.
In other words, when I generated the abstract C# class from the WSDL
file by using the MS tool wsdl.exe and then created a "service.asmx"
that I then let inherit from this generated class, then when I run
"service.asmx?wsdl" in a web browser then it is not exactly the same
WSDL as the original.
So the question is what should I do instead of the stuff I described
above, when I want to create java axis and .NET clients/servers that
can communicate with each other ???
Below I provide some code, just in case it would be unclear what I am
trying to do.
Here is the kind of end result code with a Java Axis client that I
would like to be able to use:
String webserviceURLs[] = new String[]{
"http://www.csharpedomain.com/service.asmx",
"http://www.javadomain.com/axis/services/JavaWebService"
};
MyServiceInterface myService;
MyServiceLocator myServiceLocator = new MyServiceLocator();
for (int i = 0; i < webserviceURLs.length; i++) {
myService = myServiceLocator.getMyService(webserviceURLs);
myService.myMethod(); // the polymorphistic invocation
}
Here is the kind of end result code with a C# client that I was able to
use:
public void someMethod()
{
IMyWebServiceInterface[] webServiceInterfaces = getWebServiceProxys();
foreach(IMyWebServiceInterface webServiceProxy in
webServiceInterfaces)
{
webServiceProxy.getServiceBeskrivning(); // the polymorphistic
invocation
}
}
private IMyWebServiceInterface[] getWebServiceProxys()
{
IMyWebServiceInterface[] webServiceInterfaces = new
IMyWebServiceInterface[2];
webServiceInterfaces[0] = new localhost_java_MyService();
webServiceInterfaces[1] = new localhost_csharpe_MyService();
return webServiceInterfaces;
}
However, I would prefer if there was some easier way to create a C#
client that transparently (through polymorphism) can invoke the
services than to manually create the interface "IMyWebServiceInterface"
and instantiate the concrete classes as above, i.e. I would prefer to
do something that is more like the axis client above where you can
provide url strings to the implementations of the web services that
supports the same WSDL.
/ Tom
WSDL as described further below, these are the results I have been able
to achieve:
OK: C# proxy invokes C# service
OK: C# proxy invokes Java service
OK: Java proxy invokes Java service
NOT OK: Java proxy invokes C# service
When I try to invoke a C# web service with a java axis client I get the
error message:
"Server did not recognize the value of HTTP Header SOAPAction: ."
I have been struggling with implementing web services with java and
..NET that are supporting the same WSDL and to be able to reuse client
code that are using these services.
To be more specific, I would like to implement the very same (from a
WSDL point of view) web service with both Java Axis and C# (as an
ASP.NET web services).
For both of these two servers, I would then like to create one client
with Java Axis and one client with C# that can reuse these two services
through polymorphistic invocations of a common interface.
My key question is:
Where can I find code examples that describe the best way to create
java axis clients/servers and .NET web services clients/servers which
can communicate with each other in a transparent way ???
I mean, since the location transparency is often described as a key
issue in a SOA implemented with web services then this should be a very
common problem ?
Anyone who is using UDDI to look up implementations of a certain WSDL
that is pointed to from a tModel in an UDDI server should have run into
this kind of problem, when you want to dynamically bind to different
implementations of the same WSDL interface...
(though, maybe not too many people are actually using UDDI in reality,
and maybe UDDI still essentially just occurrs on nice power point
slides showing what you can do with web services...)
This is the kind of approach I have tried:
1. Define a normal java interface
2. Generate a WSDL file from that java interface by using the java axis
tool "org.apache.axis.wsdl.Java2WSDL"
3. Generate java client and service code from the WSDL file by using
the java axis tool "org.apache.axis.wsdl.WSDL2Java" (including the
interface "MyServiceInterface" and the class "MyServiceLocator" in the
code below and also including a skeleton server class
"MyServiceSoapBindingImpl" where I then put the implementation)
4. Generate an abstract C# class from the WSDL file by using the MS
tool "wsdl.exe"
5. Create a web service "service.asmx" (with Visual Studio.NET 20003)
and manually change it so it inherits from the class generated in the
previous step 4, instead of the default inheritance from
"System.Web.Services.WebService".
In this subclass (Service1.asmx.cs) I then implement the abstract
methods and tag them with "[WebMethod]"
6. Manually define a C# interface ( "IMyWebServiceInterface" in the
code further below with the C# web service methods)
7. Generate a C# client proxy class for the java axis web service
(which I of course deployed after step 3 above) by adding a web
reference in VS.NET 2003 and then pointing to the WSDL file.
8. Manually edit the proxy class generated in step 7 above (the class
that inherits from "SoapHttpClientProtocol") so that it also implements
the interface I created in step 6 above.
9. Repeat step 7 och 8 above to create a C# proxy class that can use
the C# web service through that same C# interface created in step 6.
The only thing that I can not make work is the java axis client to
invoke the C# web service.
When I do it, I get the following SOAP faultstring message:
"Server did not recognize the value of HTTP Header SOAPAction: ."
I believe that the reason for the trouble is that the ASP.NET web
service does not generate exactly the same WSDL as the original WSDL.
In other words, when I generated the abstract C# class from the WSDL
file by using the MS tool wsdl.exe and then created a "service.asmx"
that I then let inherit from this generated class, then when I run
"service.asmx?wsdl" in a web browser then it is not exactly the same
WSDL as the original.
So the question is what should I do instead of the stuff I described
above, when I want to create java axis and .NET clients/servers that
can communicate with each other ???
Below I provide some code, just in case it would be unclear what I am
trying to do.
Here is the kind of end result code with a Java Axis client that I
would like to be able to use:
String webserviceURLs[] = new String[]{
"http://www.csharpedomain.com/service.asmx",
"http://www.javadomain.com/axis/services/JavaWebService"
};
MyServiceInterface myService;
MyServiceLocator myServiceLocator = new MyServiceLocator();
for (int i = 0; i < webserviceURLs.length; i++) {
myService = myServiceLocator.getMyService(webserviceURLs);
myService.myMethod(); // the polymorphistic invocation
}
Here is the kind of end result code with a C# client that I was able to
use:
public void someMethod()
{
IMyWebServiceInterface[] webServiceInterfaces = getWebServiceProxys();
foreach(IMyWebServiceInterface webServiceProxy in
webServiceInterfaces)
{
webServiceProxy.getServiceBeskrivning(); // the polymorphistic
invocation
}
}
private IMyWebServiceInterface[] getWebServiceProxys()
{
IMyWebServiceInterface[] webServiceInterfaces = new
IMyWebServiceInterface[2];
webServiceInterfaces[0] = new localhost_java_MyService();
webServiceInterfaces[1] = new localhost_csharpe_MyService();
return webServiceInterfaces;
}
However, I would prefer if there was some easier way to create a C#
client that transparently (through polymorphism) can invoke the
services than to manually create the interface "IMyWebServiceInterface"
and instantiate the concrete classes as above, i.e. I would prefer to
do something that is more like the axis client above where you can
provide url strings to the implementations of the web services that
supports the same WSDL.
/ Tom