Glen,
On May 14, 2008, at 12:26 AM, Glen Mazza wrote:
2008-05-13 Daniel Kulp wrote:
That said, with JAX-WS, in your "setup" method you can just call:
Endpoint ep = Endpoint.publish("http://localhost:8080/blah",
myImpl);
Interesting...I did not know that was part of JAX-WS. I always
assumed
that was either CXF-specific or part of the simple front end.
Nope. Part of the JAX-WS spec actually.
In order for this to work, though, I think myImpl (the SIB) may need
to
have more annotation values than if the SIB were wrapped within the
WAR,
correct? From what I can tell, the SIB's configuration is the sum of
its @WebService annotation values[1] plus its jaxws:endpoint
configuration in the cxf-servlet.xml[2], therefore to do
Endpoint.publish(), anything otherwise in [2] would need to move to
[1].
[1] http://www.jroller.com/gmazza/date/20080417#WFstep6
[2] http://www.jroller.com/gmazza/date/20080417#WFstep8
For the CXF stuff in [2], you only have the address and implementor
defined. Everything else is taken from the annotations. What's
interesting is that with that configuration, you are letting CXF
generate a new wsdl as there isn't a wsdlLocation specified anywhere
for CXF. Not a big deal, but I'm not sure if that's what you
intended since your metro configuration is specifying a wsdl.
For the most part, if your @WebService annotation has the portName,
serviceName, and endpointInterface stuff (actually, just the
endpointInterface really as the rest can be defaulted), it should
work. The trick is if you want it to use a wsdl or generate one.
If you want it to use a wsdl, you need the wsdlLocation specified.
Unfortunately, since that is burned into the code with an annotation,
it's hard to deal with if the location is different for your unit test
compared to when packaged in a war. However, you can also do it
via: (this works with CXF, not sure about Metro)
Endpoint ep = Endpoint.create(impl);
ep.getProperties().put(
"javax.xml.ws.wsdl.description",
wsdlLocation);
ep.publish("http://localhost:8080/blah");
You might be able to do:
Source source = new StreamSource(wsdlLocation);
ep.setMetaData(source);
or something to set the wsdl.
(BTW, is there a more precise terminology you use for WAR-file based
web
service providers vs. Endpoint.publish()'ed web service providers?)
I generally refer to the Endpoint.publish(...) stuff as "standalone"
servers/services as they don't require a hosting container. A simple
standalone main method is fine.
and CXF (or Metro) will automatically setup an embedded http server
(jetty for CXF, metro uses the http stuff that is now part of Java6)
BTW #2, how is CXF supposed to interact with Java6 now that Metro is
in
it by default--is CXF intended to be swapped in, similar to changing
the
XML parser, i.e., just by placing its libs in jre/endorsed, or will
the
CXF libs still be separate? I'm not sure how this will work.
Actually, it should just work (outside of an OSGi container running on
Java6) without endorsing anything. When you call the JAX-WS API's, it
looks in the context classloader for a META-INF/services/
javax.xml.ws.spi.Provider file that contains the classname of the
provider to use. The default impl in the JDK does not have that
file. CXF does. Thus, if CXF is on the classpath, CXF will be
used. Nothing special needs to be done. (caveat: CXF 2.1 needs JDK6
update 4 or later. CXF 2.0.x will not work on update 4 or later.
This is due to the jaxws-api version being upgraded to 2.1 in update
4). That all said, this does create some support issues. With
JDK5, if cxf is not on the classpath, nothing works. You get class
not found things. On JDK6, your application might actually work, but
it will use metro instead of CXF. Thus, CXF specific things (like
spring configuration) wouldn't be picked up and you end up with wacky
support requests. I've seen stack traces that are obviously metro
stack traces, not CXF. Something to keep an eye out for.
OSGi is more complex as finding the META-INF/services/
javax.xml.ws.spi.Provider file cannot be done in OSGi. Guillaume
Nodet is working on solutions for that. It actually affects other
things like JAX-RS, SAAJ, even woodstox, as they also all use the META-
INF/services directory to find the implementation.
Dan
Thanks,
Glen
that you can then hit. You don't need a war or anything. That may
have some issues with the wsdlLocation annotation on the classes
though. (don't forget to call stop in the tearDown)
I would just use one of the above. It's pretty simple.
The CXF systest stuff goes one further by forking the server into a
separate process instead of running it in-process with the test
client.
In general, that's probably overkill for simple unit style
testing. However, it does make sure there is a completely clean
separation between client/server and the only communication is
through
the soap messages. No "statics" or anything that can pollute the
results.
Dan
2.) Create a separate "systests" project that doesn't test anything
until the WAR is (manually) deployed on a non-embedded servlet
container--*then* run the tests. CXF also has this type of test--
but
I'm unsure how appropriate it would be for the types of tests I'm
thinking of here.
Any suggestions which is best? What have others done for web
service
provider testing?
Thanks,
Glen
[1] http://www.jroller.com/gmazza/date/20080417
---
Daniel Kulp
[EMAIL PROTECTED]
http://www.dankulp.com/blog
---
Daniel Kulp
[EMAIL PROTECTED]
http://www.dankulp.com/blog