Different lib directories of JBoss - java

There is a number of different lib directories JBoss (5.1.0) uses: I can find jboss/lib, jboss/lib/endorsed, jboss/common/lib, jboss/server/default/lib and of course the jboss/server/default/deploy/myapp/WEB-INF/lib (am I missing something ?).
From the above, I know that I need to use the last one (WEB-INF/lib) to put any jars my app needs. What about all the others ? What is their use and what should I put there ? Why put it there and not in the WEB-INF/lib ?
Thanks !

Other folders are for different sorts of shared libs. For example, if you have 10 apps using same DB driver, there is really no reason to keep one db driver jar per application (i.e. 10 jars). In that case you can simply put it into jboss/server/<server config>/lib.
jboss/server/<server config>/lib: all libs here are shared between all apps in given server config
jboss/common/lib: shared between all server configs
jboss/lib: these are libs for server itself (if I am not mistaking, they are also on your app classpath)
jboss/lib/endorsed: this is the same as above, only if you put a lib here, it will always be found before similar lib in jboss/lib. The idea is similar to Endorsed Standards Override Mechanism of JDK

Related

Why does Glassfish have two 'glassfish' folders and duplicate directories?

The question is in the title I guess. Both folders have a bin directory with some duplication of scripts, etc. Then there are multiple lib directories as well. One in the /glassfish/lib and another in /glassfish/domains//lib. It just seems odd to me and gets confusing as to where I should put classpath jars, direct env variables to, etc. Is there any specific reason for this?
Thanks
The reason for this is that it gives you the flexibility to provide libs at different visibility levels.
The folder glassfish/lib contains the libs which should be available for the whole server and all domains.
The folder glassfish/domains/domain1/lib contains only the libs which are available for domain1.
If you had a domain2, the folder glassfish/domains/domain2/lib would contain the libs which are required for domain2.
Now, as an example, if you have some libs which are required by domain1 and domain2, you can put them in the folder glassfish/lib, so they are available for the whole server and therefore for both domains.
Another example, if you have two domains, and both domains require a different version of the same lib, you have to put the specific versions into glassfish/domains/domain1/lib and glassfish/domains/domain2/lib accordingly.
As a consequence of this, you can always put your libs into glassfish/lib if you only have a single domain.
See also:
GlassFish Server 3.0.1 Guider - Chapter 2 Class Loaders
ClassLoaders in GlassFish - a FAQ
How to use 3rd party libraries in glassfish?
how can i use a shared lib in glassfish to avoid deployment of the huge libs?

2 wars sharing code

I need to create 2 war applications deployed on tomcat server.
One of the applications have the exact same logic and code as the other application but with added changes to the view and controllers.
Then App1 and App2 will have the same code to access data and I don't want to duplicate code.
My idea is create 2 WARs and these WAR files should use a library or other project (I don't know) that has access to the database.
Which solution is the best for performance?
Option 1
If you are sharing code (and it's a big piece of code, which drives you crazy while uploading the war-files) it may be an option to create a jar containing the code and add the jar file to tomcats library-folder, which is ${CATALINA_BASE}/lib/
Note that this is usually not something you want to do lightly, because that jar file will be available to ALL war-files on the tomcat, creating possible namespace-problems.
Option 2
If sharing the code with all the projects on the application-server is not an option you'll have to add the jar-file to the projects and add it into it's classpath (which happens automatically within eclipse if you add the jar into ${PROJECT_ROOT}/WebContent/WEB-INF/lib).
Preformance-wise this doesn't really make a difference since tomcat will load the class-files, which are not very big. The instances might be, but the type of deployment doesn't really have an impact upon instances.
If you want to use the same classes for both projects just simple create one .jar file which will contain those classes. Then add that .jar into your web projects' classpath and use it in both.
You can extract the common part out, and make it as a jar. And then two wars use this jar as library.
If you used maven for building your wars, it would be easier to build a project hierarchy.
something like:
parent
|_common(jar)
|_war1
|_war2

consequences of adding class files directly into an exploded deployed ear in WAS 7

I would like to know what are the pros and cons, if any, of injecting or dropping java class files into an exploded ear file that is deployed in WAS 7.
When we install the packaged ear file it gets exploded into a certain temp directory and we can actually go into the folder location of the class file and replace it with our new class file and restart the server to load it.
If we are doing it for every node in WAS 7 and restarting them one by one for HA. would there be an issue.
Thanks.
Syed...
Here's another con to worry about. If you replace the file on the node and DMGR doesn't know about it, if you do a full sync the file from the DMGR will be pushed out to the nodes.
The recommended way to do this is to properly get the new file in the EAR and do another deployment.
You might encounter problems if the class contains annotations since application deployment caches the result of annotation scanning. Otherwise, you might be able to get it to work, but I doubt you would get support from IBM if something breaks. The supported mechanism for what you're trying to do is available via AdminApp.update in wsadmin.

MANIFEST.MF file for JAR Used in Web App?

I've developed a utility library that will be used in many of our enterprise Java applications. This library has numerous additional dependencies that also need to be on the classpath. I'd like to avoid forcing our developers to add a zillion entries to their MANIFEST.MF files, and let them instead just include my library. Is there any way that my library's MANIFEST.MF file can reference its dependencies and have them picked up by the enterprise applications that will be using my library?
I've tried referencing them in my library's MANIFEST.MF file using the full path to the dependencies on the filesystem. That didn't work. I end up with ClassNotFoundException errors for all of my dependencies. Is there something else I should be trying?
When you create a web application, you'd normally put it in a WAR file. The idea is that you bundle the required dependencies in that WAR file, by adding the jars to the /WEB-INF/lib folder inside the WAR. Web containers (like in a Java EE application server) know of this structure and will include those jars on the classpath.
If your library has additional dependencies, just tell the users about it and either redistribute them with your library if the license allows it, or tell them where to obtain them. When using a decent tool for creating a web app like an IDE, Ant with Ivy, or Maven (or a combination of these), then handling and bundling dependencies should be no problem.
Alternatively, this works so long as you stick to the format very carefully, i.e. stick to exactly two spaces before each "file:" etc:
Manifest-Version: 1.0
Main-Class: package.TestClass
Class-Path: file:/D:/WebServer/Tomcat/shared/lib/BlueCove.jar
file:/D:/WebServer/Tomcat/shared/lib/classes12.jar
file:/D:/WebServer/Tomcat/shared/lib/comm.jar
file:/D:/WebServer/Tomcat/shared/lib/FTP.jar
file:/D:/WebServer/Tomcat/shared/lib/FTP2.jar
file:/D:/WebServer/Tomcat/shared/lib/iText.jar
file:/D:/WebServer/Tomcat/shared/lib/j2ee.jar
file:/D:/WebServer/Tomcat/shared/lib/jmxremote.jar
file:/D:/WebServer/Tomcat/shared/lib/jmxri.jar
file:/D:/WebServer/Tomcat/shared/lib/jmxtools.jar
file:/D:/WebServer/Tomcat/shared/lib/jpos15.jar
file:/D:/WebServer/Tomcat/shared/lib/js.jar
file:/D:/WebServer/Tomcat/shared/lib/mail.jar
...
file:/C:/WebServer/Tomcat/shared/lib/soap.jar
file:/C:/WebServer/Tomcat/shared/lib/sqljdbc.jar
file:/C:/WebServer/Tomcat/shared/lib/tools.jar
I've done this with a number of tools. It is a truly horrible hack but seems to work reliably.
Give them a special manifest to use. Something like:
Manifest-Version: 1.0
Main-Class: com.xxx.yyy.zzz.YourSpecialClassThatHacksTheClassPath
Real-Main-Class: com.ppp.qqq.TheirMainClass
In your special class, screw around with the classpath (not easy), read the manifest "Real-Main-Class" entry (a bit easier) and launch their main from that (not really difficult at all).
Obviously this will not work with a .war file.
Even I had the same problem. As mentioned above, the solution was to have exact two space after file:/ and one space after .jar file and at the end, press enter key.
I know this is not a neat solution, but it works. enjoy.

/WEB-INF/classes vs /WEB-INF/lib

I'd like to package my Java EE6 web classes (beans, filters, servlets) into jar and place it into /WEB-INF/lib/ directory along with other utility jars and abandon /WEB-INF/classes/ directory totally.
Are there any substantial differences between the two in terms of classloading, acessing application context, etc?
Thanks.
PS: Whenever googling any of java specs I'm always redirected to Oracle documentation index which is dozen clicks away from original url. Anyone knows what's happening there?
I'd go for /WEB-INF/classes. It allows you to run your application in debug mode and hot-swap classes on change. If you package everything as a jar, you'd have to repackage and redeploy the app every time you change a class.
Well, shortly: Imagine you have class org.example.Test.class, if you put it into jar and in WEB-INF/lib/ directory, and copy the same class into WEB-INF/classes/ then classloader of that application will use last one (from WEB-INF/classes/).
Sometimes you can use it as advantage - I have a library, and it has a bug... I look for source of that class (where bug is; I miss the part of how I know that bug is in that class, that's another story), I add that class to the project with fixed code, and it is compiled into WEB-INF/classes/ while library still exist in WEB-INF/lib/. Fixed class will be used until library will be fixed.
In Tomcat Servlet container's definition: WEB-INF\classes is searched before WEB-INF\lib. You can choose to delegate your classloading to your custom classloader - even then the order above is maintained.
If you choose to go with a different provider e.g. JBOss, Glassfish, Jetty it might have a different order, but I am not sure about those.

Categories