java打包成jar,并执行jar

  • Post author:
  • Post category:java


java打包成jar

1. 没有导入第三方包打包

a. 在Eclipse中打开项目, 右键点击项目,选择“Export”

b. 选择Java/JAR file

c. Select the resources to export中可以选择你想要包含的项目文件夹,一些不必要的文件夹就无需放进去了,免得增大空间;

这里有几个选项:

* Export generated class files and resources 表示只导出生成的.class文件和其他资源文件

* Export all output folders for checked projects 表示导出选中项目的所有文件夹

* Export java source file and resouces 表示导出的jar包中将包含你的源代码*.java,如果你不想泄漏源代码,那么就不要选这项了

* Export refactorings for checked projects 把一些重构的信息文件也包含进去

在Select the export destination中选择导出的jar的路径,Next

d.下一页可以选择是否导出那些含有警告warning或者错误errors的*.class文件。一般不用理他,Next

e.下一个页面里可以对项目做一些配置。(如果项目没有引入第三方jar包,这项我们采用系统默认的选项就OK,Main class一定要设置成为你项目的那个主方法入口类)

* Generate the manifest file是系统帮我们自动生成MANIFEST.MF文件,如果你的项目没有引用其他class-path,那可以选择这一项。

* Use existing mainfest from workspace。这是可以选择我们自定义的.MF文件,格式如上所写。

* Seal content。要封装整个jar或者指定的包packet

* Main class。这里可以选择你的程序入口,将来打包出来的jar就是你这个入口类的执行结果。

最后Finish,搞定

2.有导入第三方包的打包

前面的4步和上面的情况是一样,只是第5步需要选择Use existing mainfest from workspace选项,并选择你自己创建的一个MANIFEST.MF文件,因为系统默认选择的是Generate the manifest file选项,而该选项不会将项目用到得第三方jar包打入到java项目生成的jar包中去。

自定义配置文件MANIFEST.MF :

首先在项目的根目录下创建一个MANIFEST.MF文件

接下来用记事本打开该文件,并编辑:

例如:

Manifest-Version: 1.0

Main-Class: com.xx.xx

Class-Path: xxxx.jar

其中的Manifest-Version是指程序的版本号,Main-Class是指程序的主方法入口类,slass-Path就指定了外来jar包的位置。请注意假设我们的项目打包后为project.jar,那么按照上面的定义,应该在 project.jar的同层目录下有相关的jar包(即a.jar,如果有引入多个第三方jar包,则可以用空格隔开)放在里面。否则将会出现Exception in thread “main” java.lang.NoClassDefFoundError的错误。

3.打成可执行的jar

a 在要打包的项目上右击,选择Export。

b 在弹出的窗口中,选择Java -> Runnable JAR File,然后点击next按钮。

c 在Runnable JAR File Specification窗口中,选择Launch configuration和Export destination。

d 点击Finish按钮,打包完成

执行jar方法

大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个jar包的程序入口。

具体的方法是修改jar包内目录META-INF下的MANIFEST.MF文件。

比如有个叫做test.jar的jar包,里面有一个拥有main函数的main class:test.someClassName

我们就只要在MANIFEST.MF里面添加如下一句话:

Main-Class: test.someClassName

java -jar test.jar 即可以运行这个jar。

但是我们这个项目需要引用其他第三方的jar包,在eclipse里面以项目jar包的形式引用了这个叫做some.jar的包,当时放在项目的lib子目录下,最后项目打包时把这个some.jar也打进来了,但是用java -jar执行这个test.jar的时候报找不到Class异常,原因就是jar引用不到放在自己内部的jar包。

那怎么办?

失败的结果:

运行时将其加入classpath的方式行不行?就是在运行jar的同时加入classpath参数:

java -classpath some.jar -jar test.jar

这种方式是不行的,因为使用classpath指定的jar是由AppClassloader来加载,java 命令 加了-jar 参数以后,AppClassloader就只关注test.jar范围内的class了,classpath参数失效。

那该怎么引用其他的jar包呢?

方法一、使用Bootstrap Classloader来加载这些类

我们可以在运行时使用如下参数:

-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

总结:

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



版权声明:本文为lsblsb原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。