?_wadl vs ?wsdl (underscore in parameter name) - java

I've been on Google for a while this morning, haven't found my answer so far. I have a single service which returns a WSDL when I request service?wsdl, and returns a WADL when I request service?_wadl.
What is the convention re use of underscore when requesting the service's WSDL or WADL? I notice that, under documentation for JAX-RS Services Description, they use the ?_wadl notation for every example. On the other hand, documentation pertaining to the use of WSDLs (usually in the context of a client making a request using CXF to open a WSDL file, to use as a service contract rather than in the context of generating/providing a WSDL to the 'outside world') refer to service?wsdl in the URLs.
Is it to do with whether the WSDL/WADL is auto-generated? Is there a parameter which can be used to define the URL used to access the WSDL/WADL? I'm using CXF 2.7.11.

These (?wsdl, ?singleWsdl) are all conventions that happen to be fallowed by everybody (I once tried to find out from where ?wsdl originated from but was unable to find any information about it).
But just like what happened with WSDL2 (with WSDL1 still being the de facto way of describing SOAP web services), people didn't rush to jump onto the WADL wagon. _wadl is probably another convention waiting to gain speed (I think they went for an underscore just because wadl and wsdl are easily confused, and easy to mistype, both keys being next to each other - but that's just my guess, I wasn't able to find out anything about this either).
And as a counter example, Jersey has another convention, /application.wadl.
I'm not familiar with CXF but at first glance after downloading the source code, it doesn't look like you can change the way the WADL is retrieved or provide another URL to access it.

Related

JAX-WS RI generated code with hard-coded file paths?

I inherited a codebase, a chunk of which is a webservice built using the Eclipse generators. The generated code appears to have numerous file paths (for wsdls, etc) which refer to locations on the original developer's box. For example, in a service class's static constructor:
url = new URL(baseUrl, "file:/C:/Users/OldDeveloperName/workspace/ServiceProject/WebContent/WEB-INF/edmo/AXIS-1-4/MainEntityService-1.0.wsdl");
Seems like a bad thing, to my naive eyes. Is this a) OK, or b) fixable? I know I could just edit it now, but there's quite a few service files and it seems like there'd be an easy correction if it's a common problem. I mean, as-is it doesn't even look deployable to me.
Original developer obviously followed the approach to store WSDL locally, which is actually a good practice. Namely, JAX-WS client before execution needs to retrieve WSDL once more from the original location to check additional metadata etc. (it sounds weird, but that's how it works). But, what if original WSDL is not available anymore or the Web service developer updated the WSDL with e.g. new method? Your Web service call would not be executed and that is not probably what you want. Therefore, people started to store WSDL together with their client, to avoid vulnerability on WSDL availability/change.
Is this a) OK, or b) fixable?
It is not OK to store WSDL on local filesystem, and that is where the original developer made the huge mistake. WSDL should be packed together with Web service client (in same JAR) and retrieved directly from the archive. There are several ways how to retrieve WSDL locally, see this tutorial for instructions. One way or another, you will have either edit the WSDL location or completely change the old code :)
References:
Why does JAX-WS clients need WSDL access?

Accessing a remote service in Java through it's web interface using JAX-WS for SOAP

I have a public EJB class that I want accessible online as a web service. I have generated a WSDL and the SOAP mesasging seems to work. I used soapUI to test the connection. What I'm not clear about is how would I then use this exposed web service. I'd like to try another language like Python to then make calls through that interface. I know that the WSDL is supposed to help a potential client build it's client side code but I'm not sure about how to specify the connection and location and login information if I had that. I know I'm asking a large topic but any information would help. Thanks
Edit: so basicaly I'm just wondering do I have to use tools to generate my client code from the WSDL like axis2. Or whatever Python uses. Or can I write the code by hand? What's generally done. is the server reference included in that WSDL and are call methods generated usually?
Take a look at ZSI
But ZSI is too complex and spends more time to generate proxies
I suggest you to use suds. suds generates the proxies On the fly and so fast, i used it in some projects.
another packages are available:
soaplib
SOAPy
pysimplesoap

Errors when creating a Web service client in Java

I've seen this problem all over the Web, but still haven't found a clear solution that has worked for me. Here's the issue:
I am trying to create a Web service client in Java. The client needs to be a console app that will be placed on a server and automatically run at a certain time interval. The Web service I am trying to consume was written and is hosted by a third party company. The service was written in ASP.NET. The company in question has several services that we hit. All of them are written in ASP.NET. I have never dealt with these services until 2 days ago when I was tasked with consuming 2 of the services and building an Excel spreadsheet from the data. Before I continue, let me describe my development environment. Some of this is relevant, some is not, but I want to include everything:
Windows 7 Professional 32-bit
NetBeans IDE 6.9.1
Java JDK 1.6.0_17
jre6
Glassfish 3 Open Source Full-Platform Release
All software has had all available updates applied
On to the problem. When I added the first Web Service Client to my console app, I was surprised at how smoothly the process went. Most of my experience writing Web Service apps is in .NET. I was able to import the WSDL and NetBeans generated all classes on the first try. Within 5 minutes, I was able to make my first call to the service and was greeted with the expected response, letting me know that my attempt was successful. I then added the second Web Service Client to the console app using the address to the second WSDL I needed. This is where I ran into a major problem.
Upon importing the WSDL, I was alerted to an error by NetBeans stating:
Web Service Client can not be created by JAXWS:wsimport utility.
Reason: undefined element declaration 's:schema'
After abusing Google for the next hour looking for a solution, I finally decided to apply some trial and error. Looking at the Output window in NetBeans, I could see that it was complaining about 3 specific lines. Once I took a look at the WSDL, I could see that those 3 lines were exactly the same, as follows:
<s:element ref="s:schema" />
These 3 lines were found in random places from the top of the WSDL, down to about half-way through. I removed these lines from the WSDL found in the Web Service References folder, leaving the WSDL in the META-INF folder alone. I then did a refresh on the service reference and much to my surprise, NetBeans parsed the WSDL and generated my classes just as before. Great, right? Well, here's where problem #2 comes into play.
Now that I was able to compile my app with no errors, I had to try to hit the service to see if my hack had worked. It did not. Because of another bug in JAXWS, I have to provide the URL to the WSDL in the constructor when creating a service object. This means that the WSDL I fixed is being ignored and the service is now back to using the WSDL that can not be parsed. When I tried to provide the location of WSDL I edited locally within my project, I was greeted with another compilation error stating that I had a NullPointerException. It said that I needed to initialize the object before using it.
I have researched what seems like an infinite amount of topics on this site looking for and trying any solutions that have been provided. I have also tried solutions from all over the Web, all with no luck. If anyone has any advice for me, any tips, tricks, hacks, please let me know. I'm open to any suggestions at this point.
Thanks in advance for any assistance provided.
One-sided contract changes may lead to problems.
Assuming the s prefix refers to the http://www.w3.org/2001/XMLSchema namespace, it looks like your WSDL references XML schema types. JAX-WS is probably unable to resolve this when generating the JAXB bindings.
You can download the XSD from http://www.w3.org/2001/XMLSchema.html; at a minimum, you'll need XMLSchema.xsd, XMLSchema.dtd and datatypes.dtd. Generating Java types from this may require fiddling with your JAXB binding configuration.
Alternatively, it may be easier to just use dynamic JAX-WS client code. You can use a tool like soapUI to create/test sample XML requests.
If you do decide to edit the WSDL, the generated service code should have a constructor of the form Foo_Service(URL, QName) that allows you to provision the WSDL locally (e.g. from your classpath).
The first thing I'd do is try to open it in one of the tools meant for testing SOAP services, like SoapUI. If you have schema not resolving, that is possible there will be pieces of code that you may need that won't be generated as well. I had that happen recently with a vendor supplied "web service", and after much dissembling they "miraculously" found an alternative set of services that worked fine.
You could also try some of the alternatives to Jax-Ws, like CXF or Axis.

javax.jws.WebService.wsdlLocation with jboss 4.2.2

How specifically can you use the javax.jws.WebService.wsdlLocation in JBoss 4.2.2? (This is for an EJB3 bean deployed as a web service).
There is some documentation around that it is supported, but what exactly is the format? I have tried an http, I have tried a relative URL. How does JBoss look for it, a URL, something on the classpath of the EJB, something else?
You should take a look at JBWS-2206 and related issues JBWS-1714 and JBWS-1837.
From the information I could gather, JBoss internally uses Metro (the RI) for JAX-WS. I'm not very sure about this, but it appears that Metro reads WSDLs, if provided via the wsdllocation attribute, using the classloader, thereby making META-INF/wsdl of the EJB JAR a safe choice to place WSDLs. The example file in JBWS-2206 would help as a reference.
Update
A thorough overview on how to provide your own WSDL is present in the JBoss forums.
Update #2
The JAX-WS specification, gives a better idea on why this is the case. In the section 5.2.5.3 Use of #WebService(wsdlLocation) and Metadata, one can find the specification stating that
The value of the wsdlLocation annotation element on an endpoint implementation class, if any, MUST
be a relative URL. The document it points to MUST be packaged with the application. Moreover, it MUST
follow the requirements in section 5.2.5.4 below (”Application-specified Service”).
Furthermore, it states that
A JAX-WS implementation MUST patch the location attributes of all wsdl:import and xsd:import
statement in local documents that point to local documents. An implementation MUST NOT patch any
other location attributes.
defining how the generated WSDL should appear.

What is the best way to expose a WCF service so that it can be easily consumed from Java/CXF?

We've written a WCF service to be used by a Java shop, who is using CXF to generate the adapters. We're not that familiar with Java, but have exposed the service using basicHttpBinding, SSL, and basic authentication. Integration tests show that a .NET client can consume the service just fine. However, the Java shop is having trouble consuming the service. Specifically, they getthe following JAXB error: Two declarations cause a collision in the ObjectFactory class. This is usually caused if 2 operations have the same name and namespace when CXF attempts to create adapter classes.
We can't find any type or operation names that should cause any sort of collision. We have made sure that all custom types specify a namespace, and tempuri.org is not specified anywhere in the WSDL. The Java shop suspects the error is because the generated WSDL contains <xsd:import elements.
So, my questions:
Is there any better way than CXF for the Java shop consume the WCF service? Project Tango looks interesting, but I don't know enough to tell them to consider using it. Is CXF a defacto standard in Java?
BasicHttpBinding/SSL/Basic Auth are MS recommended for interop scenarios, but the client still seems to have interop problems. Should we consider other bindings or settings to make this easier to consume?
Is there a way to configure WCF to always output a single WDSL with no schema imports?
The "Two declarations cause a collision in the ObjectFactory class" error message usually has nothing to do with imports. That's a JAXB error message that is usually caused by having multiple elements or similar that cause the generated field names to be the same. For example, if you have elements like:
<element name="Foo" .../>
and
<element name="foo" .../>
That can cause that error. Another is using thing like hyphens and underscores and such that are usually eliminated+capped:
<element name="doFoo" .../>
and
<element name="do_foo" .../>
With 2.1.4, you can TRY running the wsdl2java with the -autoNameResolution flag. That SOMETIMES helps with this, but not always. Unfortunately, the information that JAXB gives in these cases is nearly worthless and lots of times it's just trial and error to find the conflicting types. :-(
I am deep into Java & WCF interoperability. As someone else said you need to flatten your WSDL if you are working with file based WSDL. However I use Netbeans 6.5 and if you point to a real url like http://myservice/?wsdl , Netbeans can cope easily with the default wsdl generated by WCF.
In real life other things you need to consider is service versioning, optional datamembers (doesn't go well in java, so I suggest to make all datamembers IsRequired=true), order etc.
The real tough thing to get going was security. I had to make mutual certificate authentication working and it still has some issues.
The only way for your java client to talk to a WCF component will be one of the HTTP methods - basicHttpBinding, ws*, etc just as MS recommends. Java can't talk to WCF over TCP or namedPipes or MSMQ, etc.
I'd start with a super simple WCF component - something with a single method that spits out a string. Get that working with Java and then work your way up. Make sure that everything you're exposing is working with base types or well defined [DataContract] objects.
I've developped WCF with Axis2 clients. The authentication methods I've sucessfully uses is BasicHttpBinding/SSL/Basic (Transport) and WS-Security with Username (and MTOM).
The Metro implementation is used by SUN and Microsoft to test the interop :
http://weblogs.java.net/blog/haroldcarr/archive/2007/11/metro_web_servi.html
Sorry no clue about the import generated by WCF for the schema definition.
The problem with xsd:import is very common. Some toolkits or runtimes cannot cope with that. To address this, you can flatten the WSDL that is generated by WCF.
Check this post.
Regarding whether CXF is the right Java stack - I have never heard of it? I have used AXIS successfully, as well as JAX-WS. Both have been pretty straightforward.
This is a Jaxb issue. I ran into the same issue but used the xmlbeans option instead in wsdl2java client generation. To be honest I seem to prefer the xmlbeans objects more over jaxb as far a consumer to this webservice.

Categories

Resources