1

i have a few batch java command-line applications which are planned to be deployed as:

batch_apps
  app_1
    batch1.jar
    run_batch1.sh
  app_2
    batch2.jar
    run_batch3.sh
{...etc...}

what would be the best practice on organizing a shared library pool - for example log4j:

batch_apps
  app_1
    batch1.jar
    run_batch1.sh
  app_2
    batch2.jar
    run_batch3.sh
  libs
    log4j.jar
    ojdbc.jar

?

and include individual log4j.xml's in each app's own jar file? i understand i would need to add 'libs' to the classpath either in manifests or in run_batchX.sh (which way is preferable?)

I am mostly wondering what would be the most efficient setup performance-wise.

thanks

webwesen
  • 1,242
  • 4
  • 17
  • 30
  • Why "performance-wise"? What do your applications do that you worry about performance consequences of libraries' location?! Most of the time I wouldn't even bother to setup a shared location: this simplifies upgrades, but what if an upgrade forced by one application breaks another? – Jacek Szymański Apr 03 '09 at 19:31
  • i guess i just lack knowledge on how multiple JVM's read shared libs. as for why shared - i am handling jars of 20-30MB with 25MB of those being libraries, so I am wondering if I move them to the root - i will definitely have less time to spend on ftp'ing stuff around. but what are the trade-offs? – webwesen Apr 03 '09 at 19:51
  • Every JVM reads for itself. As for ftping, if you don't make a shared dir, you can easily write deployment scripts to upload libraries with the app itself so if you're not transferring over a very slow connection, I don't think you should bother. – Jacek Szymański Apr 03 '09 at 20:44
  • Of course you can write scripts for the shared dir version as well, but it's in fact harder to maintain: for every library version change you need to test not only whether this new version is good with the app it is to be used for but also with all other. – Jacek Szymański Apr 03 '09 at 20:46

4 Answers4

2

Having a shared libs directory at the root of your install dir is definitely the way to go. Since libs will be loaded in memory once, when the JVM launches, there is no impact on performance whatever solution you choose.

I would not put the classpath in the jar files, as this would force you to change your jars if you need to relocate your lib dir. Editing a script is much simpler.

I would not include the log4j conf file in your jar files either, for the same reason.

Varkhan
  • 16,601
  • 5
  • 31
  • 24
  • i decided to go this route. it is closer to my understanding of code re-use and clean overall project setup. – webwesen May 14 '09 at 18:55
1

It appears your applications don't share a single JVM instance. (i.e. They are individually started via 'java -jar batch1.jar' or some such.) Therefore, sharing library .jar files only saves you DISK space not RAM.

If the apps are not sharing a single JVM then ease-of-deployment should take precedence over disk space. (Your time is worth more than a few "wasted" MB.)

In this instance I would recommend making each application self contained, in either a single .jar file including all its libraries, or a single folder of .jar files. (i.e. Put the libs for each app in a folder for that app.)

If the apps were sharing a single JVM then I would recommend the shared library folder option.

Chris Nava
  • 6,614
  • 3
  • 25
  • 31
0

This doesn't directly answer your question, but I have already tried the approach that you propose but would now create a single jar per application (see how to do it with Ant). That way, no need to include anything in the classpath:

java -jar myApp.jar

is all you need. I find it cleaner but everything is debatable.

It doesn't make any difference from a performance point-of-view since each application is run inside its own JVM.

The only downside is that some libraries will be present in each jar file. It only costs more to store on the HD, but these days, MB are pretty cheap :-) I trade simplicity (no external lib folder) and no jar hell (not placing your jars inside the Java ext folder) over storage price any time. If your application doesn't include terrabyte of libraries, I think it's fine.

For the Log4j configuration file, I would place one default file inside the jar but provide a sample config file (log4j-custom.xml.sample) that someone can modify and specify in the command line:

java -Dlog4j.configuration=log4j-custom.xml -jar myApp.jar
Community
  • 1
  • 1
Vladimir
  • 6,853
  • 2
  • 26
  • 25
0

You can use the java extension mechanism. Place them in JAVA_HOME/lib/ext and they will be accessible by all apps. Of course, this may not be the best for all deployments, but its certainly easier.

John Ellinwood
  • 14,291
  • 7
  • 38
  • 48