问题
I want to use JNDI lookup for MongoDB, inside WAB/OSGi, running Liberty Profile.
import com.mongodb.DB;
@WebServlet("/MongoServlet")
public class MongoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
DB db = (DB) new InitialContext().lookup("java:comp/env/mongodb");
} catch (NamingException e) {
e.printStackTrace();
}
}
}
The JNDI lookup gives below exception.
[ERROR ] SRVE0777E: Exception thrown by application class 'com.osgi.jndi.web.MongoServlet.doGet:57'
java.lang.ClassCastException: com.mongodb.DBApiLayer incompatible with com.mongodb.DB
com.mongodb.DBApiLayer is subclass of com.mongodb.DB.
I believe that the ClassCastException is because of different classloaders being used by my application, and OSGi bootclassloader. But, I don't know how to troubleshoot it.
回答1:
Currently there is no way to use the mongodb-2.0
feature with an OSGi application.
Looking up a com.mongodb.DB
resource will return you back an instance of DBApiLayer
, but that's not the issue (since DBApiLayer
extends DB
). You would still get a ClassCastException even if you did this:
DBApiLayer db = (DBApiLayer) new InitialContext().lookup("java:comp/env/mongodb");
Would throw:
java.lang.ClassCastException: com.mongodb.DBApiLayer incompatible with com.mongodb.DBApiLayer
The reason for this limitation is that the mongodb-2.0
feature will use a Classloader from Liberty to load com.mongodb classes, and an OSGi application will use a separate Classloader to load com.mongodb classes, no matter how you configure things.
Normal Java EE applications can do things like this:
<library id="MongoLib">
<file name="${server.config.dir}/lib/mongo-java-driver-2.11.4.jar"/>
</library>
<application name="myApp">
<classloader commonLibraryRef="MongoLib"/>
</application>
However, <osgiApplication>
elements do not have that capability. Unfortunately, the only solution here is to open an RFE with IBM (or upvote one if an RFE already exists for this).
来源:https://stackoverflow.com/questions/22447446/classcastexception-during-jndi-lookup-for-mongodb-inside-wab-running-liberty