Single jar vs Multiple jars - performance benefits - java

I have an application which is deployed into Jetty but is not packaged into single war file. Contrary, it is stored as a folder. There are quite a lot of dependencies in war/WEB-INF/lib folder which I am thinking of merging into one jar.
Are there any performance benefits that I would get by doing so?

It does not matter. I do not know about jetty but all other servers I know extract archives anyway, i.e. store war/ear files in temporary directory in extracted form.

#markovuksanovic: performance should not really matter or very insignificant.
Jar file is meant for archiving set of meaningful collection of classes and resources...that is all...

Related

Java files in a jar file

Is there a technical reason for not having the source java files in the jar file? I came across a service jar that had both the class jars and the source java files in the same jar. Typical third-party libraries will bundle these different types of files into separate jars. The binary is necessary for execution and the src.jar file is useful to debug using the exact code that the class files were built with.
To me the reasoning is: it slows down server startup because the additional files need to be decompressed and perhaps indexed. Are there any other reasons I can use to advocate for abandoning this one-off build process?
Please do not respond that jar files are essentially zip files and anything goes, I am looking for technical reasons during runtime to avoid this situation. BTW the services using these JARs have been working for a long time, so it is not manifesting any actual perceived defects.
It shouldn't cause any problems to have source files in the JAR with the binary class files. The main reason to keep them separate is to avoid making JARs bigger than necessary for runtime deployment. As far as I know, the convention of distributing a -sources JAR file for open source libraries originated with Maven, which will produce artifacts in this way by default.

Is it possible to store all jars in Tomcat lib folder?

We have a few projects and we store libs in project  folders (each project has it’s own libs)  and we store shared libs in tomcat lib folder:
·Project1\lib
·Project2\lib
·…
·Tomcat\lib
Our manager proposed to combine all libs and put all jars in Tomcat lib folder.
Advantages of this approach are the following:
It will decrease compile time to .war file
It will decrease size of .war file
I feel that this decision is not the best one the but I can’t prove it. Is there any disadvantages of this approach?
The resultant .war application file is less portable. Additional installation steps since the webapp is no longer self-contained.
Or to argue against your boss' logic.
Compiling should be automated in continuous integration, so time spent is not real person time
Space is cheap
Don't consolidate. Consolidation will prevent different projects from using different versions of a particular 3rd party library. This is why different webapps are isolated from each other.
Some libraries also store things statically (sigh), which can cause cross-webapp pollution.

what is the difference between simple project/lib and project/web/WEB-INF/lib?

what is the difference between simple project/lib and project/web/WEB-INF/lib?
which jar should be in project/lib folder and which jars should be in web/WEB-INF/lib?
there is no standard project/lib thing, it might be a specific project designed that way to hold library there and while compiling and deploying it might be configured to read jars from there,
where as if you put it in WEB-INF/lib web contains puts all the jars from this directory in runtime classpath so they would be available when application is running
better to use maven without needing to holding library in source control and with lots of other advantages maven brings

What is a good deployment directory structure for java console apps

I have a Java console application that I am ready to deploy onto a Unix server. I am writing a shell script to run the application.
I plan to put my shell scripts in one folder, my application jar and dependent jars (spring, etc.) into a different folder and properties files (those that need to be maintained 'live') in a separate folder again. I would then have my shell script iterate through the files in the 'jars' and 'properties' folders, appending them to the classpath, before finally calling java ...
Is this a 'good' deployment structure? Are there any guidelines for how to arrange files to maximise maintainability and stability? Are there obvious 'wrong' ways to do this that are best avoided?
I should add that, for a previous project, I put all shell scripts (those that start java processes and those that don't) into a scripts folder, my application jar into a folder with the library jars in a library subfolder and external resources into a config subfolder. I then wrote a script that explicitly loads all the files. It was long winded to write and needs to be maintained whenever I upgrade a library jar. This time around I'd like to do it better. Also, it feels unnecessary to separate my application JAR from the libraries.
For what it's worth, this is what we use;
/
/class
//package hierarchy here, raw .class files
/lib
//library jars here, apache commons, gson etc, all .jars
/conf
//.properties files go here, including ones for libraries
/doc
//program documentation files, typically .txt
/javadocs
//java doc html root
/sh
//shell scripts including execute.sh and compile.sh
We use ant for building, often have a src folder for the source tree if necessary. This way you just add /class and /lib to your classpath, and that never changes.
Good structure for your case is so called uberJar or oneJar, that can be made with number of utils, just google it. Also I can recommend such a nice piece of code as http://www.jdotsoft.com/JarClassLoader.php
Frankly, if it is just a small app, I would put it all under /opt/<my_java_app> and have a directory substructure there just like you did in dev.
If you want to be more compliant with the UNIX recommended practices, then put your executable (including your jar) in /usr/local/bin/<my_java_app>, config files in /etc/<my_java_app>, log files and other data files in /var/<my_java_app>.
Also, you may want to refer to this document.
Build a system-native package, and use system defaults. If using Debian, create a .deb direct from your build system (for instance, using ant deb task). If using rpms, use the rpm task. That way you can easily deploy, undeploy and update the application just like any other one.
The system package should separate libraries (I use /usr/share/java/AppName for my jars) and configuration (to /etc/AppName or /home/UserName/.AppName); the launch-scripts I symlink to /usr/bin. Beyond that, there is no great complication getting things to work. I recommend finding well-known java-based packages in your distribution and copying their launch scripts (in particular, their VM-locating magic).

How to use common libraries for multiple Java web project

I am having four different project, and i am using Weblogic to deploy my projects. There are several libraries ( jar files ) which are common for all projects. Currently each of my project are having lib directory and have almost same set of libraries. Now, is it possible to have this lib directory outside WAR files and access them.
Resist the temptation of putting the jar files in the "shared" folder of your container. It is better to keep the jar files where they are now. It may sound a good idea to use a shared folder now, but in the future you may need to deploy an application that requires a shared library, but a different version.
That being said, I have no experience with WebLogic. In Tomcat there is a shared folder with libraries common for all deployed applications. It is not a good idea to use this. If WebLogic can be configured to use a shared folder per a set of applications (and not for all deployed applications) you could go for it.
Do you want to do this ? Unless you're stuck for deployment space, I would (perhaps) advise against it.
Why ? At the moment you have 4 solutions running off these libs. If you have to upgrade one of the libs (say, if you discover a bug, or if you require a new feature), then you're going to have to test compatibility and functionality for all 4 solutions. If each solution has its own set of libs, then they're sandboxed and you don't have to move all 4 in step.
Note that all this hinges on how easy it is to regression-test your solutions. You may find it easy, in which case using the same set of libs is feasible.
Don't do that.
The whole idea of WAR files is that they are self-contained units. This makes deployment so much easier.
In addition to the possible version conflicts that others have pointed out, putting jar files in /shared can have very nested consequences for class visibility. They will be on a separate classloader, and be unable to see the classes in the WAR file. If you use libraries that rely on Class.forName() to work (and there are plenty), this could get very painful.
If you really, really cannot afford the extra disk space and memory look at OSGi or Spring DM. They have solved this problem, but at the price of increased complexity.
Put all the shared jar files under common\lib folder of weblogic. common\lib is accessible by all the deployed apps.
Well first of all you can put your libs all on the same place and have your build process import the ones needed.
Has for on deploy the new Weblogic 10 has a lib folder in each domain where you can put shared libs. i dont think that is possible before Weblogic 10
You can put the jars in their own ear file and deploy it as a shared library.
You can also put the wars in an ear and add the shared jars to APP-INF/lib. This is a Weblogic extension of J2EE, so it won't work on other servers.
I'm currently using another approach.
Create a central repository folder and put all common libraries in there.
In each project you can create a reference to all needed libraries. In Subversion it works with externals
Everytime, the local working copy is updated, the externals are updated to, so you just need to commit to the central folder and it's automatically distributed to all projects.

Categories