在JABI中查找MongoDB期间的ClassCastException,在WAB内部运行Liberty

时间:2014-03-17 05:16:22

标签: mongodb osgi jndi websphere-liberty

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

1 个答案:

答案 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)。