Best practice to dependency resolve in Jboss EAP - jboss

In case of war file deployment, there are two possible ways to resolve dependency in Jboss EAP:
we could keep all the dependent jar files in Jboss modules and get access of them using jboss-deployment-structure.xml file.
we could keep all the jar files in WEB-INF/lib folder inside war file.
Which one is the best practice to follow and why?

It depends on what you prefer.
#1 means you need to configure server and application(s), and this is more effective when you have more applications on server using these modules as dependencies. So you save space from duplicating libraries in more applications.
#2 means you have almost all dependencies in your deployment application => bigger file/directory (but don't forget some dependencies are automatically enabled by container based on what you use Servlets, JPA etc.).

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.

JBoss eap 6 (as 7) - 2 different classes with same package and name

I am having an issue with a 3rd party developer.
They have provided a number of jars, and unfortunately in 2 different jars they have different implementations of a class (same name, same package).
We deploy using a single war file where both jars (among many others) are packaged together in web-inf/lib directory and unfortunately both jars are needed.
Is there a way where I can guarantee in JBoss eap 6 that the class from a.jar gets loaded before the class from b.jar?
Thanks.
All of your answers about classloading on JBoss can be found here at this link. But since now I advise you to read the "JBoss Deployment Structure File" section
With the "jboss-deployment-structure.xml" JBoss specific deployment descriptor you can control class loading in a fine grained manner. It should be placed in the top level deployment, in META-INF (or WEB-INF for web deployments). It can do the following:
Prevent automatic dependencies from being added
Add additional dependencies
Define additional modules
Change an EAR deployments isolated class loading behaviour
Add additional resource roots to a module

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.

JBoss Custom lib directory

I have this third party framework which comes with a huge set of dependent libraries, which by the way, have not yet been indexed in any Maven repository. I want to use this framework with some Web Apps, but for obvious reasons I don't want to put all those libraries under WEB-INF/lib, neither do I want just to place them all under server/default/lib to avoid mixing them with other local and third party libraries.
Is there some way under JBoss 4.2.2 or higher to specify a custom lib directory for certain Web Apps? It's possible and/or advisable to have something like server/default/lib/myAppLib?
Any suggestion on this regard?
You can add the following entry in your server/default/conf/jboss-service.xml for putting your jars in server/default/myLibDir:
<classpath codebase="myLibDir" archives="*"/>
To my knowledge, you have three options:
Package you WARs in an EAR and move the library JARs out of WEB-INF/lib and
place them in a lib folder at the root of the EAR. No extra configuration required. This (non portable) solution is described in Configuring JBoss shared libs.
Move the library JARs out of WEB-INF/lib and place them into server/xxx/lib.
Deploy the JARs in the deploy/ folder and disable WAR file class loader isolation.
I don't recommend option #3. Option #2 is what you don't want. This leaves us with option #1 (which is IMO the cleanest).
Related questions
Jboss shared library
In JBoss can I configure a “shared library” location?

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.