We got a WSDL from a client, asking us to implement the service on our side.
The WSDL contains 3 port-bindings, with different names and bindings, but identical <soap:adress> --- like this:
<port name="Name1" binding="tns:Binding1">
<soap:address location="http://localhost/Service/ServicePort" />
</port>
<port name="Name2" binding="tns:Binding2">
<soap:address location="http://localhost/Service/ServicePort" />
</port>
<port name="Name3" binding="tns:Binding3">
<soap:address location="http://localhost/Service/ServicePort" />
</port>
Is such WSDL possible to implement with CXF?
When I run wsdl2java, CXF generates 3 java-interfaces.
I first tried a single implementation-class, like
class MyServiceClass implements Interface1, Interface2, Interface3 {...}
But when I deployed it and checked with SoapUI, for some reason,
it would only expose Port-binding for Interface1,
and seemed to ignore the 2 other ones. Why?
I then tried instead, to implement 3 different ServiceClasses (each implementing one of the interfaces),
then put multiple <jaxws:endpoint> with identical address attributes in cxf-config.xml
But I then get deployment-error:
RuntimeException: Soap 1.1 endpoint already registered on address /Address
Any hints, how to implement such WSDL in CXF?
Is it possible?
But when I deployed it and checked with SoapUI, for some reason, it would only expose Port-binding for Interface1, and seemed to ignore the 2 other ones. Why?
If you will see your implementation class, you will find this annotation,
#WebService(endpointInterface = "yourPackageName.Interface1")
Which is referring to your interface1 only. That's why on deploying it is ignoring rest 2 interface implementations.
So, you have to implement these 3 interface separately in different implemenataion class as you did as per your explanantion. Because only one endpointInterface is allowed in each implementation class.
Is such WSDL possible to implement with CXF?
Yes, it is possible.
During the deployement in your endpoint publisher class, you need to wrap these 3 interface implementation class object in one object and publish for a single end point.
I am still not clear how to do that, ill update the answer later.
Few useful links: It's same requirement but little confusing.
http://cxf.547215.n5.nabble.com/Deploying-multiple-endpoints-ports-for-a-service-td569470.html
Also read about JavaBeans endpoint implementation , i think in this case, it will be more easier than this.
Related
I'm trying to learn how to use WSDL's to call web services from a Grails project. I've been provided with the WSDL and some XML results for reference.
I've been able to generate Java code from the WSDL, and everything seems to be working correctly.
Here's the WSDL: http://www.restfulwebservices.net/rest/USAZipCodeService.svc?wsdl
And here is the XML: http://api.geonames.org/postalCodeSearch?placename=MN&username=demo
I am receiving this exception in my project:
ERROR client.WebServiceClientFactoryImpl$WSClientInvocationHandler - No namespace on "geonames" element.
javax.xml.ws.soap.SOAPFaultException: No namespace on "geonames" element.
It seems like it is saying that the XML returned isn't valid for SOAP? Am I missing/misunderstanding some pieces the puzzle here? It is all pretty new to me.
Edit:
I am trying to use a Grails plugin called cxf client: https://github.com/ctoestreich/cxf-client
It is configured with the following in Config.groovy (something could be wrong/missing here?):
wsdl = "http://www.restfulwebservices.net/wcf/USAZipCodeService.svc?wsdl"
namespace = "cxf.client.postalcode"
clientInterface = "cxf.client.postalcode.IPostalCodeService"
serviceEndpointAddress = "http://api.geonames.org/postalCodeSearch"
I guess you just sent the XML returned from http://api.geonames.org/postalCodeSearch?placename=MN&username=demo as a parameter to the web service. Obviously, from the WSDL description returned you can see there is no such element named geonames, so the SOAPFaultException exception is quite a fair result.
To fix it, you have to refer to the WSDL description carefully, to make sure the invoke method has the right parameters work with whatever defined in the USAZipCodeService WSDL description tags like <wsdl:operation> and <wsdl:message>.
Another issue: 2 different WSDLs were metioned in your invoker and Config.groovy. The former is a RESTful service, and the later is a SOAP one. They work with different invoke methods and parameters, so make sure your code has consistent invoker and parameters, too.
I'm simply trying to convert a WSDl into a number of different HTTP-requests from data supplied by the WSDL. I have read through a ton of similar questions, but none really provided an answer.
Some say to use SOAPUI - I am familiar with this application and do use it. But I need to create these HTTP-requests from the WSDL on my own.
Some say to try JAXWS - I looked at a number of tutorials on this as well as on Axis and these translate the WSDL into Java class bindings and you use those methods to test the web services. I really would like to just generate the HTTP-request myself so that at one point I can manipulate the request and send my own tests.
I started using wsdl4j to begin parsing the WSDL myself but would rather not go down this path until I'm absolutely sure I'm not reinventing the wheel. Seems to me there has been a need for this in past? But with WSDL4J and every other library I do not see a WSDL to Soap message translation.
Any suggestions would be very helpful. The goal is I want to be able to take a WSDL, examine it and create HTTP-SOAP requests for each method in the WSDL and be able to than test them for security issues. The first step is to create those requests!
When calling a SOAP web service you can use a static invocation or a dynamic invocation.
Static invocation means creating a stub from the WSDL and using that to perform the call. This creates all the "plumbing" code for you, but is tightly tied to just that web service and you can't use it for other web services with different contracts. For each WSDL you need to create another stub.
With dynamic invocation, you read the WSDL at runtime and figure out how to call the web service based on the info you get from the WSDL. Feed it multiple WSDLs and the client adapts.
The dynamic invocation is what SoapUI uses to generate the sample requests and responses.
It reads the WSDL you feed it, extracts the XML schema from the types section and generates XML instances. To do so, it uses Wsdl4j and XmlBeans under the hood.
Your decision to use Wsdl4j is good as it gives you control when parsing the WSDL. But also have a look at XmlBeans; it has some other tools you might find useful, like the schema to instance class for example.
If you need to see it in action (maybe debug it to see what's going on) you could create a quick dirty test with the SoapUI API:
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlImporter;
public class Test {
public static void main(String[] args) throws Exception {
WsdlProject project = new WsdlProject();
WsdlInterface[] wsdls = WsdlImporter.importWsdl(project, "http://www.html2xml.nl/Services/Calculator/Version1/Calculator.asmx?wsdl");
WsdlInterface wsdl = wsdls[0];
System.out.println(wsdl.getOperationByName("Add").createRequest(true));
System.exit(0); // just to clear up some threads created by the project
}
}
The message you should see printed (for the Add operation of the Calculator WS) would be something like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:Add>
<tem:a>?</tem:a>
<tem:b>?</tem:b>
</tem:Add>
</soapenv:Body>
</soapenv:Envelope>
Hope this helps you move beyond the first step.
I am new to GWT. i have below line of code.
SomeClientServiceAsync someService = GWT.create(SomeClientService.class);
what does above line means and why cannot i use any other alternatives to instantiate it?
Please help me!
Thanks.
GWT.create is used for deferred binding. This allows you to supply different implementations of the same service based on the user's browser. See the following question:
Why use GWT.create() instead of new?
If you do not need to have multiple implementations of your service, just create it via new!
GWT works by creating a service just like RMI does. Here you are creating the service SomeClientService which resides in the client package. It contains all the functions that can be called server-side.
GWT.create works in different ways:
It tries to see if in the gwt.xml files there is no declaration of which implementation to use depending on a GWT property. This GWT property can be the well known user agent which in this case will have the effect of selecting different implementations for each browser, but it can also be used for other things, for example to disable logging (the fact that logging is enabled or not has nothing to do with in which browser it runs)
Example:
<replace-with class="com.x.app.client.ui.base.button.CustomSlicedButtonCellAppearance">
<when-type-is class="com.x.app.client.ui.base.button.CustomButtonCellAppearance" />
<when-property-is name="gxt.css3.enabled" value="false"/>
<when-property-is name="gxt.theme" value="themeName" />
</replace-with>
In this case it will use CustomSlicedButtonCellAppearance for a call to GWT.create(CustomButtonCellAppearance.class) only if css3 is not supported and for the given theme. Notice that "when-property-is" is optional, and if not supplied it will always use that implementation for the given interface.
It also looks for generators, in which case a new class is generated during GWT compilation (or in devmode) usually based on annotation that are present in the interface passed to the create method.
Example:
<generate-with class="org.fusesource.restygwt.rebind.RestServiceGenerator">
<when-type-assignable class="org.fusesource.restygwt.client.RestService" />
</generate-with>
In this case the RestServiceGenerator will generate code to submit the request.
Another example is how UIBinder works: besides using the annotations in the interface it also generates code based on what is inside the ui.xml file.
If no declaration matches the class/interface passed to the GWT.create method, then it will try to do a new on that class (in case of an interface it will fail).
Declarations in gwt.xml files can be overwritten by other declarations that are processed afterwards, so if you are using a module which declares a rule you can change that rule by declaring a new rule after the inherits declaration of the module containing the original declaration.
I'm generating java code based on various WSDL's. We have a different WSDL for every new version of the WebService that we release, each with its own namespace.
The thing is that normally the changes are minimal from one release to another, but I want to keep classes divided by namespace.
Is there a way to configure JAXB so that the auto generated classes implement a single interface/extend a single class, so I can refer to either of them without changing my code?
Dummy example:
WebService method: listScripts(ResultSize size);
Auto generated classes:
com.test.ws1.ResultSize
com.test.ws2.ResultSize
Both classes are exactly the same. Is there a way to arrange them in a class hierarchy so my code is isolated from changes in version numbers? i.e. a com.test.ResultSize interface implemented by both classes?
XJC has an extension for this purpose
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="2.0">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<xjc:superClass name="com.mycompany.xml.UserRootObject"/>
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
.
.
.
</xs:schema>
For more information see:
http://jaxb.java.net/nonav/2.0.2/docs/vendorCustomizations.html
The schema annotations can also be supplied via an external bindings file. For an example see:
How do you customize how JAXB generates plural method names?
It turned out that I can use a plugin provided in the JAXB2 Basics package:
Inheritance plugin
With this plugin I can specify different super classes for my generated ones, although I couldn't make the auto generated enums to implement a given interface.
To use it in Maven it was a pain (I'm generating classes from a WSDL, not using JAXB directly), so I switched to an external Ant task as specified in this blog
I'm trying to access a data source that is defined within a web container (JBoss) from a fat client outside the container.
I've decided to look up the data source through JNDI. Actually, my persistence framework (Ibatis) does this.
When performing queries I always end up getting this error:
java.lang.IllegalAccessException: Method=public abstract java.sql.Connection java.sql.Statement.getConnection() throws java.sql.SQLException does not return Serializable
Stacktrace:
org.jboss.resource.adapter.jdbc.remote.WrapperDataSourceService.doStatementMethod(WrapperDataSourceS
ervice.java:411),
org.jboss.resource.adapter.jdbc.remote.WrapperDataSourceService.invoke(WrapperDataSourceService.java
:223),
sun.reflect.GeneratedMethodAccessor106.invoke(Unknown Source),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25),
java.lang.reflect.Method.invoke(Method.java:585),
org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155),
org.jboss.mx.server.Invocation.dispatch(Invocation.java:94),
org.jboss.mx.server.Invocation.invoke(Invocation.java:86),
org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264),
org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659),
My Datasource:
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>jdbc/xxxxxDS</jndi-name>
<connection-url>jdbc:oracle:thin:#xxxxxxxxx:1521:xxxxxxx</connection-url>
<use-java-context>false</use-java-context>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>xxxxxxxx</user-name>
<password>xxxxxx</password>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
</local-tx-datasource>
</datasources>
Does anyone have a clue where this could come from?
Maybe someone even knows a better way how to achieve this.
Any hints are much appreciated!
Cheers,
Michael
Not sure if this is the same issue?
JBoss DataSource config
DataSource wrappers are not usable outside of the server VM
#Michael Well, java.sql.Connection is an Interface - it might technically be possible for the concrete implementation you're getting from JBoss to be Serializable - but I don't think you're really going to have any options you can use. If it was possible, it would probably be easy :)
I think #toolkit might have said the right words with useable outside the VM - the JDBC drivers will be talking to native driver code running in the underlying OS I guess, so that might explain why you can't just pass a connection over the network elsewhere.
My advice, (if you don't get any better advice!) would be to find a different approach - if you have access to locate the resource on the JBoss directory, maybe implement a proxy object that you can locate and obtain from the directory that allows you to use the connection remotely from your fat client. That's a design pattern called data transfer object I think Wikipedia entry
#toolkit:
Well, not exactly. Since I can access the data source over JNDI, it is actually visible and thus usable.
Or am I getting something totally wrong?
#Brabster:
I think you're on the right track. Isn't there a way to make the connection serializable? Maybe it's just a configuration issue...
I've read up on Ibatis now - maybe you can make your implementations of Dao etc. Serializable, post them into your directory and so retrieve them and use them in your fat client? You'd get reuse benefits out of that too.
Here's an example of something looks similar for Wicket
JBoss wraps up all DataSources with it's own ones.
That lets it play tricks with autocommit to get the specified J2EE behaviour out of a JDBC connection. They are mostly serailizable. But you needn't trust them.
I'd look carefully at it's wrappers. I've written a surrogate for JBoss's J2EE wrappers wrapper for JDBC that works with OOCJNDI to get my DAO code unit test-able standalone.
You just wrap java.sql.Driver, point OOCJNDI at your class, and run in JUnit.
The Driver wrapper can just directly create a SQL Driver and delegate to it.
Return a java.sql.Connection wrapper of your own devising on Connect.
A ConnectionWrapper can just wrap the Connection your Oracle driver gives you,
and all it does special is set Autocommit true.
Don't forget Eclipse can wrt delgates for you. Add a member you need to delegate to , then select it and right click, source -=>add delgage methods.
This is great when you get paid by the line ;-)
Bada-bing, Bada-boom, JUnit out of the box J2EE testing.
Your problem is probably amenable to the same thing, with JUnit crossed out and FatCLient written in an crayon.
My FatClient uses RMI generated with xdoclet to talk to the J2EE server, so I don't have your problem.
I think the exception indicates that the SQLConnection object you're trying to retrieve doesn't implement the Serializable interface, so it can't be passed to you the way you asked for it.
From the limited work I've done with JDNI, if you're asking for an object via JNDI it must be serializable. As far as I know, there's no way round that - if I think of a better way I'll post it up...
OK, one obvious option is to provide a serializable object local to the datasource that uses it but doesn't have the datasource as part of its serializable object graph. The fat client could then look up that object and query it instead.
Or create a (web?) service through which to access the datasource is governed - again your fat client would hit the service - this would probably be better encapsulated and more reuseable approach if those are concerns for you.