How hard is it to load JARs from another location? - java

I have the following scenario. I'm working with a server which has a lib folder which contains all of its JARs, but things get kind of complicated when having multiple applications for the server, as the lib directory gets kind of crazy.
What I'd like to do is put all of my application's JARs in a different location and instruct the classloader to load them when my application is loaded. How can I do this? How will I need to rewrite my application to facilitate this?

As far as I know, it is not possible to load the jar files or set the CLASSPATH at runtime unless you have written your own class loader. Tomcat is a good illustration in which the tomcat's class loader loads the jar files dynamically in multi-level.
http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html
There is a common class loader which allow the jar files to be shared accross all web application. However, if you want to addthe jar files which are only loaded for the web application then you should add it under webroot, e.g. WEB-INF/lib. The libraries in this folder are not shared to all applications. For example, this means if two web applications are using different versions of the same library, they will not be mixed up.
Since I am using maven to manage the project, I do not need to worry about where to put my ja dependencies. Maven automatically bundles the libraries into war file for me.
So if you are not using servlet container, e.g. tomcat, jetty, etc. , then you will need to write a class loader. If that is necessary, then have a look into tomcat but it may not be easy.

You can add directories to the class path in Java 6.

Related

3rd party jars outside of ear to be accessed from classes inside the ear

I want to use a 3rd party jar in my application. But its too huge in size. So i want to access it without embedding it in the .ear file. How can i access 3rd party jars outside of ear from classes inside the ear.
I have tried to add the jar files to the lib folder on the server where its deployed. But its not working. Also in clustered environment i will have to keep copies of it on each server.
How can i avoid this. Can i somehow remotely access the 3rd party jar.
3rd party jars outside of ear to be accessed from classes inside the ear
You can create a shared library in your EE server console, specifying the directory where these jar files are located.
Then, don't forget to bind this shared library to your application, so the classes from these jars could be loaded by your application classloader. There could be a flag like "use an isolated classloader for library", so you can use that option as well.
The implementation of this behaviour is not defined by current Java EE specifications. However, most vendors will provide some way of adding client libraries such as this.
Therefore, you need to look to your vendor's documentation to accomplish this.

Force Java runtime to use Jar in NSF instead of Jar on server of same name for XPages application

I am trying to tackle a persistent ClassNotFoundException. We have an application specific jar that calls a shared commons jar, and uses reflection create an object that we specify in an XML file. This is where it fails.
The application specific jar resides in my NSF. The commons jar resides on the server. I wish to keep the jars in the NSF, because I will be replacing them frequently and don't have access to the server directories, even in Unit.
We put the application jar in the same package as the commons and this didn't help. My suspicion is that the server jar cannot find the application jar. The application jar successfully calls the commons jar, so it is working in that direction.
I tried putting a copy of the commons jar in the NSF, and this didn't help. I think it is still running the server jar first. Jars have same name.
My question is: How do I force the Domino Server runtime to use the application's 'commons' jar instead of the server's 'commons' jar? The thinking being that the local commons jar will find the class of the application jar in the same package, and I can get past this exception.
UPDATE: This process runs when run from a jUnit test, and when a main method is created.
The key is going to be identifying if it's failing because of a security exception or just not finding the jar. If it hits a security exception loading the jar, it just gives that ClassNotFoundException. That can be because it's using the same ClassLoader as the XPpages runtime and was the problem I hit with apache.commons.lang.
If a jar is likely to change regularly and you want it from multiple NSFs, but don't have access to the server, the best option is to create an OSGi plugin (aka Extension Library). This will overcome most security exceptions as well as using a different classloader.
Put it in WebContent\lib, then right-click on it and choose Build Path > Add to Build Path. It will then use a different ClassLoader. See the comments on this blog post http://www.intec.co.uk/how-to-add-in-built-java-packages/. The lib folder is added by default in R9. You do need to add it to the build path, then it jumps into a Referenced Libraries folder.

How to Deploy Java EE Project which reference external JAR files in weblogic

I have a web application which consist of JSP pages, Servlet and Consumes Web Services.
It also references apache axis and excel libraries.
Now I want to deploy my application directly in Weblogic server
How do i do that.Whcih archive shud i make WAR or JAR??
ALso how to ensures that it covers all the referenced libraries.
I have made my application in Jdeveloper, but I dont want to deploy it using Jdevelper..
I would package my solution as a .war file, containing all dependent .jar files.
That way your solution is self-contained. You can deploy to an app server containing other apps with their own versions of your libraries (dependent or developed). If you put the dependent jars directly into the app server (as you can do), then you're forcing those versions on all applications deployed, and that could well cause you grief.
The downside is that your developed .war file can become sizable. It's not normally a major problem, and I wouldn't worry about it until it's identified as an issue.
A JAR-file cannot contain a JAR-file, so that option is out. Since you mention JSPs and servlets a WAR would seem the appropriate option, although an EAR with a WAR and several JARs could also be a way forward...
Cheers,
Consider a WAR with your JAR files in WEB-INF/lib. Or, create an EAR with APP-INF/lib folder.

Tomcat 7 Class Load preference order

I've got the following scenario:
On the one hand, I've got a tomcat instance with a lot of applications that need the activemq-all.jar which contains slf4j libraries, so I've deployed it into the lib directory, it is not optional for me to include this jar file on each app.
On the other hand I need to install a monitor application which I can't control and ships with a different version of slf4j.
Running the last application on another tomcat instance is also not an option.
I would like to configure tomcat's ClassLoader to try and load first the jars on the webapps and then the jars on the lib/ directory.
Is this possible? How can be achieved?
By Default tomcat loads the web app classes first and gives them a higher preference than classes in its own lib directory. You can keep the mentioned jar is the lb folder. Typically i would recommend the catalina_base directory
Load the common jars under the Common class loader. By default, the common class loader looks for jars under:
$CATALINA_BASE/lib
$CATALINA_HOME/lib
Any jars packaged with you web app should take precedence over those found in the Common class loader.

GWT web-app vs system classpath for dynamic loaded classes

In my GWT web app I am keeping all my jar files outside of my project and referencing them using classpath variables. This allows me to link to jars from other projects/teams without having to put a copy of the jar in my web app lib directory. Hosted mode kindly looks up the classes in this system classpath and then adds them to the web-app classpath warning me that it is doing so. When I deploy my build system pulls in only the jars I need to ship in my web app and is not a problem.
The issue I have is that some code uses dynamic lookups, searching the classpath for implementations. If a jar has not yet been added to the web app classpath beacuse no classes have yet benn loaded from the jar it is not included in the search.
The particular problem I am having is with Persistence - it looks up EntityManagerFactory implementations by searching for META-INF/services files. I have also had a similar problem with Rome and its module extensions.
I have got a workaround, in the dev/hosted mode I simply refer to a class I know is in a jar I want and this causes it to be added to my web app classpath. I do this my by calling
private void devModeClassPathHack() {
Class<?> gwtDevModeHack1 = EntityManagerImpl.class;
}
from my development mode Guice module.
My question is simple - is there a "nicer" way of doing this?
I don't think, there's a nicer way - using this makeshift "self-healing" mechanism of the GWT Jetty/dev mode is already a hack :) If you ever have the need to run the server side code on e. g. JBoss during development (together with GWT dev mode for the client side), this will stop working.
(As an additional problem, the order of classloading - and consequently the precedence in cases when there are multiple versions of a class in different jars - will depend on program flow. This can be very nasty to debug.)
You mention, that you pull in all the jars from outside. What I would do in that case, is to set .svnignore (or .gitignore/...) to "*.jar" in the WEB-INF/lib dir. Then I'd run the same build step which is used to create the production build to copy the jars into the lib dir before starting the server.

Categories