I had a .Net webService that returns a custom class, lets call it "MyClass", used like this example:
[WebMethod]
public MyClass sampleMethod()
{
return new MyClass();
}
If works ok when invoked from a .Net application.
From a Java application using AXIS I am getting the error "MyClass is referenced but not defined".
How can I overcome this issue?
Two things that spring to mind:
You're missing a schema that defines MyClass
A namespace issue surrounding the definition of MyClass
People will be able to help you further if you can post the WSDL and Schema(s)
First, you have to create a Java proxy: This can be achieved by generating a client by pointing axis to the Web Service WSDL location.
Your Web Service might look like this: http(s)://server:port/path/service_def.asmx and add ?wsdl to the end of the wsdl definition (i.e. like this http(s)://server:port/path/service_def.asmx?wsdl).
From there, generate and client and use the proxy to talk to your .NET Web Service.
PS The possible cause for this is that your class is not defined in a namespace. Check your WSDL definition and see if there's an <xsd:element /> for your class and try adding an ns: to it and generate java proxy with Axis.
Related
So there is a SOAP webservice. The targetNamespace in the WSDL dynamically changes based on customer's configurable string. Think of it like
targetNamespace="http://myservice."+ [CouldBeAnyString] + "domain.com"
I have two questions:
My basic research tells me that this is a pretty weird(bad?) practice for developing webservices. Thoughts ?
How does one write a client for such a webservice ? I have tested using jax-ws stub and it isn't compatible when targetNamespace changes. Any other suggestions ? I have been trying to understand dynamic client generation based on wsdl. Would prefer a nicer path though if one exists
Update:
I am only the client. Service is provided by someone else.
Same customer has multiple environments (eg test,production) where the service is hosted under different targetNamespaces
If the SOAPUI call works even if the targetNamespace has change, you could use a lightweight HTTP library called HTTPCLIENT.
With this library you don't need to generate client, since you are sending the SOAP envelope as a string, the way you would do via SOAPUI.
The downside is to work with Strings.
In theory, it is feasible to create such a Web Service client.
Steps:
Create Java artifacts based on the WSDL using wsimport.exe of JDK (see: http://www.mkyong.com/webservices/jax-ws/jax-ws-wsimport-tool-example as a reference)
For the purposes of the code displayed below, I have used the Calculator WSDL provided by Microsoft
Create a "Dynamic Web Project" via Eclipse J2EE
Copy the Java artifacts created in step #1, under src folder of the project created in step #2.
Create a new Class containing you main method. Normally you would have something similar to:
String wsdlLocation = "127.0.0.1:8088";//Normally you should retrieve that value dynamically
Url url = new URL(wsdlLocation + "?wsdl");// ?wsdl is actually needed
String namespaceURI = "http://Example.org";//Normally you should retrieve that value dynamically
String localPart = "CalculatorService";// as specified in WSDL file (see name attribute of service tag)
QName qname = new QName(namespaceURI, localPart);
CalculatorService service = new CalculatorService(url,qname);
ICalculator iCalculator = service.getICalculator();
int response = iCalculator.add(1, 2);
System.out.println(response);
Now for the tricky part:
If you have followed the example with the aforementioned WSDL, you should now have several Annotated Classes having hard-coded namespace (e.g. ICalculator is annotated with:
#WebResult(name = "result", targetNamespace = "..."))//where ... is similar to http ://example .org
Using Java reflection modify all the hard-coded values at runtime (see an example here: https://stackoverflow.com/a/14276270/2625635 on how to modify Annotations)
The aforementioned solution should do the trick.
Most client frameworks allow you to create an interface for calling your client (i.e. they create a contract interface). They also provide an implementation for that interface and it is the implementation that has specific annotations or extends "SOAP aware" classes, while the interface is clean of such details.
From what you posted I assume the clients have the same interface, it's just the implementation namespace that's different? If yes, then write your application to use the interface then build a jar for each environment's implementation. When you deploy on test servers deploy with the test jar, while on production deploy with the production jar (i.e. pick a different implementation for the same contract depending on the environment).
Even if the framework you use doesn't create an interface for you, you can create one yourself and hide the various implementations behind an adapter of some sort.
You can also do something like edubriguenti suggested but I wouldn't go as far as working with strings. Work with SAAJ instead.
I have a model that is used to create a Web Service endpoint on a server. The same model is used for the client. However when a new operation is added to the server but the client still uses the older model, service creation fails with an exception like the following (line breaks added for clarity):
Exception in thread "main" javax.xml.ws.WebServiceException:
Method someNewMethod is exposed as WebMethod, but there is no
corresponding wsdl operation with name someNewMethod in the
wsdl:portType{http://example.com}MyService
I understand the problem but is it possible to ignore this? I'd like to be backwards compatible when consuming the Web service. As long as methods are merely added this should work just fine most of the time.
The problem occurs in the getPort method:
Service s = Service.create(
new URL("http://example.com/foo?wsdl"),
new QName("http://example.com", "MyService"));
MyService m = s.getPort(MyService.class);
Just for reference.
You can also annotate the method with
#WebMethod(exclude=true)
This will make sure the method is ignored for comparing with the wsdl.
Use an local WSDL File:
The client App has an local WSDL File of the service e.g inside the jar file.
The you get it with
URL wsdlURL = this.getClass().getClassLoader()
.getResource("MyWebService.wsdl");
That worked for a App that i wrote. The server later extended an additional WSDL attribute, while the client still uses the local one.
I just deleted the webservice reference and created again using the interface.
Your Service class contains a static constructor with a local wsdl file variable. Check if local wsdl file has the someNewMethod. If not download the wsdl file from original Url and save to local.
The soap address location value at the end of the wsdl is also important.
Sometimes https turns to http.
When I create a new Web service using RSA 7.5 IDE and Web Sphere 7.0 server from a Web Application, then I can see a few auto-generated files created by this process, namely:
1) For the service, a SEI file is created
2) For the models, ser, deser and helper files are created.
But I cant understand what are the use of all these SEI, ser, deser and helper files.
Any valid explanation on this will be much appreciated.
BOUNTY EDIT:
Bounty-Edit:
Since I did not get any response I would like to ask this question again - offering a bounty to encourage an in-depth answer. I would love to know how and when are these files used internally?
Regards,
Service Endpoint Interface (SEI):
SEI is the Java interface corresponding to the Web service port type
being implemented. It is defined by the JAX-RPC, which specifies the
language mapping from WSDL 1.1 to Java. Ref
Or
A service endpoint interface (SEI) is a Java interface that
declares the methods that a client can invoke on the service. Ref
These ser,dser,helper are helpers to convert an XML document into a java object and vice versa (WebServices). Ref
Files generated in the server project: (WebSphere Application Server 6.1 Ref)
According to the settings made during the run of the wizard, the following files in the WeatherJavaBeanWeb project have been created:
Service endpoint interface (SEI): itso.bean.WeatherJavaBean_SEI.java is the interface defining the methods exposed in the Web service.
WSDL file: /WebContent/WEB-INF/wsdl/WeatherJavaBean.wsdl describes the Web service.
Deployment descriptor: webservices.xml, ibm-webservices-ext.xml and ibm-webservices-bnd.xml. These files describe the Web service according to the Web services for J2EE style (JSR 109). The JAX-RPC mapping is described in the WeatherJavaBean_mapping.xml file.
Data mapping files: The helper beans in the itso.objects package perform the data conversion from XML to Java objects and back.
A servlet is defined in the Web deployment descriptor to invoke the JavaBean.
Hope this information help you.
Those files are related to the WebSphere mapping between Java, WSDL, and XML. They are automatically generated, and should not need to be edited. You should pretend they are not there (except if they are not there you may have trouble deploying...).
SEI - Service Endpoint Interface
ser - Serialize
deser - Deserialize
helper - ?
Here are some psuedo-helpful links, that may provide some more insight into your question:
IBM Technotes
WebSphere v6.1 Handbook (check Chapter 15 -> Creating a Web Service --> Generated Files)
All these files are basically generated for webservice.
A web service ia basically a port between 2 running applications independant of the framework or language.
Leta say if you are using java from one side of web service then for complete compilation the java end would need some class files that have those methids which you wish to call on the service.
For this a stub is generated. This stub is basically an interface(SEI).
Also websphere needs additional files for implementing the webservices functionality, thus tge helper files.
This is basically the summary of it.
I'm trying to call a web service. I used wsimport to create stub classes based on the WSDL. I created a small console app to test them in Eclipse, and this apps works correctly. I then moved these classes into a CMS I'm using (Day CQ 5.3), modified the package name accordingly, and created a small JSP page to test them. When I attempt to view the page, I get an error that says "A WebService annotation is not present on class package.name.ProductsSoap".
However, 1) ProductsSoap is an interface, not a class. 2) ProductsSoap does indeed have a WebService annotation. 3) There were no generated classes that implement the ProductsSoap interface.
What would cause this?
Do you use spring framework to consume your web service? You should have spring-ws-core and spring-ws-core-tiger in your classpath.
I have a web service written in Java now I want to consume that web service in the .NET world. I use the WSDL to add a proxy class to my .NET application but when I invoke the Java web service method the response is always null. Anyone familiar with this issue?
UPDATE 1:
Another thing I noted is that I opened one of the svcinfo files and found the following code:
<endpoint normalizedDigest="<?xml version="1.0" encoding="utf-16"?><Data address="http://fff.mywebserive/somewebservie" binding="basicHttpBinding" bindingConfiguration="DOC_TOI_Binding" contract="ServiceReference1.DOC_TOI_PortType" name="DOC_TOI_Port" />" digest="<?xml version="1.0" encoding="utf-16"?><Data
This does not look right to me!
UPDATE 2: Solution (Kind of)
The problem was that the response had a different namespace than used by the client proxy class. This way the object was never deserialized correctly. Once, I changed the namespace to match the response namespace it worked fine. But now if I update the web service reference I will again get the same issue as the namespace will be updated. What is a good way to solve this problem? The only solution I can think of is to ask the creator of the webservice to use the correct namespace.
Using .Net, we can add the java web service in our application using Service Referrence or Web Service Referrence.
Service Reference - This is a dedicated way of calling Microsoft WCF Web Services 3.5 and higher.
Web Service Reference - Way of referencing Non Microsoft Web Service and lower version of Microsoft webservice such as 2.0
We can also use Service reference in non Microsoft web service, we just need to modify some configuration in app.config such as Security Configurations()
Now, when Invoking the web service request method it always ends up with the NULL object response.
(This is caused by the discrepancy between the proxy namespace expected response and the actual xml namespace webservice response )
Sample:
Proxy Code
[return: System.Xml.Serialization.XmlElementAttribute("GetResponse ", Namespace = "http://AJ_TUASON.COM ")]
Public GetResponse Get()
{}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://AJ_TUASON.COM")]
public partial class GetResponse
{}
Actual XML Namespace Response
webservice:GetResponse xmlns:"http://AJTUASON.COM"
To resolve this issue, install fiddler2. This will helps you track and confirm that the web services are working fine.
Then, copy the actual namespace in the XML response from web service.
Paste the actual xml namespace response in proxy class of .NET:
Sample:
[return: System.Xml.Serialization.XmlElementAttribute("GetResponse ", Namespace = "http://AJTUASON.COM ")]
Public GetResponse Get()
{}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://AJTUASON.COM")]
public partial class GetResponse
{}
This will resolve the Null issue.
Note: Do not always rely on the tool that generates proxy class. Tools can surely translate but doing analysis is another thing - AJ
It suggests to me that either your WSDL or your client is incorrect. The client should not be able to tell from the WSDL what language it's implemented in. Check your namespaces.
SOAP UI is a very nice tool for testing SOAP services. I'd recommend it for sorting out this issue.
Looks to me like something tried to escape that snippet. You don't want > you want >
You need to make sure that the service and the client are using the same namespace. Communication is paramount here.