I use XFire to create a webservice wrapper around my application. XFire provides the webservice interface and WSDL at runtime (or creates them at compile time, don't know exactly).
Many of our customers don't know webservices very well and additionally they simply don't read any external documentation like Javadoc. I know that it's possible to add documentation (for parameters and methods) directly to the WSDL file.
I thought about Annotations or Aegis XML files but I don't know how... Do you know a way?
Edit: I just found this JIRA issue but the last activity was 2006. Any ideas?
XFire is slowly headed for /dev/null. Use CXF instead. In other words, XFire is being deprecated in favor of CXF - it's pretty much the same developers.
Since you use the Java-first approach, I suggest you generate you WSDL once and for all with CXF's java2wsdl tool, then you put your documentation in that and tell CXF to use that documented WSDL instead of letting CXF generate its own (undocumented) WSDL at runtime/deploy-time.
This page has pretty much everything you need to know about creating a web service in CXF.
And my last hint regarding CXF - use Aegis for data binding instead of JAXB. It doesn't work for complex POJO.
In my experience we have no problem with complex POJO and JAXB, the only problem is that the code starts to be cluttered with JAXBElements. On the other hand, Aegis documentation is pretty sparse and not well-maintained with relation to CXF.
Let's me add my two cents regarding XFire. We had very serious issue with XFie under JDK6 (both Tomcat 6.0 and 5.5).Please take a glance at that issue. In our case XFire with 4+ web services under JDK6 leads to hanging application servers (thread deadlocks etc.). It's interesting, but under JDK5 everything was OK.
And I completely agree with Christian Vest regarding migration to CXF from XFire. It has sense in many cases e.g. ESB Mule 2 doesn't support native XFire connectors anymore (see also).
And I wish to add that migration from XFire to CXF is not straitforward way (e.g. CXF has jar dependences that conflict with some hibernate releases see also), but it's doable. In our case we did it for couple days without code correction (Spring only configuration).
And my last hint regarding CXF - use Aegis for data binding instead of JAXB. It doesn't work for complex POJO.
Related
For SOAP Based Web Services, why one should choose Spring WS over JAX-WS.
I had gone through some article even Spring WS doc feature but still I am not clear.
If I need to convince someone to use Spring WS I can't.
So I want the difference in simple terms that any Web Service Developer can understand.
Thanks in advance.
I am not going into the details of JAX-WS versus Spring-WS.
You might want to refer to the link here for details on that and google it.
From my personal experience :
Spring-WS Advantages over JaxWS
You want to use a databinding other than JAXB (JibX, Castor or
others)
You want extreme fine grained control on the endpoint mapping strategy
You are choosing a WSDL first approach (though many argue that JAXWS also supports a WSDL first approach, it is generally accepted to be more flexible in spring-ws)
JaxWS over SpringWS
You want to go for a java first approach
You want to make your code flexible (since JAXWS is a specification you can have multiple implementations)
You want to use other annotation driven development of JAX-WS
I've been doing my research about exposing Eclipse plugins as web services, but I'm getting confused.
My requirement is basically to build an Equinox back end for a set of web services.
I'll be using EMF and related projects heavily, so with this goal in mind I've been reading about Equinox/OSGI and options to build what I need.
However, there are some mysterious points and in general an abundance of projects around. Given the findings below, I'd like hear your suggestions. Maybe there is an option I'm missing, or maybe you've done this before. Here are the nominees (drumroll)
Hosting Equinox in a web container. Using bridge.war, the plugins can expose a servlet. The problem is, to use nice REST frameworks such as RestEasy (my favourite), the REST framework needs to be a osgi bundle that'd live in the Equionox runtime. I've spend 3 days, and due to classloader issues, this is not working. I am now convinced that I won't be able to have RestEasy in Equinox. I can have RestEasy in web container, and use XML serialization/deserialization to make code in web container talk to code in Equionox, but this feels like such a waste of resources. Still, this may work.
The other option seems to be ECF, which is an implementation of distributed OSGI, which seems to support SOAP/Rest. However, I could not find a clear tutorial that just exposes Equinox hosted functionality as a web service. So this still forces me no not to use RestEasy, but at least it seems to give me a proper framework to talk to Equinox. I'd probably still have to keep this in a web contaner for scalability.
Then there is Eclipse Virgo, which seems to support hosting web applications alongside OSGI runtime, and apparently web container hosted code can talk to OSGI runtime code. Still, I am not sure if I can pass around classes since a Jaxb annotated type A created under web container is likely to use a differnet classloader than the OSGI runtime plugin. Also, this setup locks me into Virgo, and I would rather go with JBoss etc for production use.
So given these options, and possibly more I do not know about at the moment, how would you expose EMF and other Eclipse framework based projects as web services?
Edit:
based on the great response I'd like to add more. Partially details of the question, partially comments which did not fit into comment section.
My research after the question let me to the exact same point with the accepted answer: Apache CXF is now an implementation of Distributed OSGI, which is good. I have given up on RestEasy. My current concern is, I already have a XSD that has created my classes. RestEasy made it very easy to expose these, and I'd have to do the same here. My plugins would have to use these JAXB based classes. In the worst case, I may attempt to use Eclipse Link project which offers JAXB support, in order to create XML content, and pass it through either basic servlet use or as string values based on CXF. So solutions discussed here don't feel perfect, but I guess this is the best one can do at the moment.
I work on a product that has done this. We have Equinox inside the web container. We expose SOAP and REST web services using Apache CXF. It took some black magic to get everything wired up correctly. I found the CXF documentation to be not so great, especailly for OSGI.
As I am sure you know, hosting Equinox in the web container is not a recommended practice, although it is a hard one to avoid if you want to use OSGI. We too experienced a number of classloading issues. In fact we never really enjoyed the advertised benefits from OSGI (modularity, etc). It's too late for us to turn back now. OSGI should not be entered into lightly.
So here is a quick overview of how we have enabled SOAP/REST using CXF. Hopefully this will at least point you in the right direction.
1) Install CXF OSGI bundles, both core and DOSGI - We are using the following:
cxf-bundle-minimal-2.2.12.jar
cxf-dosgi-ri-discovery-local-1.1.jar
cxf-dosgi-ri-dsw-cxf-1.1.jar
Links:
http://cxf.apache.org/download.html
2) Install JAX-RS (REST) and JAX-WS (SOAP) APIs
-The API definition are in org.apache.servicemix.specs.jsr311-api-1.0-1.3.0.jar and org.apache.servicemix.specs.jaxws-api-2.1-1.1.1.jar (these are the versions we have)
-These may or may not be bundled with CXF. IN our case, only the JAX-WS jar was included. We had to hunt down the JAX-RS bundle.
-In addition to installing the bundles in the webapp (WEB-INF/eclipse/plugins), we also had to add them to the ECLIPSE/plugins directory for compilation.
3) Tell Equinox to load CXF plugins. There are probably other ways to do this. We accomplished this with entries in WEB-INF/eclipse/configuration/config.ini.
-If this file exists, add your new jars to the osgi.bundles property:
osgi.bundles=... org.apache.servicemix.specs.jaxb-api-2.1-1.1.1.jar#start, org.apache.servicemix.specs.jaxws-api-2.1-1.1.1.jar#start, org.apache.servicemix.specs.jsr311-api-1.0-1.3.0.jar#start, \
cxf-dosgi-ri-discovery-local-1.1.jar#5:start, \
cxf-bundle-minimal-2.2.12.jar#5:start, \
cxf-dosgi-ri-dsw-cxf-1.1.jar#5:start
4) That's it. You should now be able to start writing SOAP and REST services. This is a Java-first approach (as opposed to XML-schema first). What this means is that you:
-Define a Java interface
-Configure CXF to publish you interface as either REST or SOAP endpoint.
Here's a very simple example for REST. It comes with the standard disclaimer that it is specific to our environment. YMMV.
a) We use declarative services, so first we define the DS file in our bundle's manifest
Service-Component: META-INF/ds/helloworld.xml
b) Here is the DS file: META-INF/ds/helloworld.xml. The DS file defines the services in your OSGI bundle and their dependencies. Those entries have been omitted for brevity.
<?xml version="1.0"?>
<components xmlns="http://www.osgi.org/xmlns/scr/v1.0.0">
<component name="hello_world_service" xmlns="http://www.osgi.org/xmlns/scr/v1.0.0">
<!-- Defines this as a REST service --->
<property name="service.exported.configs" value="org.apache.cxf.rs"/>
<!-- This is the URI of your REST resource.
It is realtive to the Equinox bridge servlet in your webapp -->
<property name="org.apache.cxf.rs.httpservice.context" value="/helloworld" />
<!-- This is the java interace that will be exposed . You
will use JAX-RS annotations to map these java methods to HTTP verbs. -->
<property name="service.exported.interfaces" value="com.foo.IHelloWorldService"/>
...
</components>
c) Here is the interface class:
package com.foo;
#Path("/greeting")
public Interface IHelloWorldService {
#GET
#Produces("application/xml")
public Greeting getGreeting();
}
public class HelloWorldService implements IHelloWorldService {
#override
public Greeting getGreeting() {
Greeting g = new Greeting();
g.message = "Hello World";
return g;
}
}
d) So, once this is all in place, you should be able to GET the following URL:
/<web-app-name>/bridge/helloworld/greeting
and receive the following response:
<Greeting>
<message>Hello World</message>
</Greeting>
Good luck. Hope this helps.
Unfortunately I think that RESTeasy is the problem here. As per your comment in another question, RESTeasy uses the Java ServiceLoader API to lookup classes dynamically, which unfortunately makes assumptions about classloading that are untrue in any non-flat (i.e. modular) classloading architecture.
I would encourage you to ask on the RESTeasy forums about alternatives to the ServiceLoader approach to looking up these classes. It may be possible to explicitly register those classes, for example.
However failing a solution that allows you to continue using RESTeasy, there are alternative REST APIs that do work very well in OSGi. Restlet for example has explicit OSGi support. I have successfully used Jersey as well.
I want to convert WSDL file into java classes file.Suggest me the package used for it. I found one that is axis 2.0 .But i want to more packages used to do this job. please suggest me any article where i can find about the comparison related to different-2 packages for their performance.
Thanks
Use wsimport.
I worked on two packages axis 2 and cxf .I used WSDL2JAVA tool for conversion and find that Axis2 is structured modularly, has many features and can be used as an application server for Web Services. A special feature of Axis2 is the support of exchangeable binding frameworks, for example XMLBeans. Axis2 together with the XMLBeans framework is well suited for Web Services which are using very complex schema definitions. The disadvantages of Axis2 are its complexity as well as the insufficient JAX-WS support. Therefore anyone who wants to work with JAX-WS should choose Apache CXF or the reference implementation.
Those who prefer a seamless integration with the Spring framework are well advised with Apache CXF. Furthermore CXF is slim and easy to use. CXF is the tool of choice if a SOAP engine has to be embedded into existing software.
Thanks.
I am starting on a new project with commercial vendor. I need to write an integration module in our application to consume commercial vendor's web service. So, WSDL is not controlled by us.
I think the general approach is to do a "Contract First" development and generate stubs from the WSDL file. I would like to know what technologies are available to do this? I would really like the simplest approach that works. We use Maven 3.0.3 and Spring 3.0.5 extensively. Can I use Spring WebServiceTemplate?
Please let me know if the question isn't clear or additional details are needed.
Thanks,
Tapasvi
You can generate the java stubs with the maven plugin for JAX-WS. Then you can use the stubs in spring to expose them as a webservice. Luckily, it's quite simple :).
Just a suggestion, don't re-generate the stubs every time you build the project, as (obviously) you won't be able to add any code to the stubs, which is sometimes very useful. I made this mistake long time ago and it was quite painful, because I had to put code in places where it didn't belong. In the last few years I used a maven profile to generate the stubs on demand and then I merged them "manually" to add the extra code. Of course, this is only viable if the WSDL doesn't change very often.
I have used axis and the easiest way to do is to run the utility wsdl2java and pass the location of the webservice along with the ?wdsl option.
I know lots of IDE's these days will allow to generate you stubs from within. MyeclipseIDE has an option to ingest an WSDL so does intelliJ. I think the safer approach is to use wsdl. Also if you are using jax-ws you can try
wsimport -keep -verbose location to wsdl
JAX-WS is included in the standard Java 6 distribution making it very simple to use.
Generate stubs with wsimport in the JDK (remember to enable as many warnings as possible, as you want to know anything that may cause problems).
I'm looking for a solution of dynamic web service client such as DII from JAX-RPC.
I need to generate a client from a WSDL.
But the WSDL is only known at runtime (so I don't have any available interface).
I had a look on JbossESB, JbossWS, JaxWS,JaxRPC, but I could'nt find anything that fits this requirements.
Thanks for your help.
It appears that this is possible with CXF and some java reflection.
jax-ws-dynamic-dispatch-with-cxf
I'm personally looking for a solution for this + a dynamic server model as well.
Good luck.
finding a ready-made solution to your problem is not easy. at least none exist AFAIK. due to the inherent, unknown complexity of the backing schema types associated w/ an operation's request and response, it's not possible to have such a solution.
however, putting together the correct tools, or using some open-source frameworks/libraries/tools you might be able to achieve something similar. basically you'll need to have a WSDL4J implementation, along with a schema parser like XMLBeans to get this working.
A tool which comes to my mind is SoapUI. it achieves something similar - user loads a WSDL at runtime and thereafter can execute operations. the source of this tool is also available for modification under LGPL here. you'll need to strip and salvage the core functionality that suits your need. or best, build one of your own :]