你是否在使用java -jar参数运行打包好的jar应用程序的时候发现应用程序无法找到classpath下设置好的第三方类库的内容?无论怎么设置classpath参数都无济于事,总是会报ClassNotFound的错误?那么本篇帖子可以帮助你摆脱烦恼 :)
当
用java -jar
yourJarExe.jar来运行一个经过打包的应用程序的时候,你会发现如何设置-classpath参数应用程序都找不到相应的第三方类,报
ClassNotFound错误。实际上这是由于当使用-jar参数运行的时候,java
VM会屏蔽所有的外部classpath,而只以本身yourJarExe.jar的内部class作为类的寻找范围。
**解决方案**
一 BootStrap class扩展方案
Java 命令行提供了如何扩展bootStrap 级别class的简单方法.
-Xbootclasspath: 完全取代基本核心的Java class 搜索路径.
不常用,否则要重新写所有Java 核心class
-Xbootclasspath/a: 后缀在核心class搜索路径后面.常用!!
-Xbootclasspath/p: 前缀在核心class搜索路径前面.不常用,避免
引起不必要的冲突.
语法如下:
(分隔符与classpath参数类似,unix使用:号,windows使用;号,这里以unix为例)
java -Xbootclasspath/a:/usrhome/thirdlib.jar: -jar yourJarExe.jar
二 extend class 扩展方案
Java exten class 存放在{Java_home}\jre\lib\ext目录下.当调用Java时,对扩展class路径的搜索是自动的.总会搜索的.这样,解决的方案就很简单了,将所有要使用的第三方的jar包都复制到ext 目录下.
三 User class扩展方案
当使用-jar执行可执行Jar包时,JVM将Jar包所在目录设置为codebase目录,所有的class搜索都在这个目录下开始.所以如果使用了其他第三方的jar包,一个比较可以接受的可配置方案,就是利用jar包的Manifest扩展机制.
步骤如下:
1.将需要的第三方的jar包,复制在同可执行jar所在的目录或某个子目录下. 比如:jar 包在 /usrhome/yourJarExe.jar 那么你可以把所有jar包复制到/usrhome目录下或/usrhome/lib 等类似的子目录下.
2.修改Manifest 文件
在Manifest.mf文件里加入如下行
Class-Path:classes12.jar lib/thirdlib.jar
Class-Path 是可执行jar包运行依赖的关键词.详细内容可以参考 http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html
。要注意的是 Class-Path
只是作为你本地机器的CLASSPATH环境变量的一个缩写,也就是说用这个前缀表示在你的jar包执行机器上所有的CLASSPATH目录下寻找相应的
第三方类/类库。你并不能通过 Class-Path
来加载位于你本身的jar包里面(或者网络上)的jar文件。因为从理论上来讲,你的jar发布包不应该再去包含其他的第三方类库(而应该通过使用说明来
提醒用户去获取相应的支持类库)。如果由于特殊需要必须把其他的第三方类库(jar, zip,
class等)直接打包在你自己的jar包里面一起发布,你就必须通过实现自定义的ClassLoader来按照自己的意图加载这些第三方类库。
以上三种方法推荐第一种,扩展性好,操作起来也最方便.
另外编写自己的ClassLoader,来动态载入class,是更加复杂和高级技术.限于篇幅,不赘述.有兴趣了解可以去google一下custom classloader,或者参考我的另一篇日志:让classpath参数走开。
Java的安全机制随不同的JDK版本有不同的变化,会影响很多核心CLASS,比如Thread,所以很多大型商业软件,要求JDK的版本很严格.部分原因也在此.这也要求在发布自己编写的应用时候,不管大小,都要说明开发和测试的JDK版本.
本文所述方法测试基于j2sdk 1.4.2_04-b05
----------------------------------------------------------------------------------------------
附:背景知识
自JDK 1.2以后,JVM采用了委托(delegate)模式来载入class.采用这种设计的原因可以参考http://java.sun.com/docs/books/tutorial/ext/basics/load.html
归纳来讲:是基于JVM sandbox(沙盒)安装模型上提供应用层的可定制的安全机制.
Java虚拟机(JVM)寻找Class的顺序
1. Bootstrap classes
属于Java 平台核心的class,比如java.lang.String等.及rt.jar等重要的核心级别的class.这是由JVM Bootstrap class loader来载入的.一般是放置在{java_home}\jre\lib目录下
2. Extension classes
基于Java扩展机制,用来扩展Java核心功能模块.比如Java串口通讯模块comm.jar.一般放置在{Java_home}\jre\lib\ext目录下
3. User classes
开发人员或其他第三方开发的Java程序包.通过命令行的-classpath或-cp,或者通过设置CLASSPATH环境变量来引用.JVM通
过放置在{java_home}\lib\tools.jar来寻找和调用用户级的class.常用的javac也是通过调用tools.jar来寻找用
户指定的路径来编译Java源程序.这样就引出了User class路径搜索的顺序或优先级别的问题.
3.1 缺省值:调用Java或javawa的当前路径(.),是开发的class所存在的当前目录
3.2 CLASSPATH环境变量设置的路径.如果设置了CLASSPATH,则CLASSPATH的值会覆盖缺省值
3.3 执行Java的命令行-classpath或-cp的值,如果制定了这两个命令行参数之一,它的值会覆盖环境变量CLASSPATH的值
3.4
-jar 选项:如果通过java -jar 来运行一个可执行的jar包,这当前jar包会覆盖上面所有的值.换句话说,-jar
后面所跟的jar包的优先级别最高,如果指定了-jar选项,所有环境变量和命令行制定的搜索路径都将被忽略.JVM
APPClassloader将只会以jar包为搜索范围.
有关可执行jar有许多相关的安全方面的描述,可以参考http://java.sun.com/docs/books/tutorial/jar/
来全面了解.
这也是为什么应用程序打包成可执行的jar包后,不管你怎么设置classpath都不能引用到第三方jar包的东西了.
最后,还有一种重要的方法执行jar的语句:
即:
java -classpath aaa.jar:bbb.jar:ccc.jar net.kentop.Hello
即是将所有的包都加进classpath 再指定主方法,如果有配置文件时,可以这样加入
java -classpath aaa.jar:bbb.jar:ccc.jar net.kentop.Hello /opt/predial.conf
分享到:
相关推荐
MySQL Connector/J 8.0.30 是 MySQL 官方提供的用于 Java 应用程序的数据库驱动程序,它实现了 JDBC(Java Database Connectivity)规范,使得 Java 开发人员能够方便地在 MySQL 数据库上进行数据操作。这篇内容将...
Java打包技术是将Java应用程序和必要的运行环境(如JDK)整合到一起,使得用户无需安装额外的Java环境即可运行程序。在Java开发过程中,为了方便分发和部署,我们通常会将应用及其依赖打包成一个可执行的格式,比如...
Java开发工具包(Java Development Kit,简称JDK)是用于编写Java程序的必备软件包,它包含Java编译器、Java运行环境(JRE)、Java类库和其他开发工具。在这个"JAVA 环境安装包 jdk-jar-8u261-windows-x64.zip"中,...
使用 JAR 文件时,需要设置 classpath 路径,以便 Java 虚拟机可以找到 JAR 文件中的类文件。例如: ``` set classpath=./util.jar ``` 其中 `./util.jar` 是要使用的 JAR 文件的路径。 JAR 包的注意事项 1. 在...
本压缩包中的"泛微E-cology 二次开发JAVA jar包",重点在于"jar"文件,这是一种Java平台下的可执行文件格式,用于打包类库、资源文件等,便于Java程序调用。E8版本表示这是泛微E-cology的一个特定版本,可能包含了...
7. 输入 Java 最小 Jre 版本号,即低于这个版本的 Jre 无法运行该程序,接着点击“Advanced Options”-“Search sequence”,设置一下我们的 JRE。 8. 点击绿色“+”来选择捆绑的 JRE 位置,在弹出对话框中选择...
Java开发中的JAR(Java Archive)文件是Java平台特有的归档格式,用于打包类库、资源文件和其他相关组件。在Java应用程序或Web应用中,JAR文件常常被用来减少网络传输的数据量,提高加载速度,并方便代码管理。下面...
例如,在使用第三方jar包时,需要将其添加到classpath中,以便于Java应用程序可以正确引用。 在本文中,我们使用了一个名为`lib`的文件夹来存储第三方jar包,并将其添加到classpath中。 总结 本文详细介绍了如何...
使用java -jar命令可以运行包含MANIFEST.MF的JAR文件,Java虚拟机会自动找到指定的主类并执行。如果JAR包依赖于其他库,可以在命令行通过-classpath或-cp参数指定。 5. **依赖管理** 如果JAR包依赖于其他库(如...
`fatjar`是一款用于合并Java类库和应用程序主类的工具,它能将所有的类文件、资源文件以及第三方库打包成一个独立的JAR文件,这样用户就不需要额外安装JRE(Java Runtime Environment)就能运行程序。`fatjar`通过...
Java 1.6 Jar包是Java开发中的一个重要组成部分,它是一种归档文件格式,用于集合Java类、资源文件以及元数据,便于分发和运行Java应用程序。在Java平台中,jar(Java Archive)文件扮演着类库的角色,包含了多个类...
* Class-Path 指定了依赖的第三方类库。 Step 2:将项目打包成 EXE 首先,在任意目录创建一个文件夹,命名和项目名相同。在这个文件夹中,拷贝所有的资源文件以及生成的可执行 JAR 文件。然后,打开 exe4j,选择...
`lib`中的`jar`(Java Archive)文件是Java类库的集合,包含了编译后的`.class`文件,这些文件是Java应用程序或库运行的基础。`jar`文件的使用极大地简化了代码的分发和管理,因为它们可以作为一个单独的单元进行...
在开发过程中,有时候我们需要将 Java 项目转换为 Windows 下的可执行文件(EXE 文件),这主要是为了提高程序的用户友好度,同时也方便那些没有安装 Java 运行环境(JRE)的用户直接运行应用程序。本文将详细介绍...
Java开发工具中的`rt.jar`是一个非常重要的组件,它包含了Java运行时环境(JRE)的核心类库。这个文件是Java标准版(Java SE)的一部分,提供了Java平台的基础API,使得开发者可以编写出能在Java虚拟机(JVM)上运行...
如果Java程序被打包成一个JAR文件,并且该JAR文件包含了一个主类(即在MANIFEST.MF文件中定义了`Main-Class`),则可以直接使用 `-jar` 选项启动。例如: ``` java -jar hello-world.jar ``` 这种方式是最常见的部署...
### 如何安装Java JDK及正确设置...正确配置`CLASSPATH`对于Java应用程序来说至关重要,特别是当程序依赖于外部类库时。遵循上述步骤可以帮助开发者成功安装JDK并正确配置环境变量,从而实现Java程序的顺利运行。
在IT行业中,jar(Java Archive)包是一种广泛使用的文件格式,主要用于封装Java类库,使得开发者可以将多个类文件、资源文件以及元数据打包在一起,便于分发和部署。本话题将聚焦于“jar包所在文件夹”,并讨论其中...
**标题解析:**"jsp-api.jar" 是Java服务器页面(JSP)的API库,它包含了一组类和接口,使得开发者能够在Java Web应用程序中创建动态网页。这个jar包是Tomcat服务器的一部分,版本为9.0.58,表明它是针对Tomcat 9的...