0

I have a servlet where I store a object into attribute storage of ServletContext:

@WebServlet(name = "MainTestServlet", urlPatterns = {"/MainTestServlet"})
public class MainTestServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {        
        IFStoreCredentials creds = new StoreCreds();
        this.getServletContext().setAttribute("creds2", creds);   
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

This object (IFStoreCredentials) should be accessable in a other Web Service Application which is running within same Tomcat container instance:

@WebService(serviceName = "TestWebService")
public class TestWebService {
    @Resource
    private WebServiceContext context;
    @WebMethod(operationName = "hello")
    public String hello(@WebParam(name = "name") String txt) {       
        ServletContext servletContext =
                (ServletContext) context.getMessageContext().get(
                        MessageContext.SERVLET_CONTEXT);        
        IFStoreCredentials creds = (IFStoreCredentials) servletContext.getContext("/TestServlet").getAttribute("creds2");       
        return "Hello " + creds.getUserName() + " !";
    }
}

Because the two web applications did not know about shared class name I created an external library which should act as an interface:

package com.data.credentials.manager;

public interface IFStoreCredentials {    
    public String getUserName();    
    public String getPassword();
}

I included this library in each application and implement the interface in a concrete class.

The problem is know that not the interface which is known by each application is used but still the concrete class name. If a execute the Web Service method I got a ClassCastException:

 test.main.StoreCreds cannot be cast to com.data.credentials.manager.IFStoreCredentials
java.lang.ClassCastException: test.main.StoreCreds cannot be cast to com.data.credentials.manager.IFStoreCredentials
    at com.test.webservice.TestWebService.hello(TestWebService.java:30)

Question: Why is this class cast exception is thrown? I have created an interface which should be used but it seems that object is still from type "test.main.StoreCreds". How to solve this problem?

sk2212
  • 1,688
  • 4
  • 23
  • 43

1 Answers1

0

The fact that your class test.main.StoreCreds implements an interface com.data.credentials.manager.IFStoreCredentials doesn't change the fact that your object is still an instance of the concrete test.main.StoreCreds. And if the wabapp doesn't know about this concrete class, it can't use an object of this type, because it can't find the byte-code of the class of the object, which is obviously needed to use it.

The concrete class must be shared by both applications. That said, shared sessions is not standard, and should be avoided. Consider making it a single application, or storing the data you want to share between apps in a shared database.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Okay. I just included conrete class into shared library and create a object from this library class and I got: "java.lang.ClassCastException: com.data.credentials.manager.StoreCredentialsVo cannot be cast to com.data.credentials.manager.StoreCredentialsVo". at com.test.webservice.TestWebService.hello(TestWebService.java:31) – sk2212 Jul 16 '13 at 11:10
  • It makes sense. Now you have an instance of the class, loaed by the first webapp's class loader, stored in the session. And you try to cast it to an a class loaded by the second webapp's class loader. The class should be loaded by the common class loader, and only this one. See http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html. Or better: don't share the session between webapps. – JB Nizet Jul 16 '13 at 11:17
  • Okay. Thank you. Then a last question. How to get this class loaded by tomcat classloader? I but the jar file into the "lib" directory of tomcat home folder. But it seems that the library is not loaded at all. – sk2212 Jul 16 '13 at 12:51
  • If the documentation is right, it should be loaded. Make sure you start Tomcat with the standard startup script, and not using your IDE or some other way, which could have a stale copy of the set of jars. – JB Nizet Jul 16 '13 at 13:20
  • Sure, but how to compile and deploy the application without the IDE which did not recognized the jar file (in the moment)? It seems that I have to find another way and put both applications together to get rid of session sharing. – sk2212 Jul 16 '13 at 14:41
  • To compile your two apps, the common library jar must be added to the project build classpath, but not inside the WEB-INF/lib directory. – JB Nizet Jul 16 '13 at 14:44