我想在运行Liberty Profile的WAB / OSGi中使用MongoDB的JNDI查找。
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();
}
}
}
JNDI查找给出了以下异常。
[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.
我认为ClassCastException是因为我的应用程序和OSGi bootclassloader使用了不同的类加载器。但是,我不知道如何解决它。
答案 0 :(得分:0)
目前,无法在OSGi应用程序中使用mongodb-2.0
功能。
查找com.mongodb.DB
资源会返回DBApiLayer
的实例,但这不是问题(因为DBApiLayer
扩展DB
)。即使你这样做,你仍会得到ClassCastException:
DBApiLayer db = (DBApiLayer) new InitialContext().lookup("java:comp/env/mongodb");
会抛出:
java.lang.ClassCastException: com.mongodb.DBApiLayer incompatible with com.mongodb.DBApiLayer
这种限制的原因是mongodb-2.0
功能将使用Liberty的Classloader加载com.mongodb类,而OSGi应用程序将使用单独的Classloader加载com.mongodb类,无论你如何配置东西。
普通Java EE应用程序可以执行以下操作:
<library id="MongoLib">
<file name="${server.config.dir}/lib/mongo-java-driver-2.11.4.jar"/>
</library>
<application name="myApp">
<classloader commonLibraryRef="MongoLib"/>
</application>
但是,<osgiApplication>
元素没有该功能。不幸的是,这里唯一的解决方案是与IBM开启一个RFE(或者如果已经存在RFE,则为up)。