Debugging Web Service Issues When Migrating from Glassfish Version 2 to 3.

For the most part our migration of web applications (including web services) from Glassfish version 2 to version 3 has been relatively painless. We did however encounter a strange issue with one of our server apps that has both a web service and an RMI server component. The application has been running without problems on Glassfish 2, but when we attempted to deploy to Glassfish 3 we encountered the error message shown in the screenshot below:

“Error occurred during deployment: Exception while preparing the app: Servlet CarrierBillWS implements 2 web service endpoints but must only implement 1”

image

The initial thought was to go ahead and migrate the application from Java EE 5 to Java EE 6, and hope that corrected the issue. This however did not change anything and we were left with the same error. Googling didn’t produce any useful results so I decided to take a look through some of the glassfish code where the exception was being thrown from.

         WebServicesDescriptor webServices = bundle.getWebServices();
          Collection endpoints =
                 webServices.getEndpointsImplementedBy(webComponentImpl);

         if( endpoints.size() > 1 ) {
             String msg = "Servlet " + getWebComponentLink() +
                     " implements " + endpoints.size() + " web service endpoints " +
                     " but must only implement 1";
             throw new IllegalStateException(msg);
         }

It appears that there could possibly a name collision with classes in the application, which wasn’t being checked for in Glassfish 2. The web service class itself is pretty simple:

@WebService()
public class CarrierBillWS {

    protected CarrierBillWSActor actor;
    protected Logger logger;

    public CarrierBillWS() {
        logger = Logger.getLogger(getClass());
        actor = new CarrierBillWSActor(PropertyManager.getInstance().getProperty(PropKey.UV_SESSION));
    }

    @WebMethod(operationName = "reopenBill")
    public void reopenBill( String dispatchId, String locationCode ) {
        logger.info( "Web service Request received to reopen carrier bill: " + dispatchId + " from location: " + locationCode );
        actor.reopenBill(dispatchId, locationCode);

    }
}

For fun, I commented out the @WebService annotation and deployed the application without any issues, with the obvious result being that there was no CarrierBillWS web service listed in the Glassfish admin console, but I was at least able to deploy. I then did a grep for “CarrierBillWS” and to my surprise found another class with the same name in one of the web service app’s dependencies. This dependency is a .jar file that is shared across multiple applications here at Lynden, including the web service. So, why was there a class with the same name in this library? It was because the library also contained code for a client of this CarrierBill web service which other applications depended on for communicating with the service. The CarrierBillWS application itself depends on this .jar file for other functionality that is shared across multiple apps. When the jar was built, it pulled down the WSDL from the web service and auto generated the client side classes, which included a CarrierBillWS client side class. This .jar was then bundled in the web service’s .war file, and Glassfish was finding both classes and then complaining.

The solution to the problem was pretty simple; override some of the default values of the @WebService annotation, and then rebuild the dependency using a new WSDL.

@WebService(serviceName="CarrierBillWebService", name="CarrierBillWebService")
public class CarrierBillWS {

The new “serviceName” and “name” properties on the WebService annotation will cause the client project to generate code with a class name of CarrierBillWebService rather than CarrierBillWS. When the .jar is built, the Web Service and its client related classes in the dependent jar now have different names and Glassfish v3 loads the application without any issues.

Since there wasn’t much info out there on this particular issue, I’m hoping that this may help someone in the future who encounters a similar problem.

Twitter: @RobTerp

Leave a Reply