Hi all,

We are writing our own Servlet Context Initializer for new ProtoBufServices
(Binary Services). We have deployed a  ProtoBufService (HelloService). When
ServletContainerInitializer finds the annotation "@ProtoBufService", the
onStartup() method is triggered. Everything works fine except one thing
which is explained here.


@HandlesTypes({ ProtoBufService.class })
public class ProtoBufServletContextInitializer implements
ServletContainerInitializer {

    @Override
    public void onStartup(Set<Class<?>> classes, ServletContext
servletContext)


throws ServletException {

        if (classes == null || classes.size() == 0) {
            return;
        }

        for (Class<?> clazz : classes) {

                Method myMethod=null;
                try {
                    myMethod =
clazz.getInterfaces()[0].getDeclaringClass().getMethod("newReflectiveBlockingService",
clazz.getInterfaces()[0]);
                } catch (NoSuchMethodException | SecurityException e) {
                    e.printStackTrace();
                }


                // get newReflectiveBlockingService() will return a
BlockingService object.
                Object blockingServiceObj=null;
                try {
                    blockingServiceObj = myMethod.invoke(null,
clazz.newInstance());
                } catch (IllegalAccessException | IllegalArgumentException
                        | InvocationTargetException |
InstantiationException e) {
                    e.printStackTrace();
                }


                BlockingService blockingService = (BlockingService)
blockingServiceObj;
                /*
                 * Casting throws ClassCastException.
                 */



System.out.println(blockingServiceObj.getClass().getClassLoader());
                /*
                 * Output :
                 *
                 * WebappClassLoader
                          context: /org.wso2.carbon.binary.sample.hello
                          delegate: false
                          repositories:
                            /WEB-INF/classes/
                        ----------> Parent Classloader:
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@5db01ad1

[org.wso2.carbon.tomcat.patch:4.3.0.SNAPSHOT(id=365)]
                 */



                System.out.println(BlockingService.class.getClassLoader());

                /*
                 * Output :
                 *
                 *
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@31887be4
[com.google.protobuf:2.5.0(id=30)]
                 */

        }
    }

}


Now,

BlockingService blockingService= (BlockingService) obj;

throws following ClassCastExecption,

java.lang.ClassCastException:
org.wso2.carbon.binary.sample.Hello$HelloService$2 cannot be cast to
com.google.protobuf.BlockingService


But, HelloService  is type of BlockingService.

*Reason for this error.*

BlockingService is coming from an OSGi bundle (protobuf) and it is loaded
by a classloader,
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@31887be4
[com.google.protobuf:2.5.0(id=30)]

obj is obtained at run time within servlet context initializer and it is
loaded by another classloader,
WebappClassLoader
                          context: /org.wso2.carbon.binary.sample.hello
                          delegate: false
                          repositories:
                            /WEB-INF/classes/
                        ----------> Parent Classloader:
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@5db01ad1

[org.wso2.carbon.tomcat.patch:4.3.0.SNAPSHOT(id=365)]


Even though obj and BlockingService are of same type, they cannot be cast
because they are loaded by different class loaders.

How can I solve this problem?

Is there any way we can load protobuf OSGi using the same classloader as
servlet context initializer?

Thanks.


-- 
Rajkumar Rajaratnam
Software Engineer | WSO2, Inc.
Mobile +94777568639 | +94783498120
_______________________________________________
Dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/dev

Reply via email to