开发者

Deployment Concepts: Packaging JAR Dependencies, When & Why

So I'm relatively new to Java EE and I am having a tough time understanding when, where and why Java deployment files are packaged with their dependencies.

Say I build my project into myapp.jar, and it depends on fizz.jar, buzz.jar and JODA (joda-time-2.0.jar).

I've heard that the default classloader doesn't package jars inside of other jars, so I have to assume that if I called a jar task from Ant, then the default classloader would get invoked and myapp.jar would be created without those 3 dependencies in it.

Is this because the mentality is to deploy main-less jars in containers or other systems that will provide its requirements at runtime? If not, then how does myapp.jar ever run correctly?

What about executable jars? To met, these must be different than main-less jars, because they are meant to be standalone units, right? That means they would need all of their dependencies packaged with them, right?

Last but not least, what about jars that depend on jars that depend on jars...etc. (i.e., dependencygraphs that are huge)?

I guess all of these questions can be summed up as follows:

  1. Is the idea behind a non-executable jar that it will be ran in such a way that it will know what classpath(s) to look on for its dependencies at runtime? (And thus doesn't need to be packaged with its dependencies)?
  2. Is the idea behin开发者_高级运维d an executable jar that it is a standalone unit and should be pacakged with its dependencies?
  3. If my assertion to Question #1 above is correct, how does such classpath configuration take place? Are these settings that are stored inside the jar (such as in the manifest)? Else, how would a JRE know where to search for a particular jars dependencies at runtime?

Answers to these questions will actually clarify quite a lot of hangups I have with Java fundamentals, and so any input/help here will be appreciated enormously! Thanks


Jars do not know about other jars (unless assisted by some tools like Maven). The inter dependency of the jars is purely resolved by the Classloaders. I strongly recommend to have some idea about classloaders.

To address your questions,

Is the idea behind a non-executable jar that it will be ran in such a way that it will know what classpath(s) to look on for its dependencies at runtime? (And thus doesn't need to be packaged with its dependencies)?

  • NO. As mentioned, it's the classloader which looks the classpath and the jars mentioned therein. The jars do not have any information about other jars.

Is the idea behind an executable jar that it is a standalone unit and should be packaged with its dependencies?

  • NO. A classloader loads the standalone executable jars at the start of execution. If it needs other dependency jars it'll look into the classpath for those jars.

If my assertion to Question #1 above is correct, how does such classpath configuration take place? Are these settings that are stored inside the jar (such as in the manifest)? Else, how would a JRE know where to search for a particular jars dependencies at runtime?

  • For standalone jar (executable jar), the classloader looks for the classpath variable OR classpath passed while invoking the application.
  • For other type of application (WAR, EAR), There are predefined places/folders where the dependencies should be placed in order to get picked up. This is standardized by specs.

In a nutshell, it's the classloader which is pulling all the threads. There is standard places where it looks for all the dependent jars. This link nicely describes how the classloaders in standalone application and in a deployed (in some container) works.


JAR files are a way to package togher complex java application. Jar application are easy to move between diffrent machines and operating system.

I think the right way to use Jars is not tu put everything (every dependencies) into a single jar.

For example if your application uses a jar libryra (for example jdbc) to access a database you should not put the jdbc jar into your jar.

You had better to build a jar file with only your .class file.

Of course your code needs the jdbc jar to work properly. Here comes to explain how the virtual machine searches for extarnal classes:

-it first searches in the directories that contain the classes that come standard with J2SE (the path depends on your installation)

-it searches in the directories specified by the classpath (a classpath is either an environment variable or an option of the java command)

for example:

java -jar -c /your/path/ yourApp.jar

will run your application and will search th classes your application refers to in the directory /your/path/ so if you have external jars you can put them in that directory.

For detailed documentation: http://download.oracle.com/javase/tutorial/deployment/jar/index.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜