How to use 3rd party libraries in glassfish? - mongodb

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?

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

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.

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.

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

Go to your Glassfish doamin directory.
Then go to lib folder.
Place the libraries there.
Restart the glassfish and run.
(Ex) C:\glassfish3\glassfish\domains\domain1\lib

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

Related

ClassNotFoundException oracle.jdbc.driver.OracleDriver only in servlet, using Eclipse and oracle

The code below fails on the line: Class.forName("oracle.jdbc.driver.OracleDriver");
with the error:
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
The two printlns print: Wed_Jun_22_11:18:51_PDT_2005 false This makes me think the class exists and can be found. Also this exact same class works in an a non-servlet application.
I have rebooted everything multiple times and regenerated the application/servlet multiple times. All values have been hard coded to make it simple and short.
I'm using: Eclipse JavaEE 1.4.2 Tomcat 7 jdk1.7 Oracle 11g R2 Windows 7 64bit
I have already added the jar files in web-inf. but it is still giving the following error: java.lang.NoClassDefFoundError: oracle/jdbc/driver/OracleDriver.
Any suggestions would be great.
It is a bit hard to tell what exactly going wrong without looking into your application and tomcat server. But there are a couple of hints for your issue.
NoClassDefFoundError always makes me think that there is class collision rather than missing jar file. Be ware of the difference between ClassNotFound and NoClassDefFoundError
tomcat loads class in a different way as what normal java app does. Normally, the class loaders in a stand along java app will follow delegate pattern, which means the child class loader will always delegate the class loading job to its parent class loader. But tomcat does not exactly follow this. So it will load(find source file, read byte code and create a instace of class Class) by itself.
So check your tomcat lib as well as all the web apps under the tomcat and see if there are multiple version of ojdbcXXX.jar
Go through C:\apache-tomcat-7.0.47\lib path(this path may be differ ->based on where you pasted the Tomcat server ) then past ojdbc14.jar if its not contain.
Then restart the server in eclipse then run your app on server

Running servlet within Eclipse requires libs to be defined 3 times - am I doing something wrong?

Hullo - issue is this:
I wrote a servlet in Eclipse which requires mysql-connector-java-5.1.22-bin.jar
To compile I need to add the jar via the project's "Java Build Path"
To deploy I need to add the jar to the project's "Deployment Assembly"
To run the servlet within eclipse I need to add the jar to the servlet's Run Configuration -> Classpath
It's not the end of the world re-re-repeating myself like this, but it does seem odd.
Given that Eclipse gets a lot of other stuff correct I'm guessing / hoping that maybe I'm overlooking some feature to avoid this silliness (I cannot imagine a scenario where you'd benefit from entering this in 3 different spots ... but maybe I'm being uncreative here ...).
Insights appreciated :-)
The only thing you need to do is to drop the jar in WebContent/WEB-INF/lib.
You are developing a Java Web project, so the traditional place to put the required libs (JAR files etc) is under /WEB-INF/lib. And you do it only once.
In Eclipse, when you create Dynamic Web Project the appropriate project structure is generated for you (this is a development structure). In this case you place your JAR files in ProjectName/WebContent/WEB-INF/lib folder. And this folder is *automatically included in the project's build path.
Considering the fact that it is a Java Web project (you said you use servlets) you have to deploy your web app to some Application Server, like GlassFish, JBoss, WebLogic, WebSphere etc, or more simple Web Container like Apache Tomcat. If you do this thru Eclipse, then again your web project is automatically deployed.
NB!
There may be some additional details related to using libraries.
For instance, when it comes to using database drivers (MySql, PostgreSQL, Oracle etc) Tomcat advises the following while configuring JNDI Datasource (quote):
Before you proceed, don't forget to copy the JDBC Driver's jar into
$CATALINA_HOME/lib
In your case (MySQL) see the example here: MySQL DBCP Example
Also see my answer related to Webapp configuration file organization convention.
Hope this will help you.
P.S. Here is a step-by-step example: How do I access MySQL from a web application?

OSGI bundle , not able to resolve javax.servlet classes

I am trying to build an OSGI bundle of a class which imports the following:
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
I am trying to build this as a plugin project in Eclipse. I added j2ee jar which resolved the errors but export as a plugin fails.
I also didn't want to add the j2ee jar to it since there might me mismatch in the OSGi container. What'es the best way to resolve this? I am new to OSGI..
There are bundles available from Geronimo and ServiceMix which provide the Servlet API. Though you probably still need a web-container to run your OSGi-Web application. So how is your container setup to look like?
For the OSGi Containers there are Apache Karaf and Eclipse Virgo. Both of them provide also a Web-Container. If you want to setup your own Container you might want to take a look at Pax-Web. This one also provides the needed Servlet APIs.
I'm sure there is a bundlified version of the j2ee.jar for use in an OSGi container. If this is not the case, just bundle it yourself.

How can you develop bottom-up JAX-WS web services referencing classes contained in separate jar files?

I am developing a Java EE 6 bottom-up JAX-WS to expose an EJB3.1 stateless session bean. The web service in a WAR is failing to install on deployment because it references an external jar (or shared library) which one can assume is not loaded yet.
The common suggestion is to include the jars in the /lib folder, which does fix the issue, however the jars need to remain in this external shared library location and NOT in the ear file, because they amount to 30MB.
What are some techniques to get around this issue in a Websphere (WAS v.8) environment or any server environment.
Some suggestions I have found include:
1. define classpath in META-INF file.
2. define the resources in deployment.xml
3. alter class loading order
4. (from ibm) In the case where the jars are part of a Shared Library configured on WebSphere Application Server, then a User Library must be used to configure the project for development before generating the WebService.
However, I have been unsuccessful to find any help online in these areas. Is there another technique or does anyone know anything about accomplishing this? Thanks in advance.
EDIT: If I specify the libraries in the META-INF using class-path, they are loaded before extensions, shared libraries..etc, but they are still loaded after the WAR which is not good. Again, this isn't a runtime issue because the web services are created at deployment on the fly.
I submitted a ticket to IBM. The libraries referenced by the web service are needed during deployment and must be bundled into the Ear in some fashion. I threw them in the web-inf/lib folder. However, if the referenced libraries then depend on additional libraries, these can be placed in the Shared Libraries. Seems odd to me too, but let's all just admit "shared libraries" are a hack anyways.
If you still have issues, just make sure your class loading is set to parent_last.

Java EE, GWT, NoClassDefException

I have an app, built on GWT (google web toolkit) and JPA (eclipselink 2.3). it's not using GAE (app engine).
when I finished application, I ran 'google->gwt compile' menu in eclipse and then uploaded /war content to the tomcat directory...
application is running, but when I try to do one specific action in gui, I get an error message and Tomcat log contains this exception: http://paste2.org/p/1879857 (java.lang.NoClassDefFoundError)
during development of the application, I encountered this kind of exception several times, it was always caused by absence of library .jar file in the war/WEB-INF/lib/... anytime it has occurred, I stored .jar to the folder and it worked... but not this time...
this class is located in gwt-dev.jar (yes, it is there - have searched the archive) and it didn't help me to store archive to the lib/ folder...
it is also included in classpath, and compiler had no problem... compilation finished without errors (so compiler can see the class).
do you have any idea, how to make tomcat to see the class?
thanks
gwt-dev.jar shouldn't be in WEB-INF/lib/, it is the GWT compiler, and shouldn't be needed or used at runtime. At the same time, that HashSet (com.google.gwt.dev.util.collect.HashSet, part of dev mode) shouldn't be used outside the compiler - use java.util.HashSet instead.
Change the HashSet import in GroupImpl.java from com.google.gwt.dev.util.collect.HashSet to java.util.HashSet. You shouldn't need gwt-dev.jar to run your application.