jmkgreen
jmkgreen

Reputation: 1643

Glassfish web.xml servlet mapping to @WebService gets ClassCastException

Am trying to gain control over the URL endpoints of my web services when deployed to Glassfish (and preferably to TomEE too).

I have a class:

@Stateless
@WebService(
    targetNamespace = "http://foo.net/doc/2012-08-01",
    name = "FooService",
    portName = "FooPort",
    serviceName = "FooService")
public class FooSoapService extends SoapBase {
...
}

And a web.xml:

<servlet>
    <description>SOAP Endpoint for Foo operations.</description>
    <servlet-name>Foo</servlet-name>
    <servlet-class>com.foo.FooSoapService</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>FooPack</servlet-name>
    <url-pattern>/soap/FooPack</url-pattern>
</servlet-mapping>

If I visit /context-root/soap/FooPack?wsdl when deployed in Glassfish I end up with:

java.lang.ClassCastException: com.foo.FooSoapService cannot be cast to javax.servlet.Servlet

There's virtually nothing else in the web.xml excepting some jax-rs stuff.

Any ideas?

Upvotes: 4

Views: 6711

Answers (2)

Pawan Kaushal
Pawan Kaushal

Reputation: 11

glassfish 4.0 has this capability too. The configuration is deployable without errors.

Upvotes: 0

Paulius Matulionis
Paulius Matulionis

Reputation: 23415

Well, FooSoapService class which you are claiming to be a web service implementation class needs to implement the service interface, probably FooService defined in your @WebService annotation serviceName property.

The reason you are getting this exception is because your FooSoapService class is not an instance of javax.servlet.Servlet and it is for sure that it does not need to be one. In your web.xml you can't expose your web service endpoint. It needs to be done via sun-jaxws.xml. Something like this:

<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
     <endpoint name="FooPort" implementation="com.foo.FooSoapService" url-pattern="/services/FooService"/>
</endpoints>

And your web.xml should look something like this:

<listener>
    <listener-class>
            com.sun.xml.ws.transport.http.servlet.WSServletContextListener
    </listener-class>
</listener>
<servlet>
    <servlet-name>Foo</servlet-name>
    <servlet-class>
        com.sun.xml.ws.transport.http.servlet.WSServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Foo</servlet-name>
    <url-pattern>/services/FooService</url-pattern>
</servlet-mapping>

If you would make those changes then you would be able to get the WSDL from:

/context-root/services/FooService?wsdl

Upvotes: 2

Related Questions