views:

845

answers:

2

I need to connect to a MongoDB instance from my EJB3 application, running on glassfish 3.0.1. The Mongo project provides a set of drivers, and I'm able to use them in a standalone Java application.

How would I use them in a JEE application? Or maybe better phrasing: how would I make a 3rd party library available to my application when it runs in an EJB container?

At the moment, I'm getting a java.lang.NoClassDefFoundError when deploying a bean that tries to import from the library:

[#|2010-03-24T11:42:15.164+0100|SEVERE|glassfishv3.0|global|_ThreadID=28;_ThreadName=Thread-1;|Class [ com/mongodb/DBObject ] not found. Error while loading [ class mvs.core.LocationCacheService ]|#]
[#|2010-03-24T11:42:15.164+0100|WARNING|glassfishv3.0|javax.enterprise.system.tools.deployment.org.glassfish.deployment.common|_ThreadID=28;_ThreadName=Thread-1;|Error in annotation processing: java.lang.NoClassDefFoundError: com/mongodb/DBObject|#]

[#|2010-03-24T11:42:15.259+0100|SEVERE|glassfishv3.0|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadID=28;_ThreadName=Thread-1;|Exception while loading the app
org.glassfish.deployment.common.DeploymentException: java.lang.NoClassDefFoundError: com/mongodb/DBObject
at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:171)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:125)
at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:224)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:338)

I tried adding it to the NetBeans project (Properties -> Libraries -> Compile -> Add Jar, enable 'Package'), and I also tried manually copying the jar file to $GF_HOME/glassfish/domains/domain1/lib (where the mysql-connector already resides).

Do I need to 'register' the library with the container? Reference it via Annotation? Extend the classpath of the container to include the library?

+1  A: 

Hmm... Shouldn't you put this "driver" in glassfishv3/glassfish/domains/domain1/lib/ext?

Pascal Thivent
@Pascal: thank you! I thought I had tried this, too. Anyway, works like a charm. Is that a good way though? Shouldn't this be part of the deployment?
Hank
@Hank I don't know how the MongoDB driver is used but if it isn't used by the container (like a JDBC driver would be to create a connection pool) nor shared between apps of the domain, then you should maybe package it inside your application.
Pascal Thivent
A: 

You could put shared libs to lib/ext of your domain. commons-logging and jdbc drivers are often added in this domain path.

Common Class Loader

GlassFish v2 has a well defined Class Loader hierarchy which identifies the common class loader as the proper way to deal with shared libraries. So to make a long story short, putting you libraries and other framework JARs in domains/domain1/lib is all you need to do.

lib/, not lib/ext

The person asking me the question had tried putting the libraries in domains/domain1/lib/ext which triggered an interesting ClassNotFoundError for core Java EE classes such as javax.servlet.http.HttpServlet. Shing Wai Chan was quick to explain that domains/domain1/lib/ext is part of -Djava.ext.dirs which makes any of its JARs be considered as a JDK extension which means web app frameworks placed there will be loaded before webcontainer implementation classes as they are higher up in the classloader delegation chain.

Sebastien Lorber
Did you try the above with GlassFish v3?
Pascal Thivent
will try glassfish3 asap but not yet :)http://blogs.sun.com/alexismp/entry/glassfish_equivalent_to_websphere_s
Sebastien Lorber

related questions