Including the MySql's connector/j as part of an EAR file: Glassfish - deployment

We want to simplify the deployment process of an app by including the MySql connector/j jar as part of the EAR. (so we won't need to manually copy it in the /lib folder of our Glassfish servers)
Is it possible?
UPDATE: We have read this is possible using the SAR files in JBoss, but we don't think it's available in Glassfish.

Because of the classloader hierarchy in Glassfish I don't think this is possible. The mysql driver jar needs to be available outside of your application's classloader because the connection pool is globally available.
http://download.oracle.com/docs/cd/E19226-01/820-7695/6niugesfp/index.html#indexterm-28
From what I can find, Glassfish doesn't support anything like .sar files:
http://old.nabble.com/Migrating-From-jboss-4.2.1-to-GlassFish-td18629992.html
Maybe vote for this issue, or create your own for a .sar-like deployment option:
http://java.net/jira/browse/GLASSFISH-16915

Related

JBoss Client directory

I recently started learning more about JBoss Application sever. After installation I was looking inside all directories created by JBoss installation. (I'm using JBoss AS version - jboss-5.0.1.GA)
I referred documentation available at this link
It says 'client' directory contains Jar files needed by remote clients.
client: The JARs that are required for clients that run outside of JBoss are located in the client directory.
When I looked inside 'client' directory after installation, it contains 90 jar files overall. Does that mean If I create a remote ejb client I would need to include all the 90 jars in my remote application classpath?
With JBoss AS 5.x things got complicated.
Placing all of the client jar files on classpath will certainly work.
In JBoss 4.x there was an option to use jbossall-client.jar which integrated other numerous client libs into single file. If you'll look into same named jar in JBoss 5.x you'll find out that it's reduced to manifest referencing other jars. Placing this single jar in your classpath will work as long as all of the jars referenced by manifest are present in the same directory.
If accessing remote EJB is all you need then only a subset of jars is required, unfortunatelly it's hard to tell which ones is it.
Following this coderanch link (I've found it here on SO) you'll find such subset prepared for JBoss 5.1.0.GA.
Be warned though, list of jars published on coderanch has abbreviated names, some misquotations and at least two jars are not present in server version 5.0.1. If reducing number of dependencies is your priority, use this list wisely and enhance/extend it by trials and errors.

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?

Deploying to Glassfish classpath not set for com.mysql.jdbc.jdbc2.optional.MysqlXADataSource

Glassfish is not loading the com.mysql.jdbc.jdbc2.optional.MysqlXADataSource package.
The following error is thrown
javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence
Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException:
Error in allocating a connection. Cause: Class name is wrong or classpath is not set
for:com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
Error Code: 0 at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy
(EntityManagerSetupImpl.java:517)...
I have copied the mysql-connector jar file to the lib directory of Glassfish but I still get the above error.
How do I ensure that Glassfish can find my JDBC driver for my deployed application?
You will need to make the MySQL JDBC jar file available to Glassfish.
http://ushainformatique.com/blog/2010/03/19/jdbcwithglassfish/
EDIT:
How do I use different JDBC drivers? Where should I copy the jar(s)?
It is recommended to place JDBC drivers, that are used by all the
applications in the domain, in domain-dir/lib or
domain-dir/lib/classes. A restart of the application server instance
is required today so that the JDBC drivers are visible to applications
deployed in the domain.
From https://blogs.oracle.com/sivakumart/entry/classloaders_in_glassfish_an_attempt
So move the jar file into the lib dir below the domain into which you are deploying your app. The default Glassfish domain is domain1.
Restart Glassfish and this should work.
There is a Maven Glassfish plugin which may be worth evaluating http://maven-glassfish-plugin.java.net/ Using Maven and this plugin would help automate the deployment step. This would be more robust than doing manual deployments. Your call though of course.
Besides adding the driver to your classpath, you should try adding the appserv-rt.jar file to your project's build path (the jar is located in Glassfish's lib directory). If you don't want to include all the other jars you should first create a library containing the appserv-rt jar and then add it to your project's build path.
We could fix using
./asadmin start-database
This starts Derby (don't know why this is required, may be a bug, and I dont use this DB in my app)
:)

jndi.properties in JBoss and GlassFish deployment

Currently an EJB / Web Application project uses a JBoss-specific JNDI configuration file, placed either in the conf directory or in the Jar file (both works fine).
How can I make this project portable between JBoss (4.2.3 or 5) and GlassFish 3? Is there a recommended way to set different JNDI configuration parameters depending on the container?
According to their EJB FAQ, Glassfish developers have put a jndi.properties file within appserv-rt.jar. The JNDI machinery in Java SE automatically detects this file when used in conjunction with no-arg InitialContext() and bootstraps the correct naming provider.
My understanding is that this should work in Glassfish also. Did you try do deploy your application without the jndi.properties file specific to JBoss (and to place it into the conf directory when deploying on JBoss)?

Are there reasons to place a dependency in a web server's lib directory instead of including it in the War file?

If I have an dependency Jar for my application is it better to place it in the war files lib directory or to place it in the global application server (like Tomcat) lib directory? What do I gain by using one approach over another?
Diskspace springs to mind, but we live in a time when diskspace is cheap. Is there a memory usage difference? Can someone with more experience then me list the pros and cons of both options?
Generally speaking, it's much better to have WAR self-contained so you don't have to rely on the container configuration. It makes deployment much easier also. So try to put library in the WAR if you can.
However, I ran into cases when installing libraries to container makes sense. For example,
We have some internal libraries used by every webapp and they are huge. We install them to container so all the webapps use the same version and it saves on memory and diskspace too.
Libraries installed in WEB-INF/lib is not available to container. If you need to reference these in context.xml (like JDBC driver defined in Resources), you have to put them in server/lib.
If you want send log4j logs from all the webapps to the same file, you have to put log4j jar in the server/lib. Otherwise, each webapp uses its own logger.
If you want to use the container's resource management capabilities -- e.g. connecting to a SQL database and providing a JNDI lookup and connection pool for it -- then the container software itself will need access to the libraries and drivers to manage the resources.
Otherwise you probably don't want to install them in the server /lib directory and assume they are there and will work, as different web applications might have subtly different version requirements.
For a in-depth description of the class loader hierarchy implemented by Catalina, you should check Tomcat's Class Loaders HOW-TO. This will help you to understand when to make jars available to the container, to all webapps, to a single webapp only... and where to put them.