Hi, According to our offline discussion, we are trying to achieve this casting.
BlockingService blockingService= (BlockingService) *obj*; But, at the end of the day, we are going to call the following method which is defined in our BinaryServiceRegistry. registerService(BlockingService blockingService) Here, BlockingService is already loaded by a classloader ( org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@31887be4 [com.google.protobuf:2.5.0(id=30)]) Hence, registerService() method will only accept a BlockingService instance which is loaded by the same classloader as above. So what we should do is to load the *obj* in the same classloader as above. Otherwise we will not be able to register this *obj* in our BinaryServiceRegistry. But we were not able to do so. Because, this *obj* is already loaded by the WebAppClassLoader. I tried casting with transloader[1]. Its Reflection cloning is failing. And we can't use its Serialization cloning because our auto-generated stubs are not serializable. Any ideas? 1. https://code.google.com/p/transloader/ Thanks. On Sun, Jun 1, 2014 at 2:35 PM, Kasun Gajasinghe <[email protected]> wrote: > Hi Rajkumar, > > You can get the webapp classloader instance via ServletContext [1]. Then > you could temporarily set the current thread context classloader just for > the casting operation [2]. After that, set it back to the previous > classloader. There might be better ways to do this though! > > > [1] > http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getClassLoader() > [2] > http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setContextClassLoader(java.lang.ClassLoader) > > Regards, > KasunG > > > > On Sun, Jun 1, 2014 at 11:37 AM, Rajkumar Rajaratnam <[email protected]> > wrote: > >> 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 >> > > > > -- > > *Kasun Gajasinghe*Senior Software Engineer, WSO2 Inc. > email: kasung AT spamfree wso2.com > linked-in: http://lk.linkedin.com/in/gajasinghe > blog: http://kasunbg.org > > > -- Rajkumar Rajaratnam Software Engineer | WSO2, Inc. Mobile +94777568639 | +94783498120
_______________________________________________ Dev mailing list [email protected] http://wso2.org/cgi-bin/mailman/listinfo/dev
