使用 EJB 模块连接到 Marklogic

Connecting to Marklogic using EJB module

我正尝试在 EMB 中使用来自 java 的 java api 客户端连接到 marklogic,如下所示。我在 netbeans 中创建了一个 maven EJB 模块项目,并将 marklogic 依赖项添加到 pom.xml 文件中。

   <dependency>
        <groupId>com.marklogic</groupId>
        <artifactId>java-client-api</artifactId>
        <version>3.0.1</version>
    </dependency>



    package com.xx.yy;
    import java.io.IOException;
    import java.util.concurrent.atomic.AtomicLong;
    import javax.ejb.ActivationConfigProperty;
    import javax.ejb.MessageDriven;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageListener;
    import javax.jms.TextMessage;
    import javax.xml.xpath.XPathExpressionException;


    @MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
        @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/MyTopic"),
        @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
        @ActivationConfigProperty(propertyName = "clientId", propertyValue = "jms/MyTopic"),
        @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "jms/MyTopic")
    })
    public class CreateBlock implements MessageListener {

        AtomicLong count = new AtomicLong(0);

        public CreateBlock() {
        }

        @Override
        public void onMessage(Message m){
            long i;

            try {
                if (m instanceof TextMessage) {
                    i = count.incrementAndGet();

                    System.out.println("Reading message: " + m.getBody(String.class));
                    GenerateBlock.createblock(m.getBody(String.class));

                } else {
                    System.err.println("Message is not a TextMessage");
                }
            } catch (JMSException e) {
                System.err.println("JMSException in onMessage(): " + e.toString());
            }
            catch ( IOException e){
                System.err.println("IOException in onMessage(): " + e.toString());
            }
            catch (XPathExpressionException e){
                  System.err.println("XPathExpressionException in onMessage(): " + e.toString());

            }
        }
}

它执行以下 java api 客户端说明书中的一些代码,以确认我可以从数据库中读取

package com.xx.yy;
import java.io.IOException;
import javax.xml.xpath.XPathExpressionException;
import org.w3c.dom.Document;

import com.marklogic.client.DatabaseClient;
import com.marklogic.client.DatabaseClientFactory;
import com.marklogic.client.document.XMLDocumentManager;
import com.marklogic.client.DatabaseClientFactory.Authentication;


public class GenerateBlock {


    public static void createblock(String docId) throws IOException, XPathExpressionException {


        DatabaseClient client = DatabaseClientFactory.newClient(
                    "domain.com", 8012, "dbname", "admin", "password",
                    Authentication.valueOf("DIGEST"));

        XMLDocumentManager docMgr = client.newXMLDocumentManager();
        docMgr.setForestName("forestname");

        // read the document content
        Document document = docMgr.readAs(docId, Document.class);

        // access the document content
        String rootName = document.getDocumentElement().getTagName();
        System.out.println("(Shortcut) Read " + docId + " content with the <" + rootName + "/> root element");
        client.release();
    }

}

然而,当代码在接收到 JMS 消息时执行,会出现以下异常

**

Info:   MQJMSRA_MR1101: run:Message returned & marked for routing to the DMQ
    Warning:   MDB00037: [StoneManBuilder:CreateBlock]: Message-driven bean invocation exception: [javax.ejb.EJBException]    
    Warning:   javax.ejb.EJBException
    javax.ejb.EJBException
    at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.java:750)
    at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:700)
    at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:505)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
    at org.glassfish.ejb.mdb.MessageBeanContainer.afterMessageDeliveryInternal(MessageBeanContainer.java:1326)
    at org.glassfish.ejb.mdb.MessageBeanContainer.afterMessageDelivery(MessageBeanContainer.java:1301)
    at org.glassfish.ejb.mdb.MessageBeanListenerImpl.afterMessageDelivery(MessageBeanListenerImpl.java:86)
    at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:143)
    at com.sun.proxy.$Proxy348.afterDelivery(Unknown Source)
    at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:361)
    at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:107)
    at com.sun.corba.ee.impl.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
    at com.sun.corba.ee.impl.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
    Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.marklogic.client.DatabaseClientFactory
    at com.kode100.stonemanbuilder.GenerateBlock.createblock(GenerateBlock.java:31)
    at com.kode100.stonemanbuilder.CreateBlock.onMessage(CreateBlock.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
    at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:73)
    at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
    at sun.reflect.GeneratedMethodAccessor196.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4758)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4746)
    at org.glassfish.ejb.mdb.MessageBeanContainer.deliverMessage(MessageBeanContainer.java:1219)
    at org.glassfish.ejb.mdb.MessageBeanListenerImpl.deliverMessage(MessageBeanListenerImpl.java:81)
    at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:171)
    at com.sun.proxy.$Proxy348.onMessage(Unknown Source)
    at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:283)
    ... 3 more

**

我可以使用相同的连接代码和参数从将文件上传到数据库的 JSF 应用程序连接到数据库。然后它释放客户端并使用 JMS 调用上述代码,以便最终对数据进行更多处理,读取和写入 marklogic。

我是否应该使用不同类型的项目来使用 JMS 来处理 marklogic,或者我的代码是否有问题?

问候 康特

鉴于核心错误是:

Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.marklogic.client.DatabaseClientFactory

您可能遇到环境问题而不是代码问题 -- 特别是使 MarkLogic jar 可用于 EJB class 加载程序的问题。

顺便说一句,在生产代码中,您可能希望创建一次客户端并针对同一主机上的所有请求重复使用它,而不是为每个请求创建一个新客户端。

每个食谱食谱都是独立的,这就是为什么它们不共享同一个数据库客户端的原因。

希望对您有所帮助,