mongodb

glassfish

java-ee-6

glassfish-3

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 Java EE 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?

Solution 1

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

Solution 2

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.

Solution 3

Glassfish has own Class loader hierarchy, http://docs.oracle.com/cd/E19798-01/821-1752/beade/index.html
I face the same problem in my project and then I put all my Third party libraries in domain/domain1/lib and my problem solved. On other way round, my problem was solved too by putting libraries in glassfish/lib.

Solution 4

In my case I was using Oracle Express Edition 11gR2 and Glassfish 3.1.2 and the ONLY way that works in my case was putting the ojdbc6 in:

C:\Program Files\glassfish-3.1.2.2\glassfish\lib

Solution 5

  1. Go to your Glassfish doamin directory.

  2. Then go to lib folder.

  3. Place the libraries there.

  4. Restart the glassfish and run.

(Ex) C:\glassfish3\glassfish\domains\domain1\lib

Solution 6

Try to put Your libs into $GF_HOME/glassfish/modules/. It's dirty, but will work.