1

我想在 WAB/OSGi 中使用 JNDI 查找 MongoDB,运行 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();
        }
    }
}

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 引导类加载器使用了不同的类加载器。但是,我不知道如何解决它。

4

1 回答 1

0

目前没有办法在mongodb-2.0OSGi 应用程序中使用该功能。

查找com.mongodb.DB资源将返回一个实例DBApiLayer,但这不是问题(因为DBApiLayerextends 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 已经存在,则支持一个)。

于 2015-12-22T02:12:49.233 回答