I have a java ear archive, which containts "lib" folder, declared as library directory in the application.xml.
My problem is that some of the jars inside lib folder are not needed by some modules. furthermore, one of my modules (a .war archive) contains in its own lib folder a library which is older compared to the one inside the .ear. This causes a clash between the two libraries.
I want that my module gets in its classpath only the libraries defined in its own lib folder. Is this possible?
Thanks
A lot depends on which app server you are using for deployment - you can create custom classloader hierarchy within weblogic
more here -https://docs.oracle.com/cd/E24329_01/web.1211/e24368/classloading.htm#WLPRG295
for websphere - you can use PARENT_LAST attribute in the deployment.xml to control this hierarchy to an extent.
Related
I dont seem to find a solution to that, I have the following problem :
I have a bunch of jar dependencies that are put in lib folder under my ear.
Besides, I put other jars in shared lib references.
When I reference the shared lib, I seem to have ClassNotFound from classes in the lib jar under ear, I do not know if we can actually have access to both anyhow?
Thanks a lot!
Assuming WebSphere traditional, shared libraries associated with the application will share a class loader with jars in the EAR/lib directory, unless you select the "use an isolated class loader" setting for the shared libraries - that gives them their own class loader that is not able to "see" classes in EAR/lib.
If your EAR/lib libraries aren't being found at all (from any scope), I'd suggest checking application.xml to ensure that your application is not declared as a Java EE <5 application - if the application.xml specifies J2EE 1.2-1.4, that predates the addition of library-directory to the specification, and the server will not add that directory to the class path.
This question already has answers here:
How to add JAR libraries to WAR project without facing java.lang.ClassNotFoundException? Classpath vs Build Path vs /WEB-INF/lib
(5 answers)
Closed 7 years ago.
I've seen a lot of tutorials and applications that put their jars inside a build path while others put it inside their web-inf/lib folder, Are there any significant difference? What are the pros and cons of both? What is an indicator for me to put a certain jar inside the libs folder and put the jar in the build path?
An application with WEB-INF folder is a web application. Meaning it will be packed as a WAR file and deployed on a server.
If you are using an IDE like eclipse, and you export the project as a WAR file, it will automatically take jars under the lib folder and pack them with the WAR and that will make them available for the application running on the server (jars under WEB-INF/lib are included in the application classpath).
If you just put them anywhere else and include them in the build path, when you export the project you have to declare that you want the jars in the build path to be included as well.
Basically, there is no big difference but if you know you need this jar in runtime (i.e. after deploying the application to the server), it is better to put it under the WEB-INF/lib folder.
What do you mean by build path? Most of the JARs you use need to be available during building (compiling) because your code depends on them - otherwise it won't compile.
The real question is between placing JARs in WEB-INF/lib vs. your container /lib directory. In general you should always put your JARs inside an application in WEB-INF/lib. Placing them globally has several consequences:
singletons are now global to all web applications (one class loader) if multiple deployed
it's easier to introduce memory leak if a library holds a reference to any of your classes (see above)
you don't duplicate the same classes (each web application will reuse the same class as opposed to having a separate copy in each class loader
In my application I have a directory that is in CLASS_PATH and where I store jar files. I use ATG so have to use my .class in properie file to have a way to init components (in this situation it's servlet). So I need my webapp.war in my CLASS_PATH direcory. I put this war file but it does'nt work. How can I put my compiled servlet classes to this directory?
Of course it's not good idea to put only this compiled classes from archive :)
I think what you are looking for is a custom class loader, adapted to handle WAR files. Such a class loader would unpack or peek into the WAR file, to extract the class files.
I have never heard of anyone loading from within WAR files, but it should not be that hard to implement.
Your classloader can not find the servlet classes in war because are in WEB-INF/classes.
Try to unzip and copy WEB-INF/classes to a classpath location
In ATG, Classpath setting start from the way in which you build the ear. Every module in ATG has a MANIFEST file, which specifies an attribute called "ATG Classpath". The value of this attribute is used to construuct the classpath at runtime. So, if you include the path to your class files as a value to this attribute, ATG automatically sets this in the classpath (runAssembler, to be more specific) when creating the ear. Jboss when deploying the ear will then pick it up.
My goal is pretty simple: to use ant to build an EAR which contains 1 EJB and 1 jar containing all of the dependencies. This jar, called common.jar for the sake of example has vendor jar files in it as well as other xml files that the EJB depends on and will need to be able to see during runtime....
So far I have everything packaged correctly as an EAR like this:
EARFILE.ear
-EJBFILE.jar
/META-INF
-MANIFEST.MF
-common.jar
/META-INF
-MANIFEST.MF
/lib
-(all vendor jars inside here)
-(All the xml config files are inside the root of the common.jar)
Inside the MANIFEST.MF for the EJBFILE.jar is...
Class-path: ../../common.jar
Inside the MANIFEST.MF for the common.jar is...
Class-path: ../lib/some_common.jar
When I deploy this the appserver (websphere) cannot find the JAR file when I try to start the server. I am getting the ClassDefNotFoundError because the classes inside the EJB cant find the vendor JAR files when I try to start the instance. However I know that common.jar is setup correctly though, else the EJB wouldn't have compiled since it needed to have those vendor jars on the classpath for javac.
So what I want to know is this:
How can I get the runtime to correctly see the Vendor jar files.
Will the EJB be able to see the xml files at run-time? I am concerned about this because these xml files are located outside of the EJB inside of a jar that is just in the EAR, it isn't even a module its just a jar inside the EAR.
Does it even matter when using websphere? From what I gather some containers don't even care what is in the Class-path of MANIFEST.MF.
There are several improvements I can suggest, based on running into similar problems.
First and most importantly, use the appxml attribute of the Ant ear task to specify your deployment descriptor (usually named application.xml); also include references to the vendor JAR files bundled as defined below
I would recommend you not put your vendor JAR files into another JAR - instead, just copy them into the EAR at the same level as EJBFILE.jar
The configuration XML files can go in a sub-directory of the EJBFILE.jar (such as config), and then you can reference them as /config/filename.xml.
The application.xml file will tell WebSphere where to find your JAR files. Classpath traversal in an application server is not the same as that of a compiler, which JBoss has taught me the hard way.
I am using all of the above patterns, and my in-container code (deployed in the EAR) can see all my XML files, as well as find all my dependencies.
could anyone please clarify the meaning of class libraries on the classpath in the case of Tomcat in the following line:
Actually all classes used by the web-app(unless they're part of the class libraries on the classpath) must follow the same rules as servlet classes-inside WEB-INF/classes, in a directory structure matching the package (or in the appropriate package directories within a JAR inside WEB-INF/lib).
What do they mean with class libraries and classpath in the above paragraph?
The classpath is a list of locations where the JVM should look to find classes. By default, this has things like rt.jar and vm.jar on it which contain the classes like java.lang.String. You can append directories and jars to the classpath to allow the VM to find classes beyond those installed by default.
A class library is a collection of classes packaged to be used by applications. For all practical purposes, it is a jar with useful classes in it like junit.jar.
What the message is saying is: If you want to use a library class (like something from log4j), it needs to be on the classpath, in WEB-INF/classes or WEB-INF/lib.
Sounds like they're distinguishing between the .class files in your web app, packaged in a WAR file using the standard WEB-INF idiom, and those on the app server itself (e.g., in server/lib and common/lib for Tomcat 5.x and lib for Tomcat 6.x).
The important thing for you to know is that Tomcat has a hierarchy of class loaders. You need to understand how they work to use Tomcat effectively.
UPDATE: If understanding CLASSPATH is your issue, you need to know that anything WEB-INF/classes and in JARs under WEB-INF/lib in your deployment are in the CLASSPATH, along with JARs that are installed on your app server that all deployed applications share. That's what I meant when I said common/lib and server/lib for Tomcat 5.x and lib for Tomcat 6.
I don't think I understand what your question is. Do you not understand CLASSPATH? The CLASSPATH is all the places that the JVM knows to look when it needs a .class file that hasn't been loaded yet. That includes the JARs available to all applications deployed on Tomcat and WEB-INF/classes and WEB-INF/lib directories for your particular deployment.