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