java -jar命令运行jar包时指定外部依赖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来加载
首先介绍下java.ext.dirs参数的使用和环境变量:java中系统属性java.ext.dirs指定的目录由ExtClassLoader加载器加载,如果您的程序没有指定该系统属性(-Djava.ext.dirs=sss/lib)那么该加载器默认加载$JAVA_HOME/lib/ext目录下的所有jar文件。但如果你手动指定系统属性且忘了把$JAVA_HOME/lib/ext路径给加上,那么ExtClassLoader不会去加载$JAVA_HOME/lib/ext下面的jar文件,这意味着你将失去一些功能,例如java自带的加解密算法实现。
在一个小项目中,出于简化需要,没有划分不同的模块,而是视为一个模块,打成一个jar包,通过java -cp 类名的方式进行不同的调用。因为引用的jar包比较多,所以使用了java.ext.dirs进行简化处理。为了保证java自身的ext jar包引用,需要在java.ext.dirs中增加相应路径。命令行如下:
java -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:/project/script/ -cp /project/script/ -Dlog4j.configuration=file:/project/script/log4j.properties com.galaxy.Comments 洛阳 /project/out/
这样,在 /project/script/中的所有jar文件都会自动加入到classpath中,该命令在shell模式中运行正常。
或者你可以把需要加载的jar都扔到%JRE_HOME%/lib/ext下面,这个目录下的jar包会在Bootstrap Classloader工作完后由Extension Classloader来加载。非常方便,非常省心。:)
java -cp命令介绍
java -cp .;c:\dir1\lib.jar Test
-cp和-classpath 一样,是指定类运行所依赖其他类的路径,通常是类库,jar包之类,需要全路径到jar包,window上";"分隔,linux上是":"分隔。不支持通配符,需要列出所有jar包,用"."代表当前路径。虽然现在都有eclipse之类的IDE了,但有时候后会手工编译和运行一些程序,很多人包括多年开发经验的人都不知道怎么在命令行参数运行类。
使用范例:
java -cp ..\lib\hsqldb.jar org.hsqldb.Server -database mydb 或
java -cp ../lib/hsqldb.jar org.hsqldb.Server -database.0 mydb -dbname.0 mydb
java -jar minusyhd.jar
Manifest-Version: 1.0
Main-Class: minusyhd.MinusYHD
Class-Path: jconn4.jar
-cp 参数后面是类路径,是指定给解释器到哪里找到你的.class文件, 写法:
java -cp .;myClass.jar packname.mainclassname
classpath中的jar文件能使用通配符,如果是多个jar文件,要一个一个地罗列出来,从某种意义上说jar文件也就是路径。
要指定各个JAR文件具体的存放路径,相同路径有多个可使用通配符
java -cp .;c:\classes\myClass.jar;d:\classes\*.jar packname.mainclassname
bat文件写法:
java -cp MinusYHD.jar minusyhd.MinusYHD > minusyhed.log
exit
注:"> minusyhed.log" 指定System.out输出文件名
方法三、还是用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
总结:
以上四种方法都可以用,特别是程序运行在非常单纯的环境中时。但是,如果是运行在多任务,多应用的环境中时,最好每个应用都能相互独立,第一种和第二种方案都有可能对其他应用产生影响,因此最好就是选择第三种和第四种。
参考:
java命令执行jar包的方式
java -cp 命令介绍
jar命令图解
java -jar命令运行jar包时指定外部依赖jar包相关推荐
- 通过命令运行jar包(指定外部依赖jar包)
前提条件: 1.本机已安装jdk 2.已配好jdk的环境变量 通过以下命令查询jdk是否配好 java -version 执行出现java版本信息即配好 lizhi@LiZhideMacBook-Ai ...
- MR作业提交时指定第三方依赖jar
为什么80%的码农都做不了架构师?>>> 前言 在提交MR作业时,如何将第三方依赖的jar追加运行环境 解决方法 首先构建一个项目基本架构,包括bin.lib等文件夹,,如下: ...
- Java中通过命令行启动jar包时指定编码
场景 Java中运行jar包的命令是 java -jar badao.jar 但是在Windows中通过这种方式运行jar包的话,会因为中文乱码的问题导致 Jar包运行异常. 注: 博客: https ...
- 运行jar包时指定prod时报异常
1 问题 运行jar包时指定prod时报异常,异常如下: PS D:\Workspace\ZJ\dataPlatform\dataPlatform-api\target> java -jar . ...
- java 运行jar包命令_用java –jar 命令运行Jar包
摘要 这个技巧阐明了如何不直接处理清单文件而将一个不能运行jar包转换成一个可以执行的jar包.学会如何写一段转换jar包的程序,将你的jar包转换成你能使用java -jar 命令运行jar包或象在 ...
- java -jar 运行jar包_用java –jar 命令运行Jar包
用java –jar 命令运行Jar包 摘要 这个技巧阐明了如何不直接处理清单文件而将一个不能运行jar包转换成一个可以执行的jar包.学会如何写一段转换jar包的程序,将你的jar包转换成你能使用j ...
- 用java –jar 命令运行Jar包
摘要 这个技巧阐明了如何不直接处理清单文件而将一个不能运行jar包转换成一个可以执行的jar包.学会如何写一段转换jar包的程序,将你的jar包转换成你能使用java -jar 命令运行jar包或象在 ...
- Dockerfile中通过ENV指定动态参数在RUN时传递参数(部署后台jar包时指定端口为例)
场景 CentOS7中使用Dockerfile部署后台jar包: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/119818808 ...
- maven打jar包,并将依赖jar打入外部lib文件中
在pom.xml中加入如下配置,在mainClass里写程序的入口方法 <!-- maven打jar包,并将依赖jar打入外部lib文件中 --> <plugins> < ...
最新文章
- python数组转换为列表_python - 将一系列数组转换为单个列表 - SO中文参考 - www.soinside.com...
- 解决 Successfully created project '' on GitHub, but initial push failed: Could not read from remote re
- VS11在Win8上的Metro应用
- 微软发布 Visual Studio 2019年第二季度路线图
- [Noip2018]旅行
- 您真的理解了SQLSERVER的日志链了吗?
- 【xcode 插件】快速插件安装
- Dart基础第2篇:变量、常量、命名规则、入口方法的两种定义方式
- MySQL破log_MySQL中的binlog相关命令和恢复技巧
- linux网络线序MDI,网线RJ45(水晶头)线序排列以及八字口诀
- 2020年全国大学生数学建模竞赛辽宁赛区获奖名单(本科组)
- easywechat 网页授权登录
- 工厂食堂3D指纹考勤系统解决方案
- 海湾gst5000协议号_海湾GST5000主机基本操作
- 计算机在当今社会的重要性
- Google学术映像
- Supervisor(四)
- 游戏图形测试软件,今日共有3款免费测试网络游戏(组图)
- Mysql密码修改方式
- 超详细的AD8031ARZ介绍,就在这里
热门文章
- 《计算机网络技术》第一章课后习题答案(全)
- 使用STM32f103点亮led灯——库函数版本
- Flutter: 弹性布局Flex(Expanded)、流式布局Wrap、Flow
- Review Troller
- WLAN领域AP集群化的关键 CAPWAP协议
- 亚马逊英国站产品审核要求英国代理人英代办理英国授权代表英代DOC符合性声明
- Vue+element ui表单中省市区级联选择—v-distpicker/Cascader
- 中鑫优配热点前瞻:循环经济+降解塑料+甲酸概念+高铁轨交
- 股票、期货、期权的差异
- iOS 播放gif图片