Reputation: 1614
I'm trying to connect to marklogic using the java api client from java within a EMB as follows. I created in netbeans a maven EJB Module project and have added the marklogic dependency to the pom.
<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());
}
}
}
which executes the following,,, just some code from the java api client cookbook to confirm I can read from the database
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();
}
}
however when the code executes as a JMS message is received, the following exceptions occur
**
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
**
I can connect to the database with the same connection code and parameters from a JSF application that uploads files to the database. It then releases the client and calls the above code using JMS in order to eventually do more processing on the data, read and writes to marklogic.
Should I be using a different type of project to work with marklogic using JMS or is there something incorrect with my code?
Regards Conteh
Upvotes: 2
Views: 168
Reputation: 7335
Given that the core error is:
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.marklogic.client.DatabaseClientFactory
you may have an environment issue instead of a code issue -- in particular, an issue with making the MarkLogic jar available to the EJB class loader.
In production code, by the way, you would want to create the client once and use it repeatedly for all requests on the same host instead of creating a new client for each request.
Each cookbook recipe stands alone, which is why they don't share the same database client.
Hoping that helps,
Upvotes: 3