Hi Sagara, KasunG, Will this approach work?
Lets have a parent classloader for WebAppClassLoader. We will load the BlockingService using parent classloader. *obj* will be loaded by WebAppClassLoader. Since its parent knows about BlockingService, we will be able to cast. Is this possible to have a meeting today to sort out this issue? Thanks. On Mon, Jun 2, 2014 at 7:29 PM, Rajkumar Rajaratnam <rajkum...@wso2.com> wrote: > 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 <kas...@wso2.com> 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 <rajkum...@wso2.com> >> 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 > -- Rajkumar Rajaratnam Software Engineer | WSO2, Inc. Mobile +94777568639 | +94783498120
_______________________________________________ Dev mailing list Dev@wso2.org http://wso2.org/cgi-bin/mailman/listinfo/dev