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




Reply via email to