Monday, November 29, 2004

Wrestling with Axis

More on Axis. Started playing with the examples, and got 1 and 2 working just fine. That .jws thing is pretty cool.

Then I got to example3. I got the MyService.java and Client.java files to compile fine, then ran AdminClient on deploy.wsdd to deploy them. Got a "401 Unauthorized" back in an AxisFault, and went looking for how to setup admin security. Poked around a bit, and found not much on AdminClient. Started looking at AdminServlet, which said not much, and AxisServlet, which has a WSDL that just exposes an AdminService method, but says nothing about how to configure it on the back end.

I had seen mention of server-config.wsdd, but when I looked for it, I didn't find it. Eventually, I grepped the docs for mention of it, and found in reference.html that Axis will create it if it doesn't exist, and will add to it when you deploy things. So I created it, and added a globalconfiguration section and an adminPassword parameter. The 401 went away, replaced instead by a "500 Internal Server Error" and a voluminous stack trace.

Looking at the exception output, it said "Invalid WSDD element 'globalConfiguration' (wanted 'deployment')", which contradicts reference.html. Ah, (oops), it wants that globalConfiguration wrapped in a deployment tag. (Googled and found an example server-config.wsdd, and mirrored the relevant parts of that; did I mention that I love Google?)

So now my AxisFault says "Server.NoService", and "The AXIS engine could not find a target service to invoke! targetService is null" when I run AdminClient. Seems that if server-config.wsdd is missing, AdminService (and Version) get deployed, but if server-config.wsdd is present, only those services listed therein get deployed. Okay, fine, how do I deploy AdminService manually? No wsdd file ships with Axis, it seems (apart from the ones in the samples dir).

I then reread the install instructions, that say that "the client" (presumably AdminClient) has a default password, so I decide to go look at the source and find out what the default password is (on the server) so I can provide it to the client; I assume that it's out of sync. In the process, (of looking through the Axis CVS), I find a server-config.wsdd that has reasonable-looking entries for AdminService (and Version). Plopped them into my server-config.wsdd, kicked Axis via Tomcat, and I'm back to a 401. Grrr.

After looking at the Admin.java source in CVS, I decide to at least try enabling the remote access, just in case. Sure enough, I make that change, and life is fine; "AdminClient list" returns the blob of XML expected. Harumph. I'm doing this all on one box, so why didn't it see that I'm local?!

Okay, back to what I had been doing. I run the example3 deploy.wsdd, and it accepts it. Running AxisServlet lists MyService. Running Client says "The AXIS engine could not find a target service to invoke! targetService is null". This is what I got before when Axis wasn't running anything, but now, if I do a "AdminClient list", it shows MyService, with allowedMethods of "*" and a correct classname.

Now, oddly enough, I went looking for the .class file under Tomcat, under WEB-INF/classes, and found an old version, that I'm guessing shipped with Axis and that I had copied over when I installed Axis under Tomcat. So I replace that with the one I just compiled. I undeployed, and the file remained. So is this where the file gets deployed? And do I have to place the .class file(s) myself, or does the deploy.wsdd and AdminClient take care of that?

I removed MyService.class, undeployed, and deployed, and can find no MyService.class anywhere under tomcat/webapps. So I copied it there. Same error. Un/redeployed (via AdminClient and the wsdd files). Same error.

If I go to the MyService URL, Axis says "Hi there, this is an AXIS service!", while if I go to another, invalid one, Axis says "No service is available at this URL". So I'm guessing that Axis at least knows that it should know about the service. But from Client, hitting either MyService or a known invalid one both generate the "targetService is null" message. Kicked Axis, then Tomcat. Same error. Removed every copy of MyService.class I could find. Same error, and yet the un/redeploy worked fine. How *does* this work?

Ran happiness page again, installed mail.jar (just for grins), and kicked Axis. Ran AxisServlet page, and got message saying "Fault - Could not find class for the service named: samples.userguide.example3.MyService. Hint: you may need to copy your class files/tree into the right location (which depends on the servlet system you are using)." Nice of them to confirm that.

Copied MyService.class file into Tomcat's webapps/axis/WEB-INF/classes/samples/userguide/example3. Reloaded AxisServlet, and the "Fault" message went away. Still get the "targetService is null" message, but at least I can see that I need to place the class files myself, and that I'm doing so in the right place. Time to post to the board, methinks.

Or just Google for "targetService". Found a message from Steve Maring (thanks, Steve) saying that you can't just pull down an incomplete version of server-config.wsdd, or use deploy.wsdd in its place. Instead, extract it from axis.jar, and modify it to include what you need. Did so, re-enabled remote admin, kicked Axis, redeployed the example, and it worked. All's well that ends well, I suppose, but somebody deserves a "grrrr"!

2 Comments:

Anonymous Jörg said...

When a customer asked me to implement an JAX-RPC 1.1 service I felt that this would be pain. And it was. I spent two complete days figuring out how to get the service running. Thanks a million to your post - it saved my day.

7:08 AM  
Blogger cappe said...

Thankyou very much !!!
grrrrrrrrrr

3:33 PM  

Post a Comment

<< Home