How the java command executes the jar package

Reprinted from: http://www.cnblogs.com/adolfmc/archive/2012/10/07/2713562.html

We all know that a java application project can be packaged into a jar , of course, you must specify a main class with a main function as the program entry of your jar package.

 

The specific method is to modify the MANIFEST.MF file under the META-INF directory in the jar package.

 

For example, there is a jar package called test.jar , which contains a main class with a main function: test.someClassName

We only need to add the following sentence in MANIFEST.MF:

Main-Class: test.someClassName

 

Then we can run the jar by typing java  - jar  test.jar in the console .

 

But our project needs to reference other third-party jar packages. In eclipse, the package called some.jar is referenced in the form of a project jar package. It was placed in the lib subdirectory of the project at that time. Finally, when the project was packaged, this some. The jar is also called in, but when the test.jar is executed with java - jar  , it reports that the Class cannot be found, because the jar cannot reference the jar package placed in itself.

 

What to do then?

 

Is it okay to add it to the classpath at runtime? It is to add the classpath parameter while running the jar :

java -classpath some.jar -jar test.jar

 

This method does not work, because the jar specified by the classpath is loaded by the AppClassloader. After adding the -jar parameter to the java  command  , the AppClassloader only pays attention to the classes within the scope of test.jar, and the classpath parameter is invalid .

 

How to reference other jar packages?

 

Method 1. Use Bootstrap Classloader to load these classes

 

We can use the following parameters at runtime:

 

 

-Xbootclasspath:完全取代系统Java classpath.最好不用。
-Xbootclasspath/a: 在系统class加载后加载。一般用这个。
-Xbootclasspath/p: 在系统class加载前加载,注意使用,和系统类冲突就不好了.

win32 java -Xbootclasspath/a: some.jar;some2.jar; -jar test.jar
unix    java -Xbootclasspath/a: some.jar:some2.jar: -jar test.jar
win32系统每个jar用分号隔开,unix系统下用冒号隔开

 

 

 

方法二、使用Extension Classloader来加载

 

你可以把需要加载的jar都扔到%JRE_HOME%/lib/ext下面,这个目录下的jar包会在Bootstrap Classloader工作完后由Extension Classloader来加载。非常方便,非常省心。:)

 

 

 

方法三、还是用AppClassloader来加载,不过不需要classpath参数了

 

我们在MANIFEST.MF中添加如下代码:

Class-Path: lib/some.jar

 

lib是和test.jar同目录的一个子目录,test.jar要引用的some.jar包就在这里面。

然后测试运行,一切正常!

 

如果有多个jar包需要引用的情况:

Class-Path: lib/some.jar lib/some2.jar

每个单独的jar用空格隔开就可以了。注意使用相对路径。

 

另:如果META-INF 下包含INDEX.LIST文件的话,可能会使Class-Path配置失效。INDEX.LIST是Jar打包工具打包时生成的索引文件,删除对运行不产生影响。

 

 

方法四、自定义Classloader来加载

这种方法是终极解决方案,基本上那些知名java应用都是那么干的,如tomcat、jboss等等。

这种方式有点复杂,需要专门开贴讨论。关于ClassLoader的原理和自定义ClassLoader可以参考这篇http://cuixiaodong214.blog.163.com/blog/static/951639820099135859761

 

总结:

以上四种方法都可以用,特别是程序运行在非常单纯的环境中时。但是,如果是运行在多任务,多应用的环境中时,最好每个应用都能相互独立,第一种和第二种方案都有可能对其他应用产生影响,因此最好就是选择第三种和第四种。

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326940368&siteId=291194637